Commit 2730f0af authored by Linus Torvalds's avatar Linus Torvalds

Import 2.1.45pre2

parent 0d1267fe
...@@ -107,7 +107,9 @@ S: USA ...@@ -107,7 +107,9 @@ S: USA
N: Randolph Bentson N: Randolph Bentson
E: bentson@grieg.seaslug.org E: bentson@grieg.seaslug.org
D: author of driver for Cyclades Cyclom-Y async mux D: author of driver for Cyclom-Y and Cyclades-Z async mux
P: 1024/39ED5729 5C A8 7A F4 B2 7A D1 3E B5 3B 81 CF 47 30 11 71
W: http://www.aa.net/~bentson/
S: 2322 37th Ave SW S: 2322 37th Ave SW
S: Seattle, Washington 98126-2010 S: Seattle, Washington 98126-2010
S: USA S: USA
...@@ -793,6 +795,12 @@ S: Schlehenweg 9 ...@@ -793,6 +795,12 @@ S: Schlehenweg 9
S: D-91080 Uttenreuth S: D-91080 Uttenreuth
S: Germany S: Germany
N: Jaroslav Kysela
E: perex@jcu.cz
D: Original Author and Maintainer for HP 10/100 Mbit Network Adapters
W: http://www.pf.jcu.cz/~perex
S: Unix Centre of Pedagogical Faculty, University of South Bohemia
N: Bas Laarhoven N: Bas Laarhoven
E: bas@vimec.nl E: bas@vimec.nl
D: Loadable modules and ftape driver D: Loadable modules and ftape driver
...@@ -842,6 +850,13 @@ S: PO Box 371 ...@@ -842,6 +850,13 @@ S: PO Box 371
S: North Little Rock, Arkansas 72115 S: North Little Rock, Arkansas 72115
S: US S: US
N: Siegfried "Frieder" Loeffler (dg1sek)
E: floeff@tunix.mathematik.uni-stuttgart.de, fl@LF.net
W: http://www.mathematik.uni-stuttgart.de/~floeff
D: Busmaster driver for HP 10/100 Mbit Network Adapters
S: University of Stuttgart, Germany and
S: Ecole Nationale Superieure des Telecommunications, Paris
N: Martin von Loewis N: Martin von Loewis
E: loewis@informatik.hu-berlin.de E: loewis@informatik.hu-berlin.de
D: script binary format D: script binary format
......
...@@ -107,6 +107,11 @@ P: Jean Tourrilhes ...@@ -107,6 +107,11 @@ P: Jean Tourrilhes
M: jt@hplb.hpl.hp.com M: jt@hplb.hpl.hp.com
S: Maintained S: Maintained
HP100: Driver for HP 10/100 Mbit/s Network Adapter Series
P: Jarsolav Kysela
M: perex@jcu.cz
S: Maintained
APM DRIVER APM DRIVER
P: Rik Faith & Stephen Rothwell P: Rik Faith & Stephen Rothwell
M: faith@cs.unc.edu, Stephen.Rothwell@canb.auug.org.au M: faith@cs.unc.edu, Stephen.Rothwell@canb.auug.org.au
......
VERSION = 2 VERSION = 2
PATCHLEVEL = 1 PATCHLEVEL = 1
SUBLEVEL = 44 SUBLEVEL = 45
ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/) ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/)
......
...@@ -195,9 +195,6 @@ CONFIG_DE4X5=y ...@@ -195,9 +195,6 @@ CONFIG_DE4X5=y
# Filesystems # Filesystems
# #
# CONFIG_QUOTA is not set # CONFIG_QUOTA is not set
# CONFIG_DCACHE_PRELOAD is not set
# CONFIG_OMIRR is not set
# CONFIG_TRANS_NAMES is not set
# CONFIG_MINIX_FS is not set # CONFIG_MINIX_FS is not set
CONFIG_EXT2_FS=y CONFIG_EXT2_FS=y
# CONFIG_FAT_FS is not set # CONFIG_FAT_FS is not set
...@@ -205,12 +202,13 @@ CONFIG_EXT2_FS=y ...@@ -205,12 +202,13 @@ CONFIG_EXT2_FS=y
# CONFIG_VFAT_FS is not set # CONFIG_VFAT_FS is not set
# CONFIG_UMSDOS_FS is not set # CONFIG_UMSDOS_FS is not set
CONFIG_PROC_FS=y CONFIG_PROC_FS=y
# CONFIG_NFS_FS is not set CONFIG_NFS_FS=y
# CONFIG_ROOT_NFS is not set
# CONFIG_NFSD is not set # CONFIG_NFSD is not set
# CONFIG_SUNRPC is not set CONFIG_SUNRPC=y
# CONFIG_LOCKD is not set CONFIG_LOCKD=y
# CONFIG_SMB_FS is not set # CONFIG_SMB_FS is not set
# CONFIG_ISO9660_FS is not set CONFIG_ISO9660_FS=y
# CONFIG_HPFS_FS is not set # CONFIG_HPFS_FS is not set
# CONFIG_SYSV_FS is not set # CONFIG_SYSV_FS is not set
# CONFIG_AFFS_FS is not set # CONFIG_AFFS_FS is not set
......
...@@ -192,9 +192,6 @@ CONFIG_EEXPRESS_PRO100=y ...@@ -192,9 +192,6 @@ CONFIG_EEXPRESS_PRO100=y
# Filesystems # Filesystems
# #
# CONFIG_QUOTA is not set # CONFIG_QUOTA is not set
# CONFIG_DCACHE_PRELOAD is not set
# CONFIG_OMIRR is not set
# CONFIG_TRANS_NAMES is not set
# CONFIG_MINIX_FS is not set # CONFIG_MINIX_FS is not set
CONFIG_EXT2_FS=y CONFIG_EXT2_FS=y
# CONFIG_FAT_FS is not set # CONFIG_FAT_FS is not set
...@@ -208,7 +205,7 @@ CONFIG_NFS_FS=y ...@@ -208,7 +205,7 @@ CONFIG_NFS_FS=y
CONFIG_SUNRPC=y CONFIG_SUNRPC=y
CONFIG_LOCKD=y CONFIG_LOCKD=y
# CONFIG_SMB_FS is not set # CONFIG_SMB_FS is not set
# CONFIG_ISO9660_FS is not set CONFIG_ISO9660_FS=y
# CONFIG_HPFS_FS is not set # CONFIG_HPFS_FS is not set
# CONFIG_SYSV_FS is not set # CONFIG_SYSV_FS is not set
# CONFIG_AFFS_FS is not set # CONFIG_AFFS_FS is not set
......
#define BLOCKMOVE #define BLOCKMOVE
static char rcsid[] = static char rcsid[] =
"$Revision: 1.36.4.27 $$Date: 1997/03/26 10:30:00 $"; "$Revision: 1.36.4.33 $$Date: 1997/06/27 19:00:00 $";
/* /*
* linux/drivers/char/cyclades.c * linux/drivers/char/cyclades.c
...@@ -29,6 +29,50 @@ static char rcsid[] = ...@@ -29,6 +29,50 @@ static char rcsid[] =
* void cleanup_module(void); * void cleanup_module(void);
* *
* $Log: cyclades.c,v $ * $Log: cyclades.c,v $
* Revision 1.36.4.33 1997/06/27 19:00:00 ivan
* Fixes related to kernel version conditional
* compilation.
*
* Revision 1.36.4.32 1997/06/14 19:30:00 ivan
* Compatibility issues between kernels 2.0.x and
* 2.1.x (mainly related to clear_bit function).
*
* Revision 1.36.4.31 1997/06/03 15:30:00 ivan
* Changes to define the memory window according to the
* board type.
*
* Revision 1.36.4.30 1997/05/16 15:30:00 daniel
* Changes to suport new cycladesZ boards.
*
* Revision 1.36.4.29 1997/05/12 11:30:00 daniel
* Merge of Bentson's and Daniel's version 1.36.4.28.
* Corrects bug in cy_detect_pci: check if there are more
* ports than the number of static structs allocated.
* Warning message during initialization if this driver is
* used with the new generation of cycladesZ boards. Those
* will be supported only in next release of the driver.
* Corrects bug in cy_detect_pci and cy_detect_isa that
* returned wrong number of VALID boards, when a cyclomY
* was found with no serial modules connected.
* Changes to use current (2.1.x) kernel subroutine names
* and created macros for compilation with 2.0.x kernel,
* instead of the other way around.
*
* Revision 1.36.4.28 1997/05/?? ??:00:00 bentson
* Change queue_task_irq_off to queue_task_irq.
* The inline function queue_task_irq_off (tqueue.h)
* was removed from latest releases of 2.1.x kernel.
* Use of macro __initfunc to mark the initialization
* routines, so memory can be reused.
* Also incorporate implementation of critical region
* in function cleanup_module() created by anonymous
* linuxer.
*
* Revision 1.36.4.28 1997/04/25 16:00:00 daniel
* Change to support new firmware that solves DCD problem:
* application could fail to receive SIGHUP signal when DCD
* varying too fast.
*
* Revision 1.36.4.27 1997/03/26 10:30:00 daniel * Revision 1.36.4.27 1997/03/26 10:30:00 daniel
* Changed for suport linux versions 2.1.X. * Changed for suport linux versions 2.1.X.
* Backward compatible with linux versions 2.0.X. * Backward compatible with linux versions 2.0.X.
...@@ -98,7 +142,7 @@ static char rcsid[] = ...@@ -98,7 +142,7 @@ static char rcsid[] =
* after -Y stuff (to make changes clearer) * after -Y stuff (to make changes clearer)
* *
* Revision 1.36.4.12 1996/07/11 15:40:55 bentson * Revision 1.36.4.12 1996/07/11 15:40:55 bentson
* Add code to poll Cyclom-Z. Add code to get & set RS-232 control. * Add code to poll Cyclades-Z. Add code to get & set RS-232 control.
* Add code to send break. Clear firmware ID word at startup (so * Add code to send break. Clear firmware ID word at startup (so
* that other code won't talk to inactive board). * that other code won't talk to inactive board).
* *
...@@ -391,7 +435,13 @@ static char rcsid[] = ...@@ -391,7 +435,13 @@ static char rcsid[] =
constant in the definition below. No other change is necessary to constant in the definition below. No other change is necessary to
support more boards/ports. */ support more boards/ports. */
#define NR_PORTS 64 //#define NR_PORTS 64
#define NR_PORTS 128
#define ZE_V1_NPORTS 64
#define ZO_V1 0
#define ZO_V2 1
#define ZE_V1 2
#define SERIAL_PARANOIA_CHECK #define SERIAL_PARANOIA_CHECK
#undef SERIAL_DEBUG_OPEN #undef SERIAL_DEBUG_OPEN
...@@ -453,35 +503,51 @@ static char rcsid[] = ...@@ -453,35 +503,51 @@ static char rcsid[] =
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/bios32.h> #include <linux/bios32.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/init.h>
#include <linux/version.h> #include <linux/version.h>
#if LINUX_VERSION_CODE >= 131328 #if (LINUX_VERSION_CODE >= 0x020100)
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <linux/init.h>
#define memcpy_fromfs copy_from_user #define cy_put_user put_user
#define memcpy_tofs copy_to_user
#define put_fs_long put_user
#define vremap ioremap
static unsigned long get_fs_long(unsigned long *addr) static unsigned long cy_get_user(unsigned long *addr)
{ {
unsigned long result = 0; unsigned long result = 0;
int error = get_user (result, addr); int error = get_user (result, addr);
if (error) if (error)
printk ("cyclades: get_fs_long: error == %d\n", error); printk ("cyclades: cy_get_user: error == %d\n", error);
return result; return result;
} }
#else
#define __initfunc(__arginit) __arginit
#define copy_from_user memcpy_fromfs
#define copy_to_user memcpy_tofs
#define cy_get_user get_fs_long
#define cy_put_user put_fs_long
#define ioremap vremap
#endif #endif
#ifndef MIN #ifndef MIN
#define MIN(a,b) ((a) < (b) ? (a) : (b)) #define MIN(a,b) ((a) < (b) ? (a) : (b))
#endif #endif
#define IS_CYC_Z(card) ((card).num_chips == 1) #define IS_CYC_Z(card) ((card).num_chips == 1)
#define Z_FPGA_CHECK(card) \
((((struct RUNTIME_9060 *)((card).ctl_addr))->init_ctrl&(1<<17))!=0)
#define ISZLOADED(card) (((ZO_V1==((struct RUNTIME_9060 *) \
((card).ctl_addr))->mail_box_0) || \
Z_FPGA_CHECK(card)) && \
(ZFIRM_ID==((struct FIRM_ID *) \
((card).base_addr+ID_ADDRESS))->signature))
#define WAKEUP_CHARS (SERIAL_XMIT_SIZE-256) #define WAKEUP_CHARS (SERIAL_XMIT_SIZE-256)
#define STD_COM_FLAGS (0) #define STD_COM_FLAGS (0)
...@@ -548,7 +614,7 @@ static struct cyclades_card *IRQ_cards[16]; ...@@ -548,7 +614,7 @@ static struct cyclades_card *IRQ_cards[16];
/* /*
* tmp_buf is used as a temporary buffer by serial_write. We need to * tmp_buf is used as a temporary buffer by serial_write. We need to
* lock it in case the memcpy_fromfs blocks while swapping in a page, * lock it in case the copy_from_user blocks while swapping in a page,
* and some other program tries to do a serial write at the same time. * and some other program tries to do a serial write at the same time.
* Since the lock will only come under contention when the system is * Since the lock will only come under contention when the system is
* swapping and available memory is low, it makes sense to share one * swapping and available memory is low, it makes sense to share one
...@@ -698,10 +764,12 @@ static void CP4(int data) ...@@ -698,10 +764,12 @@ static void CP4(int data)
{ (data<10)? CP(data+'0'): CP(data+'A'-10); }/* CP4 */ { (data<10)? CP(data+'0'): CP(data+'A'-10); }/* CP4 */
static void CP8(int data) static void CP8(int data)
{ CP4((data>>4) & 0x0f); CP4( data & 0x0f); }/* CP8 */ { CP4((data>>4) & 0x0f); CP4( data & 0x0f); }/* CP8 */
#if 0
static void CP16(int data) static void CP16(int data)
{ CP8((data>>8) & 0xff); CP8(data & 0xff); }/* CP16 */ { CP8((data>>8) & 0xff); CP8(data & 0xff); }/* CP16 */
static void CP32(long data) static void CP32(long data)
{ CP16((data>>16) & 0xffff); CP16(data & 0xffff); }/* CP32 */ { CP16((data>>16) & 0xffff); CP16(data & 0xffff); }/* CP32 */
#endif
/* /*
...@@ -758,6 +826,7 @@ do_softint(void *private_) ...@@ -758,6 +826,7 @@ do_softint(void *private_)
if (!tty) if (!tty)
return; return;
#if (LINUX_VERSION_CODE >= 0x020125)
if (test_and_clear_bit(Cy_EVENT_HANGUP, &info->event)) { if (test_and_clear_bit(Cy_EVENT_HANGUP, &info->event)) {
tty_hangup(info->tty); tty_hangup(info->tty);
wake_up_interruptible(&info->open_wait); wake_up_interruptible(&info->open_wait);
...@@ -774,6 +843,24 @@ do_softint(void *private_) ...@@ -774,6 +843,24 @@ do_softint(void *private_)
} }
wake_up_interruptible(&tty->write_wait); wake_up_interruptible(&tty->write_wait);
} }
#else
if (clear_bit(Cy_EVENT_HANGUP, &info->event)) {
tty_hangup(info->tty);
wake_up_interruptible(&info->open_wait);
info->flags &= ~(ASYNC_NORMAL_ACTIVE|
ASYNC_CALLOUT_ACTIVE);
}
if (clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event)) {
wake_up_interruptible(&info->open_wait);
}
if (clear_bit(Cy_EVENT_WRITE_WAKEUP, &info->event)) {
if((tty->flags & (1<< TTY_DO_WRITE_WAKEUP))
&& tty->ldisc.write_wakeup){
(tty->ldisc.write_wakeup)(tty);
}
wake_up_interruptible(&tty->write_wait);
}
#endif
} /* do_softint */ } /* do_softint */
...@@ -1351,7 +1438,7 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -1351,7 +1438,7 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
/***********************************************************/ /***********************************************************/
/********* End of block of Cyclom-Y specific code **********/ /********* End of block of Cyclom-Y specific code **********/
/******** Start of block of Cyclom-Z specific code *********/ /******** Start of block of Cyclades-Z specific code *********/
/***********************************************************/ /***********************************************************/
...@@ -1365,7 +1452,7 @@ cyz_fetch_msg( struct cyclades_card *cinfo, ...@@ -1365,7 +1452,7 @@ cyz_fetch_msg( struct cyclades_card *cinfo,
unsigned long loc_doorbell; unsigned long loc_doorbell;
firm_id = (struct FIRM_ID *)(cinfo->base_addr + ID_ADDRESS); firm_id = (struct FIRM_ID *)(cinfo->base_addr + ID_ADDRESS);
if (firm_id->signature != ZFIRM_ID){ if (!ISZLOADED(*cinfo)){
return (-1); return (-1);
} }
zfw_ctrl = (struct ZFW_CTRL *) zfw_ctrl = (struct ZFW_CTRL *)
...@@ -1397,7 +1484,7 @@ cyz_issue_cmd( struct cyclades_card *cinfo, ...@@ -1397,7 +1484,7 @@ cyz_issue_cmd( struct cyclades_card *cinfo,
int index; int index;
firm_id = (struct FIRM_ID *)(cinfo->base_addr + ID_ADDRESS); firm_id = (struct FIRM_ID *)(cinfo->base_addr + ID_ADDRESS);
if (firm_id->signature != ZFIRM_ID){ if (!ISZLOADED(*cinfo)){
return (-1); return (-1);
} }
zfw_ctrl = (struct ZFW_CTRL *) zfw_ctrl = (struct ZFW_CTRL *)
...@@ -1408,7 +1495,7 @@ cyz_issue_cmd( struct cyclades_card *cinfo, ...@@ -1408,7 +1495,7 @@ cyz_issue_cmd( struct cyclades_card *cinfo,
pci_doorbell = &((struct RUNTIME_9060 *) pci_doorbell = &((struct RUNTIME_9060 *)
(cinfo->ctl_addr))->pci_doorbell; (cinfo->ctl_addr))->pci_doorbell;
while( (*pci_doorbell & 0xff) != 0){ while( (*pci_doorbell & 0xff) != 0){
if (index++ == 100){ if (index++ == 1000){
return(-1); return(-1);
} }
udelay(50L); udelay(50L);
...@@ -1421,6 +1508,7 @@ cyz_issue_cmd( struct cyclades_card *cinfo, ...@@ -1421,6 +1508,7 @@ cyz_issue_cmd( struct cyclades_card *cinfo,
} /* cyz_issue_cmd */ } /* cyz_issue_cmd */
#if 0
static int static int
cyz_update_channel( struct cyclades_card *cinfo, cyz_update_channel( struct cyclades_card *cinfo,
u_long channel, u_char mode, u_char cmd) u_long channel, u_char mode, u_char cmd)
...@@ -1430,7 +1518,7 @@ cyz_update_channel( struct cyclades_card *cinfo, ...@@ -1430,7 +1518,7 @@ cyz_update_channel( struct cyclades_card *cinfo,
struct ZFW_CTRL *zfw_ctrl; struct ZFW_CTRL *zfw_ctrl;
struct CH_CTRL *ch_ctrl; struct CH_CTRL *ch_ctrl;
if (firm_id->signature != ZFIRM_ID){ if (!ISZLOADED(*cinfo)){
return (-1); return (-1);
} }
zfw_ctrl = zfw_ctrl =
...@@ -1442,6 +1530,7 @@ cyz_update_channel( struct cyclades_card *cinfo, ...@@ -1442,6 +1530,7 @@ cyz_update_channel( struct cyclades_card *cinfo,
return cyz_issue_cmd(cinfo, channel, cmd, 0L); return cyz_issue_cmd(cinfo, channel, cmd, 0L);
} /* cyz_update_channel */ } /* cyz_update_channel */
#endif
static void static void
...@@ -1467,6 +1556,7 @@ cyz_poll(unsigned long arg) ...@@ -1467,6 +1556,7 @@ cyz_poll(unsigned long arg)
u_long channel; u_long channel;
u_char cmd; u_char cmd;
u_long *param; u_long *param;
u_long hw_ver, fw_ver;
cyz_timerlist.expires = jiffies + 100; cyz_timerlist.expires = jiffies + 100;
...@@ -1476,7 +1566,7 @@ cyz_poll(unsigned long arg) ...@@ -1476,7 +1566,7 @@ cyz_poll(unsigned long arg)
firm_id = (struct FIRM_ID *) firm_id = (struct FIRM_ID *)
(cinfo->base_addr + ID_ADDRESS); (cinfo->base_addr + ID_ADDRESS);
if (firm_id->signature != ZFIRM_ID){ if (!ISZLOADED(*cinfo)){
continue; continue;
} }
...@@ -1484,6 +1574,8 @@ cyz_poll(unsigned long arg) ...@@ -1484,6 +1574,8 @@ cyz_poll(unsigned long arg)
(struct ZFW_CTRL *) (struct ZFW_CTRL *)
(cinfo->base_addr + firm_id->zfwctrl_addr); (cinfo->base_addr + firm_id->zfwctrl_addr);
board_ctrl = &zfw_ctrl->board_ctrl; board_ctrl = &zfw_ctrl->board_ctrl;
fw_ver = board_ctrl->fw_version;
hw_ver = ((struct RUNTIME_9060 *)(cinfo->ctl_addr))->mail_box_0;
while( cyz_fetch_msg( cinfo, &channel, &cmd, &param) == 1){ while( cyz_fetch_msg( cinfo, &channel, &cmd, &param) == 1){
char_count = 0; char_count = 0;
...@@ -1514,7 +1606,9 @@ cyz_poll(unsigned long arg) ...@@ -1514,7 +1606,9 @@ cyz_poll(unsigned long arg)
break; break;
case C_CM_MDCD: case C_CM_MDCD:
if (info->flags & ASYNC_CHECK_CD){ if (info->flags & ASYNC_CHECK_CD){
if( ch_ctrl[channel].rs_status & C_RS_DCD){ if (((hw_ver != 0 || fw_ver > 241)
? ((u_long)param)
: ch_ctrl[channel].rs_status) & C_RS_DCD) {
/* SP("Open Wakeup\n"); */ /* SP("Open Wakeup\n"); */
cy_sched_event(info, cy_sched_event(info,
Cy_EVENT_OPEN_WAKEUP); Cy_EVENT_OPEN_WAKEUP);
...@@ -1709,7 +1803,7 @@ cyz_poll(unsigned long arg) ...@@ -1709,7 +1803,7 @@ cyz_poll(unsigned long arg)
} /* cyz_poll */ } /* cyz_poll */
/********** End of block of Cyclom-Z specific code *********/ /********** End of block of Cyclades-Z specific code *********/
/***********************************************************/ /***********************************************************/
...@@ -1794,7 +1888,7 @@ startup(struct cyclades_port * info) ...@@ -1794,7 +1888,7 @@ startup(struct cyclades_port * info)
base_addr = (unsigned char*) (cy_card[card].base_addr); base_addr = (unsigned char*) (cy_card[card].base_addr);
firm_id = (struct FIRM_ID *) (base_addr + ID_ADDRESS); firm_id = (struct FIRM_ID *) (base_addr + ID_ADDRESS);
if (firm_id->signature != ZFIRM_ID){ if (!ISZLOADED(cy_card[card])){
return -ENODEV; return -ENODEV;
} }
...@@ -1951,7 +2045,7 @@ shutdown(struct cyclades_port * info) ...@@ -1951,7 +2045,7 @@ shutdown(struct cyclades_port * info)
#endif #endif
firm_id = (struct FIRM_ID *) (base_addr + ID_ADDRESS); firm_id = (struct FIRM_ID *) (base_addr + ID_ADDRESS);
if (firm_id->signature != ZFIRM_ID){ if (!ISZLOADED(cy_card[card])) {
return; return;
} }
...@@ -2143,7 +2237,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp, ...@@ -2143,7 +2237,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp,
base_addr = (char *)(cinfo->base_addr); base_addr = (char *)(cinfo->base_addr);
firm_id = (struct FIRM_ID *) firm_id = (struct FIRM_ID *)
(base_addr + ID_ADDRESS); (base_addr + ID_ADDRESS);
if (firm_id->signature != ZFIRM_ID){ if (!ISZLOADED(*cinfo)){
return -EINVAL; return -EINVAL;
} }
...@@ -2237,11 +2331,17 @@ cy_open(struct tty_struct *tty, struct file * filp) ...@@ -2237,11 +2331,17 @@ cy_open(struct tty_struct *tty, struct file * filp)
will make the user pay attention. will make the user pay attention.
*/ */
if (IS_CYC_Z(cy_card[info->card])) { if (IS_CYC_Z(cy_card[info->card])) {
struct FIRM_ID *firm_id = if (!ISZLOADED(cy_card[info->card])) {
(struct FIRM_ID *) if (((ZE_V1 ==((struct RUNTIME_9060 *)
(cy_card[info->card].base_addr + ID_ADDRESS); ((cy_card[info->card]).ctl_addr))->mail_box_0) &&
if (firm_id->signature != ZFIRM_ID){ Z_FPGA_CHECK(cy_card[info->card])) &&
printk("Cyclom-Z firmware not yet loaded\n"); (ZFIRM_HLT==((struct FIRM_ID *)
((cy_card[info->card]).base_addr+ID_ADDRESS))->signature))
{
printk ("Cyclades-Z Error: you need an external power supply for this number of ports.\n\rFirmware halted.\r\n");
} else {
printk("Cyclades-Z firmware not yet loaded\n");
}
return -ENODEV; return -ENODEV;
} }
} }
...@@ -2448,7 +2548,7 @@ cy_write(struct tty_struct * tty, int from_user, ...@@ -2448,7 +2548,7 @@ cy_write(struct tty_struct * tty, int from_user,
} }
if (from_user) { if (from_user) {
memcpy_fromfs(tmp_buf, buf, c); copy_from_user(tmp_buf, buf, c);
c = MIN(c, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, c = MIN(c, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
SERIAL_XMIT_SIZE - info->xmit_head)); SERIAL_XMIT_SIZE - info->xmit_head));
memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c); memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c);
...@@ -2816,7 +2916,7 @@ set_line_char(struct cyclades_port * info) ...@@ -2816,7 +2916,7 @@ set_line_char(struct cyclades_port * info)
firm_id = (struct FIRM_ID *) firm_id = (struct FIRM_ID *)
(cy_card[card].base_addr + ID_ADDRESS); (cy_card[card].base_addr + ID_ADDRESS);
if (firm_id->signature != ZFIRM_ID){ if (!ISZLOADED(cy_card[card])) {
return; return;
} }
...@@ -2956,7 +3056,7 @@ get_serial_info(struct cyclades_port * info, ...@@ -2956,7 +3056,7 @@ get_serial_info(struct cyclades_port * info,
tmp.baud_base = info->baud; tmp.baud_base = info->baud;
tmp.custom_divisor = 0; /*!!!*/ tmp.custom_divisor = 0; /*!!!*/
tmp.hub6 = 0; /*!!!*/ tmp.hub6 = 0; /*!!!*/
memcpy_tofs(retinfo,&tmp,sizeof(*retinfo)); copy_to_user(retinfo,&tmp,sizeof(*retinfo));
return 0; return 0;
} /* get_serial_info */ } /* get_serial_info */
...@@ -2970,7 +3070,7 @@ set_serial_info(struct cyclades_port * info, ...@@ -2970,7 +3070,7 @@ set_serial_info(struct cyclades_port * info,
if (!new_info) if (!new_info)
return -EFAULT; return -EFAULT;
memcpy_fromfs(&new_serial,new_info,sizeof(new_serial)); copy_from_user(&new_serial,new_info,sizeof(new_serial));
old_info = *info; old_info = *info;
if (!suser()) { if (!suser()) {
...@@ -3051,7 +3151,7 @@ get_modem_info(struct cyclades_port * info, unsigned int *value) ...@@ -3051,7 +3151,7 @@ get_modem_info(struct cyclades_port * info, unsigned int *value)
firm_id = (struct FIRM_ID *) firm_id = (struct FIRM_ID *)
(cy_card[card].base_addr + ID_ADDRESS); (cy_card[card].base_addr + ID_ADDRESS);
if (firm_id->signature == ZFIRM_ID){ if (ISZLOADED(cy_card[card])) {
zfw_ctrl = zfw_ctrl =
(struct ZFW_CTRL *) (struct ZFW_CTRL *)
(cy_card[card].base_addr + firm_id->zfwctrl_addr); (cy_card[card].base_addr + firm_id->zfwctrl_addr);
...@@ -3070,7 +3170,7 @@ get_modem_info(struct cyclades_port * info, unsigned int *value) ...@@ -3070,7 +3170,7 @@ get_modem_info(struct cyclades_port * info, unsigned int *value)
} }
} }
put_fs_long(result,(unsigned long *) value); cy_put_user(result,(unsigned long *) value);
return 0; return 0;
} /* get_modem_info */ } /* get_modem_info */
...@@ -3082,7 +3182,7 @@ set_modem_info(struct cyclades_port * info, unsigned int cmd, ...@@ -3082,7 +3182,7 @@ set_modem_info(struct cyclades_port * info, unsigned int cmd,
int card,chip,channel,index; int card,chip,channel,index;
unsigned char *base_addr; unsigned char *base_addr;
unsigned long flags; unsigned long flags;
unsigned int arg = get_fs_long((unsigned long *) value); unsigned int arg = cy_get_user((unsigned long *) value);
struct FIRM_ID *firm_id; struct FIRM_ID *firm_id;
struct ZFW_CTRL *zfw_ctrl; struct ZFW_CTRL *zfw_ctrl;
struct BOARD_CTRL *board_ctrl; struct BOARD_CTRL *board_ctrl;
...@@ -3180,7 +3280,7 @@ set_modem_info(struct cyclades_port * info, unsigned int cmd, ...@@ -3180,7 +3280,7 @@ set_modem_info(struct cyclades_port * info, unsigned int cmd,
firm_id = (struct FIRM_ID *) firm_id = (struct FIRM_ID *)
(cy_card[card].base_addr + ID_ADDRESS); (cy_card[card].base_addr + ID_ADDRESS);
if (firm_id->signature == ZFIRM_ID){ if (ISZLOADED(cy_card[card])) {
zfw_ctrl = zfw_ctrl =
(struct ZFW_CTRL *) (struct ZFW_CTRL *)
(cy_card[card].base_addr + firm_id->zfwctrl_addr); (cy_card[card].base_addr + firm_id->zfwctrl_addr);
...@@ -3281,7 +3381,7 @@ static int ...@@ -3281,7 +3381,7 @@ static int
get_mon_info(struct cyclades_port * info, struct cyclades_monitor * mon) get_mon_info(struct cyclades_port * info, struct cyclades_monitor * mon)
{ {
memcpy_tofs(mon, &info->mon, sizeof(struct cyclades_monitor)); copy_to_user(mon, &info->mon, sizeof(struct cyclades_monitor));
info->mon.int_count = 0; info->mon.int_count = 0;
info->mon.char_count = 0; info->mon.char_count = 0;
info->mon.char_max = 0; info->mon.char_max = 0;
...@@ -3335,7 +3435,7 @@ get_threshold(struct cyclades_port * info, unsigned long *value) ...@@ -3335,7 +3435,7 @@ get_threshold(struct cyclades_port * info, unsigned long *value)
+ (cy_chip_offset[chip]<<index)); + (cy_chip_offset[chip]<<index));
tmp = base_addr[CyCOR3<<index] & CyREC_FIFO; tmp = base_addr[CyCOR3<<index] & CyREC_FIFO;
put_fs_long(tmp,value); cy_put_user(tmp,value);
} else { } else {
// Nothing to do! // Nothing to do!
} }
...@@ -3354,7 +3454,7 @@ set_default_threshold(struct cyclades_port * info, unsigned long value) ...@@ -3354,7 +3454,7 @@ set_default_threshold(struct cyclades_port * info, unsigned long value)
static int static int
get_default_threshold(struct cyclades_port * info, unsigned long *value) get_default_threshold(struct cyclades_port * info, unsigned long *value)
{ {
put_fs_long(info->default_threshold,value); cy_put_user(info->default_threshold,value);
return 0; return 0;
}/* get_default_threshold */ }/* get_default_threshold */
...@@ -3401,7 +3501,7 @@ get_timeout(struct cyclades_port * info, unsigned long *value) ...@@ -3401,7 +3501,7 @@ get_timeout(struct cyclades_port * info, unsigned long *value)
+ (cy_chip_offset[chip]<<index)); + (cy_chip_offset[chip]<<index));
tmp = base_addr[CyRTPR<<index]; tmp = base_addr[CyRTPR<<index];
put_fs_long(tmp,value); cy_put_user(tmp,value);
} else { } else {
// Nothing to do! // Nothing to do!
} }
...@@ -3420,7 +3520,7 @@ set_default_timeout(struct cyclades_port * info, unsigned long value) ...@@ -3420,7 +3520,7 @@ set_default_timeout(struct cyclades_port * info, unsigned long value)
static int static int
get_default_timeout(struct cyclades_port * info, unsigned long *value) get_default_timeout(struct cyclades_port * info, unsigned long *value)
{ {
put_fs_long(info->default_timeout,value); cy_put_user(info->default_timeout,value);
return 0; return 0;
}/* get_default_timeout */ }/* get_default_timeout */
...@@ -3530,7 +3630,7 @@ cy_ioctl(struct tty_struct *tty, struct file * file, ...@@ -3530,7 +3630,7 @@ cy_ioctl(struct tty_struct *tty, struct file * file,
ret_val = error; ret_val = error;
break; break;
} }
put_fs_long(C_CLOCAL(tty) ? 1 : 0, cy_put_user(C_CLOCAL(tty) ? 1 : 0,
(unsigned long *) arg); (unsigned long *) arg);
break; break;
case TIOCSSOFTCAR: case TIOCSSOFTCAR:
...@@ -3541,7 +3641,7 @@ cy_ioctl(struct tty_struct *tty, struct file * file, ...@@ -3541,7 +3641,7 @@ cy_ioctl(struct tty_struct *tty, struct file * file,
break; break;
} }
arg = get_fs_long((unsigned long *) arg); arg = cy_get_user((unsigned long *) arg);
tty->termios->c_cflag = tty->termios->c_cflag =
((tty->termios->c_cflag & ~CLOCAL) | ((tty->termios->c_cflag & ~CLOCAL) |
(arg ? CLOCAL : 0)); (arg ? CLOCAL : 0));
...@@ -3967,8 +4067,8 @@ cy_detect_isa(void)) ...@@ -3967,8 +4067,8 @@ cy_detect_isa(void))
} }
/* probe for CD1400... */ /* probe for CD1400... */
#if LINUX_VERSION_CODE >= 131328 #if (LINUX_VERSION_CODE >= 0x020100)
cy_isa_address = vremap((unsigned int)cy_isa_address,0x2000); cy_isa_address = ioremap((unsigned int)cy_isa_address,0x2000);
#endif #endif
cy_isa_nchan = 4 * cyy_init_card(cy_isa_address,0); cy_isa_nchan = 4 * cyy_init_card(cy_isa_address,0);
if (cy_isa_nchan == 0) { if (cy_isa_nchan == 0) {
...@@ -3988,6 +4088,7 @@ cy_detect_isa(void)) ...@@ -3988,6 +4088,7 @@ cy_detect_isa(void))
printk("Cyclom-Y/ISA found at 0x%x ", printk("Cyclom-Y/ISA found at 0x%x ",
(unsigned int) cy_isa_address); (unsigned int) cy_isa_address);
printk("but no more channels are available.\n"); printk("but no more channels are available.\n");
printk("Change NR_PORTS in cyclades.c and recompile kernel.\n");
return(nboard); return(nboard);
} }
/* fill the next cy_card structure available */ /* fill the next cy_card structure available */
...@@ -3998,6 +4099,7 @@ cy_detect_isa(void)) ...@@ -3998,6 +4099,7 @@ cy_detect_isa(void))
printk("Cyclom-Y/ISA found at 0x%x ", printk("Cyclom-Y/ISA found at 0x%x ",
(unsigned int) cy_isa_address); (unsigned int) cy_isa_address);
printk("but no more cards can be used .\n"); printk("but no more cards can be used .\n");
printk("Change NR_CARDS in cyclades.c and recompile kernel.\n");
return(nboard); return(nboard);
} }
...@@ -4051,6 +4153,8 @@ cy_detect_pci(void)) ...@@ -4051,6 +4153,8 @@ cy_detect_pci(void))
unsigned int cy_pci_addr0, cy_pci_addr1, cy_pci_addr2; unsigned int cy_pci_addr0, cy_pci_addr1, cy_pci_addr2;
unsigned short i,j,cy_pci_nchan; unsigned short i,j,cy_pci_nchan;
unsigned short device_id,dev_index = 0,board_index = 0; unsigned short device_id,dev_index = 0,board_index = 0;
unsigned long mailbox;
unsigned int Ze_addr0[NR_CARDS], Ze_addr2[NR_CARDS], ZeIndex = 0;
if(pcibios_present() == 0) { /* PCI bus not present */ if(pcibios_present() == 0) { /* PCI bus not present */
return(0); return(0);
...@@ -4070,6 +4174,9 @@ cy_detect_pci(void)) ...@@ -4070,6 +4174,9 @@ cy_detect_pci(void))
} }
} }
if (device_id == 0)
break;
/* read PCI configuration area */ /* read PCI configuration area */
pcibios_read_config_byte(cyy_bus, cyy_dev_fn, pcibios_read_config_byte(cyy_bus, cyy_dev_fn,
PCI_INTERRUPT_LINE, &cy_pci_irq); PCI_INTERRUPT_LINE, &cy_pci_irq);
...@@ -4081,9 +4188,7 @@ cy_detect_pci(void)) ...@@ -4081,9 +4188,7 @@ cy_detect_pci(void))
PCI_BASE_ADDRESS_2, &cy_pci_addr2); PCI_BASE_ADDRESS_2, &cy_pci_addr2);
pcibios_read_config_byte(cyy_bus, cyy_dev_fn, pcibios_read_config_byte(cyy_bus, cyy_dev_fn,
PCI_REVISION_ID, &cyy_rev_id); PCI_REVISION_ID, &cyy_rev_id);
if (device_id == 0){ if ((device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo)
break;
}else if ((device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo)
|| (device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi)){ || (device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi)){
#ifdef CY_PCI_DEBUG #ifdef CY_PCI_DEBUG
printk("Cyclom-Y/PCI (bus=0x0%x, pci_id=0x%x, ", printk("Cyclom-Y/PCI (bus=0x0%x, pci_id=0x%x, ",
...@@ -4096,11 +4201,11 @@ cy_detect_pci(void)) ...@@ -4096,11 +4201,11 @@ cy_detect_pci(void))
cy_pci_addr1 &= 0xfffffffc; cy_pci_addr1 &= 0xfffffffc;
cy_pci_addr2 &= 0xfffffff0; cy_pci_addr2 &= 0xfffffff0;
#if LINUX_VERSION_CODE < 131328 #if (LINUX_VERSION_CODE < 0x020100)
if ((ulong)cy_pci_addr2 >= 0x100000) /* above 1M? */ if ((ulong)cy_pci_addr2 >= 0x100000) /* above 1M? */
#endif #endif
cy_pci_addr2 = cy_pci_addr2 =
(unsigned int) vremap(cy_pci_addr2,CyPCI_Ywin); (unsigned int) ioremap(cy_pci_addr2,CyPCI_Ywin);
#ifdef CY_PCI_DEBUG #ifdef CY_PCI_DEBUG
printk("Cyclom-Y/PCI: relocate winaddr=0x%x ioaddr=0x%x\n", printk("Cyclom-Y/PCI: relocate winaddr=0x%x ioaddr=0x%x\n",
...@@ -4112,12 +4217,14 @@ cy_detect_pci(void)) ...@@ -4112,12 +4217,14 @@ cy_detect_pci(void))
printk("Cyclom-Y PCI host card with "); printk("Cyclom-Y PCI host card with ");
printk("no Serial-Modules at 0x%x.\n", printk("no Serial-Modules at 0x%x.\n",
(unsigned int) cy_pci_addr2); (unsigned int) cy_pci_addr2);
i--;
continue; continue;
} }
if((cy_next_channel+cy_pci_nchan) > NR_PORTS) { if((cy_next_channel+cy_pci_nchan) > NR_PORTS) {
printk("Cyclom-Y/PCI found at 0x%x ", printk("Cyclom-Y/PCI found at 0x%x ",
(unsigned int) cy_pci_addr2); (unsigned int) cy_pci_addr2);
printk("but no channels are available.\n"); printk("but no channels are available.\n");
printk("Change NR_PORTS in cyclades.c and recompile kernel.\n");
return(i); return(i);
} }
/* fill the next cy_card structure available */ /* fill the next cy_card structure available */
...@@ -4128,6 +4235,7 @@ cy_detect_pci(void)) ...@@ -4128,6 +4235,7 @@ cy_detect_pci(void))
printk("Cyclom-Y/PCI found at 0x%x ", printk("Cyclom-Y/PCI found at 0x%x ",
(unsigned int) cy_pci_addr2); (unsigned int) cy_pci_addr2);
printk("but no more cards can be used.\n"); printk("but no more cards can be used.\n");
printk("Change NR_CARDS in cyclades.c and recompile kernel.\n");
return(i); return(i);
} }
...@@ -4167,65 +4275,101 @@ cy_detect_pci(void)) ...@@ -4167,65 +4275,101 @@ cy_detect_pci(void))
cy_next_channel += cy_pci_nchan; cy_next_channel += cy_pci_nchan;
}else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Lo){ }else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Lo){
/* print message */ /* print message */
printk("Cyclom-Z/PCI (bus=0x0%x, pci_id=0x%x, ", printk("Cyclades-Z/PCI (bus=0x0%x, pci_id=0x%x, ",
cyy_bus, cyy_dev_fn); cyy_bus, cyy_dev_fn);
printk("rev_id=%d) IRQ%d\n", printk("rev_id=%d) IRQ%d\n",
cyy_rev_id, (int)cy_pci_irq); cyy_rev_id, (int)cy_pci_irq);
printk("Cyclom-Z/PCI: found winaddr=0x%x ctladdr=0x%x\n", printk("Cyclades-Z/PCI: found winaddr=0x%x ctladdr=0x%x\n",
cy_pci_addr2, cy_pci_addr0); cy_pci_addr2, cy_pci_addr0);
printk("Cyclom-Z/PCI not supported for low addresses\n"); printk("Cyclades-Z/PCI not supported for low addresses\n");
break; break;
}else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Hi){ }else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Hi){
#ifdef CY_PCI_DEBUG #ifdef CY_PCI_DEBUG
printk("Cyclom-Z/PCI (bus=0x0%x, pci_id=0x%x, ", printk("Cyclades-Z/PCI (bus=0x0%x, pci_id=0x%x, ",
cyy_bus, cyy_dev_fn); cyy_bus, cyy_dev_fn);
printk("rev_id=%d) IRQ%d\n", printk("rev_id=%d) IRQ%d\n",
cyy_rev_id, (int)cy_pci_irq); cyy_rev_id, (int)cy_pci_irq);
printk("Cyclom-Z/PCI: found winaddr=0x%x ctladdr=0x%x\n", printk("Cyclades-Z/PCI: found winaddr=0x%x ctladdr=0x%x\n",
cy_pci_addr2, cy_pci_addr0); cy_pci_addr2, cy_pci_addr0);
#endif #endif
cy_pci_addr2 &= 0xfffffff0;
cy_pci_addr2 = (unsigned int) vremap(
cy_pci_addr2 & PAGE_MASK,
PAGE_ALIGN(CyPCI_Zwin))
+ (cy_pci_addr2 & (PAGE_SIZE-1));
cy_pci_addr0 &= 0xfffffff0; cy_pci_addr0 &= 0xfffffff0;
cy_pci_addr0 = (unsigned int) vremap( cy_pci_addr0 = (unsigned int) ioremap(
cy_pci_addr0 & PAGE_MASK, cy_pci_addr0 & PAGE_MASK,
PAGE_ALIGN(CyPCI_Zctl)) PAGE_ALIGN(CyPCI_Zctl))
+ (cy_pci_addr0 & (PAGE_SIZE-1)); + (cy_pci_addr0 & (PAGE_SIZE-1));
mailbox = ((struct RUNTIME_9060 *) cy_pci_addr0)->mail_box_0;
cy_pci_addr2 &= 0xfffffff0;
if (mailbox == ZE_V1) {
cy_pci_addr2 = (unsigned int) ioremap(
cy_pci_addr2 & PAGE_MASK,
PAGE_ALIGN(CyPCI_Ze_win))
+ (cy_pci_addr2 & (PAGE_SIZE-1));
if (ZeIndex == NR_CARDS) {
printk("Cyclades-Z/PCI found at 0x%x ",
(unsigned int) cy_pci_addr2);
printk("but no more cards can be used.\n");
printk("Change NR_CARDS in cyclades.c and recompile kernel.\n");
} else {
Ze_addr0[ZeIndex] = cy_pci_addr0;
Ze_addr2[ZeIndex] = cy_pci_addr2;
ZeIndex++;
}
i--;
continue;
} else {
cy_pci_addr2 = (unsigned int) ioremap(
cy_pci_addr2 & PAGE_MASK,
PAGE_ALIGN(CyPCI_Zwin))
+ (cy_pci_addr2 & (PAGE_SIZE-1));
}
#ifdef CY_PCI_DEBUG #ifdef CY_PCI_DEBUG
printk("Cyclom-Z/PCI: relocate winaddr=0x%x ctladdr=0x%x\n", printk("Cyclades-Z/PCI: relocate winaddr=0x%x ctladdr=0x%x\n",
cy_pci_addr2, cy_pci_addr0); cy_pci_addr2, cy_pci_addr0);
((struct RUNTIME_9060 *)(cy_pci_addr0)) if (mailbox == ZO_V1) {
((struct RUNTIME_9060 *)(cy_pci_addr0))
->loc_addr_base = WIN_CREG; ->loc_addr_base = WIN_CREG;
PAUSE PAUSE
printk("Cyclom-Z/PCI: FPGA id %lx, ver %lx\n", printk("Cyclades-Z/PCI: FPGA id %lx, ver %lx\n",
0xff & ((struct CUSTOM_REG *)(cy_pci_addr2))->fpga_id, 0xff & ((struct CUSTOM_REG *)(cy_pci_addr2))->fpga_id,
0xff & ((struct CUSTOM_REG *)(cy_pci_addr2))->fpga_version); 0xff & ((struct CUSTOM_REG *)(cy_pci_addr2))->fpga_version);
((struct RUNTIME_9060 *)(cy_pci_addr0)) ((struct RUNTIME_9060 *)(cy_pci_addr0))
->loc_addr_base = WIN_RAM; ->loc_addr_base = WIN_RAM;
} else {
printk("Cyclades-Z/PCI: New Cyclades-Z board. FPGA not loaded\n");
}
#endif #endif
/* The following clears the firmware id word. This ensures /* The following clears the firmware id word. This ensures
that the driver will not attempt to talk to the board that the driver will not attempt to talk to the board
until it has been properly initialized. until it has been properly initialized.
*/ */
PAUSE PAUSE
*(unsigned long *)(cy_pci_addr2+ID_ADDRESS) = 0L; if (mailbox == ZO_V1)
*(unsigned long *)(cy_pci_addr2+ID_ADDRESS) = 0L;
/* This must be a Cyclom-8Zo/PCI. The extendable /* This must be a Cyclades-8Zo/PCI. The extendable
version will have a different device_id and will version will have a different device_id and will
be allocated its maximum number of ports. */ be allocated its maximum number of ports. */
cy_pci_nchan = 8; cy_pci_nchan = 8;
if((cy_next_channel+cy_pci_nchan) > NR_PORTS) {
printk("Cyclades-Z/PCI found at 0x%x ",
(unsigned int) cy_pci_addr2);
printk("but no channels are available.\n");
printk("Change NR_PORTS in cyclades.c and recompile kernel.\n");
return(i);
}
/* fill the next cy_card structure available */ /* fill the next cy_card structure available */
for (j = 0 ; j < NR_CARDS ; j++) { for (j = 0 ; j < NR_CARDS ; j++) {
if (cy_card[j].base_addr == 0) break; if (cy_card[j].base_addr == 0) break;
} }
if (j == NR_CARDS) { /* no more cy_cards available */ if (j == NR_CARDS) { /* no more cy_cards available */
printk("Cyclom-Z/PCI found at 0x%x ", printk("Cyclades-Z/PCI found at 0x%x ",
(unsigned int) cy_pci_addr2); (unsigned int) cy_pci_addr2);
printk("but no more cards can be used.\n"); printk("but no more cards can be used.\n");
printk("Change NR_CARDS in cyclades.c and recompile kernel.\n");
return(i); return(i);
} }
...@@ -4235,9 +4379,9 @@ cy_detect_pci(void)) ...@@ -4235,9 +4379,9 @@ cy_detect_pci(void))
SA_INTERRUPT,"cyclomZ",NULL)) SA_INTERRUPT,"cyclomZ",NULL))
{ {
printk("Could not allocate IRQ%d ", printk("Could not allocate IRQ%d ",
(unsigned int) cy_pci_addr2);
printk("for Cyclom-Z/PCI at 0x%x.\n",
cy_pci_irq); cy_pci_irq);
printk("for Cyclades-Z/PCI at 0x%x.\n",
(unsigned int) cy_pci_addr2);
return(i); return(i);
} }
} }
...@@ -4254,12 +4398,12 @@ cy_detect_pci(void)) ...@@ -4254,12 +4398,12 @@ cy_detect_pci(void))
/* print message */ /* print message */
/* don't report IRQ if board is no IRQ */ /* don't report IRQ if board is no IRQ */
if( (cy_pci_irq < 15) && (cy_pci_irq > 1) ) { if( (cy_pci_irq < 15) && (cy_pci_irq > 1) ) {
printk("Cyclom-Z/PCI #%d: 0x%x-0x%x, IRQ%d, ", printk("Cyclades-Z/PCI #%d: 0x%x-0x%x, IRQ%d, ",
j+1,cy_pci_addr2, j+1,cy_pci_addr2,
(cy_pci_addr2 + CyPCI_Zwin - 1), (cy_pci_addr2 + CyPCI_Zwin - 1),
(int)cy_pci_irq); (int)cy_pci_irq);
}else{ }else{
printk("Cyclom-Z/PCI #%d: 0x%x-0x%x, ", printk("Cyclades-Z/PCI #%d: 0x%x-0x%x, ",
j+1,cy_pci_addr2, j+1,cy_pci_addr2,
(cy_pci_addr2 + CyPCI_Zwin - 1)); (cy_pci_addr2 + CyPCI_Zwin - 1));
} }
...@@ -4268,6 +4412,93 @@ cy_detect_pci(void)) ...@@ -4268,6 +4412,93 @@ cy_detect_pci(void))
cy_next_channel += cy_pci_nchan; cy_next_channel += cy_pci_nchan;
} }
} }
for (; ZeIndex != 0 && i < NR_CARDS; i++) {
cy_pci_addr0 = Ze_addr0[0];
cy_pci_addr2 = Ze_addr2[0];
for (j = 0 ; j < ZeIndex-1 ; j++) {
Ze_addr0[j] = Ze_addr0[j+1];
Ze_addr2[j] = Ze_addr2[j+1];
}
ZeIndex--;
mailbox = ((struct RUNTIME_9060 *) cy_pci_addr0)->mail_box_0;
#ifdef CY_PCI_DEBUG
printk("Cyclades-Z/PCI: relocate winaddr=0x%x ctladdr=0x%x\n",
cy_pci_addr2, cy_pci_addr0);
printk("Cyclades-Z/PCI: New Cyclades-Z board. FPGA not loaded\n");
#endif
/* The following clears the firmware id word. This ensures
that the driver will not attempt to talk to the board
until it has been properly initialized.
*/
PAUSE
/* This must be the new Cyclades-Ze/PCI. */
cy_pci_nchan = ZE_V1_NPORTS;
if((cy_next_channel+cy_pci_nchan) > NR_PORTS) {
printk("Cyclades-Z/PCI found at 0x%x ",
(unsigned int) cy_pci_addr2);
printk("but no channels are available.\n");
printk("Change NR_PORTS in cyclades.c and recompile kernel.\n");
return(i);
}
/* fill the next cy_card structure available */
for (j = 0 ; j < NR_CARDS ; j++) {
if (cy_card[j].base_addr == 0) break;
}
if (j == NR_CARDS) { /* no more cy_cards available */
printk("Cyclades-Z/PCI found at 0x%x ",
(unsigned int) cy_pci_addr2);
printk("but no more cards can be used.\n");
printk("Change NR_CARDS in cyclades.c and recompile kernel.\n");
return(i);
}
/* allocate IRQ only if board has an IRQ */
if( (1 < cy_pci_irq) && (cy_pci_irq < 15) ) {
if(request_irq(cy_pci_irq,cyz_interrupt,
SA_INTERRUPT,"cyclomZ",NULL))
{
printk("Could not allocate IRQ%d ",
cy_pci_irq);
printk("for Cyclades-Z/PCI at 0x%x.\n",
(unsigned int) cy_pci_addr2);
return(i);
}
}
/* set cy_card */
cy_card[j].base_addr = cy_pci_addr2;
cy_card[j].ctl_addr = cy_pci_addr0;
cy_card[j].irq = (int) cy_pci_irq;
cy_card[j].bus_index = 1;
cy_card[j].first_line = cy_next_channel;
cy_card[j].num_chips = 1;
IRQ_cards[cy_pci_irq] = &cy_card[j];
/* print message */
/* don't report IRQ if board is no IRQ */
if( (cy_pci_irq < 15) && (cy_pci_irq > 1) ) {
printk("Cyclades-Z/PCI #%d: 0x%x-0x%x, IRQ%d, ",
j+1,cy_pci_addr2,
(cy_pci_addr2 + CyPCI_Ze_win - 1),
(int)cy_pci_irq);
}else{
printk("Cyclades-Z/PCI #%d: 0x%x-0x%x, ",
j+1,cy_pci_addr2,
(cy_pci_addr2 + CyPCI_Ze_win - 1));
}
printk("%d channels starting from port %d.\n",
cy_pci_nchan,cy_next_channel);
cy_next_channel += cy_pci_nchan;
}
if (ZeIndex != 0) {
printk("Cyclades-Z/PCI found at 0x%x ",
(unsigned int) Ze_addr2[0]);
printk("but no more cards can be used.\n");
printk("Change NR_CARDS in cyclades.c and recompile kernel.\n");
}
return(i); return(i);
#else #else
return(0); return(0);
...@@ -4319,6 +4550,8 @@ cy_init(void)) ...@@ -4319,6 +4550,8 @@ cy_init(void))
struct cyclades_card *cinfo; struct cyclades_card *cinfo;
int number_z_boards = 0; int number_z_boards = 0;
int board,port,i; int board,port,i;
unsigned long mailbox;
int nports;
show_version(); show_version();
...@@ -4416,10 +4649,13 @@ cy_init(void)) ...@@ -4416,10 +4649,13 @@ cy_init(void))
/* initialize per-port data structures for each valid board found */ /* initialize per-port data structures for each valid board found */
for (board = 0 ; board < cy_nboard ; board++) { for (board = 0 ; board < cy_nboard ; board++) {
cinfo = &cy_card[board]; cinfo = &cy_card[board];
if (cinfo->num_chips == 1){ /* Cyclom-8Zo/PCI */ if (cinfo->num_chips == 1){ /* Cyclades-8Zo/PCI */
number_z_boards++; number_z_boards++;
mailbox = ((struct RUNTIME_9060 *)
cy_card[board].ctl_addr)->mail_box_0;
nports = (mailbox == ZE_V1) ? ZE_V1_NPORTS : 8;
for (port = cinfo->first_line ; for (port = cinfo->first_line ;
port < cinfo->first_line + 8; port < cinfo->first_line + nports;
port++) port++)
{ {
info = &cy_port[port]; info = &cy_port[port];
...@@ -4523,7 +4759,7 @@ cy_init(void)) ...@@ -4523,7 +4759,7 @@ cy_init(void))
cyz_timerlist.expires = jiffies + 1; cyz_timerlist.expires = jiffies + 1;
add_timer(&cyz_timerlist); add_timer(&cyz_timerlist);
#ifdef CY_PCI_DEBUG #ifdef CY_PCI_DEBUG
printk("Cyclom-Z polling initialized\n"); printk("Cyclades-Z polling initialized\n");
#endif #endif
} }
......
...@@ -168,6 +168,11 @@ static void aux_write_dev(int val) ...@@ -168,6 +168,11 @@ static void aux_write_dev(int val)
outb_p(val, KBD_DATA_REG); /* Write data */ outb_p(val, KBD_DATA_REG); /* Write data */
} }
/*
* Write to device & handle returned ack
*/
#ifdef INITIALIZE_DEVICE
__initfunc(static void aux_write_dev_nosleep(int val)) __initfunc(static void aux_write_dev_nosleep(int val))
{ {
poll_aux_status_nosleep(); poll_aux_status_nosleep();
...@@ -176,11 +181,6 @@ __initfunc(static void aux_write_dev_nosleep(int val)) ...@@ -176,11 +181,6 @@ __initfunc(static void aux_write_dev_nosleep(int val))
outb_p(val, KBD_DATA_REG); outb_p(val, KBD_DATA_REG);
} }
/*
* Write to device & handle returned ack
*/
#ifdef INITIALIZE_DEVICE
__initfunc(static int aux_write_ack(int val)) __initfunc(static int aux_write_ack(int val))
{ {
aux_write_dev_nosleep(val); aux_write_dev_nosleep(val);
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <linux/config.h> #include <linux/config.h>
/* /*
Define types for some of the structures that interface with the rest Define types for some of the structures that interface with the rest
of the Linux Kernel and SCSI Subsystem. of the Linux Kernel and SCSI Subsystem.
......
...@@ -50,13 +50,8 @@ ...@@ -50,13 +50,8 @@
#include <linux/string.h> #include <linux/string.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/config.h> #include <linux/config.h>
#include <linux/init.h>
#include <linux/version.h>
#if LINUX_VERSION_CODE < 66354 /* 1.3.50 */
#include "../block/blk.h"
#else
#include <linux/blk.h> #include <linux/blk.h>
#endif
#include "scsi.h" #include "scsi.h"
#include "hosts.h" #include "hosts.h"
...@@ -69,13 +64,10 @@ ...@@ -69,13 +64,10 @@
#define PCI_DEVICE_ID_AMD53C974 PCI_DEVICE_ID_AMD_SCSI #define PCI_DEVICE_ID_AMD53C974 PCI_DEVICE_ID_AMD_SCSI
#ifndef VERSION_ELF_1_2_13
struct proc_dir_entry proc_scsi_tmscsim ={ struct proc_dir_entry proc_scsi_tmscsim ={
PROC_SCSI_DC390T, 7 ,"tmscsim", PROC_SCSI_DC390T, 7 ,"tmscsim",
S_IFDIR | S_IRUGO | S_IXUGO, 2 S_IFDIR | S_IRUGO | S_IXUGO, 2
}; };
#endif
static USHORT DC390_StartSCSI( PACB pACB, PDCB pDCB, PSRB pSRB ); static USHORT DC390_StartSCSI( PACB pACB, PDCB pDCB, PSRB pSRB );
static void DC390_DataOut_0( PACB pACB, PSRB pSRB, PUCHAR psstatus); static void DC390_DataOut_0( PACB pACB, PSRB pSRB, PUCHAR psstatus);
...@@ -675,11 +667,7 @@ DoNextCmd( PACB pACB, PDCB pDCB ) ...@@ -675,11 +667,7 @@ DoNextCmd( PACB pACB, PDCB pDCB )
* Description: * Description:
* Return the disk geometry for the given SCSI device. * Return the disk geometry for the given SCSI device.
***********************************************************************/ ***********************************************************************/
#ifdef VERSION_ELF_1_2_13
int DC390_bios_param(Disk *disk, int devno, int geom[])
#else
int DC390_bios_param(Disk *disk, kdev_t devno, int geom[]) int DC390_bios_param(Disk *disk, kdev_t devno, int geom[])
#endif
{ {
int heads, sectors, cylinders; int heads, sectors, cylinders;
PACB pACB; PACB pACB;
...@@ -1046,14 +1034,10 @@ void DC390_initDCB( PACB pACB, PDCB pDCB, PSCSICMD cmd ) ...@@ -1046,14 +1034,10 @@ void DC390_initDCB( PACB pACB, PDCB pDCB, PSCSICMD cmd )
***********************************************************************/ ***********************************************************************/
void DC390_initSRB( PSRB psrb ) void DC390_initSRB( PSRB psrb )
{ {
#ifndef VERSION_ELF_1_2_13
#ifdef DC390_DEBUG0 #ifdef DC390_DEBUG0
printk("DC390 init: %08lx %08lx,",(ULONG)psrb,(ULONG)virt_to_bus(psrb)); printk("DC390 init: %08lx %08lx,",(ULONG)psrb,(ULONG)virt_to_bus(psrb));
#endif #endif
psrb->PhysSRB = virt_to_bus( psrb ); psrb->PhysSRB = virt_to_bus( psrb );
#else
psrb->PhysSRB = (ULONG) psrb;
#endif
} }
...@@ -1084,7 +1068,7 @@ void DC390_linkSRB( PACB pACB ) ...@@ -1084,7 +1068,7 @@ void DC390_linkSRB( PACB pACB )
* Inputs : psh - pointer to this host adapter's structure * Inputs : psh - pointer to this host adapter's structure
* *
***********************************************************************/ ***********************************************************************/
void DC390_initACB( PSH psh, ULONG io_port, UCHAR Irq, USHORT index ) __initfunc(void DC390_initACB( PSH psh, ULONG io_port, UCHAR Irq, USHORT index ))
{ {
PACB pACB; PACB pACB;
USHORT i; USHORT i;
...@@ -1098,7 +1082,6 @@ void DC390_initACB( PSH psh, ULONG io_port, UCHAR Irq, USHORT index ) ...@@ -1098,7 +1082,6 @@ void DC390_initACB( PSH psh, ULONG io_port, UCHAR Irq, USHORT index )
pACB = (PACB) psh->hostdata; pACB = (PACB) psh->hostdata;
#ifndef VERSION_ELF_1_2_13
psh->max_id = 8; psh->max_id = 8;
#ifdef CONFIG_SCSI_MULTI_LUN #ifdef CONFIG_SCSI_MULTI_LUN
if( eepromBuf[index][EE_MODE2] & LUN_CHECK ) if( eepromBuf[index][EE_MODE2] & LUN_CHECK )
...@@ -1106,7 +1089,6 @@ void DC390_initACB( PSH psh, ULONG io_port, UCHAR Irq, USHORT index ) ...@@ -1106,7 +1089,6 @@ void DC390_initACB( PSH psh, ULONG io_port, UCHAR Irq, USHORT index )
else else
#endif #endif
psh->max_lun = 1; psh->max_lun = 1;
#endif
pACB->max_id = 7; pACB->max_id = 7;
if( pACB->max_id == eepromBuf[index][EE_ADAPT_SCSI_ID] ) if( pACB->max_id == eepromBuf[index][EE_ADAPT_SCSI_ID] )
...@@ -1155,7 +1137,7 @@ void DC390_initACB( PSH psh, ULONG io_port, UCHAR Irq, USHORT index ) ...@@ -1155,7 +1137,7 @@ void DC390_initACB( PSH psh, ULONG io_port, UCHAR Irq, USHORT index )
* Inputs : psh - pointer to this host adapter's structure * Inputs : psh - pointer to this host adapter's structure
* *
***********************************************************************/ ***********************************************************************/
int DC390_initAdapter( PSH psh, ULONG io_port, UCHAR Irq, USHORT index ) __initfunc(int DC390_initAdapter( PSH psh, ULONG io_port, UCHAR Irq, USHORT index))
{ {
USHORT ioport; USHORT ioport;
UCHAR bval; UCHAR bval;
...@@ -1179,11 +1161,7 @@ int DC390_initAdapter( PSH psh, ULONG io_port, UCHAR Irq, USHORT index ) ...@@ -1179,11 +1161,7 @@ int DC390_initAdapter( PSH psh, ULONG io_port, UCHAR Irq, USHORT index )
if( !used_irq ) if( !used_irq )
{ {
#ifdef VERSION_ELF_1_2_13
if( request_irq(Irq, DC390_Interrupt, SA_INTERRUPT, "tmscsim"))
#else
if( request_irq(Irq, DC390_Interrupt, SA_INTERRUPT, "tmscsim", NULL)) if( request_irq(Irq, DC390_Interrupt, SA_INTERRUPT, "tmscsim", NULL))
#endif
{ {
printk("DC390: register IRQ error!\n"); printk("DC390: register IRQ error!\n");
return( -1 ); return( -1 );
...@@ -1533,8 +1511,8 @@ DC390_ToMech( USHORT Mechnum, USHORT BusDevFunNum ) ...@@ -1533,8 +1511,8 @@ DC390_ToMech( USHORT Mechnum, USHORT BusDevFunNum )
* field of the pACB structure MUST have been set. * field of the pACB structure MUST have been set.
***********************************************************************/ ***********************************************************************/
static int __initfunc(static int
DC390_init (PSHT psht, ULONG io_port, UCHAR Irq, USHORT index, USHORT MechNum) DC390_init (PSHT psht, ULONG io_port, UCHAR Irq, USHORT index, USHORT MechNum))
{ {
PSH psh; PSH psh;
PACB pACB; PACB pACB;
...@@ -1614,8 +1592,8 @@ DC390_init (PSHT psht, ULONG io_port, UCHAR Irq, USHORT index, USHORT MechNum) ...@@ -1614,8 +1592,8 @@ DC390_init (PSHT psht, ULONG io_port, UCHAR Irq, USHORT index, USHORT MechNum)
* *
***********************************************************************/ ***********************************************************************/
int __initfunc(int
DC390_detect(Scsi_Host_Template *psht) DC390_detect(Scsi_Host_Template *psht))
{ {
#ifdef FOR_PCI_OK #ifdef FOR_PCI_OK
UCHAR pci_bus, pci_device_fn; UCHAR pci_bus, pci_device_fn;
...@@ -1626,19 +1604,13 @@ DC390_detect(Scsi_Host_Template *psht) ...@@ -1626,19 +1604,13 @@ DC390_detect(Scsi_Host_Template *psht)
UCHAR irq; UCHAR irq;
UCHAR istatus; UCHAR istatus;
#ifndef VERSION_ELF_1_2_13
UINT io_port; UINT io_port;
#else
ULONG io_port;
#endif
USHORT adaptCnt = 0; /* Number of boards detected */ USHORT adaptCnt = 0; /* Number of boards detected */
USHORT pci_index = 0; /* Device index to PCI BIOS calls */ USHORT pci_index = 0; /* Device index to PCI BIOS calls */
USHORT MechNum, BusDevFunNum; USHORT MechNum, BusDevFunNum;
ULONG wlval; ULONG wlval;
#ifndef VERSION_ELF_1_2_13
psht->proc_dir = &proc_scsi_tmscsim; psht->proc_dir = &proc_scsi_tmscsim;
#endif
InitialTime = 1; InitialTime = 1;
pSHT_start = psht; pSHT_start = psht;
...@@ -1726,8 +1698,6 @@ DC390_detect(Scsi_Host_Template *psht) ...@@ -1726,8 +1698,6 @@ DC390_detect(Scsi_Host_Template *psht)
} }
#ifndef VERSION_ELF_1_2_13
/******************************************************************** /********************************************************************
* Function: tmscsim_set_info() * Function: tmscsim_set_info()
* *
...@@ -1848,7 +1818,6 @@ int tmscsim_proc_info(char *buffer, char **start, ...@@ -1848,7 +1818,6 @@ int tmscsim_proc_info(char *buffer, char **start,
else else
return length; return length;
} }
#endif /* VERSION_ELF_1_2_13 */
#ifdef MODULE #ifdef MODULE
...@@ -1909,11 +1878,7 @@ int DC390_release(struct Scsi_Host *host) ...@@ -1909,11 +1878,7 @@ int DC390_release(struct Scsi_Host *host)
#ifdef DC390_DEBUG0 #ifdef DC390_DEBUG0
printk("DC390: Free IRQ %i.",host->irq); printk("DC390: Free IRQ %i.",host->irq);
#endif #endif
#ifndef VERSION_ELF_1_2_13
free_irq(host->irq,NULL); free_irq(host->irq,NULL);
#else
free_irq(host->irq);
#endif
} }
} }
......
...@@ -5,26 +5,6 @@ mainmenu_option next_comment ...@@ -5,26 +5,6 @@ mainmenu_option next_comment
comment 'Filesystems' comment 'Filesystems'
bool 'Quota support' CONFIG_QUOTA bool 'Quota support' CONFIG_QUOTA
bool 'Preload dcache entries in readdir() [ALPHA, currently dangerous!]' CONFIG_DCACHE_PRELOAD
bool 'Include support for omirr online mirror' CONFIG_OMIRR
bool 'Translate filename suffixes' CONFIG_TRANS_NAMES
if [ "$CONFIG_TRANS_NAMES" = "y" ]; then
bool ' Restrict translation to specific gid' CONFIG_TRANS_RESTRICT
if [ "$CONFIG_TRANS_RESTRICT" = "y" ]; then
int ' Enter gid to compile in' CONFIG_TRANS_GID 4
fi
bool ' Translate nodename' CONFIG_TR_NODENAME
bool ' Translate compiled-in kernelname' CONFIG_TR_KERNNAME
if [ "$CONFIG_TR_KERNNAME" = "y" ]; then
string ' Enter kernelname string to compile in' CONFIG_KERNNAME banana
fi
bool ' Translate compiled-in kerneltype' CONFIG_TR_KERNTYPE
if [ "$CONFIG_TR_KERNTYPE" = "y" ]; then
string ' Enter kerneltype string to compile in' CONFIG_KERNTYPE default
fi
bool ' Translate machine type' CONFIG_TR_MACHINE
bool ' Translate sysname' CONFIG_TR_SYSNAME
fi
tristate 'Minix fs support' CONFIG_MINIX_FS tristate 'Minix fs support' CONFIG_MINIX_FS
tristate 'Second extended fs support' CONFIG_EXT2_FS tristate 'Second extended fs support' CONFIG_EXT2_FS
......
...@@ -136,7 +136,7 @@ static int autofs_root_lookup(struct inode *dir, struct qstr *str, struct inode ...@@ -136,7 +136,7 @@ static int autofs_root_lookup(struct inode *dir, struct qstr *str, struct inode
return -EACCES; return -EACCES;
} }
if ( !oz_mode && S_ISDIR(res->i_mode) && res->i_dentry->d_covers == res->i_dentry ) { if ( !oz_mode && S_ISDIR(res->i_mode) && i_dentry(res)->d_covers == i_dentry(res)) {
/* Not a mount point yet, call 1-800-DAEMON */ /* Not a mount point yet, call 1-800-DAEMON */
DPRINTK(("autofs: waiting on non-mountpoint dir, inode = %lu, pid = %u, pgrp = %u\n", res->i_ino, current->pid, current->pgrp)); DPRINTK(("autofs: waiting on non-mountpoint dir, inode = %lu, pid = %u, pgrp = %u\n", res->i_ino, current->pid, current->pgrp));
iput(res); iput(res);
...@@ -208,7 +208,7 @@ static int autofs_root_symlink(struct inode *dir, struct dentry *dentry, const c ...@@ -208,7 +208,7 @@ static int autofs_root_symlink(struct inode *dir, struct dentry *dentry, const c
memcpy(ent->name, dentry->d_name.name,ent->len = dentry->d_name.len); memcpy(ent->name, dentry->d_name.name,ent->len = dentry->d_name.len);
autofs_hash_insert(dh,ent); autofs_hash_insert(dh,ent);
d_instantiate(dentry, iget(dir->i_sb,ent->ino), 0); d_instantiate(dentry, iget(dir->i_sb,ent->ino));
return 0; return 0;
} }
...@@ -295,7 +295,7 @@ static int autofs_root_mkdir(struct inode *dir, struct dentry *dentry, int mode) ...@@ -295,7 +295,7 @@ static int autofs_root_mkdir(struct inode *dir, struct dentry *dentry, int mode)
ent->ino = sbi->next_dir_ino++; ent->ino = sbi->next_dir_ino++;
autofs_hash_insert(dh,ent); autofs_hash_insert(dh,ent);
dir->i_nlink++; dir->i_nlink++;
d_instantiate(dentry, iget(dir->i_sb,ent->ino), D_DIR); d_instantiate(dentry, iget(dir->i_sb,ent->ino));
return 0; return 0;
} }
......
...@@ -114,7 +114,7 @@ do_aout_core_dump(long signr, struct pt_regs * regs) ...@@ -114,7 +114,7 @@ do_aout_core_dump(long signr, struct pt_regs * regs)
#else #else
corefile[4] = '\0'; corefile[4] = '\0';
#endif #endif
if (open_namei(corefile,O_CREAT | 2 | O_TRUNC,0600,&inode,NULL)) { if (open_namei(corefile,O_CREAT | 2 | O_TRUNC,0600,&inode)) {
inode = NULL; inode = NULL;
goto end_coredump; goto end_coredump;
} }
......
...@@ -501,8 +501,7 @@ do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -501,8 +501,7 @@ do_load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
if (retval >= 0) { if (retval >= 0) {
old_fs = get_fs(); /* This could probably be optimized */ old_fs = get_fs(); /* This could probably be optimized */
set_fs(get_ds()); set_fs(get_ds());
retval = open_namei(elf_interpreter, 0, 0, retval = open_namei(elf_interpreter, 0, 0, &interpreter_inode);
&interpreter_inode, NULL);
set_fs(old_fs); set_fs(old_fs);
} }
...@@ -1078,7 +1077,7 @@ static int elf_core_dump(long signr, struct pt_regs * regs) ...@@ -1078,7 +1077,7 @@ static int elf_core_dump(long signr, struct pt_regs * regs)
#else #else
corefile[4] = '\0'; corefile[4] = '\0';
#endif #endif
if (open_namei(corefile,O_CREAT | 2 | O_TRUNC,0600,&inode,NULL)) { if (open_namei(corefile,O_CREAT | 2 | O_TRUNC,0600,&inode)) {
inode = NULL; inode = NULL;
goto end_coredump; goto end_coredump;
} }
......
...@@ -79,7 +79,7 @@ static int do_load_em86(struct linux_binprm *bprm,struct pt_regs *regs) ...@@ -79,7 +79,7 @@ static int do_load_em86(struct linux_binprm *bprm,struct pt_regs *regs)
* Note that we use open_namei() as the name is now in kernel * Note that we use open_namei() as the name is now in kernel
* space, and we don't need to copy it. * space, and we don't need to copy it.
*/ */
retval = open_namei(interp, 0, 0, &bprm->inode, NULL); retval = open_namei(interp, 0, 0, &bprm->inode);
if (retval) if (retval)
return retval; return retval;
bprm->dont_iput=0; bprm->dont_iput=0;
......
...@@ -78,7 +78,7 @@ static int do_load_java(struct linux_binprm *bprm,struct pt_regs *regs) ...@@ -78,7 +78,7 @@ static int do_load_java(struct linux_binprm *bprm,struct pt_regs *regs)
* OK, now restart the process with the interpreter's inode. * OK, now restart the process with the interpreter's inode.
*/ */
bprm->filename = binfmt_java_interpreter; bprm->filename = binfmt_java_interpreter;
retval = open_namei(binfmt_java_interpreter, 0, 0, &bprm->inode, NULL); retval = open_namei(binfmt_java_interpreter, 0, 0, &bprm->inode);
if (retval) if (retval)
return retval; return retval;
bprm->dont_iput=0; bprm->dont_iput=0;
...@@ -121,7 +121,7 @@ static int do_load_applet(struct linux_binprm *bprm,struct pt_regs *regs) ...@@ -121,7 +121,7 @@ static int do_load_applet(struct linux_binprm *bprm,struct pt_regs *regs)
* OK, now restart the process with the interpreter's inode. * OK, now restart the process with the interpreter's inode.
*/ */
bprm->filename = binfmt_java_appletviewer; bprm->filename = binfmt_java_appletviewer;
retval = open_namei(binfmt_java_appletviewer, 0, 0, &bprm->inode, NULL); retval = open_namei(binfmt_java_appletviewer, 0, 0, &bprm->inode);
if (retval) if (retval)
return retval; return retval;
bprm->dont_iput=0; bprm->dont_iput=0;
......
...@@ -77,7 +77,7 @@ static int do_load_script(struct linux_binprm *bprm,struct pt_regs *regs) ...@@ -77,7 +77,7 @@ static int do_load_script(struct linux_binprm *bprm,struct pt_regs *regs)
/* /*
* OK, now restart the process with the interpreter's inode. * OK, now restart the process with the interpreter's inode.
*/ */
retval = open_namei(interp, 0, 0, &bprm->inode, NULL); retval = open_namei(interp, 0, 0, &bprm->inode);
if (retval) if (retval)
return retval; return retval;
bprm->dont_iput=0; bprm->dont_iput=0;
......
...@@ -16,25 +16,8 @@ ...@@ -16,25 +16,8 @@
#include <linux/string.h> #include <linux/string.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/dalloc.h>
#include <linux/dlists.h>
#include <linux/malloc.h> #include <linux/malloc.h>
/* this should be removed after the beta phase */
/*#define DEBUG*/
/*#undef DEBUG*/
/*#define DEBUG_DDIR_COUNT*/
void printpath(struct dentry * entry);
DEF_INSERT(alias,struct dentry,d_next,d_prev)
DEF_REMOVE(alias,struct dentry,d_next,d_prev)
DEF_INSERT(hash,struct dentry,d_hash_next,d_hash_prev)
DEF_REMOVE(hash,struct dentry,d_hash_next,d_hash_prev)
struct dentry * the_root = NULL;
/* /*
* This is the single most critical data structure when it comes * This is the single most critical data structure when it comes
* to the dcache: the hashtable for lookups. Somebody should try * to the dcache: the hashtable for lookups. Somebody should try
...@@ -46,102 +29,59 @@ struct dentry * the_root = NULL; ...@@ -46,102 +29,59 @@ struct dentry * the_root = NULL;
#define D_HASHBITS 10 #define D_HASHBITS 10
#define D_HASHSIZE (1UL << D_HASHBITS) #define D_HASHSIZE (1UL << D_HASHBITS)
#define D_HASHMASK (D_HASHSIZE-1) #define D_HASHMASK (D_HASHSIZE-1)
struct dentry * dentry_hashtable[D_HASHSIZE]; struct list_head dentry_hashtable[D_HASHSIZE];
static inline unsigned long dentry_hash(struct dentry *dir, int name_hash)
{
unsigned long hash = name_hash + (unsigned long) dir;
hash = hash ^ (hash >> D_HASHBITS) ^ (hash >> D_HASHBITS*2);
return hash & D_HASHMASK;
}
unsigned long name_cache_init(unsigned long mem_start, unsigned long mem_end)
{
return mem_start;
}
#ifdef DEBUG
/* throw this away after the beta phase */
/*************************************************************************/
extern void xcheck(char * txt, struct inode * p);
static int x_alloc = 0;
static int x_freed = 0;
static int x_free = 0;
static void * tst[20000]; void d_free(struct dentry *dentry)
static int cnt = 0;
static void ins(void* ptr)
{
extern int inodes_stat;
tst[cnt++] = ptr;
if(cnt % 1000 == 0)
printk("------%d allocated: %d: %d %d %d\n", inodes_stat, cnt,
x_alloc, x_freed, x_free);
if (cnt>=20000) panic("stop");
}
#if 0
static inline int search(void* ptr)
{
int i;
for(i = cnt-1; i>=0; i--)
if (tst[i] == ptr)
return i;
return -1;
}
#define TST(n,x) if(search(x)<0) printk("%s bad ptr %p line %d\n", n, x, __LINE__)
#else
#define TST(n,x) /*nothing*/
#endif
void LOG(char * txt, struct dentry * entry)
{ {
static int count = 0; if (dentry) {
if (entry) { kfree(dentry->d_name.name);
TST(txt,entry); kfree(dentry);
}
if (count) {
count--;
printk("%s: entry=%p\n", txt, entry);
} }
} }
#ifdef DEBUG_DDIR_COUNT void dput(struct dentry *dentry)
void recursive_test(struct dentry * entry)
{
}
#else
#define recursive_test(e) /*nothing*/
#endif
#else
#define TST(n,x) /*nothing*/
#define LOG(n,x) /*nothing*/
#define xcheck(t,i) /*nothing*/
#define recursive_test(e) /*nothing*/
/*****************************************************************************/
#endif
void printpath(struct dentry * entry)
{
if (!IS_ROOT(entry))
printpath(entry->d_parent);
printk("/%s", entry->d_name.name);
}
void d_free(struct dentry *dentry)
{ {
repeat:
if (dentry) { if (dentry) {
kfree(dentry->d_name.name); dentry->d_count--;
kfree(dentry); if (dentry->d_count < 0) {
printk("dentry->count = %d for %s\n",
dentry->d_count, dentry->d_name.name);
return;
}
/*
* This is broken right now: we should really put
* the dentry on a free list to be reclaimed later
* when we think we should throw it away.
*
* Instead we free it completely if the inode count
* indicates that we're the only ones holding onto
* the inode - if not we just fall back on the old
* (broken) behaviour of not reclaiming it at all.
*/
if (!dentry->d_count && (!dentry->d_inode || atomic_read(&dentry->d_inode->i_count) == 1)) {
struct dentry *parent = dentry->d_parent;
if (parent != dentry) {
struct inode * inode = dentry->d_inode;
if (inode) {
list_del(&dentry->d_list);
iput(inode);
dentry->d_inode = NULL;
}
list_del(&dentry->d_hash);
d_free(dentry);
dentry = parent;
goto repeat;
}
}
} }
} }
#define NAME_ALLOC_LEN(len) ((len+16) & ~15) #define NAME_ALLOC_LEN(len) ((len+16) & ~15)
struct dentry * d_alloc(struct dentry * parent, struct qstr *name, int isdir) struct dentry * d_alloc(struct dentry * parent, const struct qstr *name)
{ {
char *str; char *str;
struct dentry *res; struct dentry *res;
...@@ -164,123 +104,89 @@ struct dentry * d_alloc(struct dentry * parent, struct qstr *name, int isdir) ...@@ -164,123 +104,89 @@ struct dentry * d_alloc(struct dentry * parent, struct qstr *name, int isdir)
res->d_parent = parent; res->d_parent = parent;
res->d_mounts = res; res->d_mounts = res;
res->d_covers = res; res->d_covers = res;
res->d_flag = isdir ? D_DIR : 0; res->d_flags = 0;
res->d_name.name = str; res->d_name.name = str;
res->d_name.len = name->len; res->d_name.len = name->len;
res->d_name.hash = name->hash; res->d_name.hash = name->hash;
#ifdef DEBUG
x_alloc++;
#endif
return res; return res;
} }
extern blocking struct dentry * d_alloc_root(struct inode * root_inode, struct dentry *old_root) /*
* Fill in inode information in the entry.
*
* This turns negative dentries into productive full members
* of society.
*
* NOTE! This assumes that the inode count has been incremented
* (or otherwise set) by the caller to indicate that it is now
* in use by the dcache..
*/
void d_instantiate(struct dentry *entry, struct inode * inode)
{ {
struct dentry *res; if (inode)
struct qstr name = { "/", 1, 0 }; /* dummy qstr */ list_add(&entry->d_list, &inode->i_dentry);
if (!root_inode) entry->d_inode = inode;
return NULL;
res = d_alloc(NULL, &name, 1);
LOG("d_alloc_root", res);
res->d_parent = res;
d_instantiate(res, root_inode, D_DIR);
return res;
} }
static inline struct dentry ** d_base_qstr(struct dentry * parent, struct qstr * s) struct dentry * d_alloc_root(struct inode * root_inode, struct dentry *old_root)
{ {
return dentry_hashtable + dentry_hash(parent, s->hash); struct dentry *res = NULL;
}
static inline struct dentry ** d_base_entry(struct dentry * pdir, struct dentry * entry) if (root_inode) {
{ res = d_alloc(NULL, &(const struct qstr) { "/", 1, 0 });
return d_base_qstr(pdir, &entry->d_name); res->d_parent = res;
d_instantiate(res, root_inode);
}
return res;
} }
static inline struct list_head * d_hash(struct dentry * parent, unsigned long hash)
static /*inline*/ blocking void _d_remove_from_parent(struct dentry * entry,
struct dentry * parent)
{ {
if (entry->d_flag & D_HASHED) { hash += (unsigned long) parent;
struct dentry ** base = d_base_entry(parent, entry); hash = hash ^ (hash >> D_HASHBITS) ^ (hash >> D_HASHBITS*2);
return dentry_hashtable + (hash & D_HASHMASK);
remove_hash(base, entry);
entry->d_flag &= ~D_HASHED;
}
} }
static inline struct dentry * __dlookup(struct dentry * base, struct dentry * parent, struct qstr * name) static inline struct dentry * __dlookup(struct list_head *head, struct dentry * parent, struct qstr * name)
{ {
if (base) { struct list_head *tmp = head->next;
struct dentry * tmp = base; int len = name->len;
int len = name->len; int hash = name->hash;
int hash = name->hash; const unsigned char *str = name->name;
const unsigned char *str = name->name;
while (tmp != head) {
do { struct dentry * dentry = list_entry(tmp, struct dentry, d_hash);
if (tmp->d_name.hash == hash &&
tmp->d_name.len == len && tmp = tmp->next;
tmp->d_parent == parent && if (dentry->d_name.hash != hash)
!(tmp->d_flag & D_DUPLICATE) && continue;
!memcmp(tmp->d_name.name, str, len)) if (dentry->d_name.len != len)
return tmp; continue;
tmp = tmp->d_hash_next; if (dentry->d_parent != parent)
} while(tmp != base); continue;
if (memcmp(dentry->d_name.name, str, len))
continue;
return dentry;
} }
return NULL; return NULL;
} }
struct dentry * d_lookup(struct dentry * dir, struct qstr * name) struct dentry * d_lookup(struct dentry * dir, struct qstr * name)
{ {
struct dentry ** base = d_base_qstr(dir, name); return __dlookup(d_hash(dir, name->hash), dir, name);
return __dlookup(*base, dir, name);
} }
static /*inline*/ blocking void _d_insert_to_parent(struct dentry * entry, static inline void d_insert_to_parent(struct dentry * entry, struct dentry * parent)
struct dentry * parent,
struct inode * inode,
int flags)
{ {
struct dentry ** base; list_add(&entry->d_hash, d_hash(dget(parent), entry->d_name.hash));
base = d_base_qstr(parent, &entry->d_name);
if (entry->d_flag & D_HASHED) {
printk("VFS: dcache entry is already hashed\n");
return;
}
insert_hash(base, entry);
entry->d_flag |= D_HASHED;
} }
/* static inline void d_remove_from_parent(struct dentry * dentry, struct dentry * parent)
* Fill in inode information in the entry.
*
* This turns negative dentries into productive full members
* of society.
*
* NOTE! This assumes that the inode count has been incremented
* (or otherwise set) by the caller to indicate that it is now
* in use by the dcache..
*/
void d_instantiate(struct dentry *entry, struct inode * inode, int flags)
{ {
entry->d_flag = (entry->d_flag & ~D_NEGATIVE) | flags; list_del(&dentry->d_hash);
dput(parent);
if (inode && !(flags & D_NEGATIVE)) {
if (entry->d_flag & D_DIR) {
if (inode->i_dentry) {
printk("VFS: creating dcache directory alias\n");
return;
}
}
insert_alias(&inode->i_dentry, entry);
}
entry->d_inode = inode;
} }
/* /*
...@@ -293,39 +199,19 @@ void d_instantiate(struct dentry *entry, struct inode * inode, int flags) ...@@ -293,39 +199,19 @@ void d_instantiate(struct dentry *entry, struct inode * inode, int flags)
*/ */
void d_delete(struct dentry * dentry) void d_delete(struct dentry * dentry)
{ {
struct inode * inode = dentry->d_inode; list_del(&dentry->d_hash);
/*
_d_remove_from_parent(dentry, dentry->d_parent); * Make the hash lists point to itself.. When we
if (inode) { * later dput this, we want the list_del() there
remove_alias(&inode->i_dentry, dentry); * to not do anything strange..
dentry->d_inode = NULL; */
iput(inode); INIT_LIST_HEAD(&dentry->d_hash);
}
} }
blocking void d_add(struct dentry * entry, struct inode * inode, int flags) void d_add(struct dentry * entry, struct inode * inode)
{ {
struct dentry * parent = entry->d_parent; d_insert_to_parent(entry, entry->d_parent);
d_instantiate(entry, inode);
#ifdef DEBUG
if (inode)
xcheck("d_add", inode);
if (IS_ROOT(entry)) {
printk("VFS: d_add for root dentry ");
printpath(entry);
printk(" -> ");
printk("\n");
return;
}
if (!parent)
panic("d_add with parent==NULL");
LOG("d_add", entry);
#endif
if(entry->d_flag & D_HASHED)
printk("VFS: d_add of already added dcache entry\n");
_d_insert_to_parent(entry, parent, inode, flags);
d_instantiate(entry, inode, flags);
} }
static inline void alloc_new_name(struct dentry * entry, struct qstr *newname) static inline void alloc_new_name(struct dentry * entry, struct qstr *newname)
...@@ -347,47 +233,18 @@ static inline void alloc_new_name(struct dentry * entry, struct qstr *newname) ...@@ -347,47 +233,18 @@ static inline void alloc_new_name(struct dentry * entry, struct qstr *newname)
entry->d_name.hash = hash; entry->d_name.hash = hash;
} }
static inline void d_remove_old_parent(struct dentry * entry) void d_move(struct dentry * dentry, struct dentry * newdir, struct qstr * newname)
{ {
struct dentry * parent; if (!dentry)
struct inode * inode;
parent = entry->d_parent;
inode = entry->d_inode;
_d_remove_from_parent(entry, parent);
}
static inline void d_add_new_parent(struct dentry * entry, struct dentry * parent)
{
struct inode * inode;
entry->d_parent = parent;
inode = entry->d_inode;
_d_insert_to_parent(entry, parent, inode, entry->d_flag);
}
blocking void d_move(struct dentry * entry, struct dentry * newdir, struct qstr * newname)
{
struct inode * inode;
int flags;
if (!entry)
return; return;
inode = entry->d_inode;
flags = entry->d_flag;
if (!inode) {
printk("VFS: moving negative dcache entry\n");
}
if (flags & D_ZOMBIE) { if (!dentry->d_inode)
printk("VFS: moving zombie entry\n"); printk("VFS: moving negative dcache entry\n");
}
d_remove_old_parent(entry); d_remove_from_parent(dentry, dentry->d_parent);
alloc_new_name(entry, newname); alloc_new_name(dentry, newname);
d_add_new_parent(entry, newdir); dentry->d_parent = newdir;
d_insert_to_parent(dentry, newdir);
} }
int d_path(struct dentry * entry, struct dentry * chroot, char * buf) int d_path(struct dentry * entry, struct dentry * chroot, char * buf)
...@@ -407,3 +264,16 @@ int d_path(struct dentry * entry, struct dentry * chroot, char * buf) ...@@ -407,3 +264,16 @@ int d_path(struct dentry * entry, struct dentry * chroot, char * buf)
return len + entry->d_name.len; return len + entry->d_name.len;
} }
} }
void dcache_init(void)
{
int i;
struct list_head *d = dentry_hashtable;
i = D_HASHSIZE;
do {
INIT_LIST_HEAD(d);
d++;
i--;
} while (i);
}
...@@ -959,7 +959,7 @@ int quota_on(kdev_t dev, short type, char *path) ...@@ -959,7 +959,7 @@ int quota_on(kdev_t dev, short type, char *path)
return(-EBUSY); return(-EBUSY);
if ((error = getname(path, &tmp)) != 0) if ((error = getname(path, &tmp)) != 0)
return(error); return(error);
error = open_namei(tmp, O_RDWR, 0600, &inode, 0); error = open_namei(tmp, O_RDWR, 0600, &inode);
putname(tmp); putname(tmp);
if (error) if (error)
return(error); return(error);
......
...@@ -587,7 +587,7 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs) ...@@ -587,7 +587,7 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
bprm->p = copy_strings(1, dynloader, bprm->page, bprm->p, 2); bprm->p = copy_strings(1, dynloader, bprm->page, bprm->p, 2);
bprm->argc++; bprm->argc++;
bprm->loader = bprm->p; bprm->loader = bprm->p;
retval = open_namei(dynloader[0], 0, 0, &bprm->inode, NULL); retval = open_namei(dynloader[0], 0, 0, &bprm->inode);
if (retval) if (retval)
return retval; return retval;
bprm->dont_iput = 0; bprm->dont_iput = 0;
...@@ -649,7 +649,7 @@ int do_execve(char * filename, char ** argv, char ** envp, struct pt_regs * regs ...@@ -649,7 +649,7 @@ int do_execve(char * filename, char ** argv, char ** envp, struct pt_regs * regs
bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *); bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
for (i=0 ; i<MAX_ARG_PAGES ; i++) /* clear page-table */ for (i=0 ; i<MAX_ARG_PAGES ; i++) /* clear page-table */
bprm.page[i] = 0; bprm.page[i] = 0;
retval = open_namei(filename, 0, 0, &bprm.inode, NULL); retval = open_namei(filename, 0, 0, &bprm.inode);
if (retval) if (retval)
return retval; return retval;
bprm.filename = filename; bprm.filename = filename;
......
...@@ -346,10 +346,10 @@ static int ext2_delete_entry (struct ext2_dir_entry * dir, ...@@ -346,10 +346,10 @@ static int ext2_delete_entry (struct ext2_dir_entry * dir,
/* /*
* By the time this is called, we already have created * By the time this is called, we already have created
* the directory cache entry for the new file, but it * the directory cache entry for the new file, but it
* is so far marked "D_NEGATIVE". * is so far negative - it has no inode.
* *
* If the create succeeds, remove the D_NEGATIVE flag, * If the create succeeds, we fill in the inode information
* and fill in the inode information with d_instantiate(). * with d_instantiate().
*/ */
int ext2_create (struct inode * dir, struct dentry * dentry, int mode) int ext2_create (struct inode * dir, struct dentry * dentry, int mode)
{ {
...@@ -382,7 +382,7 @@ int ext2_create (struct inode * dir, struct dentry * dentry, int mode) ...@@ -382,7 +382,7 @@ int ext2_create (struct inode * dir, struct dentry * dentry, int mode)
wait_on_buffer (bh); wait_on_buffer (bh);
} }
brelse (bh); brelse (bh);
d_instantiate(dentry, inode, 0); d_instantiate(dentry, inode);
return 0; return 0;
} }
...@@ -439,7 +439,7 @@ int ext2_mknod (struct inode * dir, struct dentry *dentry, int mode, int rdev) ...@@ -439,7 +439,7 @@ int ext2_mknod (struct inode * dir, struct dentry *dentry, int mode, int rdev)
wait_on_buffer (bh); wait_on_buffer (bh);
} }
brelse(bh); brelse(bh);
d_instantiate(dentry, inode, 0); d_instantiate(dentry, inode);
return 0; return 0;
} }
...@@ -503,7 +503,7 @@ int ext2_mkdir(struct inode * dir, struct dentry * dentry, int mode) ...@@ -503,7 +503,7 @@ int ext2_mkdir(struct inode * dir, struct dentry * dentry, int mode)
} }
dir->i_nlink++; dir->i_nlink++;
mark_inode_dirty(dir); mark_inode_dirty(dir);
d_instantiate(dentry, inode, D_DIR); d_instantiate(dentry, inode);
brelse (bh); brelse (bh);
return 0; return 0;
} }
...@@ -775,7 +775,7 @@ int ext2_symlink (struct inode * dir, struct dentry *dentry, const char * symnam ...@@ -775,7 +775,7 @@ int ext2_symlink (struct inode * dir, struct dentry *dentry, const char * symnam
wait_on_buffer (bh); wait_on_buffer (bh);
} }
brelse (bh); brelse (bh);
d_instantiate(dentry, inode, 0); d_instantiate(dentry, inode);
return 0; return 0;
} }
...@@ -810,7 +810,7 @@ int ext2_link (struct inode * inode, struct inode * dir, struct dentry *dentry) ...@@ -810,7 +810,7 @@ int ext2_link (struct inode * inode, struct inode * dir, struct dentry *dentry)
inode->i_ctime = CURRENT_TIME; inode->i_ctime = CURRENT_TIME;
mark_inode_dirty(inode); mark_inode_dirty(inode);
atomic_inc(&inode->i_count); atomic_inc(&inode->i_count);
d_instantiate(dentry, inode, 0); d_instantiate(dentry, inode);
return 0; return 0;
} }
......
...@@ -110,7 +110,8 @@ static int trunc_direct (struct inode * inode) ...@@ -110,7 +110,8 @@ static int trunc_direct (struct inode * inode)
return retry; return retry;
} }
static int trunc_indirect (struct inode * inode, int offset, u32 * p) static int trunc_indirect (struct inode * inode, int offset, u32 * p,
int in_inode)
{ {
int i, tmp; int i, tmp;
struct buffer_head * bh; struct buffer_head * bh;
...@@ -124,16 +125,16 @@ static int trunc_indirect (struct inode * inode, int offset, u32 * p) ...@@ -124,16 +125,16 @@ static int trunc_indirect (struct inode * inode, int offset, u32 * p)
#define INDIRECT_BLOCK ((int)DIRECT_BLOCK - offset) #define INDIRECT_BLOCK ((int)DIRECT_BLOCK - offset)
int indirect_block = INDIRECT_BLOCK; int indirect_block = INDIRECT_BLOCK;
tmp = *p; tmp = in_inode ? *p : le32_to_cpu(*p);
if (!tmp) if (!tmp)
return 0; return 0;
ind_bh = bread (inode->i_dev, tmp, inode->i_sb->s_blocksize); ind_bh = bread (inode->i_dev, tmp, inode->i_sb->s_blocksize);
if (tmp != *p) { if (tmp != (in_inode ? *p : le32_to_cpu(*p))) {
brelse (ind_bh); brelse (ind_bh);
return 1; return 1;
} }
if (!ind_bh) { if (!ind_bh) {
*p = 0; *p = in_inode ? 0 : cpu_to_le32(0);
return 0; return 0;
} }
repeat: repeat:
...@@ -184,100 +185,15 @@ static int trunc_indirect (struct inode * inode, int offset, u32 * p) ...@@ -184,100 +185,15 @@ static int trunc_indirect (struct inode * inode, int offset, u32 * p)
if (ind_bh->b_count != 1) if (ind_bh->b_count != 1)
retry = 1; retry = 1;
else { else {
tmp = *p; tmp = in_inode ? *p : le32_to_cpu(*p);
*p = 0; *p = in_inode ? 0 : cpu_to_le32(0);
inode->i_blocks -= blocks; inode->i_blocks -= blocks;
mark_inode_dirty(inode); mark_inode_dirty(inode);
ext2_free_blocks (inode, tmp, 1); ext2_free_blocks (inode, tmp, 1);
bforget(ind_bh);
ind_bh = NULL;
} }
if (IS_SYNC(inode) && buffer_dirty(ind_bh)) { if (IS_SYNC(inode) && ind_bh && buffer_dirty(ind_bh)) {
ll_rw_block (WRITE, 1, &ind_bh);
wait_on_buffer (ind_bh);
}
brelse (ind_bh);
return retry;
}
static int trunc_indirect_swab32 (struct inode * inode, int offset, u32 * p)
{
int i, tmp;
struct buffer_head * bh;
struct buffer_head * ind_bh;
u32 * ind;
unsigned long block_to_free = 0;
unsigned long free_count = 0;
int retry = 0;
int addr_per_block = EXT2_ADDR_PER_BLOCK(inode->i_sb);
int blocks = inode->i_sb->s_blocksize / 512;
int indirect_block = INDIRECT_BLOCK;
tmp = le32_to_cpu(*p);
if (!tmp)
return 0;
ind_bh = bread (inode->i_dev, tmp, inode->i_sb->s_blocksize);
if (tmp != le32_to_cpu(*p)) {
brelse (ind_bh);
return 1;
}
if (!ind_bh) {
*p = cpu_to_le32(0);
return 0;
}
repeat:
for (i = indirect_block ; i < addr_per_block ; i++) {
if (i < 0)
i = 0;
if (i < indirect_block)
goto repeat;
ind = i + (u32 *) ind_bh->b_data;
tmp = le32_to_cpu(*ind);
if (!tmp)
continue;
bh = get_hash_table (inode->i_dev, tmp,
inode->i_sb->s_blocksize);
if (i < indirect_block) {
brelse (bh);
goto repeat;
}
if ((bh && bh->b_count != 1) || tmp != le32_to_cpu(*ind)) {
retry = 1;
brelse (bh);
continue;
}
*ind = cpu_to_le32(0);
mark_buffer_dirty(ind_bh, 1);
bforget(bh);
if (free_count == 0) {
block_to_free = tmp;
free_count++;
} else if (free_count > 0 && block_to_free == tmp - free_count)
free_count++;
else {
ext2_free_blocks (inode, block_to_free, free_count);
block_to_free = tmp;
free_count = 1;
}
/* ext2_free_blocks (inode, tmp, 1); */
inode->i_blocks -= blocks;
mark_inode_dirty(inode);
}
if (free_count > 0)
ext2_free_blocks (inode, block_to_free, free_count);
ind = (u32 *) ind_bh->b_data;
for (i = 0; i < addr_per_block; i++)
if (le32_to_cpu(*(ind++)))
break;
if (i >= addr_per_block)
if (ind_bh->b_count != 1)
retry = 1;
else {
tmp = le32_to_cpu(*p);
*p = cpu_to_le32(0);
inode->i_blocks -= blocks;
mark_inode_dirty(inode);
ext2_free_blocks (inode, tmp, 1);
}
if (IS_SYNC(inode) && buffer_dirty(ind_bh)) {
ll_rw_block (WRITE, 1, &ind_bh); ll_rw_block (WRITE, 1, &ind_bh);
wait_on_buffer (ind_bh); wait_on_buffer (ind_bh);
} }
...@@ -286,7 +202,7 @@ static int trunc_indirect_swab32 (struct inode * inode, int offset, u32 * p) ...@@ -286,7 +202,7 @@ static int trunc_indirect_swab32 (struct inode * inode, int offset, u32 * p)
} }
static int trunc_dindirect (struct inode * inode, int offset, static int trunc_dindirect (struct inode * inode, int offset,
u32 * p) u32 * p, int in_inode)
{ {
int i, tmp; int i, tmp;
struct buffer_head * dind_bh; struct buffer_head * dind_bh;
...@@ -297,75 +213,16 @@ static int trunc_dindirect (struct inode * inode, int offset, ...@@ -297,75 +213,16 @@ static int trunc_dindirect (struct inode * inode, int offset,
#define DINDIRECT_BLOCK (((int)DIRECT_BLOCK - offset) / addr_per_block) #define DINDIRECT_BLOCK (((int)DIRECT_BLOCK - offset) / addr_per_block)
int dindirect_block = DINDIRECT_BLOCK; int dindirect_block = DINDIRECT_BLOCK;
tmp = *p; tmp = in_inode ? *p : le32_to_cpu(*p);
if (!tmp)
return 0;
dind_bh = bread (inode->i_dev, tmp, inode->i_sb->s_blocksize);
if (tmp != *p) {
brelse (dind_bh);
return 1;
}
if (!dind_bh) {
*p = 0;
return 0;
}
repeat:
for (i = dindirect_block ; i < addr_per_block ; i++) {
if (i < 0)
i = 0;
if (i < dindirect_block)
goto repeat;
dind = i + (u32 *) dind_bh->b_data;
tmp = le32_to_cpu(*dind);
if (!tmp)
continue;
retry |= trunc_indirect_swab32 (inode, offset + (i * addr_per_block),
dind);
mark_buffer_dirty(dind_bh, 1);
}
dind = (u32 *) dind_bh->b_data;
for (i = 0; i < addr_per_block; i++)
if (le32_to_cpu(*(dind++)))
break;
if (i >= addr_per_block)
if (dind_bh->b_count != 1)
retry = 1;
else {
tmp = *p;
*p = 0;
inode->i_blocks -= blocks;
mark_inode_dirty(inode);
ext2_free_blocks (inode, tmp, 1);
}
if (IS_SYNC(inode) && buffer_dirty(dind_bh)) {
ll_rw_block (WRITE, 1, &dind_bh);
wait_on_buffer (dind_bh);
}
brelse (dind_bh);
return retry;
}
static int trunc_dindirect_swab32 (struct inode * inode, int offset,
u32 * p)
{
int i, tmp;
struct buffer_head * dind_bh;
u32 * dind;
int retry = 0;
int addr_per_block = EXT2_ADDR_PER_BLOCK(inode->i_sb);
int blocks = inode->i_sb->s_blocksize / 512;
int dindirect_block = DINDIRECT_BLOCK;
tmp = le32_to_cpu(*p);
if (!tmp) if (!tmp)
return 0; return 0;
dind_bh = bread (inode->i_dev, tmp, inode->i_sb->s_blocksize); dind_bh = bread (inode->i_dev, tmp, inode->i_sb->s_blocksize);
if (tmp != le32_to_cpu(*p)) { if (tmp != (in_inode ? *p : le32_to_cpu(*p))) {
brelse (dind_bh); brelse (dind_bh);
return 1; return 1;
} }
if (!dind_bh) { if (!dind_bh) {
*p = cpu_to_le32(0); *p = in_inode ? 0 : cpu_to_le32(0);
return 0; return 0;
} }
repeat: repeat:
...@@ -378,8 +235,8 @@ static int trunc_dindirect_swab32 (struct inode * inode, int offset, ...@@ -378,8 +235,8 @@ static int trunc_dindirect_swab32 (struct inode * inode, int offset,
tmp = le32_to_cpu(*dind); tmp = le32_to_cpu(*dind);
if (!tmp) if (!tmp)
continue; continue;
retry |= trunc_indirect_swab32 (inode, offset + (i * addr_per_block), retry |= trunc_indirect(inode, offset + (i * addr_per_block),
dind); dind, 0);
mark_buffer_dirty(dind_bh, 1); mark_buffer_dirty(dind_bh, 1);
} }
dind = (u32 *) dind_bh->b_data; dind = (u32 *) dind_bh->b_data;
...@@ -390,13 +247,15 @@ static int trunc_dindirect_swab32 (struct inode * inode, int offset, ...@@ -390,13 +247,15 @@ static int trunc_dindirect_swab32 (struct inode * inode, int offset,
if (dind_bh->b_count != 1) if (dind_bh->b_count != 1)
retry = 1; retry = 1;
else { else {
tmp = le32_to_cpu(*p); tmp = in_inode ? *p : le32_to_cpu(*p);
*p = cpu_to_le32(0); *p = in_inode ? 0 : cpu_to_le32(0);
inode->i_blocks -= blocks; inode->i_blocks -= blocks;
mark_inode_dirty(inode); mark_inode_dirty(inode);
ext2_free_blocks (inode, tmp, 1); ext2_free_blocks (inode, tmp, 1);
bforget(dind_bh);
dind_bh = 0;
} }
if (IS_SYNC(inode) && buffer_dirty(dind_bh)) { if (IS_SYNC(inode) && dind_bh && buffer_dirty(dind_bh)) {
ll_rw_block (WRITE, 1, &dind_bh); ll_rw_block (WRITE, 1, &dind_bh);
wait_on_buffer (dind_bh); wait_on_buffer (dind_bh);
} }
...@@ -436,9 +295,9 @@ static int trunc_tindirect (struct inode * inode) ...@@ -436,9 +295,9 @@ static int trunc_tindirect (struct inode * inode)
if (i < tindirect_block) if (i < tindirect_block)
goto repeat; goto repeat;
tind = i + (u32 *) tind_bh->b_data; tind = i + (u32 *) tind_bh->b_data;
retry |= trunc_dindirect_swab32(inode, EXT2_NDIR_BLOCKS + retry |= trunc_dindirect(inode, EXT2_NDIR_BLOCKS +
addr_per_block + (i + 1) * addr_per_block * addr_per_block, addr_per_block + (i + 1) * addr_per_block * addr_per_block,
tind); tind, 0);
mark_buffer_dirty(tind_bh, 1); mark_buffer_dirty(tind_bh, 1);
} }
tind = (u32 *) tind_bh->b_data; tind = (u32 *) tind_bh->b_data;
...@@ -454,8 +313,10 @@ static int trunc_tindirect (struct inode * inode) ...@@ -454,8 +313,10 @@ static int trunc_tindirect (struct inode * inode)
inode->i_blocks -= blocks; inode->i_blocks -= blocks;
mark_inode_dirty(inode); mark_inode_dirty(inode);
ext2_free_blocks (inode, tmp, 1); ext2_free_blocks (inode, tmp, 1);
bforget(tind_bh);
tind_bh = 0;
} }
if (IS_SYNC(inode) && buffer_dirty(tind_bh)) { if (IS_SYNC(inode) && tind_bh && buffer_dirty(tind_bh)) {
ll_rw_block (WRITE, 1, &tind_bh); ll_rw_block (WRITE, 1, &tind_bh);
wait_on_buffer (tind_bh); wait_on_buffer (tind_bh);
} }
...@@ -479,10 +340,10 @@ void ext2_truncate (struct inode * inode) ...@@ -479,10 +340,10 @@ void ext2_truncate (struct inode * inode)
while (1) { while (1) {
retry = trunc_direct(inode); retry = trunc_direct(inode);
retry |= trunc_indirect (inode, EXT2_IND_BLOCK, retry |= trunc_indirect (inode, EXT2_IND_BLOCK,
(u32 *) &inode->u.ext2_i.i_data[EXT2_IND_BLOCK]); (u32 *) &inode->u.ext2_i.i_data[EXT2_IND_BLOCK], 1);
retry |= trunc_dindirect (inode, EXT2_IND_BLOCK + retry |= trunc_dindirect (inode, EXT2_IND_BLOCK +
EXT2_ADDR_PER_BLOCK(inode->i_sb), EXT2_ADDR_PER_BLOCK(inode->i_sb),
(u32 *) &inode->u.ext2_i.i_data[EXT2_DIND_BLOCK]); (u32 *) &inode->u.ext2_i.i_data[EXT2_DIND_BLOCK], 1);
retry |= trunc_tindirect (inode); retry |= trunc_tindirect (inode);
if (!retry) if (!retry)
break; break;
......
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
#include <linux/config.h> #include <linux/config.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/nametrans.h>
#include <linux/minix_fs.h> #include <linux/minix_fs.h>
#include <linux/ext2_fs.h> #include <linux/ext2_fs.h>
...@@ -45,10 +44,6 @@ __initfunc(static void do_sys_setup(void)) ...@@ -45,10 +44,6 @@ __initfunc(static void do_sys_setup(void))
binfmt_setup(); binfmt_setup();
#ifdef CONFIG_TRANS_NAMES
init_nametrans();
#endif
#ifdef CONFIG_EXT2_FS #ifdef CONFIG_EXT2_FS
init_ext2_fs(); init_ext2_fs();
#endif #endif
......
...@@ -7,8 +7,6 @@ ...@@ -7,8 +7,6 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/dalloc.h>
#include <linux/list.h>
/* /*
* New inode.c implementation. * New inode.c implementation.
...@@ -105,6 +103,7 @@ static inline void init_once(struct inode * inode) ...@@ -105,6 +103,7 @@ static inline void init_once(struct inode * inode)
{ {
memset(inode, 0, sizeof(*inode)); memset(inode, 0, sizeof(*inode));
init_waitqueue(&inode->i_wait); init_waitqueue(&inode->i_wait);
INIT_LIST_HEAD(&inode->i_dentry);
sema_init(&inode->i_sem, 1); sema_init(&inode->i_sem, 1);
} }
...@@ -301,6 +300,7 @@ void clean_inode(struct inode *inode) ...@@ -301,6 +300,7 @@ void clean_inode(struct inode *inode)
inode->i_sock = 0; inode->i_sock = 0;
inode->i_op = NULL; inode->i_op = NULL;
inode->i_nlink = 1; inode->i_nlink = 1;
inode->i_writecount = 0;
memset(&inode->i_dquot, 0, sizeof(inode->i_dquot)); memset(&inode->i_dquot, 0, sizeof(inode->i_dquot));
sema_init(&inode->i_sem, 1); sema_init(&inode->i_sem, 1);
} }
......
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
#include <linux/string.h> #include <linux/string.h>
#include <linux/stat.h> #include <linux/stat.h>
#include <linux/locks.h> #include <linux/locks.h>
#include <linux/dalloc.h>
#include <linux/init.h> #include <linux/init.h>
#include <asm/system.h> #include <asm/system.h>
......
...@@ -227,7 +227,7 @@ int minix_create(struct inode * dir, struct dentry *dentry, int mode) ...@@ -227,7 +227,7 @@ int minix_create(struct inode * dir, struct dentry *dentry, int mode)
de->inode = inode->i_ino; de->inode = inode->i_ino;
mark_buffer_dirty(bh, 1); mark_buffer_dirty(bh, 1);
brelse(bh); brelse(bh);
d_instantiate(dentry, inode, 0); d_instantiate(dentry, inode);
return 0; return 0;
} }
...@@ -280,7 +280,7 @@ int minix_mknod(struct inode * dir, struct dentry *dentry, int mode, int rdev) ...@@ -280,7 +280,7 @@ int minix_mknod(struct inode * dir, struct dentry *dentry, int mode, int rdev)
de->inode = inode->i_ino; de->inode = inode->i_ino;
mark_buffer_dirty(bh, 1); mark_buffer_dirty(bh, 1);
brelse(bh); brelse(bh);
d_instantiate(dentry, inode, 0); d_instantiate(dentry, inode);
return 0; return 0;
} }
...@@ -340,7 +340,7 @@ int minix_mkdir(struct inode * dir, struct dentry *dentry, int mode) ...@@ -340,7 +340,7 @@ int minix_mkdir(struct inode * dir, struct dentry *dentry, int mode)
dir->i_nlink++; dir->i_nlink++;
dir->i_dirt = 1; dir->i_dirt = 1;
brelse(bh); brelse(bh);
d_instantiate(dentry, inode, D_DIR); d_instantiate(dentry, inode);
return 0; return 0;
} }
...@@ -563,7 +563,7 @@ int minix_symlink(struct inode * dir, struct dentry *dentry, ...@@ -563,7 +563,7 @@ int minix_symlink(struct inode * dir, struct dentry *dentry,
de->inode = inode->i_ino; de->inode = inode->i_ino;
mark_buffer_dirty(bh, 1); mark_buffer_dirty(bh, 1);
brelse(bh); brelse(bh);
d_instantiate(dentry, inode, 0); d_instantiate(dentry, inode);
return 0; return 0;
} }
...@@ -598,7 +598,7 @@ int minix_link(struct inode * inode, struct inode * dir, ...@@ -598,7 +598,7 @@ int minix_link(struct inode * inode, struct inode * dir,
inode->i_nlink++; inode->i_nlink++;
inode->i_ctime = CURRENT_TIME; inode->i_ctime = CURRENT_TIME;
inode->i_dirt = 1; inode->i_dirt = 1;
d_instantiate(dentry, inode, 0); d_instantiate(dentry, inode);
return 0; return 0;
} }
......
...@@ -19,10 +19,7 @@ ...@@ -19,10 +19,7 @@
#include <linux/fcntl.h> #include <linux/fcntl.h>
#include <linux/stat.h> #include <linux/stat.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/dalloc.h>
#include <linux/nametrans.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/omirr.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
...@@ -236,9 +233,9 @@ void put_write_access(struct inode * inode) ...@@ -236,9 +233,9 @@ void put_write_access(struct inode * inode)
* We get the directory semaphore, and after getting that we also * We get the directory semaphore, and after getting that we also
* make sure that nobody added the entry to the dcache in the meantime.. * make sure that nobody added the entry to the dcache in the meantime..
*/ */
static struct dentry * real_lookup(struct dentry * dentry, struct qstr * name) static struct dentry * real_lookup(struct dentry * parent, struct qstr * name)
{ {
struct inode *dir = dentry->d_inode; struct inode *dir = parent->d_inode;
struct dentry *result; struct dentry *result;
struct inode *inode; struct inode *inode;
int error = -ENOTDIR; int error = -ENOTDIR;
...@@ -252,26 +249,21 @@ static struct dentry * real_lookup(struct dentry * dentry, struct qstr * name) ...@@ -252,26 +249,21 @@ static struct dentry * real_lookup(struct dentry * dentry, struct qstr * name)
if (!error || error == -ENOENT) { if (!error || error == -ENOENT) {
struct dentry *new; struct dentry *new;
int isdir = 0, flags = D_NOCHECKDUP;
if (error) { if (error)
flags = D_NEGATIVE;
inode = NULL; inode = NULL;
} else if (S_ISDIR(inode->i_mode)) {
isdir = 1; new = d_alloc(parent, name);
flags = D_DIR|D_NOCHECKDUP;
}
new = d_alloc(dentry, name, isdir);
/* /*
* Ok, now we can't sleep any more. Double-check that * Ok, now we can't sleep any more. Double-check that
* nobody else added this in the meantime.. * nobody else added this in the meantime..
*/ */
result = d_lookup(dentry, name); result = d_lookup(parent, name);
if (result) { if (result) {
d_free(new); d_free(new);
} else { } else {
d_add(new, inode, flags); d_add(new, inode);
result = new; result = new;
} }
} }
...@@ -280,16 +272,39 @@ static struct dentry * real_lookup(struct dentry * dentry, struct qstr * name) ...@@ -280,16 +272,39 @@ static struct dentry * real_lookup(struct dentry * dentry, struct qstr * name)
} }
/* Internal lookup() using the new generic dcache. */ /* Internal lookup() using the new generic dcache. */
static inline struct dentry * cached_lookup(struct dentry * dentry, struct qstr * name) static inline struct dentry * cached_lookup(struct dentry * parent, struct qstr * name)
{ {
return d_lookup(dentry, name); struct dentry * dentry = d_lookup(parent, name);
if (dentry) {
/*
* FIXME! We should have something like
dentry = dentry->revalidate(dentry);
* here - we need to ask the low-level filesystem permission
* to use the cached entry (NFS needs to time them out, and
* /proc might go away etc).
*/
/*
* The parent d_count _should_ be at least 2: one for the
* dentry we found, and one for the fact that we are using
* it.
*/
if (parent->d_count <= 1) {
printk("lookup of %s success in %s, but parent count is %d\n",
dentry->d_name, parent->d_name, parent->d_count);
}
}
return dentry;
} }
/* /*
* "." and ".." are special - ".." especially so because it has to be able * "." and ".." are special - ".." especially so because it has to be able
* to know about the current root directory and parent relationships * to know about the current root directory and parent relationships
*/ */
static struct dentry * reserved_lookup(struct dentry * dir, struct qstr * name) static struct dentry * reserved_lookup(struct dentry * parent, struct qstr * name)
{ {
struct dentry *result = NULL; struct dentry *result = NULL;
if (name->name[0] == '.') { if (name->name[0] == '.') {
...@@ -300,12 +315,12 @@ static struct dentry * reserved_lookup(struct dentry * dir, struct qstr * name) ...@@ -300,12 +315,12 @@ static struct dentry * reserved_lookup(struct dentry * dir, struct qstr * name)
if (name->name[1] != '.') if (name->name[1] != '.')
break; break;
if (dir != current->fs->root) { if (parent != current->fs->root) {
dir = dir->d_covers->d_parent; parent = parent->d_covers->d_parent;
} }
/* fallthrough */ /* fallthrough */
case 1: case 1:
result = dget(dir); result = dget(parent);
break; break;
} }
} }
...@@ -425,7 +440,7 @@ struct dentry * lookup_dentry(const char * name, struct dentry * base, int follo ...@@ -425,7 +440,7 @@ struct dentry * lookup_dentry(const char * name, struct dentry * base, int follo
dentry = lookup(base, &this); dentry = lookup(base, &this);
if (IS_ERR(dentry)) if (IS_ERR(dentry))
break; break;
if (dentry->d_flag & D_NEGATIVE) if (!dentry->d_inode)
break; break;
/* Last component? */ /* Last component? */
...@@ -466,8 +481,8 @@ int __namei(const char *pathname, struct inode **res_inode, int follow_link) ...@@ -466,8 +481,8 @@ int __namei(const char *pathname, struct inode **res_inode, int follow_link)
if (!IS_ERR(dentry)) { if (!IS_ERR(dentry)) {
error = -ENOENT; error = -ENOENT;
if (dentry) { if (dentry) {
if (!(dentry->d_flag & D_NEGATIVE)) { struct inode *inode = dentry->d_inode;
struct inode *inode = dentry->d_inode; if (inode) {
atomic_inc(&inode->i_count); atomic_inc(&inode->i_count);
*res_inode = inode; *res_inode = inode;
error = 0; error = 0;
...@@ -509,20 +524,21 @@ static inline struct inode *lock_parent(struct dentry *dentry) ...@@ -509,20 +524,21 @@ static inline struct inode *lock_parent(struct dentry *dentry)
* which is a lot more logical, and also allows the "no perm" needed * which is a lot more logical, and also allows the "no perm" needed
* for symlinks (where the permissions are checked later). * for symlinks (where the permissions are checked later).
*/ */
int open_namei(const char * pathname, int flag, int mode, int open_namei(const char * pathname, int flag, int mode, struct inode ** res_inode)
struct inode ** res_inode, struct dentry * base)
{ {
int error; int error;
int acc_mode;
struct inode *inode; struct inode *inode;
struct dentry *dentry; struct dentry *dentry;
mode &= S_IALLUGO & ~current->fs->umask; mode &= S_IALLUGO & ~current->fs->umask;
mode |= S_IFREG; mode |= S_IFREG;
dentry = lookup_dentry(pathname, base, 1); dentry = lookup_dentry(pathname, NULL, 1);
if (IS_ERR(dentry)) if (IS_ERR(dentry))
return PTR_ERR(dentry); return PTR_ERR(dentry);
acc_mode = ACC_MODE(flag);
if (flag & O_CREAT) { if (flag & O_CREAT) {
struct inode *dir; struct inode *dir;
...@@ -531,7 +547,7 @@ int open_namei(const char * pathname, int flag, int mode, ...@@ -531,7 +547,7 @@ int open_namei(const char * pathname, int flag, int mode,
* The existence test must be done _after_ getting the directory * The existence test must be done _after_ getting the directory
* semaphore - the dentry might otherwise change. * semaphore - the dentry might otherwise change.
*/ */
if (!(dentry->d_flag & D_NEGATIVE)) { if (dentry->d_inode) {
error = 0; error = 0;
if (flag & O_EXCL) if (flag & O_EXCL)
error = -EEXIST; error = -EEXIST;
...@@ -543,6 +559,8 @@ int open_namei(const char * pathname, int flag, int mode, ...@@ -543,6 +559,8 @@ int open_namei(const char * pathname, int flag, int mode,
if (dir->i_sb && dir->i_sb->dq_op) if (dir->i_sb && dir->i_sb->dq_op)
dir->i_sb->dq_op->initialize(dir, -1); dir->i_sb->dq_op->initialize(dir, -1);
error = dir->i_op->create(dir, dentry, mode); error = dir->i_op->create(dir, dentry, mode);
/* Don't check for write permission */
acc_mode = 0;
} }
up(&dir->i_sem); up(&dir->i_sem);
iput(dir); iput(dir);
...@@ -551,15 +569,15 @@ int open_namei(const char * pathname, int flag, int mode, ...@@ -551,15 +569,15 @@ int open_namei(const char * pathname, int flag, int mode,
} }
error = -ENOENT; error = -ENOENT;
if (dentry->d_flag & D_NEGATIVE) inode = dentry->d_inode;
if (!inode)
goto exit; goto exit;
inode = dentry->d_inode;
error = -EISDIR; error = -EISDIR;
if (S_ISDIR(inode->i_mode) && (flag & 2)) if (S_ISDIR(inode->i_mode) && (flag & FMODE_WRITE))
goto exit; goto exit;
error = permission(inode,ACC_MODE(flag)); error = permission(inode,acc_mode);
if (error) if (error)
goto exit; goto exit;
...@@ -636,7 +654,7 @@ int do_mknod(const char * filename, int mode, dev_t dev) ...@@ -636,7 +654,7 @@ int do_mknod(const char * filename, int mode, dev_t dev)
dir = lock_parent(dentry); dir = lock_parent(dentry);
error = -EEXIST; error = -EEXIST;
if (!(dentry->d_flag & D_NEGATIVE)) if (dentry->d_inode)
goto exit_lock; goto exit_lock;
error = -EROFS; error = -EROFS;
...@@ -710,7 +728,7 @@ static inline int do_mkdir(const char * pathname, int mode) ...@@ -710,7 +728,7 @@ static inline int do_mkdir(const char * pathname, int mode)
dir = lock_parent(dentry); dir = lock_parent(dentry);
error = -EEXIST; error = -EEXIST;
if (!(dentry->d_flag & D_NEGATIVE)) if (dentry->d_inode)
goto exit_lock; goto exit_lock;
error = -EROFS; error = -EROFS;
...@@ -766,7 +784,7 @@ static inline int do_rmdir(const char * name) ...@@ -766,7 +784,7 @@ static inline int do_rmdir(const char * name)
dir = lock_parent(dentry); dir = lock_parent(dentry);
error = -ENOENT; error = -ENOENT;
if (dentry->d_flag & D_NEGATIVE) if (!dentry->d_inode)
goto exit_lock; goto exit_lock;
error = -EROFS; error = -EROFS;
...@@ -894,7 +912,7 @@ static inline int do_symlink(const char * oldname, const char * newname) ...@@ -894,7 +912,7 @@ static inline int do_symlink(const char * oldname, const char * newname)
goto exit; goto exit;
error = -EEXIST; error = -EEXIST;
if (!(dentry->d_flag & D_NEGATIVE)) if (dentry->d_inode)
goto exit; goto exit;
dir = lock_parent(dentry); dir = lock_parent(dentry);
...@@ -961,18 +979,18 @@ static inline int do_link(const char * oldname, const char * newname) ...@@ -961,18 +979,18 @@ static inline int do_link(const char * oldname, const char * newname)
dir = lock_parent(new_dentry); dir = lock_parent(new_dentry);
error = -ENOENT; error = -ENOENT;
if (old_dentry->d_flag & D_NEGATIVE) inode = old_dentry->d_inode;
if (!inode)
goto exit_lock; goto exit_lock;
error = -EEXIST; error = -EEXIST;
if (!(new_dentry->d_flag & D_NEGATIVE)) if (new_dentry->d_inode)
goto exit_lock; goto exit_lock;
error = -EROFS; error = -EROFS;
if (IS_RDONLY(dir)) if (IS_RDONLY(dir))
goto exit_lock; goto exit_lock;
inode = old_dentry->d_inode;
error = -EXDEV; error = -EXDEV;
if (dir->i_dev != inode->i_dev) if (dir->i_dev != inode->i_dev)
goto exit_lock; goto exit_lock;
...@@ -1067,7 +1085,7 @@ static inline int do_rename(const char * oldname, const char * newname) ...@@ -1067,7 +1085,7 @@ static inline int do_rename(const char * oldname, const char * newname)
double_down(&new_dir->i_sem, &old_dir->i_sem); double_down(&new_dir->i_sem, &old_dir->i_sem);
error = -ENOENT; error = -ENOENT;
if (old_dentry->d_flag & D_NEGATIVE) if (!old_dentry->d_inode)
goto exit_lock; goto exit_lock;
error = permission(old_dir,MAY_WRITE | MAY_EXEC); error = permission(old_dir,MAY_WRITE | MAY_EXEC);
......
...@@ -395,7 +395,7 @@ static int nfs_create(struct inode *dir, struct dentry * dentry, int mode) ...@@ -395,7 +395,7 @@ static int nfs_create(struct inode *dir, struct dentry * dentry, int mode)
if (!inode) if (!inode)
return -EACCES; return -EACCES;
d_instantiate(dentry, inode, 0); d_instantiate(dentry, inode);
return 0; return 0;
} }
...@@ -434,7 +434,7 @@ static int nfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rde ...@@ -434,7 +434,7 @@ static int nfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rde
if (!inode) if (!inode)
return -EACCES; return -EACCES;
d_instantiate(dentry, inode, 0); d_instantiate(dentry, inode);
return 0; return 0;
} }
...@@ -471,7 +471,7 @@ static int nfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) ...@@ -471,7 +471,7 @@ static int nfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
if (!inode) if (!inode)
return -EACCES; return -EACCES;
d_instantiate(dentry, inode, D_DIR); d_instantiate(dentry, inode);
return 0; return 0;
} }
...@@ -561,7 +561,7 @@ static int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *sym ...@@ -561,7 +561,7 @@ static int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *sym
if (!inode) if (!inode)
return -EACCES; return -EACCES;
d_instantiate(dentry, inode, 0); d_instantiate(dentry, inode);
return 0; return 0;
} }
...@@ -588,7 +588,7 @@ static int nfs_link(struct inode *inode, struct inode *dir, struct dentry *dentr ...@@ -588,7 +588,7 @@ static int nfs_link(struct inode *inode, struct inode *dir, struct dentry *dentr
return error; return error;
atomic_inc(&inode->i_count); atomic_inc(&inode->i_count);
d_instantiate(dentry, inode, 0); d_instantiate(dentry, inode);
return 0; return 0;
} }
......
...@@ -4,7 +4,6 @@ ...@@ -4,7 +4,6 @@
* Copyright (C) 1991, 1992 Linus Torvalds * Copyright (C) 1991, 1992 Linus Torvalds
*/ */
#include <linux/config.h>
#include <linux/vfs.h> #include <linux/vfs.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/utime.h> #include <linux/utime.h>
...@@ -21,7 +20,6 @@ ...@@ -21,7 +20,6 @@
#include <linux/file.h> #include <linux/file.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/omirr.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/bitops.h> #include <asm/bitops.h>
...@@ -211,11 +209,6 @@ asmlinkage int sys_utime(char * filename, struct utimbuf * times) ...@@ -211,11 +209,6 @@ asmlinkage int sys_utime(char * filename, struct utimbuf * times)
goto iput_and_out; goto iput_and_out;
} }
error = notify_change(inode, &newattrs); error = notify_change(inode, &newattrs);
#ifdef CONFIG_OMIRR
if(!error)
omirr_printall(inode, " U %ld %ld %ld ", CURRENT_TIME,
newattrs.ia_atime, newattrs.ia_mtime);
#endif
iput_and_out: iput_and_out:
iput(inode); iput(inode);
out: out:
...@@ -257,11 +250,6 @@ asmlinkage int sys_utimes(char * filename, struct timeval * utimes) ...@@ -257,11 +250,6 @@ asmlinkage int sys_utimes(char * filename, struct timeval * utimes)
goto iput_and_out; goto iput_and_out;
} }
error = notify_change(inode, &newattrs); error = notify_change(inode, &newattrs);
#ifdef CONFIG_OMIRR
if(!error)
omirr_printall(inode, " U %ld %ld %ld ", CURRENT_TIME,
newattrs.ia_atime, newattrs.ia_mtime);
#endif
iput_and_out: iput_and_out:
iput(inode); iput(inode);
out: out:
...@@ -312,11 +300,11 @@ asmlinkage int sys_chdir(const char * filename) ...@@ -312,11 +300,11 @@ asmlinkage int sys_chdir(const char * filename)
goto out; goto out;
error = -ENOENT; error = -ENOENT;
if (dentry->d_flag & D_NEGATIVE) inode = dentry->d_inode;
if (!inode)
goto dput_and_out; goto dput_and_out;
error = -ENOTDIR; error = -ENOTDIR;
inode = dentry->d_inode;
if (!S_ISDIR(inode->i_mode)) if (!S_ISDIR(inode->i_mode))
goto dput_and_out; goto dput_and_out;
...@@ -340,7 +328,6 @@ asmlinkage int sys_fchdir(unsigned int fd) ...@@ -340,7 +328,6 @@ asmlinkage int sys_fchdir(unsigned int fd)
{ {
struct file *file; struct file *file;
struct inode *inode; struct inode *inode;
struct dentry *dentry, *tmp;
int error; int error;
lock_kernel(); lock_kernel();
...@@ -361,10 +348,14 @@ asmlinkage int sys_fchdir(unsigned int fd) ...@@ -361,10 +348,14 @@ asmlinkage int sys_fchdir(unsigned int fd)
if (error) if (error)
goto out; goto out;
dentry = dget(inode->i_dentry); {
tmp = current->fs->pwd; struct dentry *dentry, *tmp;
current->fs->pwd = dentry;
dput(tmp); dentry = dget(i_dentry(inode));
tmp = current->fs->pwd;
current->fs->pwd = dentry;
dput(tmp);
}
out: out:
unlock_kernel(); unlock_kernel();
return error; return error;
...@@ -384,11 +375,11 @@ asmlinkage int sys_chroot(const char * filename) ...@@ -384,11 +375,11 @@ asmlinkage int sys_chroot(const char * filename)
goto out; goto out;
error = -ENOENT; error = -ENOENT;
if (dentry->d_flag & D_NEGATIVE) inode = dentry->d_inode;
if (!inode)
goto dput_and_out; goto dput_and_out;
error = -ENOTDIR; error = -ENOTDIR;
inode = dentry->d_inode;
if (!S_ISDIR(inode->i_mode)) if (!S_ISDIR(inode->i_mode))
goto dput_and_out; goto dput_and_out;
...@@ -619,7 +610,7 @@ static int do_open(const char * filename,int flags,int mode, int fd) ...@@ -619,7 +610,7 @@ static int do_open(const char * filename,int flags,int mode, int fd)
flag++; flag++;
if (flag & O_TRUNC) if (flag & O_TRUNC)
flag |= 2; flag |= 2;
error = open_namei(filename,flag,mode,&inode,NULL); error = open_namei(filename,flag,mode,&inode);
if (error) if (error)
goto cleanup_file; goto cleanup_file;
if (f->f_mode & FMODE_WRITE) { if (f->f_mode & FMODE_WRITE) {
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/stat.h> #include <linux/stat.h>
#include <linux/dalloc.h>
static int proc_readlink(struct inode *, char *, int); static int proc_readlink(struct inode *, char *, int);
static struct dentry * proc_follow_link(struct inode *, struct dentry *); static struct dentry * proc_follow_link(struct inode *, struct dentry *);
...@@ -105,7 +104,7 @@ static struct dentry * proc_follow_link(struct inode *inode, struct dentry *base ...@@ -105,7 +104,7 @@ static struct dentry * proc_follow_link(struct inode *inode, struct dentry *base
vma = p->mm->mmap; vma = p->mm->mmap;
while (vma) { while (vma) {
if (vma->vm_flags & VM_EXECUTABLE) if (vma->vm_flags & VM_EXECUTABLE)
return dget(vma->vm_inode->i_dentry); return dget(i_dentry(vma->vm_inode));
vma = vma->vm_next; vma = vma->vm_next;
} }
...@@ -123,7 +122,7 @@ static struct dentry * proc_follow_link(struct inode *inode, struct dentry *base ...@@ -123,7 +122,7 @@ static struct dentry * proc_follow_link(struct inode *inode, struct dentry *base
break; break;
if (!p->files->fd[ino]->f_inode) if (!p->files->fd[ino]->f_inode)
break; break;
result = dget(p->files->fd[ino]->f_inode->i_dentry); result = dget(i_dentry(p->files->fd[ino]->f_inode));
break; break;
} }
} }
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#include <linux/string.h> #include <linux/string.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/dalloc.h>
#include <linux/omirr.h> #include <linux/omirr.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
......
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/fd.h> #include <linux/fd.h>
#include <linux/dalloc.h>
#include <linux/init.h> #include <linux/init.h>
#include <asm/system.h> #include <asm/system.h>
...@@ -745,7 +744,7 @@ int do_mount(kdev_t dev, const char * dev_name, const char * dir_name, const cha ...@@ -745,7 +744,7 @@ int do_mount(kdev_t dev, const char * dev_name, const char * dir_name, const cha
if (IS_ERR(dir_d)) if (IS_ERR(dir_d))
return error; return error;
if (dir_d->d_flag & D_NEGATIVE) { if (!dir_d->d_inode) {
dput(dir_d); dput(dir_d);
return -ENOENT; return -ENOENT;
} }
......
/* $Revision: 1.7 $$Date: 1997/03/26 10:30:00 $ /* $Revision: 2.0 $$Date: 1997/06/30 10:30:00 $
* linux/include/linux/cyclades.h * linux/include/linux/cyclades.h
* *
* This file is maintained by Marcio Saito <marcio@cyclades.com> and * This file is maintained by Marcio Saito <marcio@cyclades.com> and
...@@ -6,6 +6,14 @@ ...@@ -6,6 +6,14 @@
* *
* This file contains the general definitions for the cyclades.c driver * This file contains the general definitions for the cyclades.c driver
*$Log: cyclades.h,v $ *$Log: cyclades.h,v $
*Revision 2.0 1997/06/30 10:30:00 ivan
*added some new doorbell command constants related to IOCTLW and
*UART error signaling
*
*Revision 1.8 1997/06/03 15:30:00 ivan
*added constant ZFIRM_HLT
*added constant CyPCI_Ze_win ( = 2 * Cy_PCI_Zwin)
*
*Revision 1.7 1997/03/26 10:30:00 daniel *Revision 1.7 1997/03/26 10:30:00 daniel
*new entries at the end of cyclades_port struct to reallocate *new entries at the end of cyclades_port struct to reallocate
*variables illegally allocated within card memory. *variables illegally allocated within card memory.
...@@ -86,6 +94,8 @@ typedef unsigned char ucchar; /* 8 bits, unsigned */ ...@@ -86,6 +94,8 @@ typedef unsigned char ucchar; /* 8 bits, unsigned */
*/ */
#define DP_WINDOW_SIZE (0x00080000) /* window size 512 Kb */ #define DP_WINDOW_SIZE (0x00080000) /* window size 512 Kb */
#define ZE_DP_WINDOW_SIZE (0x00100000) /* window size 1 Mb (Ze and
8Zo V.2 */
#define CTRL_WINDOW_SIZE (0x00000100) /* runtime regs 256 bytes */ #define CTRL_WINDOW_SIZE (0x00000100) /* runtime regs 256 bytes */
/* /*
...@@ -183,6 +193,7 @@ struct RUNTIME_9060 { ...@@ -183,6 +193,7 @@ struct RUNTIME_9060 {
#define ID_ADDRESS 0x00000180L /* signature/pointer address */ #define ID_ADDRESS 0x00000180L /* signature/pointer address */
#define ZFIRM_ID 0x5557465AL /* ZFIRM/U signature */ #define ZFIRM_ID 0x5557465AL /* ZFIRM/U signature */
#define ZFIRM_HLT 0x59505B5CL /* ZFIRM needs external power supply */
struct FIRM_ID { struct FIRM_ID {
uclong signature; /* ZFIRM/U signature */ uclong signature; /* ZFIRM/U signature */
uclong zfwctrl_addr; /* pointer to ZFW_CTRL structure */ uclong zfwctrl_addr; /* pointer to ZFW_CTRL structure */
...@@ -238,7 +249,10 @@ struct FIRM_ID { ...@@ -238,7 +249,10 @@ struct FIRM_ID {
#define C_IN_RXBRK 0x00001000 /* Break received */ #define C_IN_RXBRK 0x00001000 /* Break received */
#define C_IN_PR_ERROR 0x00002000 /* parity error */ #define C_IN_PR_ERROR 0x00002000 /* parity error */
#define C_IN_FR_ERROR 0x00004000 /* frame error */ #define C_IN_FR_ERROR 0x00004000 /* frame error */
#define C_IN_OVR_ERROR 0x00008000 /* overrun error */
#define C_IN_RXOFL 0x00010000 /* RX buffer overflow */
#define C_IN_IOCTLW 0x00020000 /* I/O control w/ wait */
/* flow control */ /* flow control */
#define C_FL_OXX 0x00000001 /* output Xon/Xoff flow control */ #define C_FL_OXX 0x00000001 /* output Xon/Xoff flow control */
...@@ -294,6 +308,8 @@ struct FIRM_ID { ...@@ -294,6 +308,8 @@ struct FIRM_ID {
#define C_CM_RXBRK 0x84 /* Break received */ #define C_CM_RXBRK 0x84 /* Break received */
#define C_CM_PR_ERROR 0x85 /* Parity error */ #define C_CM_PR_ERROR 0x85 /* Parity error */
#define C_CM_FR_ERROR 0x86 /* Frame error */ #define C_CM_FR_ERROR 0x86 /* Frame error */
#define C_CM_OVR_ERROR 0x87 /* Overrun error */
#define C_CM_RXOFL 0x88 /* RX buffer overflow */
#define C_CM_CMDERROR 0x90 /* command error */ #define C_CM_CMDERROR 0x90 /* command error */
#define C_CM_FATAL 0x91 /* fatal error */ #define C_CM_FATAL 0x91 /* fatal error */
#define C_CM_HW_RESET 0x92 /* reset board */ #define C_CM_HW_RESET 0x92 /* reset board */
...@@ -468,9 +484,10 @@ struct cyclades_port { ...@@ -468,9 +484,10 @@ struct cyclades_port {
#define CyMaxChipsPerCard 8 #define CyMaxChipsPerCard 8
#define CyPCI_Ywin 0x4000 #define CyPCI_Ywin 0x4000
#define CyPCI_Zctl 0x100 #define CyPCI_Zctl 0x100
#define CyPCI_Zwin 0x80000 #define CyPCI_Zwin 0x80000
#define CyPCI_Ze_win (2 * CyPCI_Zwin)
/**** CD1400 registers ****/ /**** CD1400 registers ****/
......
#ifndef DALLOC_H #ifndef __LINUX_DCACHE_H
#define DALLOC_H #define __LINUX_DCACHE_H
/* /*
* $Id: dalloc.h,v 1.3 1997/06/13 04:39:34 davem Exp $ * linux/include/linux/dcache.h
* *
* include/linux/dalloc.h - alloc routines for dcache * Directory cache data structures
* alloc / free space for pathname strings
* Copyright (C) 1997, Thomas Schoebel-Theuer,
* <schoebel@informatik.uni-stuttgart.de>.
*/ */
#define D_MAXLEN 1024 #define D_MAXLEN 1024
/* public flags for d_add() */
#define D_NORMAL 0
#define D_BASKET 1 /* put into basket (deleted/unref'd files) */
#define D_DUPLICATE 2 /* allow duplicate entries */
#define D_NOCHECKDUP 4 /* no not check for duplicates */
#define D_NEGATIVE 8 /* negative entry */
#define D_PRELOADED 16
#define D_DIR 32 /* directory entry - look out for allocation issues */
#define D_HASHED 64
#define D_ZOMBIE 128
#define D_INC_DDIR 512
/* public flags for d_del() */
#define D_REMOVE 0
#define D_NO_CLEAR_INODE 1
#define IS_ROOT(x) ((x) == (x)->d_parent) #define IS_ROOT(x) ((x) == (x)->d_parent)
/* "quick string" -- I introduced this to shorten the parameter list /*
* of many routines. Think of it as a (str,stlen,hash) pair. * "quick string" -- eases parameter passing, but more importantly
* Storing the len instead of doing strlen() very often is performance * saves "metadata" about the string (ie length and the hash).
* critical.
*/ */
struct qstr { struct qstr {
const unsigned char * name; const unsigned char * name;
int len, hash; unsigned int len, hash;
}; };
/* Name hashing routines. Initial hash value */ /* Name hashing routines. Initial hash value */
...@@ -58,63 +39,44 @@ static inline unsigned long end_name_hash(unsigned long hash) ...@@ -58,63 +39,44 @@ static inline unsigned long end_name_hash(unsigned long hash)
} }
struct dentry { struct dentry {
unsigned int d_flag; int d_count;
unsigned int d_count; unsigned int d_flags;
struct inode * d_inode; /* Where the name belongs to */ struct inode * d_inode; /* Where the name belongs to - NULL is negative */
struct dentry * d_parent; /* parent directory */ struct dentry * d_parent; /* parent directory */
struct dentry * d_mounts; /* mount information */ struct dentry * d_mounts; /* mount information */
struct dentry * d_covers; struct dentry * d_covers;
struct dentry * d_next; /* hardlink aliasname / empty list */ struct list_head d_list; /* hardlink aliasname / empty list */
struct dentry * d_prev; /* hardlink aliasname */ struct list_head d_hash;
struct dentry * d_hash_next;
struct dentry * d_hash_prev;
struct dentry * d_basket_next;
struct dentry * d_basket_prev;
struct qstr d_name; struct qstr d_name;
}; };
extern struct dentry * the_root;
/* /*
* These are the low-level FS interfaces to the dcache.. * These are the low-level FS interfaces to the dcache..
*/ */
extern void d_instantiate(struct dentry *, struct inode *, int); extern void d_instantiate(struct dentry *, struct inode *);
extern void d_delete(struct dentry *); extern void d_delete(struct dentry *);
/* Note that all these routines must be called with vfs_lock() held */ /* Note that all these routines must be called with vfs_lock() held */
/* get inode, if necessary retrieve it with iget() */ /* get inode, if necessary retrieve it with iget() */
extern blocking struct inode * d_inode(struct dentry ** changing_entry); extern struct inode * d_inode(struct dentry ** changing_entry);
/* allocate/de-allocate */ /* allocate/de-allocate */
extern void d_free(struct dentry *); extern void d_free(struct dentry *);
extern struct dentry * d_alloc(struct dentry * parent, struct qstr *name, int isdir); extern struct dentry * d_alloc(struct dentry * parent, const struct qstr *name);
/* only used at mount-time */ /* only used at mount-time */
extern blocking extern struct dentry * d_alloc_root(struct inode * root_inode, struct dentry * old_root);
struct dentry * d_alloc_root(struct inode * root_inode, struct dentry * old_root);
/* /*
* This adds the entry to the hash queues and initializes "d_inode". * This adds the entry to the hash queues and initializes "d_inode".
* The entry was actually filled in earlier during "d_alloc()" * The entry was actually filled in earlier during "d_alloc()"
*/ */
extern blocking extern void d_add(struct dentry * entry, struct inode * inode);
void d_add(struct dentry * entry, struct inode * inode, int flags);
/* combination of d_alloc() and d_add(), less lookup overhead */
extern blocking
struct dentry * d_entry(struct dentry * parent, struct qstr * name, struct inode * inode);
extern blocking
void d_entry_preliminary(struct dentry * parent, struct qstr * name, unsigned long ino);
/* recursive d_del() all successors */
extern blocking
void d_del(struct dentry * entry, int flags);
/* used for rename() and baskets */ /* used for rename() and baskets */
extern blocking extern void d_move(struct dentry * entry, struct dentry * newparent, struct qstr * newname);
void d_move(struct dentry * entry, struct dentry * newparent, struct qstr * newname);
/* appendix may either be NULL or be used for transname suffixes */ /* appendix may either be NULL or be used for transname suffixes */
extern struct dentry * d_lookup(struct dentry * dir, struct qstr * name); extern struct dentry * d_lookup(struct dentry * dir, struct qstr * name);
...@@ -122,19 +84,7 @@ extern struct dentry * d_lookup(struct dentry * dir, struct qstr * name); ...@@ -122,19 +84,7 @@ extern struct dentry * d_lookup(struct dentry * dir, struct qstr * name);
/* write full pathname into buffer and return length */ /* write full pathname into buffer and return length */
extern int d_path(struct dentry * entry, struct dentry * chroot, char * buf); extern int d_path(struct dentry * entry, struct dentry * chroot, char * buf);
extern struct dentry * d_basket(struct dentry * dir_entry); /* Allocation counts.. */
extern int d_isbasket(struct dentry * entry);
/*
* Whee..
*/
static inline void dput(struct dentry *dentry)
{
if (dentry)
dentry->d_count--;
}
static inline struct dentry * dget(struct dentry *dentry) static inline struct dentry * dget(struct dentry *dentry)
{ {
if (dentry) if (dentry)
...@@ -142,4 +92,14 @@ static inline struct dentry * dget(struct dentry *dentry) ...@@ -142,4 +92,14 @@ static inline struct dentry * dget(struct dentry *dentry)
return dentry; return dentry;
} }
#endif extern void dput(struct dentry *);
/*
* This is ugly. The inode:dentry relationship is a 1:n
* relationship, so we have to return one (random) dentry
* from the list. We select the first one..
*/
#define i_dentry(inode) \
list_entry((inode)->i_dentry.next, struct dentry, d_list)
#endif /* __LINUX_DCACHE_H */
...@@ -16,16 +16,12 @@ ...@@ -16,16 +16,12 @@
#include <linux/kdev_t.h> #include <linux/kdev_t.h>
#include <linux/ioctl.h> #include <linux/ioctl.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/dcache.h>
#include <asm/atomic.h> #include <asm/atomic.h>
#include <asm/bitops.h> #include <asm/bitops.h>
/* Prefixes for routines (having no effect), but indicate what
* the routine may do. This can greatly ease reasoning about routines...
*/
#define blocking /*routine may schedule()*/
#include <linux/dalloc.h>
/* /*
* It's silly to have NR_OPEN bigger than NR_FILE, but I'll fix * It's silly to have NR_OPEN bigger than NR_FILE, but I'll fix
...@@ -155,7 +151,7 @@ extern int max_files, nr_files; ...@@ -155,7 +151,7 @@ extern int max_files, nr_files;
extern void buffer_init(void); extern void buffer_init(void);
extern void inode_init(void); extern void inode_init(void);
extern void file_table_init(void); extern void file_table_init(void);
extern unsigned long name_cache_init(unsigned long start, unsigned long end); extern void dcache_init(void);
typedef char buffer_block[BLOCK_SIZE]; typedef char buffer_block[BLOCK_SIZE];
...@@ -331,7 +327,7 @@ struct inode { ...@@ -331,7 +327,7 @@ struct inode {
struct page *i_pages; struct page *i_pages;
struct dquot *i_dquot[MAXQUOTAS]; struct dquot *i_dquot[MAXQUOTAS];
struct dentry *i_dentry; struct list_head i_dentry;
unsigned int i_state; unsigned int i_state;
...@@ -685,8 +681,7 @@ extern int notify_change(struct inode *, struct iattr *); ...@@ -685,8 +681,7 @@ extern int notify_change(struct inode *, struct iattr *);
extern int permission(struct inode * inode,int mask); extern int permission(struct inode * inode,int mask);
extern int get_write_access(struct inode *inode); extern int get_write_access(struct inode *inode);
extern void put_write_access(struct inode *inode); extern void put_write_access(struct inode *inode);
extern int open_namei(const char * pathname, int flag, int mode, extern int open_namei(const char * pathname, int flag, int mode, struct inode ** res_inode);
struct inode ** res_inode, struct dentry * base);
extern int do_mknod(const char * filename, int mode, dev_t dev); extern int do_mknod(const char * filename, int mode, dev_t dev);
extern int do_pipe(int *); extern int do_pipe(int *);
...@@ -738,18 +733,18 @@ extern inline void vfs_unlock(void) ...@@ -738,18 +733,18 @@ extern inline void vfs_unlock(void)
extern void _get_inode(struct inode * inode); extern void _get_inode(struct inode * inode);
extern void iput(struct inode * inode); extern void iput(struct inode * inode);
extern blocking struct inode * iget(struct super_block * sb, unsigned long nr); extern struct inode * iget(struct super_block * sb, unsigned long nr);
extern blocking void clear_inode(struct inode * inode); extern void clear_inode(struct inode * inode);
extern blocking struct inode * get_empty_inode(void); extern struct inode * get_empty_inode(void);
/* Please prefer to use this function in future, instead of using /* Please prefer to use this function in future, instead of using
* a get_empty_inode()/insert_inode_hash() combination. * a get_empty_inode()/insert_inode_hash() combination.
* It allows for better checking and less race conditions. * It allows for better checking and less race conditions.
*/ */
blocking struct inode * get_empty_inode_hashed(dev_t i_dev, unsigned long i_ino); extern struct inode * get_empty_inode_hashed(dev_t i_dev, unsigned long i_ino);
extern void insert_inode_hash(struct inode *); extern void insert_inode_hash(struct inode *);
extern blocking struct inode * get_pipe_inode(void); extern struct inode * get_pipe_inode(void);
extern int get_unused_fd(void); extern int get_unused_fd(void);
extern void put_unused_fd(int); extern void put_unused_fd(int);
extern struct file * get_empty_filp(void); extern struct file * get_empty_filp(void);
......
#ifndef NAMETRANS_H
#define NAMETRANS_H
/*
* $Id: nametrans.h,v 1.1 1997/06/04 08:26:57 davem Exp $
*
* include/linux/nametrans.h - context-dependend filename suffixes.
* Copyright (C) 1997, Thomas Schoebel-Theuer,
* <schoebel@informatik.uni-stuttgart.de>.
*/
#include <linux/dalloc.h>
#include <linux/sysctl.h>
#define MAX_DEFAULT_TRANSLEN 128
/* only filenames matching the following length restrictions can be
* translated. I introduced these restrictions because they *greatly*
* simplify buffer management (no need to allocate kernel pages and free them).
* The maximal total length of a context-dependend filename is the
* sum of both constants. */
#define MAX_TRANS_FILELEN 128 /* max len of a name that could be translated */
#define MAX_TRANS_SUFFIX 64 /* max len of a #keyword=value# suffix */
/* max number of translations */
#define MAX_TRANSLATIONS 16
struct translations {
int count;
struct qstr name[MAX_TRANSLATIONS];
struct qstr c_name[MAX_TRANSLATIONS];
};
/* global/default translations */
extern char nametrans_txt[MAX_DEFAULT_TRANSLEN];
/* Any changer of a built-in translation must set this flag */
extern int translations_dirty;
/* called once at boot time */
extern void init_nametrans(void);
/* set global translations */
extern void nametrans_setup(char * line);
/* return reusable global buffer. needed by VFS. */
struct translations * get_translations(char * env);
/* if the _first_ environment variable is "NAMETRANS", return
* a pointer to the list of appendices.
* You can set the first environment variable using
* 'env - NAMETRANS=... "`env`" command ...'
*/
extern char * env_transl(void);
/* if name has the correct suffix "#keyword=correct_context#",
* return position of the suffix, else 0.
*/
extern char* testname(int restricted, char* name);
/* for use in kernel/sysctrl.h */
extern int nametrans_dostring(ctl_table * table, int write, struct file * filp,
void * buffer, size_t * lenp);
extern int nametrans_string(ctl_table * table, int * name, int nlen,
void * oldval, size_t * oldlenp,
void * newval, size_t newlen, void ** context);
#endif
/*
* fs/proc/omirr.c - online mirror support
*
* (C) 1997 Thomas Schoebel-Theuer
*/
#ifndef OMIRR_H
#define OMIRR_H
#include <linux/fs.h>
#include <linux/dalloc.h>
extern int omirr_print(struct dentry * ent1, struct dentry * ent2,
struct qstr * suffix, const char * fmt, ...);
extern int omirr_printall(struct inode * inode, const char * fmt, ...);
#endif
...@@ -57,7 +57,7 @@ extern void kmem_cache_free(kmem_cache_t *, void *); ...@@ -57,7 +57,7 @@ extern void kmem_cache_free(kmem_cache_t *, void *);
extern void *kmalloc(size_t, int); extern void *kmalloc(size_t, int);
extern void kfree(const void *); extern void kfree(const void *);
extern void kfree_s(void *, size_t); extern void kfree_s(const void *, size_t);
extern int kmem_cache_reap(int, int, int); extern int kmem_cache_reap(int, int, int);
extern int get_slabinfo(char *); extern int get_slabinfo(char *);
......
...@@ -32,7 +32,6 @@ ...@@ -32,7 +32,6 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/major.h> #include <linux/major.h>
#include <linux/blk.h> #include <linux/blk.h>
#include <linux/nametrans.h>
#include <linux/init.h> #include <linux/init.h>
#ifdef CONFIG_ROOT_NFS #ifdef CONFIG_ROOT_NFS
#include <linux/nfs_fs.h> #include <linux/nfs_fs.h>
...@@ -558,12 +557,6 @@ __initfunc(static int checksetup(char *line)) ...@@ -558,12 +557,6 @@ __initfunc(static int checksetup(char *line))
ide_setup(line); ide_setup(line);
return 1; return 1;
} }
#endif
#ifdef CONFIG_TRANS_NAMES
if(!strncmp(line,"nametrans=",10)) {
nametrans_setup(line+10);
return 1;
}
#endif #endif
while (bootsetups[i].str) { while (bootsetups[i].str) {
int n = strlen(bootsetups[i].str); int n = strlen(bootsetups[i].str);
...@@ -886,7 +879,6 @@ __initfunc(asmlinkage void start_kernel(void)) ...@@ -886,7 +879,6 @@ __initfunc(asmlinkage void start_kernel(void))
memory_start = kmem_cache_init(memory_start, memory_end); memory_start = kmem_cache_init(memory_start, memory_end);
sti(); sti();
calibrate_delay(); calibrate_delay();
memory_start = name_cache_init(memory_start,memory_end);
#ifdef CONFIG_BLK_DEV_INITRD #ifdef CONFIG_BLK_DEV_INITRD
if (initrd_start && !initrd_below_start_ok && initrd_start < memory_start) { if (initrd_start && !initrd_below_start_ok && initrd_start < memory_start) {
printk(KERN_CRIT "initrd overwritten (0x%08lx < 0x%08lx) - " printk(KERN_CRIT "initrd overwritten (0x%08lx < 0x%08lx) - "
...@@ -901,6 +893,7 @@ __initfunc(asmlinkage void start_kernel(void)) ...@@ -901,6 +893,7 @@ __initfunc(asmlinkage void start_kernel(void))
#endif #endif
uidcache_init(); uidcache_init();
filescache_init(); filescache_init();
dcache_init();
vma_init(); vma_init();
buffer_init(); buffer_init();
inode_init(); inode_init();
......
...@@ -21,7 +21,6 @@ ...@@ -21,7 +21,6 @@
#include <linux/fcntl.h> #include <linux/fcntl.h>
#include <linux/acct.h> #include <linux/acct.h>
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/nametrans.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/notifier.h> #include <linux/notifier.h>
...@@ -431,7 +430,7 @@ asmlinkage int sys_acct(const char *name) ...@@ -431,7 +430,7 @@ asmlinkage int sys_acct(const char *name)
if ((error = getname(name, &tmp)) != 0) if ((error = getname(name, &tmp)) != 0)
goto out; goto out;
error = open_namei(tmp, O_RDWR, 0600, &inode, 0); error = open_namei(tmp, O_RDWR, 0600, &inode);
putname(tmp); putname(tmp);
if (error) if (error)
goto out; goto out;
......
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/sysctl.h> #include <linux/sysctl.h>
#include <linux/swapctl.h> #include <linux/swapctl.h>
#include <linux/nametrans.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/malloc.h> #include <linux/malloc.h>
#include <linux/stat.h> #include <linux/stat.h>
...@@ -172,10 +171,6 @@ static ctl_table kern_table[] = { ...@@ -172,10 +171,6 @@ static ctl_table kern_table[] = {
{KERN_JAVA_APPLETVIEWER, "java-appletviewer", binfmt_java_appletviewer, {KERN_JAVA_APPLETVIEWER, "java-appletviewer", binfmt_java_appletviewer,
64, 0644, NULL, &proc_dostring, &sysctl_string }, 64, 0644, NULL, &proc_dostring, &sysctl_string },
#endif #endif
#ifdef CONFIG_TRANS_NAMES
{KERN_NAMETRANS, "nametrans", nametrans_txt, MAX_DEFAULT_TRANSLEN,
0644, NULL, &nametrans_dostring, &nametrans_string},
#endif
#ifdef __sparc__ #ifdef __sparc__
{KERN_SPARC_REBOOT, "reboot-cmd", reboot_command, {KERN_SPARC_REBOOT, "reboot-cmd", reboot_command,
256, 0644, NULL, &proc_dostring, &sysctl_string }, 256, 0644, NULL, &proc_dostring, &sysctl_string },
......
...@@ -1275,7 +1275,7 @@ kmem_report_alloc_err(const char *str, kmem_cache_t * cachep) ...@@ -1275,7 +1275,7 @@ kmem_report_alloc_err(const char *str, kmem_cache_t * cachep)
} }
static void static void
kmem_report_free_err(const char *str, void *objp, kmem_cache_t * cachep) kmem_report_free_err(const char *str, const void *objp, kmem_cache_t * cachep)
{ {
if (cachep) if (cachep)
SLAB_STATS_INC_ERR(cachep); SLAB_STATS_INC_ERR(cachep);
...@@ -1456,7 +1456,7 @@ __kmem_cache_alloc(kmem_cache_t *cachep, int flags) ...@@ -1456,7 +1456,7 @@ __kmem_cache_alloc(kmem_cache_t *cachep, int flags)
* it should be in this state _before_ it is released. * it should be in this state _before_ it is released.
*/ */
static inline void static inline void
__kmem_cache_free(kmem_cache_t *cachep, void *objp) __kmem_cache_free(kmem_cache_t *cachep, const void *objp)
{ {
kmem_slab_t *slabp; kmem_slab_t *slabp;
kmem_bufctl_t *bufp; kmem_bufctl_t *bufp;
...@@ -1653,7 +1653,7 @@ kfree(const void *objp) ...@@ -1653,7 +1653,7 @@ kfree(const void *objp)
} }
void void
kfree_s(void *objp, size_t size) kfree_s(const void *objp, size_t size)
{ {
struct page *page; struct page *page;
int nr; int nr;
......
...@@ -67,7 +67,6 @@ ...@@ -67,7 +67,6 @@
#include <linux/socket.h> #include <linux/socket.h>
#include <linux/fcntl.h> #include <linux/fcntl.h>
#include <linux/file.h> #include <linux/file.h>
#include <linux/dalloc.h>
#include <linux/net.h> #include <linux/net.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
......
...@@ -459,7 +459,7 @@ static unix_socket *unix_find_other(struct sockaddr_un *sunname, int len, ...@@ -459,7 +459,7 @@ static unix_socket *unix_find_other(struct sockaddr_un *sunname, int len,
{ {
old_fs=get_fs(); old_fs=get_fs();
set_fs(get_ds()); set_fs(get_ds());
err = open_namei(sunname->sun_path, 2, S_IFSOCK, &inode, NULL); err = open_namei(sunname->sun_path, 2, S_IFSOCK, &inode);
set_fs(old_fs); set_fs(old_fs);
if(err<0) if(err<0)
{ {
...@@ -550,7 +550,7 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) ...@@ -550,7 +550,7 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
err=do_mknod(sunaddr->sun_path, S_IFSOCK|S_IRWXUGO, 0); err=do_mknod(sunaddr->sun_path, S_IFSOCK|S_IRWXUGO, 0);
if (!err) if (!err)
err=open_namei(sunaddr->sun_path, 2, S_IFSOCK, &inode, NULL); err=open_namei(sunaddr->sun_path, 2, S_IFSOCK, &inode);
set_fs(old_fs); set_fs(old_fs);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment