diff -Naurp linux-2.4.20-wolk4.15-fullkernel/2.4-WOLK-CHANGELOG linux-2.4.20-wolk4.16-fullkernel/2.4-WOLK-CHANGELOG --- linux-2.4.20-wolk4.15-fullkernel/2.4-WOLK-CHANGELOG 2004-06-29 13:23:02.000000000 +0200 +++ linux-2.4.20-wolk4.16-fullkernel/2.4-WOLK-CHANGELOG 2004-09-09 13:30:42.000000000 +0200 @@ -1,3 +1,86 @@ +Changelog from v4.15s -> v4.16s +------------------------------- +o added: Autonegotiation on|off|sense for sk98lin driver if + compiled statically into the kernel via config +o added: calculate default broadcast even when using SIOCSIGNETMASK +o added: NDIS wrapper v0.9 +o added: AGP: Intel i915G support +o added: nForce Ethernet v0.29 +o added: Broadcom BCM4400 (b44, alternate driver) v0.93 +o added: Intel PRO/10GbE support v1.0.65 +o added: Statistic support for LSI MegaRAID (v2.10.6) in /proc +o added: /proc/sys/net/ipv4/netdebug, default on + disable this if you get annoyed by things like: + - hw tcp v4 csum failed + - TCP: Treason uncloaked! Peer shrinks window . + - udp v4 hw csum failure + Bonus: Made error messages consistent! +o added: 3c920n 9100 IGP support to 3c59x network driver +o added: WCCP tunnels over IP (IPWCCP) +o fixed: compile problems with RANDEXEC enabled +o fixed: RANDEXEC works now with RMAP :p +o fixed: ntpd segfaults with grsecurity +o fixed: CAN-2004-0497: missing DAC check on sys_chown +o fixed: CAN-2004-0587: QLA2xxx device permissions +o fixed: CAN-2004-0394: potential buffer overflow in panic +o fixed: CAN-2004-0415: fix an exploitable race in file offset + handling which allows unpriviledged users from potentially + reading kernel memory. This touches several drivers and + generic proc code. +o fixed: wtd semaphore race condition +o fixed: ext3 direct io +o fixed: removed bogus __set_current_state(TASK_RUNNING) +o fixed: some compiler warnings in kernel/ksyms.c +o fixed: With PREEMPT and SMP, machines rebooted immediately :( +o fixed: /proc/config.gz output was fucked up on SMP +o fixed: duplicated /proc//status:TGid field +o fixed: now really fix the oops output to get kallsyms feature back. +o fixed: compile warnings in all QLA2xxx drivers +o fixed: pcmcia shared irq on qlogicfas +o fixed: repair scsi/pcmcia modules so that they can build by only + including scsi_module.c for non-PCMCIA builds +o fixed: some xconfig holy shit brain damage +o fixed: unresolved symbol 'ipv6_skip_exthdr' in ip6_tables.o +o updated: LUFS v0.9.7 +o updated: XFS (up to 2.4.27-pre3) +o updated: JFS (up to 2.4.28-pre3) +o updated: Loop-AES v2.2b +o updated: Loop Cyphers: Blowfish, twofish, serpent v2.0i +o updated: CryptoAPI (up to 2.4.28-pre3) +o updated: Bluetooth 2.4.20-mh18 +o updated: Broadcom BCM5700 v7.3.5 +o updated: Broadcom Tigon3 (tg3) v3.9 +o updated: SysKonnect SK-98xx v7.07 +o updated: 3ware 9xxx SATA-RAID support v2.24.00.011fw +o updated: HP CISS Driver v2.4.52 +o updated: Compaq SMART2 Driver v2.4.28 +o updated: IBM ServeRAID v7.10.18 (New driver series) +o updated: Openswan v1.0.7 +o updated: CIFS v1.20c +o updated: grsecurity v2.0.1 as an replacement patch you have to apply + manually to use v2.0.1 instead of v1.9.15. Please use + gradm2 from ./gradm2 directory and make sure, /dev/grsec + has minor number 12 instead of 10. +o updated: Bonding v2.6.0 + mpxor support + ifenslave v1.1.0 +o updated: 802.1Q VLAN support v1.8 +o updated: Ethernet Link Aggregation (veth) v0.6.5 +o updated: Redundancy of Link Segment (lr) v0.8.5 +o updated: NTFS v2.1.6b +o updated: AutoFS v4 2.4.20-20040508 +o removed: QIC-02 tape support (tpqic02): non-GPL. Mainline will follow! +o removed: FTP file system support (use LUFS instead) +o removed: enchanced SFQ: breaks normal SFQ, HTB and whatelse +o removed: ikconfig support +o removed: /proc/config.gz: merged better support, this was broken! +o changed: net.ipv4.tcp_default_win_scale default to 7 +o changed: net.ipv4.tcp_vegas_cong_avoid default to 1 +o changed: net.ipv4.tcp_moderate_rcvbuf default to 1 +o changed: net.ipv4.tcp_rfc1337 default to 1 +o changed: net.ipv4.ipfrag_secret_interval default to 300 +o changed: net.ipv4.route.secret_interval default to 300 + + + Changelog from v4.14s -> v4.15s ------------------------------- o added: grsecurity v2.0.1 as an replacement patch you have to apply @@ -21,7 +104,7 @@ o added: Ethernet Link Aggregation Anyway, works in production with a SysKonnect SK-9844 SX Dual NIC on 2 machines routing ~1000 connections per second and this works damn well! :) -o added: Redundancy of Link Segment (lt) v0.8.4 +o added: Redundancy of Link Segment (lr) v0.8.4 If you don't know what this is, you'll never need this! o added: TCP RFC2385 MD5 support o added: TCP Westwood support @@ -68,6 +151,8 @@ o added: Introduce /proc/sys/kernel o added: BIC-TCP backport from 2.6 o added: TCP Vegas backport from 2.6 o added: 3ware 9xxx SATA-RAID support v2.24.00.006fw +o added: Quantum unlock support (TiVo) - Merged by Cory Visi +o added: TiVo partition map support - Merged by Cory Visi o added: A holy cool VM tuning knob. It was intended by me as drop behind but ended as something completely different. @@ -159,7 +244,8 @@ o fixed: workaround rmap vs. PaX se o fixed: PaX: large file mapping bug introduced by vma mirroring o fixed: wrong dependences for grsecurity/PaX configure system o fixed: memory pools goes crazy sometimes. Backported 2.6 fixes -o updated: Broadcom BCM5700 driver v7.1.22 +o updated: Bluetooth 2.4.20-mh17 +o updated: Broadcom BCM5700 v7.1.22 o updated: AIC7xxx v6.3.9 / AIC79xx v2.0.12 (v2004-05-22) o updated: IBM ServeRAID v7.00.15 (New driver series) o updated: RAID code (up to 2.4.27-rc2) @@ -173,10 +259,10 @@ o updated: CryptoAPI (up to 2.4.27-rc o updated: PPP Microsoft encryption/compression (MPPE/MPPC) v0.99 o updated: libata (S-ATA support via SCSI layer) same as 2.4.27-pre4 + ICH5/ICH6 -o updated: Intel e100 driver v2.3.40 -o updated: Intel e1000 driver v5.2.51 +o updated: Intel e100 v2.3.40 +o updated: Intel e1000 v5.2.51 o updated: Broadcom Tigon3 (tg3) v3.6 -o updated: SysKonnect SK-98xx driver v6.24 +o updated: SysKonnect SK-98xx v6.24 o updated: Realtek 8139cp v1.1 o updated: SiS 900 v1.08.06 o updated: Sundance v1.01+LK1.09a @@ -402,8 +488,8 @@ o fixed: speedup 'make dep' again a o fixed: loop handling of sector size ioctl o fixed: asm constraint bug in arch/i386/kernel/pci-pc.c o updated: IBM ServeRAID v6.10.24 -o updated: Broadcom BCM4400 driver v2.0.5 -o updated: Broadcom BCM5700 driver v6.2.17 +o updated: Broadcom BCM4400 v2.0.5 +o updated: Broadcom BCM5700 v6.2.17 o updated: SysKonnect SK-98xx driver v6.17 o updated: iSCSI support (SCSI-over-Network) v3.4.0.3 o updated: XFS v1.3.0 Final diff -Naurp linux-2.4.20-wolk4.15-fullkernel/2.4-WOLK-README linux-2.4.20-wolk4.16-fullkernel/2.4-WOLK-README --- linux-2.4.20-wolk4.15-fullkernel/2.4-WOLK-README 2004-06-29 13:03:35.000000000 +0200 +++ linux-2.4.20-wolk4.16-fullkernel/2.4-WOLK-README 2004-09-09 16:57:33.000000000 +0200 @@ -1,4 +1,4 @@ -Kernel - patched - WOLK v4.15s - Base: Linux kernel 2.4.20 +Kernel - patched - WOLK v4.16s - Base: Linux kernel 2.4.20 located at http://sf.net/projects/wolk by Marc-Christian Petersen -------------------------------------------------------------------------- @@ -40,10 +40,12 @@ https://sourceforge.net/mail/?group_id=4 Some of the features: --------------------- -O(1) Scheduler, RMAP VM, GRsecurity, Crypto, XFS, KDB, Preempt, Systrace, -Super FreeS/WAN, Trustees, IPVS, i2c/lmsensors, TUX, EVMS, BadMEM, ftpfs, +O(1) Scheduler, RMAP VM, Grsecurity, Crypto, XFS, KDB, Preempt, Systrace, +Openswan, Trustees, IPVS, i2c/lmsensors, TuX, EVMS, BadMEM, ftpfs, lufs, HostAP, all known security fixes, all known filesystem fixes, and many more. +Addon: Grsecurity v2.0.1 + Credits go to all the people who created the patches, working hard on improving the quality. diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/INFO linux-2.4.20-wolk4.16-fullkernel/3rdparty/INFO --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/INFO 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/INFO 2004-09-09 16:59:26.000000000 +0200 @@ -0,0 +1,4 @@ +avm-fritz-dsl: Sources used: ftp://ftp.avm.de/cardware/fritzcrd.dsl_v20/linux/suse.90/fcdsl2-suse9.0-03.11.04.tar.gz + +avm-fritz-pci: Sources used: ftp://ftp.avm.de/cardware/fritzcrd.pci/linux/suse.82/fcpci-suse8.2-03.11.02.tar.gz + diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/make.card linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/make.card --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/make.card 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/make.card 2004-08-13 00:00:00.000000000 +0200 @@ -0,0 +1,2 @@ +CARD=fcdsl2 + diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/makefile linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/makefile --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/makefile 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/makefile 2004-08-13 00:00:00.000000000 +0200 @@ -0,0 +1,12 @@ +include make.card + +.PHONY: all clean install + +all: drv + +clean: ; (cd src.drv; make clean CARD=$(CARD)) + +install: ; (cd src.drv; make install CARD=$(CARD)) + +drv: ; (cd src.drv; make CARD=$(CARD)) + diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/ca.h linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/ca.h --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/ca.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/ca.h 2004-08-13 00:00:00.000000000 +0200 @@ -0,0 +1,120 @@ +/* + * ca.h + * Copyright (C) 2002, AVM GmbH. All rights reserved. + * + * This Software is free software. You can redistribute and/or + * modify such free software under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * The free software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this Software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or see + * http://www.opensource.org/licenses/lgpl-license.html + * + * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de + */ + +#ifndef __have_ca_h__ +#define __have_ca_h__ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void CA_INIT (unsigned Len, void (* Register) (void *adata, unsigned ApplId), + void (* Release) (void * adata), + void (* Down) (void)); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +char *CA_PARAMS (void); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int CA_GET_MESSAGE (unsigned char *Msg); +void CA_PUT_MESSAGE (unsigned char *Msg); + +unsigned char *CA_NEW_DATA_B3_IND (unsigned ApplId, unsigned long NCCI, + unsigned Index); +void CA_FREE_DATA_B3_REQ (unsigned ApplId, unsigned char *data); + +int CA_NEW_NCCI (unsigned ApplId, unsigned long NCCI, unsigned WindowSize, + unsigned BlockSize); +void CA_FREE_NCCI (unsigned ApplId, unsigned long NCCI); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void *CA_MALLOC (unsigned); +void CA_FREE (void *p); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#define MSEC_PER_SEC 1000l + +unsigned long CA_MSEC (void); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void CA_Delay (unsigned usec); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +unsigned CA_KARTE (void); +unsigned CA_BLOCKSIZE (unsigned ApplId); +unsigned CA_WINDOWSIZE (unsigned ApplId); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +typedef struct { + + unsigned Nr; + char *Buffer; +} __ApplsFirstNext, *_ApplsFirstNext; + +void *CA_APPLDATA (unsigned ApplId); +_ApplsFirstNext CA_APPLDATA_FIRST (_ApplsFirstNext s); +_ApplsFirstNext CA_APPLDATA_NEXT (_ApplsFirstNext s); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +typedef enum { + + CA_TIMER_END = 0, + CA_TIMER_RESTART = 1, + CA_TIMER_RESTART_NOT_SET_TIME = 2 +} CA_RESTARTTIMER; + +int CA_TIMER_NEW (unsigned nTimers); +void CA_TIMER_DELETE (void); + +int CA_TIMER_START (unsigned index, + unsigned long TimeoutValue, + unsigned long param, + CA_RESTARTTIMER (*f)(unsigned long param)); +int CA_TIMER_STOP (unsigned index); + +void CA_TIMER_POLL (void); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void CA_PRINTF (char *s, ...); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#if !defined (NDEBUG) + +void CA_PUTS (char *); +void CA_PUTI (int); +void CA_PUTL (long); +void CA_PUTC (char); +void CA_PUTNL (void); + +#endif + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#endif diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/capilli.h linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/capilli.h --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/capilli.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/capilli.h 2004-08-13 00:00:00.000000000 +0200 @@ -0,0 +1,132 @@ +/* + * capilli.h + * Copyright (C) 2002, AVM GmbH. All rights reserved. + * + * This Software is free software. You can redistribute and/or + * modify such free software under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * The free software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this Software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or see + * http://www.opensource.org/licenses/lgpl-license.html + * + * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de + */ + +/* + * $Id: capilli.h,v 1.4 1999/07/23 08:51:05 calle Exp $ + * + * Kernel CAPI 2.0 Driver Interface for Linux + * + * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de) + * + */ +#ifndef __CAPILLI_H__ +#define __CAPILLI_H__ + +typedef struct capiloaddatapart { + int user; /* data in userspace ? */ + int len; + unsigned char *data; +} capiloaddatapart; + +typedef struct capiloaddata { + capiloaddatapart firmware; + capiloaddatapart configuration; +} capiloaddata; + +typedef struct capicardparams { + unsigned int port; + unsigned irq; + int cardtype; + int cardnr; + unsigned int membase; +} capicardparams; + +struct capi_driver; + +struct capi_ctr { + struct capi_ctr *next; /* next ctr of same driver */ + struct capi_driver *driver; + int cnr; /* controller number */ + char name[32]; /* name of controller */ + volatile unsigned short cardstate; /* controller state */ + volatile int blocked; /* output blocked */ + int traceflag; /* capi trace */ + + void *driverdata; /* driver specific */ + + /* filled before calling ready callback */ + __u8 manu[CAPI_MANUFACTURER_LEN]; /* CAPI_GET_MANUFACTURER */ + capi_version version; /* CAPI_GET_VERSION */ + capi_profile profile; /* CAPI_GET_PROFILE */ + __u8 serial[CAPI_SERIAL_LEN]; /* CAPI_GET_SERIAL */ + + /* functions */ + void (*ready)(struct capi_ctr * card); + void (*reseted)(struct capi_ctr * card); + void (*suspend_output)(struct capi_ctr * card); + void (*resume_output)(struct capi_ctr * card); + void (*handle_capimsg)(struct capi_ctr * card, + __u16 appl, struct sk_buff *skb); + void (*appl_registered)(struct capi_ctr * card, __u16 appl); + void (*appl_released)(struct capi_ctr * card, __u16 appl); + + void (*new_ncci)(struct capi_ctr * card, + __u16 appl, __u32 ncci, __u32 winsize); + void (*free_ncci)(struct capi_ctr * card, __u16 appl, __u32 ncci); + + /* management information for kcapi */ + + unsigned long nrecvctlpkt; + unsigned long nrecvdatapkt; + unsigned long nsentctlpkt; + unsigned long nsentdatapkt; + + struct proc_dir_entry *procent; + char procfn[128]; +}; + +struct capi_driver_interface { + struct capi_ctr *(*attach_ctr)(struct capi_driver *driver, char *name, void *data); + int (*detach_ctr)(struct capi_ctr *); +}; + +struct capi_driver { + char name[32]; /* driver name */ + char revision[32]; + int (*load_firmware)(struct capi_ctr *, capiloaddata *); + void (*reset_ctr)(struct capi_ctr *); + void (*remove_ctr)(struct capi_ctr *); + void (*register_appl)(struct capi_ctr *, __u16 appl, + capi_register_params *); + void (*release_appl)(struct capi_ctr *, __u16 appl); + void (*send_message)(struct capi_ctr *, struct sk_buff *skb); + + char *(*procinfo)(struct capi_ctr *); + int (*ctr_read_proc)(char *page, char **start, off_t off, + int count, int *eof, struct capi_ctr *card); + int (*driver_read_proc)(char *page, char **start, off_t off, + int count, int *eof, struct capi_driver *driver); + + int (*add_card)(struct capi_driver *driver, capicardparams *data); + + /* intitialized by kcapi */ + struct capi_ctr *controller; /* list of controllers */ + struct capi_driver *next; + int ncontroller; + struct proc_dir_entry *procent; + char procfn[128]; +}; + +struct capi_driver_interface *attach_capi_driver(struct capi_driver *driver); +void detach_capi_driver(struct capi_driver *driver); + +#endif /* __CAPILLI_H__ */ diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/common.h linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/common.h --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/common.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/common.h 2004-08-13 00:00:00.000000000 +0200 @@ -0,0 +1,128 @@ +/* + * common.h + * Copyright (C) 2003, AVM GmbH. All rights reserved. + * + * This Software is free software. You can redistribute and/or + * modify such free software under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * The free software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this Software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or see + * http://www.opensource.org/licenses/lgpl-license.html + * + * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de + */ + +#ifndef __have_common_h__ +#define __have_common_h__ + +struct __card; +struct __ndi; +struct c6205_ctx; + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +typedef void * (* code_func_t) (void *, unsigned, unsigned *); + +typedef unsigned (* timer_func_t) (void); + +typedef void (* to_pc_ack_func_t) (unsigned char); + +typedef void (* wait_func_t) (unsigned); + +typedef unsigned (* xfer_func_t) (void *, unsigned); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +typedef struct __dst { + + int tx_flag; + unsigned length; + void * alloc_ptr; + unsigned phys_addr; + unsigned virt_addr; + void * context; +} dma_struct_t, * dma_struct_p; + +typedef dma_struct_p * dma_list_t; + +typedef struct __ndi num_dma_info_t, * num_dma_info_p; + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +typedef struct __ist { + + unsigned length; + unsigned phys_addr; + unsigned virt_addr; + + unsigned char (* inb) (unsigned); + unsigned short (* inw) (unsigned); + unsigned long (* inl) (unsigned); + void (* outb) (unsigned char, unsigned); + void (* outw) (unsigned short, unsigned); + void (* outl) (unsigned long, unsigned); +} ioaddr_t, * ioaddr_p; + +typedef struct __card card_t, * card_p; +typedef struct c6205_ctx * c6205_context; + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +typedef struct __dreq { + + unsigned tx_block_num; + unsigned tx_block_size; + unsigned tx_max_trans_len; + unsigned rx_block_num; + unsigned rx_block_size; + unsigned rx_max_trans_len; + code_func_t get_code; + void * context; + wait_func_t stack_wait; +} dif_require_t, * dif_require_p; + +typedef struct __ireq { + + xfer_func_t tx_func; +} in_require_t, * in_require_p; + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +typedef void * hw_block_handle; + +typedef struct __buf_desc { + + hw_block_handle handle; /* const */ + unsigned char * buffer; /* const */ + unsigned long length; /* const */ + void * context; /* const */ +} hw_buffer_descriptor_t, * hw_buffer_descriptor_p; + +typedef void (* hw_completion_func_t) ( + const hw_buffer_descriptor_p desc, + unsigned offset, + unsigned length, + void * context +); + +typedef void (* hw_event_func_t) ( + unsigned event_mask, + const hw_buffer_descriptor_p desc, + unsigned offset, + unsigned length, + void * context +); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ + +#endif + diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/defs.h linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/defs.h --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/defs.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/defs.h 2004-09-05 18:25:37.000000000 +0200 @@ -0,0 +1,85 @@ +/* + * defs.h + * Copyright (C) 2002, AVM GmbH. All rights reserved. + * + * This Software is free software. You can redistribute and/or + * modify such free software under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * The free software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this Software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or see + * http://www.opensource.org/licenses/lgpl-license.html + * + * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de + */ + +#ifndef __have_defs_h__ +#define __have_defs_h__ + +#ifndef LINUX_VERSION_CODE +# include +#endif + +#ifndef TRUE +# define TRUE (1==1) +# define FALSE (1==0) +#endif + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#if defined (__fcdslsl__) +# define PCI_DEVICE_ID_FCDSL2 0x2700 +# define PRODUCT_LOGO "AVM FRITZ!Card DSL SL" +# define INTERFACE "pci" +#elif defined (__fcdsl2__) +# define PCI_DEVICE_ID_FCDSL2 0x2900 +# define PRODUCT_LOGO "AVM FRITZ!Card DSL v2.0" +# define INTERFACE "pci" +#else +# error Card specifier missing! +#endif +#define DRIVER_LOGO PRODUCT_LOGO " driver" +#define SHORT_LOGO TARGET "-" INTERFACE + +#define REV_DEFAULT "0.2" + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#if defined (OSDEBUG) && defined (NDEBUG) +# undef NDEBUG +#endif + +/*---------------------------------------------------------------------------*\ + * LOG_MESSAGES - CAPI trace + * LOG_ALLOC - Log heap activity + * LOG_LINK - Log buffer transfers +\*---------------------------------------------------------------------------*/ + +#define LOG_ALLOC + +#define UNUSED_ARG(x) (x)=(x) + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 13) +# define GET_PCI_BASE(d, r) (d)->base_address[r] +#else +# define GET_PCI_BASE(d, r) (d)->resource[r].start +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 43) +# define KFREE_SKB(x) dev_kfree_skb(x) +#else +# include +# define KFREE_SKB(x) dev_kfree_skb_any(x) +#endif + +#endif + diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/devif.c linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/devif.c --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/devif.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/devif.c 2004-08-13 00:00:00.000000000 +0200 @@ -0,0 +1,1328 @@ +/* + * devif.c + * Copyright (C) 2003, AVM GmbH. All rights reserved. + * + * This Software is free software. You can redistribute and/or + * modify such free software under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * The free software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this Software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or see + * http://www.opensource.org/licenses/lgpl-license.html + * + * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de + */ + +#include +#include +#include +#include +#include "tools.h" +#include "fw.h" +#include "driver.h" +#include "devif.h" + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#define DMA_BUFFER_NUM_MAX 8 +#define DMA_INVALID_NUMBER 0 +#define DMA_ALIGNMENT 8 +#define DMA_ALIGN_MASK (DMA_ALIGNMENT-1) +#define MAX_HEADER_RETRANSMIT 100 +#define MAX_LENGTH 16 * 1024 + +#define INC(x) (x)=(((x)==255)?1:(x)+1) + +#define MY_INT(x) (((x)&C6205_PCI_HSR_INTSRC)!=0) +#define PCI_INT_LINE_ON(x) (((x)&C6205_PCI_HSR_INTAVAL)!=0) + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static atomic_t is_stopped = ATOMIC_INIT (FALSE); +static atomic_t xfer_flag = ATOMIC_INIT (0); +static atomic_t window_ok = ATOMIC_INIT (0); +#if !defined (NDEBUG) +static atomic_t is_open = ATOMIC_INIT (FALSE); +static atomic_t is_started = ATOMIC_INIT (FALSE); +static atomic_t n_buffers = ATOMIC_INIT (0); +static unsigned last_to_pc_ack; +static unsigned tx_handled_count = 0; +static unsigned rx_handled_count = 0; +#endif + +static to_pc_ack_func_t to_pc_ack_func = NULL; +static timer_func_t get_timer_func = NULL; +static hw_completion_func_t rx_callback = NULL; +static hw_completion_func_t tx_callback = NULL; +static hw_event_func_t event_callback = NULL; +static xfer_func_t tx_function = NULL; +static dif_require_t dif_req = { 0, }; +static unsigned buf_disc = 0; +static ptr_queue_p tx_list = NULL; +static ptr_queue_p rx_list = NULL; +static unsigned char tx_num = 1; +static unsigned char rx_num = 1; +static unsigned rx_hdr_fail; +static unsigned rx_blk_fail; +static unsigned crrx_local; +static unsigned crrx_global; +static unsigned ro_num; +static unsigned ro_offset; +static ioaddr_p ro_pwin; +static unsigned ro_len; +static unsigned ro_next; +static unsigned ro_bufofs; +static int ro_flag = FALSE; +static card_p card_link = NULL; + +static int (* int_callback) (void *) = NULL; +static void * int_context = NULL; +static void xfer_task (unsigned long); + +static DECLARE_TASKLET(xfer_tasklet, xfer_task, 0); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +typedef struct __rbi { + + hw_buffer_descriptor_p pbd; + unsigned ofs; + unsigned len; + void * ctx; +} buf_info_t, * buf_info_p; + +/*****************************************************************************\ + * D M A B U F F E R M A N A G E M E N T +\*****************************************************************************/ + +struct __ndi { + + unsigned char num; + unsigned char cr; + unsigned short len; + unsigned timer; +} __attribute__ ((packed)); + +static dma_struct_p dma_struct[2 * DMA_BUFFER_NUM_MAX]; +#if !defined (NDEBUG) +static dma_struct_p tx_last_buffer = NULL; +static dma_struct_p rx_last_buffer = NULL; +#endif + +/*---------------------------------------------------------------------------*\ +\*-D-------------------------------------------------------------------------*/ +dma_struct_p * dma_get_struct_list (unsigned * pnum) { +#if !defined (NDEBUG) && defined (LOG_LINK) + unsigned n; + + log ("List of %u DMA structures: %p\n", buf_disc, dma_struct); + for (n = 0; n < buf_disc; n++) { + assert (dma_struct[n] != NULL); + log ( + "%02u) %cX vaddr/paddr = %08x/%08x\n", + n, + dma_struct[n]->tx_flag ? 'T' : 'R', + dma_struct[n]->virt_addr, + dma_struct[n]->phys_addr + ); + } +#endif + assert (pnum != NULL); + *pnum = buf_disc; + return dma_struct; +} /* dma_get_struct_list */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +dma_struct_p dma_alloc (void) { + dma_struct_p pdma = NULL; + + pdma = (dma_struct_p) hcalloc (sizeof (dma_struct_t)); + info (pdma != NULL); + return pdma; +} /* dma_alloc */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void dma_free (dma_struct_p * ppdma) { + + assert (ppdma != NULL); + assert (*ppdma != NULL); + assert ((*ppdma)->virt_addr == 0); + hfree (*ppdma); + *ppdma = NULL; +} /* dma_free */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static unsigned dma_min_buf_size (dma_struct_p pdma, int tx_flag) { + unsigned bs; + + if (pdma != NULL) { + tx_flag = pdma->tx_flag; + } + bs = sizeof (num_dma_info_t) + + sizeof (unsigned); + if (!tx_flag) { + bs += sizeof (unsigned); + } + return bs; +} /* dma_min_buf_size */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static unsigned dma_eff_buf_size (dma_struct_p pdma) { + + assert (pdma != NULL); + assert (pdma->length >= dma_min_buf_size (pdma, 0)); + return pdma->length - dma_min_buf_size (pdma, 0); +} /* dma_eff_buf_size */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static char * dma_eff_buf_virt (dma_struct_p pdma) { + + assert (pdma != NULL); + return ((char *) pdma->virt_addr) + sizeof (num_dma_info_t); +} /* dma_eff_buf_virt */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void dma_reset_buf (dma_struct_p pdma) { + + assert (pdma != NULL); + memset ((void *) pdma->virt_addr, 0, pdma->length); + log ("DMA buffer %p reset\n", pdma->virt_addr); +} /* dma_reset_buf */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void dma_invalidate (dma_struct_p pdma, int fall) { + num_dma_info_p pndi = (num_dma_info_p) pdma->virt_addr; + unsigned short len; + + assert (pdma != NULL); + assert (pndi != NULL); + len = (fall) ? pdma->length : pndi->len + dma_min_buf_size (pdma, 0); + assert (len <= pdma->length); + assert (len >= dma_min_buf_size (pdma, 0)); + assert (DMA_INVALID_NUMBER == 0); + assert (len >= sizeof (num_dma_info_t)); + + memset (pndi, 0, len); +} /* dma_invalidate */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int dma_setup (dma_struct_p pdma, unsigned long buf_size) { + void * buf1; + void * buf2; + + assert (buf_size > dma_min_buf_size (pdma, 0)); + assert (buf_size > 0); + assert (pdma != NULL); + assert (pdma->virt_addr == 0); + if (NULL == (buf1 = kmalloc (buf_size + DMA_ALIGNMENT, GFP_ATOMIC))) { + pdma->virt_addr = 0; + return FALSE; + } + if ((((unsigned) buf1) & DMA_ALIGN_MASK) != 0) { + log ("Buffer is not %d-aligned (%p)\n", DMA_ALIGNMENT, buf1); + buf2 = (void *) ((((unsigned) buf1) + DMA_ALIGNMENT - 1) & ~DMA_ALIGN_MASK); + } else { + buf2 = buf1; + } + assert ((((unsigned) buf2) & DMA_ALIGN_MASK) == 0); + memset (buf2, 0, buf_size); + pdma->length = (unsigned) buf_size; + pdma->alloc_ptr = buf1; + pdma->virt_addr = (unsigned) buf2; + pdma->phys_addr = virt_to_bus (buf2); + log ( + "Allocated DMA buffer vaddr %08x, paddr %08x, length %u\n", + pdma->virt_addr, + pdma->phys_addr, + pdma->length + ); + assert (pdma->length == buf_size); + return TRUE; +} /* dma_setup */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int dma_init (dma_struct_p pdma, unsigned long buf_size) { + int res; + + if (TRUE == (res = dma_setup (pdma, buf_size))) { + dma_invalidate (pdma, TRUE); + } + return res; +} /* dma_init */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static int dma_init_xx (dma_struct_p pdma, unsigned long buf_size, int tx_flag) { + int res; + + if (TRUE == (res = dma_init (pdma, buf_size))) { + pdma->tx_flag = tx_flag; + log ("... is a %s DMA buffer\n", pdma->tx_flag ? "TX" : "RX"); + } + return res; +} /* dma_init_xx */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void dma_free_buffer (dma_struct_p pdma) { + + assert (pdma != NULL); + info (pdma->virt_addr != 0); + if (pdma->virt_addr != 0) { + kfree (pdma->alloc_ptr); + pdma->virt_addr = + pdma->phys_addr = 0; + } +} /* dma_free_buffer */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void dma_exit (dma_struct_p pdma) { + + assert (pdma != NULL); + info (pdma->virt_addr != 0); + if (pdma->virt_addr != 0) { + log ( + "Freeing %s DMA buffer vaddr %08x\n", + pdma->tx_flag ? "TX" : "RX", + pdma->virt_addr + ); + dma_invalidate (pdma, TRUE); + dma_free_buffer (pdma); + } +} /* dma_exit */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static unsigned char * ndi_number_back_ptr (dma_struct_p pdma, unsigned len) { + num_dma_info_p pndi = (num_dma_info_p) pdma->virt_addr; + unsigned ofs; + + assert (pdma != NULL); + assert (pndi != NULL); + ofs = len + sizeof (num_dma_info_t); + assert ((ofs + sizeof (unsigned char)) < pdma->length); + return ((unsigned char *) pndi) + ofs; +} /* ndi_number_back_ptr */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static int ndi_length_valid (dma_struct_p pdma, unsigned short len, unsigned short maxlen) { + num_dma_info_p pndi = (num_dma_info_p) pdma->virt_addr; + + assert (pdma != NULL); + assert (pndi != NULL); + if (((pndi->len) & 3) != 0) { + info (0); + return FALSE; + } + if (len > maxlen) { + info (0); + return FALSE; + } + return TRUE; +} /* ndi_length_valid */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#if !defined (NDEBUG) +static int ndi_header_valid (dma_struct_p pdma, unsigned short maxlen) { + num_dma_info_p pndi = (num_dma_info_p) pdma->virt_addr; + + assert (pdma != NULL); + assert (pndi != NULL); + if (pndi->num == DMA_INVALID_NUMBER) { + info (0); + return FALSE; + } + return ndi_length_valid (pdma, pndi->len, maxlen); +} /* ndi_header_valid */ +#endif + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#if !defined (NDEBUG) +static int ndi_buffer_valid (dma_struct_p pdma) { + num_dma_info_p pndi = (num_dma_info_p) pdma->virt_addr; + + assert (pdma != NULL); + assert (pndi != NULL); + if (!ndi_header_valid (pdma, dma_eff_buf_size (pdma))) { + return FALSE; + } + if (!pdma->tx_flag) { + unsigned char * uc = ndi_number_back_ptr (pdma, pndi->len); + + if (pndi->num != *uc) { + return FALSE; + } + } + return TRUE; +} /* ndi_buffer_valid */ +#endif + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void dma_validate_cs (dma_struct_p pdma, unsigned char num, unsigned cs) { + num_dma_info_p pndi = (num_dma_info_p) pdma->virt_addr; + unsigned bnum; + + assert (pdma != NULL); + assert (pndi != NULL); + bnum = 3 + (unsigned) ndi_number_back_ptr (pdma, pndi->len); + bnum &= ~3; +#if !defined (NDEBUG) + assert ((bnum + sizeof (unsigned)) <= (pdma->virt_addr + pdma->length)); + if ((bnum + sizeof (unsigned)) > (pdma->virt_addr + pdma->length)) { + log ("Back num %x, buffer (virtual) %p\n", bnum, pdma->virt_addr); + } +#endif + *((unsigned *) bnum) = cs; + assert (num != DMA_INVALID_NUMBER); + pndi->num = num; + assert (ndi_buffer_valid (pdma)); +} /* dma_validate_cs */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void dma_validate (dma_struct_p pdma, unsigned char cr, unsigned short len, unsigned timer) { + num_dma_info_p pndi = (num_dma_info_p) pdma->virt_addr; + + assert (pdma != NULL); + assert (pndi != NULL); + assert (len <= dma_eff_buf_size (pdma)); + assert ((len + dma_min_buf_size (pdma, pdma->tx_flag)) <= pdma->length); + + pndi->cr = cr; + pndi->len = len; + pndi->timer = timer; +} /* dma_validate */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static unsigned char ndi_get_cr (dma_struct_p pdma) { + num_dma_info_p pndi = (num_dma_info_p) pdma->virt_addr; + + assert (pdma != NULL); + assert (pndi != NULL); + return pndi->cr; +} /* ndi_get_cr */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static unsigned short ndi_get_length (dma_struct_p pdma) { + num_dma_info_p pndi = (num_dma_info_p) pdma->virt_addr; + + assert (pdma != NULL); + assert (pndi != NULL); + return pndi->len; +} /* ndi_get_length */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void ndi_set_number (dma_struct_p pdma, unsigned char x) { + num_dma_info_p pndi = (num_dma_info_p) pdma->virt_addr; + + assert (pdma != NULL); + assert (pndi != NULL); + pndi->num = x; +} /* ndi_set_number */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static unsigned char ndi_get_number (dma_struct_p pdma) { + num_dma_info_p pndi = (num_dma_info_p) pdma->virt_addr; + + assert (pdma != NULL); + assert (pndi != NULL); + return pndi->num; +} /* ndi_get_number */ + +/*****************************************************************************\ + * H E L P E R F U N C T I O N S +\*****************************************************************************/ + +static unsigned check_sum (unsigned char num, unsigned wcnt, unsigned * addr) { + unsigned sum = 0x55aa55aa; + + assert (ro_flag); + assert (addr != NULL); + assert (wcnt > 0); +#if defined (LOG_CHECKSUM) + log ("[start] sum = 0x%x\n", sum); +#endif + sum ^= (unsigned) num; +#if defined (LOG_CHECKSUM) + log ("[number] sum = 0x%x, num = 0x%x\n", sum, num); +#endif + do { + sum ^= *addr; +#if defined (LOG_CHECKSUM) + log ("[%u] sum = 0x%x, num = 0x%x\n", wcnt, sum, *addr); +#endif + ++addr; + } while (--wcnt); + return sum; +} /* check_sum */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void trigger_interrupt (card_p cp) { + + assert (cp != NULL); + assert (cp->mmio_base != 0); + POUTL (cp->mmio_base + C6205_PCI_HDCR_OFFSET, C6205_PCI_HDCR_DSPINT); +} /* trigger_interrupt */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#if !defined (NDEBUG) && defined (LOG_LINK) +static void dump_buffers (int tx_flag) { + unsigned n, ofs; + unsigned offset, val0, val1; + + ofs = tx_flag ? 0 : DMA_BUFFER_NUM_MAX; + log ("Dump buffers in %cX direction...\n", tx_flag ? 'T' : 'R'); + for (n = ofs; n < (ofs + DMA_BUFFER_NUM_MAX); n++) { + if (dma_struct[n] != NULL) { + memdump ( + (void *) dma_struct[n]->virt_addr, + 32, + dma_struct[n]->virt_addr, + tx_flag ? "TX buffer" : "RX buffer" + ); + } + if (!tx_flag && (ro_pwin != NULL)) { + offset = ro_offset + (n - 8) * ro_len + ro_bufofs; + val0 = ro_pwin->inl (ro_pwin->virt_addr + offset); + val1 = ro_pwin->inl (ro_pwin->virt_addr + offset + 4); + log ("RX%u prefix: %08X %08X\n", n, val0, val1); + } + } + log ("End of dump\n"); +} /* dump_buffers */ +#endif + +/*****************************************************************************\ + * T R A N S F E R M A N A G E M E N T +\*****************************************************************************/ + +static int receive_buf (card_p cp, dma_struct_p pdma) { + unsigned count = 0; + unsigned offset, chksum; + unsigned wc, wcnt, tmp1; + unsigned * mem; + unsigned * tmp2; + int res; + + assert (cp != NULL); + assert (pdma != NULL); + assert (ro_pwin != NULL); + offset = ro_offset + ro_next * ro_len + ro_bufofs; + mem = (unsigned *) pdma->virt_addr; + assert (mem != NULL); + do { + count++; + *mem = ro_pwin->inl (ro_pwin->virt_addr + offset); + *(mem + 1) = ro_pwin->inl (ro_pwin->virt_addr + offset + sizeof (unsigned)); + } while ((*mem != ~*(mem + 1)) && (count < MAX_HEADER_RETRANSMIT)); + if (count > 2) { + rx_hdr_fail += count - 2; + } + if (count > MAX_HEADER_RETRANSMIT) { + log ("Too many header re-transmits (%u)...\n", count); + return FALSE; + } + if (ndi_get_number (pdma) != rx_num) { +#if !defined (NDEBUG) && defined (LOG_LINK) + log ( + "Unexpected number, want:%u, have:%u...\n", + rx_num, + ndi_get_number (pdma) + ); +#endif + return FALSE; + } + res = ndi_length_valid (pdma, ndi_get_number (pdma), dma_eff_buf_size (pdma)); + if (!res) { +#if !defined (NDEBUG) && defined (LOG_LINK) + log ("Invalid length (%d)...\n", ndi_get_length (pdma)); +#endif + return FALSE; + } + assert (0 == (sizeof (num_dma_info_t) % 4)); + count = 0; + offset += sizeof (num_dma_info_t); + + /* wcnt: datalen + num + checksum */ + wcnt = (ndi_get_length (pdma) + 4 + 4) >> 2; + tmp1 = sizeof (num_dma_info_t) >> 2; + tmp2 = mem + tmp1; + do { + count++; + for (wc = 0; wc < wcnt; wc++) { + *(tmp2 + wc) = ro_pwin->inl (ro_pwin->virt_addr + offset + 4 * wc); + } + chksum = check_sum (0, wcnt + tmp1, mem); + } while ((chksum != 0) && (count < MAX_HEADER_RETRANSMIT)); + if (count > 1) { + rx_blk_fail += count - 1; + } + if (count > MAX_HEADER_RETRANSMIT) { + log ("Too many block re-transmits (%u)...\n", count); + return FALSE; + } + assert (ndi_buffer_valid (pdma)); + return TRUE; +} /* receive_buf */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void receive_done (void) { + + if (++ro_next == dif_req.rx_block_num) { + ro_next = 0; + } +} /* receive_done */ + +/*---------------------------------------------------------------------------*\ +\*-I-------------------------------------------------------------------------*/ +static unsigned int_complete_buf (int tx_flag) { + ptr_queue_p pq; + hw_completion_func_t pcf; + dma_struct_p pdma; + buf_info_p pinfo; + buf_info_t info; + void * phlp; + int res; + + if (tx_flag) { + pq = tx_list; + pcf = tx_callback; + } else { + pq = rx_list; + pcf = rx_callback; + } + phlp = NULL; + res = q_dequeue (pq, &phlp); + assert (res == TRUE); + pinfo = (buf_info_p) phlp; + assert (pinfo != NULL); + info = *pinfo; + + assert (info.pbd != NULL); + assert (info.ofs == 0); + pdma = (dma_struct_p) info.pbd->context; + + assert (pdma != NULL); + assert (info.len <= dma_eff_buf_size (pdma)); + assert (ndi_get_length (pdma) <= dma_eff_buf_size (pdma)); + + assert (!in_critical ()); + enter_critical (); + assert (ndi_buffer_valid (pdma)); + assert (pcf != NULL); + (* pcf) (info.pbd, info.ofs, ndi_get_length (pdma), info.ctx); + leave_critical (); + assert (!in_critical ()); + + return 1; +} /* int_complete_buf */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static unsigned int int_work_buffers (void) { + unsigned tx_handled = 0; + unsigned rx_handled = 0; + void * phlp = NULL; + buf_info_p pinfo; + unsigned cr; + dma_struct_p pdma; + + while (q_peek (rx_list, &phlp)) { + pinfo = (buf_info_p) phlp; + assert (pinfo != NULL); + assert (pinfo->pbd != NULL); + pdma = (dma_struct_p) pinfo->pbd->context; + assert (pdma != NULL); + assert (card_link != NULL); + if (!atomic_read (&window_ok)) { + log ("I/O window not ready!\n"); + break; + } + if (!receive_buf (card_link, pdma)) { + break; + } +#if !defined (NDEBUG) && defined (LOG_LINK) + log ("Received buf #%u\n", ndi_get_number (pdma)); +#endif + assert (ndi_get_number (pdma) == rx_num); + INC(rx_num); + receive_done (); + + cr = ndi_get_cr (pdma); + rx_handled += int_complete_buf (FALSE); + while (cr-- > 0) { + tx_handled += int_complete_buf (TRUE); + } + phlp = NULL; + } +#if !defined (NDEBUG) + assert ((tx_handled == 0) || (rx_handled > 0)); + tx_handled_count += tx_handled; + rx_handled_count += rx_handled; +#endif + return (tx_handled + rx_handled); +} /* int_work_buffers */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void set_interrupt_callback (int (* cbf) (void *), void * ctx) { + + assert (int_callback == NULL); + assert (int_context == NULL); + int_callback = cbf; + int_context = ctx; +} /* set_interrupt_callback */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void clear_interrupt_callback (void) { + + info (int_callback != NULL); + info (int_context != NULL); + int_callback = NULL; + int_context = NULL; +} /* clear_interrupt_callback */ + +/*---------------------------------------------------------------------------*\ +\*-T-------------------------------------------------------------------------*/ +void xfer_handler (card_p cp) { + unsigned int traffic_cnt = 0; + + UNUSED_ARG(cp); + atomic_set (&xfer_flag, 0); + traffic_cnt += int_work_buffers (); + if (traffic_cnt > 0) { + info (int_callback != NULL); + if (int_callback != NULL) { +#if !defined (NDEBUG) + int res = +#endif + (*int_callback) (int_context); + assert (res == TRUE); + } + } +} /* xfer_handler */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void xfer_task (unsigned long data) { + + UNUSED_ARG (data); + if (in_critical ()) { + atomic_set (&xfer_flag, 1); + } else if (spin_trylock (&stack_lock)) { + xfer_handler (capi_card); + spin_unlock (&stack_lock); + } else { + atomic_set (&xfer_flag, 1); + } +} /* xfer_task */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +irqreturn_t device_interrupt (int irq, void * args, struct pt_regs * regs) { + unsigned long intpins; + card_p cp = (card_p) args; + + UNUSED_ARG (irq); + UNUSED_ARG (regs); + assert (capi_card == cp); + + intpins = PINL (cp->mmio_base + C6205_PCI_HSR_OFFSET); + if (!MY_INT (intpins)) { + return IRQ_NONE; + } + do { + POUTL ( + cp->mmio_base + C6205_PCI_HSR_OFFSET, + C6205_PCI_HSR_INTSRC + ); + tasklet_schedule (&xfer_tasklet); + intpins = PINL (cp->mmio_base + C6205_PCI_HSR_OFFSET); + } while (MY_INT (intpins)); + return IRQ_HANDLED; +} /* device_interrupt */ + +/*****************************************************************************\ + * D E V I C E I N T E R F A C E +\*****************************************************************************/ + +void dif_xfer_requirements (dif_require_p rp, unsigned ofs) { + + assert (rp != NULL); + assert (rp->tx_block_num > 0); + assert (rp->tx_block_size > 0); + assert (rp->tx_max_trans_len == 0); + assert (rp->rx_block_num > 0); + assert (rp->rx_block_size > 0); + assert (rp->rx_max_trans_len == 0); + assert (rp->tx_block_num <= DMA_BUFFER_NUM_MAX); + assert (rp->rx_block_num <= DMA_BUFFER_NUM_MAX); + + dif_req = *rp; + assert (dif_req.tx_block_size >= dma_min_buf_size (NULL, TRUE)); + dif_req.tx_max_trans_len = dif_req.tx_block_size - dma_min_buf_size (NULL, TRUE); + assert (dif_req.rx_block_size >= (dma_min_buf_size (NULL, FALSE) + ofs)); + dif_req.rx_max_trans_len = dif_req.rx_block_size - dma_min_buf_size (NULL, FALSE) - ofs; + dif_req.tx_block_size += 4 * sizeof (unsigned char); + +#if !defined (NDEBUG) && defined (LOG_LINK) + log ( + "Requirements: TX %u/%u/%u, RX %u/%u/%u, Func/Ctx %p/%p\n", + dif_req.tx_block_num, + dif_req.tx_block_size, + dif_req.tx_max_trans_len, + dif_req.rx_block_num, + dif_req.rx_block_size, + dif_req.rx_max_trans_len, + dif_req.get_code, + dif_req.context + ); +#endif +} /* dif_xfer_requirements */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void dif_reset (void) { + + log ("Resetting device structures...\n"); + + atomic_set (&window_ok, 0); + ro_num = 0; + ro_offset = 0; + ro_pwin = NULL; + ro_len = 0; + ro_next = 0; + ro_bufofs = 0; + rx_hdr_fail = 0; + rx_blk_fail = 0; + + lock (); + q_reset (tx_list); + q_reset (rx_list); + crrx_local = 0; + crrx_global = 0; + tx_num = 1; + rx_num = 1; +#if !defined (NDEBUG) + tx_last_buffer = 0; + rx_last_buffer = 0; + tx_handled_count = 0; + rx_handled_count = 0; +#endif + atomic_set (&is_stopped, FALSE); + unlock (); + log ("Reset done.\n"); +} /* dif_reset */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void dif_set_params ( + unsigned num, + unsigned offset, + ioaddr_p pwin, + unsigned len, + unsigned bufofs +) { +#if !defined (NDEBUG) && defined (LOG_LINK) + unsigned n, ofs; +#endif + + assert (num > 0); + assert ((offset % 4) == 0); + assert (len > 0); + assert ((len % 4) == 0); + assert (pwin != NULL); + + ro_num = num; + ro_offset = offset; + ro_pwin = pwin; + ro_len = len; + ro_bufofs = bufofs; + atomic_set (&window_ok, 1); + log ("I/O window has been set!\n"); + +#if !defined (NDEBUG) && defined (LOG_LINK) + log ("dif_set_params:\n"); + for (n = 0; n < ro_num; n++) { + ofs = ro_offset + n * ro_len + ro_bufofs; + log ("buffer(%u), vaddr 0x%08x\n", n, pwin->virt_addr + ofs); + } +#endif +} /* dif_set_params */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int dif_init (card_p cp, int ro, timer_func_t timerf, to_pc_ack_func_t ackf) { + + info (get_timer_func == NULL); + info (to_pc_ack_func == NULL); + log ("Initializing device structures...\n"); + buf_disc = 0; + ro_num = 0; + ro_offset = 0; + ro_pwin = NULL; + ro_len = 0; + ro_next = 0; + ro_bufofs = 0; + rx_hdr_fail = 0; + rx_blk_fail = 0; + tx_num = 1; + rx_num = 1; + card_link = cp; + crrx_local = 0; + crrx_global = 0; + get_timer_func = timerf ? timerf : &get_timer; + to_pc_ack_func = ackf ? ackf : &pc_acknowledge; + info (ro == TRUE); + ro_flag = ro; + if (NULL == (tx_list = q_make (DMA_BUFFER_NUM_MAX))) { + log ("Could not allocate TX queue\n"); + return FALSE; + } + if (NULL == (rx_list = q_make (DMA_BUFFER_NUM_MAX))) { + log ("Could not allocate RX queue\n"); + q_remove (&tx_list); + return FALSE; + } + q_attach_mem (tx_list, DMA_BUFFER_NUM_MAX, sizeof (buf_info_t)); + q_attach_mem (rx_list, DMA_BUFFER_NUM_MAX, sizeof (buf_info_t)); + memset (&dma_struct, 0, 2 * DMA_BUFFER_NUM_MAX * sizeof (dma_struct_p)); + memset (&dif_req, 0, sizeof (dif_require_t)); + return ro_flag; +} /* dif_init */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void dif_exit (void) { + + dif_reset (); + log ("Deinitializing device...\n"); + info (get_timer_func != NULL); + get_timer_func = NULL; + info (to_pc_ack_func != NULL); + to_pc_ack_func = NULL; + if (tx_list != NULL) { + q_remove (&tx_list); + } + if (rx_list != NULL) { + q_remove (&rx_list); + } +} /* dif_exit */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int dif_start (void) { + + return TRUE; +} /* dif_start */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void dif_stop (int tx_flag) { + void * phlp = NULL; + buf_info_p pi; + ptr_queue_p pq; + dma_struct_p pdma; + unsigned n; + + pq = tx_flag ? tx_list : rx_list; + assert (pq != NULL); + while (q_dequeue (pq, &phlp)) { + pi = (buf_info_p) phlp; + assert (pi != NULL); + assert (pi->pbd != NULL); + pdma = (dma_struct_p) pi->pbd->context; + assert (pdma != NULL); + + dma_invalidate (pdma, TRUE); + assert (event_callback != NULL); + lock (); + (* event_callback) ( + DMA_REQUEST_CANCELLED, + pi->pbd, + pi->ofs, + pi->len, + pi->ctx + ); + unlock (); + + phlp = NULL; + } + for (n = 0; n < (2 * DMA_BUFFER_NUM_MAX); n++) { + info (dma_struct[n] != NULL); + if (dma_struct[n] != NULL) { + dma_reset_buf (dma_struct[n]); + } + } +} /* dif_stop */ + +/*****************************************************************************\ + * H A R D W A R E I N T E R F A C E +\*****************************************************************************/ + +unsigned OSHWBlockOpen (unsigned index, hw_block_handle * handle) { + + UNUSED_ARG (index); + assert (handle != NULL); + info (*handle == NULL); + *handle = (hw_block_handle) card_link; + assert (!atomic_xchg (&is_open, 1)); + return TRUE; +} /* OSHWBlockOpen */ + +/*---------------------------------------------------------------------------*\ +\*-O-------------------------------------------------------------------------*/ +void OSHWBlockClose (hw_block_handle handle) { + + assert (handle == (hw_block_handle) card_link); + assert (atomic_read (&n_buffers) == 0); + assert (atomic_read (&is_open)); + assert (!atomic_read (&is_started)); + assert (atomic_xchg (&is_open, 0)); +} /* OSHWBlockClose */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +extern unsigned OSHWStart ( + hw_block_handle handle, + hw_completion_func_t rx_completer, + hw_completion_func_t tx_completer, + hw_event_func_t event_handler +) { + assert (handle == (hw_block_handle) card_link); + assert (atomic_read (&is_open)); + assert (!atomic_read (&is_started)); + assert (rx_callback == NULL); + assert (tx_callback == NULL); + assert (event_callback == NULL); + + rx_callback = rx_completer; + tx_callback = tx_completer; + event_callback = event_handler; + assert (!atomic_xchg (&is_started, 1)); + + return dif_start (); +} /* OSHWStart */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void OSHWStop (hw_block_handle handle) { + + assert (handle == (hw_block_handle) card_link); + assert (atomic_read (&is_open)); + assert (atomic_read (&is_started)); + + dif_stop (TRUE); + dif_stop (FALSE); + atomic_set (&is_stopped, TRUE); + + rx_callback = NULL; + tx_callback = NULL; + event_callback = NULL; + assert (atomic_xchg (&is_started, 0)); +} /* OSHWStop */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +hw_buffer_descriptor_p OSHWAllocBuffer (hw_block_handle handle, unsigned length) { + hw_buffer_descriptor_p pbd; + dma_struct_p pstr; +#if !defined (NDEBUG) + unsigned start, stop, n; +#endif + + log ("Allocating DMA buffer of %u bytes\n", length); + assert (handle == (hw_block_handle) card_link); + assert (atomic_read (&is_open)); + assert (length < OSHWGetMaxBlockSize (handle)); + assert (dif_req.tx_block_num > 0); + assert (dif_req.rx_block_num > 0); + assert ((length == dif_req.tx_block_size) || (length == dif_req.rx_block_size)); + + if (NULL == (pbd = (hw_buffer_descriptor_p) hmalloc (sizeof (hw_buffer_descriptor_t)))) { + return NULL; + } + + if (NULL == (pstr = dma_alloc ())) { + hfree (pbd); + return NULL; + } + if (!dma_init_xx (pstr, length, (buf_disc < dif_req.tx_block_num))) { + hfree (pbd); + dma_exit (pstr); + dma_free (&pstr); + return NULL; + } + pbd->handle = handle; + pbd->buffer = dma_eff_buf_virt (pstr); + pbd->length = length; + pbd->context = pstr; + + assert (buf_disc < 2 * DMA_BUFFER_NUM_MAX); + assert (dma_struct[buf_disc] == NULL); + dma_struct[buf_disc++] = pstr; + +#if !defined (NDEBUG) + atomic_inc (&n_buffers); + start = stop = 0; + if (buf_disc == dif_req.tx_block_num) { + stop = buf_disc; + } else if (buf_disc == (dif_req.tx_block_num + dif_req.rx_block_num)) { + start = dif_req.tx_block_num; + stop = buf_disc; + } + if (start != stop) { + assert (stop > 1); + for (n = start; n < (stop - 1); n++) { + assert (dma_struct[n] != NULL); + assert (dma_struct[n + 1] != NULL); + dma_struct[n]->context = dma_struct[n + 1]; + log ( + "DMA context of structure #%u(%p) set to %p\n", + n, dma_struct[n], dma_struct[n + 1] + ); + } + dma_struct[n]->context = dma_struct[start]; + log ( + "DMA context of structure #%u(%p) set to %p\n", + n, dma_struct[n], dma_struct[start] + ); + } +#endif + + return pbd; +} /* OSHWAllocBuffer */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +extern void OSHWFreeBuffer (hw_buffer_descriptor_p desc) { + dma_struct_p pstr; + + if (desc == NULL) { + log ("Attempt to free NULL descriptor!\n"); + return; + } + pstr = (dma_struct_p) desc->context; + assert (pstr != NULL); + desc->buffer = (unsigned char *) pstr->virt_addr; + + assert (atomic_read (&is_open)); + assert (atomic_read (&n_buffers) > 0); + dma_exit (pstr); + hfree (pstr); + hfree (desc); + + assert (buf_disc > 0); + assert (buf_disc <= 2 * DMA_BUFFER_NUM_MAX); + buf_disc--; + assert (dma_struct[buf_disc] != NULL); + dma_struct[buf_disc] = NULL; +#if !defined (NDEBUG) + atomic_dec (&n_buffers); +#endif +} /* OSHWFreeBuffer */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +unsigned OSHWGetMaxBlockSize (hw_block_handle handle) { + + assert (handle == (hw_block_handle) card_link); + return 4 * 1024; +} /* OSHWGetMaxBlockSize */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +unsigned OSHWGetMaxConcurrentRxBlocks (hw_block_handle handle) { + + assert (handle == (hw_block_handle) card_link); + return dif_req.rx_block_num; +} /* OSHWGetMaxConcurrentRxBlocks */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +unsigned OSHWGetMaxConcurrentTxBlocks (hw_block_handle handle) { + + assert (handle == (hw_block_handle) card_link); + return dif_req.tx_block_num; +} /* OSHWGetMaxConcurrentRxBlocks */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void * OSHWExchangeDeviceRequirements (hw_block_handle handle, void * pin) { + in_require_p pr = (in_require_p) pin; + + assert (handle == (hw_block_handle) card_link); + info (pr != NULL); + if (pr != NULL) { + tx_function = pr->tx_func; + assert (tx_function != NULL); + } + assert (dif_req.tx_block_num > 0); + assert (dif_req.tx_block_size > 0); + assert (dif_req.tx_max_trans_len > 0); + assert (dif_req.rx_block_num > 0); + assert (dif_req.rx_block_size > 0); + assert (dif_req.rx_max_trans_len > 0); + log ("Returning requirements, TX %u/%u/%u, RX %u/%u/%u\n", + dif_req.tx_block_num, + dif_req.tx_block_size, + dif_req.tx_max_trans_len, + dif_req.rx_block_num, + dif_req.rx_block_size, + dif_req.rx_max_trans_len + ); + return (void *) &dif_req; +} /* OSHWExchangeRequirements */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +unsigned OSHWTxBuffer ( + const hw_buffer_descriptor_p desc, + unsigned offset, + unsigned length, + void * context +) { + buf_info_t info = { desc, offset, length, context } ; + dma_struct_p pdma; + unsigned chksum, timer = 0; + int res; + + assert (!atomic_read (&is_stopped)); + assert (atomic_read (&is_open)); + assert (info.pbd != NULL); + pdma = (dma_struct_p) info.pbd->context; + assert (pdma != NULL); + assert (info.ofs == 0); + assert (info.len <= dif_req.tx_max_trans_len); + assert (info.len <= dma_eff_buf_size (pdma)); + assert (info.len <= MAX_LENGTH); + + assert (q_get_count (tx_list) < dif_req.tx_block_num); + +#if !defined (NDEBUG) + assert (get_timer_func != NULL); + timer = (*get_timer_func) (); +#endif + dma_validate (pdma, 0, info.len, timer); + ndi_set_number (pdma, 0); /* 0 for chksum */ + chksum = check_sum ( + tx_num, + (sizeof (num_dma_info_t) + ndi_get_length (pdma) + 3) >> 2, + (unsigned *) pdma->virt_addr + ); + dma_validate_cs (pdma, tx_num, chksum); + res = q_enqueue_mem (tx_list, &info, sizeof (buf_info_t)); + assert (res != 0); + assert (q_get_count (tx_list) <= DMA_BUFFER_NUM_MAX); + assert (q_get_count (tx_list) <= dif_req.tx_block_num); +#if !defined (NDEBUG) + if (tx_last_buffer != NULL) { + assert ((void *) pdma == tx_last_buffer->context); + } else { + assert (pdma == dma_struct [0]); + } + tx_last_buffer = pdma; +#endif + INC(tx_num); + assert (card_link != NULL); + trigger_interrupt (card_link); + + return TRUE; +} /* OSHWTxBuffer */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +extern unsigned OSHWRxBuffer ( + const hw_buffer_descriptor_p desc, + unsigned offset, + unsigned length, + void * context +) { + buf_info_t info = { desc, offset, length, context } ; + dma_struct_p pdma; + int res; +#if !defined (NDEBUG) + unsigned time; +#endif + + assert (!atomic_read (&is_stopped)); + assert (atomic_read (&is_open)); + assert (info.pbd != NULL); + pdma = (dma_struct_p) info.pbd->context; + assert (pdma != NULL); + assert (info.ofs == 0); + assert (info.len <= dif_req.rx_max_trans_len); + + assert (info.len <= dma_eff_buf_size (pdma)); + assert (info.len <= MAX_LENGTH); + + assert (q_get_count (rx_list) < dif_req.rx_block_num); + res = q_enqueue_mem (rx_list, &info, sizeof (buf_info_t)); + assert (res != 0); +#if !defined (NDEBUG) + if (rx_last_buffer != NULL) { + assert (rx_last_buffer->context == (void *) pdma); + } else { + assert (dif_req.tx_block_num > 0); + assert (dif_req.tx_block_num < (2 * DMA_BUFFER_NUM_MAX)); + assert (pdma == dma_struct [dif_req.tx_block_num]); + } + rx_last_buffer = pdma; + assert (get_timer_func != NULL); + time = (*get_timer_func) (); + last_to_pc_ack = time; +#endif + assert (to_pc_ack_func != NULL); + (*to_pc_ack_func) (ndi_get_number (pdma)); + + return TRUE; +} /* OSHWRxBuffer */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +unsigned OSHWCancelRx (hw_block_handle handle) { + + UNUSED_ARG (handle); + assert (0); + return FALSE; +} /* OSHWCancelRx */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +unsigned OSHWCancelTx (hw_block_handle handle) { + + UNUSED_ARG (handle); + assert (0); + return FALSE; +} /* OSHWCancelTx */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/devif.h linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/devif.h --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/devif.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/devif.h 2004-08-13 00:00:00.000000000 +0200 @@ -0,0 +1,158 @@ +/* + * devif.h + * Copyright (C) 2003, AVM GmbH. All rights reserved. + * + * This Software is free software. You can redistribute and/or + * modify such free software under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * The free software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this Software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or see + * http://www.opensource.org/licenses/lgpl-license.html + * + * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de + */ + +#ifndef __have_devif_h__ +#define __have_devif_h__ + +#include +#include +#include "common.h" + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#if !defined (C6205_PCI_HSR_OFFSET) +#define C6205_PCI_HSR_OFFSET 0 +#define C6205_PCI_HDCR_OFFSET 4 +#define C6205_PCI_DSPP_OFFSET 8 +#endif + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#define C6205_PCI_HDCR_WARMRESET 1 +#define C6205_PCI_HDCR_DSPINT 2 +#define C6205_PCI_HDCR_PCIBOOT 4 +#define C6205_PCI_HSR_INTSRC 1 +#define C6205_PCI_HSR_INTAVAL 2 +#define C6205_PCI_HSR_OMTA 4 +#define C6205_PCI_HSR_CFRGERR 8 +#define C6205_PCI_HSR_EEREAD 16 + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +extern atomic_t xfer_flag; + +extern void xfer_handler (card_p); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +extern int dif_init (card_p, int, timer_func_t, to_pc_ack_func_t); +extern void dif_exit (void); + +extern void dif_set_params ( + unsigned num, + unsigned offset, + ioaddr_p pwin, + unsigned len, + unsigned bufofs +); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +extern void dif_xfer_requirements (dif_require_p, unsigned); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +extern void set_interrupt_callback (int (*f) (void *), void *); +extern void clear_interrupt_callback (void); + +extern void device_interrupt (int, void *, struct pt_regs *); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +extern dma_struct_p dma_alloc (void); +extern void dma_free (dma_struct_p *); + +extern int dma_setup (dma_struct_p, unsigned long); +extern void dma_free_buffer (dma_struct_p); + +extern int dma_init (dma_struct_p, unsigned long); +extern void dma_exit (dma_struct_p); + +extern dma_struct_p * dma_get_struct_list (unsigned *); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#if defined (USB_EVENT_HARD_ERROR) +# undef USB_EVENT_HARD_ERROR +#endif + +#define USB_REQUEST_CANCELLED 0x8000 +#define USB_RX_REQUEST 0x4000 +#define USB_TX_REQUEST 0x2000 +#define USB_EVENT_HARD_ERROR 0x0800 + +#define DMA_REQUEST_CANCELLED 0x8000 +#define DMA_RX_REQUEST 0x4000 +#define DMA_TX_REQUEST 0x2000 +#define DMA_EVENT_HARD_ERROR 0x0800 + +extern unsigned OSHWBlockOpen (unsigned, hw_block_handle *); +extern void OSHWBlockClose (hw_block_handle); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +extern unsigned OSHWStart ( + hw_block_handle, + hw_completion_func_t, + hw_completion_func_t, + hw_event_func_t +); +extern void OSHWStop (hw_block_handle); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +extern hw_buffer_descriptor_p OSHWAllocBuffer (hw_block_handle, unsigned); +extern void OSHWFreeBuffer (hw_buffer_descriptor_p); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +extern unsigned OSHWGetMaxBlockSize (hw_block_handle); +extern unsigned OSHWGetMaxConcurrentRxBlocks (hw_block_handle); +extern unsigned OSHWGetMaxConcurrentTxBlocks (hw_block_handle); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +extern void * OSHWExchangeDeviceRequirements (hw_block_handle, void *); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +extern unsigned OSHWTxBuffer ( + const hw_buffer_descriptor_p, + unsigned, + unsigned, + void * +); + +extern unsigned OSHWRxBuffer ( + const hw_buffer_descriptor_p, + unsigned, + unsigned, + void * +); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +extern unsigned OSHWCancelRx (hw_block_handle); + +extern unsigned OSHWCancelTx (hw_block_handle); + +#endif diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/driver.c linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/driver.c --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/driver.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/driver.c 2004-08-13 00:00:00.000000000 +0200 @@ -0,0 +1,1933 @@ +/* + * driver.c + * Copyright (C) 2002, AVM GmbH. All rights reserved. + * + * This Software is free software. You can redistribute and/or + * modify such free software under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * The free software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this Software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or see + * http://www.opensource.org/licenses/lgpl-license.html + * + * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "libstub.h" +#include "ca.h" +#include "capilli.h" +#include "tables.h" +#include "queue.h" +#include "lib.h" +#include "main.h" +#include "tools.h" +#include "defs.h" +#include "fw.h" +#include "devif.h" +#include "driver.h" + +#if defined (LOG_MESSAGES) +# define mlog log +#else +# define mlog(f,a...) +#endif + +#define __entry + +#define KILOBYTE 1024 +#define MEGABYTE (1024*KILOBYTE) +#define _2_MEGS_ (2*MEGABYTE) +#define _4_MEGS_ (4*MEGABYTE) +#define _8_MEGS_ (8*MEGABYTE) +#define TEN_MSECS (HZ/100) + +#define MAPPED_DATA_LEN _4_MEGS_ +#define MAPPED_CODE_LEN _8_MEGS_ +#define IO_REGION_LEN 16 +#define DEBUG_MEM_SIZE MEGABYTE +#define DEBUG_TIMEOUT 100 +#define RESET_DELAY 10 + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#define DBG_FORMAT_LEN 1024 +#define DBG_MEM_SIZE (1024 * 1024) +#define DBG_TIMEOUT 100 +#define DBG_MIN_SIZE 1024 + +typedef struct __db { + + dma_struct_p pdma; + atomic_t stop; + unsigned len; + unsigned tout; + char * pbuf; + int pid; +} dbg_buf_t, * dbg_buf_p; + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +card_p capi_card = NULL; +lib_callback_t * capi_lib = NULL; +atomic_t crit_count = ATOMIC_INIT(0); +spinlock_t stack_lock = SPIN_LOCK_UNLOCKED; + +struct capi_driver_interface * capi_driver = NULL; +static int load_flag = FALSE; +static int init_flag = FALSE; +static int nvers = 0; +static atomic_t scheduler_enabled = ATOMIC_INIT (1); +struct capi_ctr * capi_controller[2] = { NULL, NULL } ; +static bundle_t ctrl_context[2]; +static per_ctrl_t ctrl_params[2]; +static unsigned long qt_flags; +static spinlock_t qt_lock = SPIN_LOCK_UNLOCKED; +static atomic_t thread_flag = ATOMIC_INIT (0); +static atomic_t thread_capi_flag = ATOMIC_INIT (0); +static int thread_pid = -1; +static char * firmware_ptr = NULL; +static unsigned firmware_len = 0; +static unsigned pc_ack_offset = 0; +static unsigned timer_offset = 0; +static dbg_buf_p dbgbuf = NULL; + +static DECLARE_WAIT_QUEUE_HEAD(wait); +static DECLARE_WAIT_QUEUE_HEAD(capi_wait); +static DECLARE_WAIT_QUEUE_HEAD(dbg_wait); + +static DECLARE_MUTEX_LOCKED(thread_sync); + +static int irq_callback (void *); +static void enable_thread (void); +static void disable_thread (void); +static int make_thread (void); +static void kill_thread (void); +static void scheduler_control (unsigned); +static void wakeup_control (unsigned); +static void version_callback (char *); +static void kill_version (struct capi_ctr *); +static unsigned scheduler_suspend (unsigned long); +static unsigned scheduler_resume (void); +static unsigned controller_remove (void); +static unsigned controller_add (void); + +struct capi_driver capi_interface = { + + TARGET, + REV_DEFAULT, + load_ware, + reset_ctrl, + remove_ctrl, + register_appl, + release_appl, + send_msg, + proc_info, + ctr_info, + drv_info, + NULL, /* add_card */ + NULL, + NULL, + 0, + NULL, + "" +} ; + +static functions_t ca_funcs = { + + 7, + scheduler_control, + wakeup_control, + version_callback, + scheduler_suspend, + scheduler_resume, + controller_remove, + controller_add +} ; + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static char * invalid_msg = "Invalid application id #%d.\n"; + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static unsigned char minb (unsigned addr) { return MINB(addr); } +static unsigned short minw (unsigned addr) { return MINW(addr); } +static unsigned long minl (unsigned addr) { return MINL(addr); } +static unsigned char pinb (unsigned addr) { return PINB(addr); } +static unsigned short pinw (unsigned addr) { return PINW(addr); } +static unsigned long pinl (unsigned addr) { return PINL(addr); } + +static void moutb (unsigned char val, unsigned addr) { MOUTB(addr, val); } +static void moutw (unsigned short val, unsigned addr) { MOUTW(addr, val); } +static void moutl (unsigned long val, unsigned addr) { MOUTL(addr, val); } +static void poutb (unsigned char val, unsigned addr) { POUTB(addr, val); } +static void poutw (unsigned short val, unsigned addr) { POUTW(addr, val); } +static void poutl (unsigned long val, unsigned addr) { POUTL(addr, val); } + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#define PCI_NO_RESOURCE 4 +#define PCI_NO_PCI_KERN 3 +#define PCI_NO_CARD 2 +#define PCI_NO_PCI 1 +#define PCI_OK 0 + +static int alloc_resources (struct pci_dev * dev, card_p cp) { + + UNUSED_ARG (dev); + if (!request_region (cp->addr_mmio, IO_REGION_LEN, TARGET)) { + error ("Could not claim i/o region.\n"); + io_problem: + cp->mmio_base = 0; + return PCI_NO_RESOURCE; + } + cp->mmio_base = cp->addr_mmio; + cp->mmio_access_ok = TRUE; + log ("I/O region at 0x%08x\n", cp->mmio_base); + if (!(cp->data_base = ioremap_nocache (cp->addr_data, cp->len_data))) { + log ("Could not map data memory into virtual memory.\n"); + data_map_exit: + release_region (cp->addr_mmio, IO_REGION_LEN); + goto io_problem; + } + cp->data_access_ok = TRUE; + log ("Controller data memory mapped to %08x\n", cp->data_base); + if (!(cp->code_base = ioremap_nocache (cp->addr_code, cp->len_code))) { + log ("Could not map code memory into virtual memory.\n"); + /* code_map_exit: */ + iounmap (cp->data_base); + cp->data_base = NULL; + goto data_map_exit; + } + cp->code_access_ok = TRUE; + log ("Controller code memory mapped to %08x\n", cp->code_base); + pci_set_master (dev); + return PCI_OK; +} /* alloc_resources */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void free_interrupt (card_p cp) { + + log ("Free IRQ...\n"); + assert (cp); + if (cp->irq != 0) { + free_irq (cp->irq, cp); + cp->irq = 0; + log ("IRQ freed.\n"); + } +} /* free_interrupt */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void free_resources (card_p cp) { + + assert (cp->mmio_base != 0); + assert (cp->data_base != NULL); + assert (cp->code_base != NULL); + + free_interrupt (cp); + clear_interrupt_callback (); + log ("Unmapping code, data, i/o regions...\n"); + iounmap (cp->code_base); + iounmap (cp->data_base); + release_region (cp->addr_mmio, IO_REGION_LEN); + info (cp->piowin != NULL); + if (cp->piowin != NULL) { + hfree (cp->piowin); + } + log ("Resources freed.\n"); +} /* free_resources */ + +/*---------------------------------------------------------------------------*\ +\*-B-------------------------------------------------------------------------*/ +#define DBG_FORMAT_START 0xABCD1234 +#define DBG_FORMAT_STOP 0x4321DCBA + +void dump (char * p1, char * p2, char * end, unsigned l1, unsigned l2) { + + p1 += sizeof (unsigned); + p2 += sizeof (unsigned); + memdump (p1, l1, p1 - p2, ""); + if (l2 != 0) { + memdump (p2, l2, 0, ""); + } +} /* dump */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void dump_debug_buffer (dbg_buf_p dbp) { + static char * bp = NULL; + unsigned part1_len, part2_len; + unsigned total_len, check_len; + int delta; + + assert (dbp != NULL); + if ((dbp->pbuf == NULL) || atomic_read (&dbp->stop)) { + log ("No debug buffer???\n"); + return; + } + + assert (dbp->pbuf != NULL); + assert (dbp->pdma != NULL); + assert (dbp->pbuf >= (char *) dbp->pdma->virt_addr); + assert (dbp->pbuf < (char *) (dbp->pdma->virt_addr + dbp->len)); + assert ((((unsigned) dbp->pbuf) & 3) == 0); + if (bp == NULL) { + bp = dbp->pbuf; + } + part1_len = part2_len = 0; + + assert (bp >= dbp->pbuf); + assert (bp < (dbp->pbuf + dbp->len)); + total_len = * ((unsigned *) bp); + info (total_len < dbp->len); + if ((total_len > dbp->len) || ((total_len & 3) != 0)) { + log ("Debug thread needs debugging!\n"); + return; + } + + delta = ((char *) bp + total_len) - (dbp->pbuf + dbp->len); + if (delta > 0) { + part2_len = (unsigned) delta; + part1_len = total_len - part2_len; + } else { + part2_len = 0; + part1_len = total_len; + } + assert ((part2_len & 3) == 0); + assert ((part1_len & 3) == 0); + assert (part2_len < dbp->len); + + if (part1_len != 0) { + check_len = (part2_len == 0) + ? * ((unsigned *) (bp + part1_len) + 1) + : * ((unsigned *) (dbp->pbuf + part2_len) + 1); + assert (check_len == total_len); + + dump ( + bp, + dbp->pbuf, + dbp->pbuf + dbp->len, + part1_len, + part2_len + ); + + if (part2_len == 0) { + bp += 2 * sizeof (unsigned) + part1_len; + } else { + bp = dbp->pbuf + part2_len + sizeof (unsigned); + } + } +} /* dump_debug_buffer */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static int debug_thread (void * arg) { + dbg_buf_p dbp = (dbg_buf_p) arg; + unsigned to; + + assert (dbp != NULL); + to = (((dbp->tout < 10) ? 10 : dbp->tout) / 10) * TEN_MSECS; + while (!atomic_read (&dbp->stop)) { + interruptible_sleep_on_timeout (&dbg_wait, to); + dump_debug_buffer (dbp); + } + log ("Debug thread stopped.\n"); + if (dbp->pdma != NULL) { + dma_free_buffer (dbp->pdma); + dma_free (&dbp->pdma); + } + hfree (dbp); + return 0; +} /* debug_thread */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static int init_debug_buffer (dbg_buf_p dbp) { + int res = 0; + unsigned size = DBG_MEM_SIZE; + dma_struct_p pdma; + + assert (dbp != NULL); + assert (size >= DBG_MIN_SIZE); + assert (DBG_TIMEOUT > 0); + assert (dbp->pbuf == NULL); + pdma = dma_alloc (); + res = FALSE; + for ( ; size >= DBG_MIN_SIZE; size /= 2) { + if ((res = dma_setup (pdma, size))) { + break; + } + log ("Failed to allocate %u byte DMA buffer...\n", size); + } + if (!res) { + dma_exit (pdma); + dma_free (&pdma); + return FALSE; + } + log ( + "Debug DMA buffer, %u bytes, vaddr %p, paddr %p\n", + pdma->length, + (void *) pdma->virt_addr, + (void *) pdma->phys_addr + ); + assert (size == pdma->length); + dbp->pdma = pdma; + dbp->pbuf = (void *) pdma->virt_addr; + dbp->len = size; + dbp->tout = DBG_TIMEOUT; + atomic_set (&dbp->stop, 0); + dbp->pid = kernel_thread (debug_thread, dbp, 0); + return TRUE; +} /* init_debug_buffer */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void exit_debug_buffer (dbg_buf_p dbp) { + + assert (dbp != NULL); + info (find_task_by_pid (dbp->pid) != NULL); + log ("Stopping debug thread...\n"); + atomic_set (&dbp->stop, 1); + if (find_task_by_pid (dbp->pid)) { + wake_up_interruptible (&dbg_wait); + } else { + hfree (dbp); + } +} /* exit_debug_buffer */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void reset (card_p cp) { + int done = 0; + + assert (cp != NULL); + if (fw_ready ()) { + assert (cp->c6205_ctx != NULL); + log ("Loadfile based reset.\n"); + done = fw_send_reset (cp->c6205_ctx); + } + if (!done) { + assert (cp->mmio_base != 0); + log ("I/O based reset.\n"); + POUTL ( + cp->mmio_base + C6205_PCI_HDCR_OFFSET, + C6205_PCI_HDCR_WARMRESET + ); + } + mdelay (RESET_DELAY); +} /* reset */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static inline void kill_versions (void) { + + if (ctrl_context[0].ctrl != NULL) { + kill_version (capi_controller[0]); + } + kill_version (capi_controller[1]); +} /* kill_versions */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int start_stack (card_p cp) { + int res = 0; + unsigned num = 0, n; + unsigned ofs, len, bof; + ioaddr_p pwin; + dma_struct_p * ppdma; + + /* preparing the stack */ + cp->count = 0; + table_init (&cp->appls); + queue_init (&cp->queue); + + assert (capi_lib != NULL); + assert (capi_lib->cm_register_ca_functions != NULL); + assert (capi_lib->cm_start != NULL); + assert (capi_lib->cm_init != NULL); + (*capi_lib->cm_register_ca_functions) (&ca_funcs); + if ((*capi_lib->cm_start) ()) { + error ("Starting the stack failed...\n"); + early_exit: + queue_exit (&cp->queue); + table_exit (&cp->appls); + return FALSE; + } + (void) (*capi_lib->cm_init) (0, cp->irq); + assert (nvers == 2); + + /* install an interrupt handler */ + set_interrupt_callback (&irq_callback, cp); + if (0 != (res = request_irq (cp->irq, &device_interrupt, SA_INTERRUPT | SA_SHIRQ, TARGET, cp))) { + error ("Could not install irq handler.\n"); + stack_exit: + assert (capi_lib->cm_exit != NULL); + (*capi_lib->cm_exit) (); + clear_interrupt_callback (); + kill_versions (); + goto early_exit; + } else { + log ("IRQ #%d assigned to " TARGET " driver.\n", cp->irq); + } + + /* debug buffer */ + assert (capi_lib->cc_need_debug_buffer != NULL); + if ((*capi_lib->cc_need_debug_buffer) ()) { + log ("Setting up debug buffer.\n"); + if (dbgbuf == NULL) { + if (NULL != (dbgbuf = (dbg_buf_p) hcalloc (sizeof (dbg_buf_t)))) { + if (!init_debug_buffer (dbgbuf)) { + hfree (dbgbuf); + goto stack_exit; + } + assert (capi_lib->cc_init_debug != NULL); + (*capi_lib->cc_init_debug) ( + (void *) dbgbuf->pdma->phys_addr, + dbgbuf->pdma->length + ); + } + } + } else { + log ("No debug buffer.\n"); + } + + /* establish DMA buffers */ + ppdma = dma_get_struct_list (&num); + assert (capi_lib->cc_num_link_buffer != NULL); + assert (capi_lib->cc_init_dma != NULL); + n = (*capi_lib->cc_num_link_buffer) (TRUE), + (*capi_lib->cc_init_dma) ( + &ppdma[0], n, + &ppdma[n], (*capi_lib->cc_num_link_buffer) (FALSE) + ); + + assert (capi_lib->cc_link_version != NULL); + assert (capi_lib->cc_buffer_params != NULL); + if ((*capi_lib->cc_link_version) () > 1) { + num = (*capi_lib->cc_buffer_params) (&ofs, &pwin, &len, &bof); + dif_set_params (num, ofs, pwin, len, bof); + } + reset (cp); + assert (capi_lib->cc_run != NULL); + res = (*capi_lib->cc_run) (); + if (res == FALSE) { /* Failure */ + error ("Firmware does not respond!\n"); + reset_exit: + reset (cp); + if (dbgbuf != NULL) { + exit_debug_buffer (dbgbuf); + } + goto stack_exit; + } + assert (capi_lib->cc_compress_code != NULL); + (*capi_lib->cc_compress_code) (); + + /* start the stack */ + enter_critical (); + if ((*capi_lib->cm_activate) ()) { + error ("Activation of the card failed.\n"); + leave_critical (); + goto reset_exit; + } + leave_critical (); + make_thread (); + enable_thread (); + init_flag = TRUE; + return TRUE; +} /* start_stack */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void stop_stack (card_p card) { + + if (!init_flag) { + log ("Stack not initialized.\n"); + return; + } + init_flag = FALSE; + if (dbgbuf != NULL) { + exit_debug_buffer (dbgbuf); + dbgbuf = NULL; + } + (*capi_lib->cm_exit) (); + if (thread_pid != -1) { + // disable_thread (); + kill_thread (); + } + queue_exit (&card->queue); + table_exit (&card->appls); + kill_versions (); + nvers = 0; +} /* stop_stack */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static int reset_card (card_p cp) { + + reset (cp); + fw_exit (&cp->c6205_ctx); + return TRUE; +} /* reset_card */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static int test_card (card_p cp) { + + UNUSED_ARG (cp); + return TRUE; +} /* test_card */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static int params_ok (card_p cp) { + + UNUSED_ARG (cp); + return TRUE; +} /* params_ok */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static int find_card (card_p cp) { +#if !defined (CONFIG_PCI) + return PCI_NO_PCI_KERN; +#else + struct pci_dev * dev = NULL; + + if (!pci_present ()) { + return PCI_NO_PCI; + } + dev = pci_find_device (PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_FCDSL2, dev); + if (NULL == dev) { + return PCI_NO_CARD; + } + if (0 != pci_enable_device (dev)) { + log ("Failed to enable the controller.\n"); + return PCI_NO_CARD; + } + + assert (pci_resource_len (dev, 0) == MAPPED_DATA_LEN); + assert (pci_resource_len (dev, 1) == MAPPED_CODE_LEN); + assert (pci_resource_len (dev, 2) == IO_REGION_LEN); + + cp->addr_data = pci_resource_start (dev, 0); + cp->len_data = pci_resource_len (dev, 0); + cp->addr_code = pci_resource_start (dev, 1); + cp->len_code = pci_resource_len (dev, 1); + cp->addr_mmio = pci_resource_start (dev, 2); + cp->len_mmio = pci_resource_len (dev, 2); + cp->irq = dev->irq; + + log ( + "PCI: " PRODUCT_LOGO ", dev %04x, irq %d\n", + dev->device, + cp->irq + ); + log ( + " data %08x (%dM), code %08x (%dM), mmio %04x\n", + cp->addr_data, cp->len_data / MEGABYTE, + cp->addr_code, cp->len_code / MEGABYTE, + cp->addr_mmio + ); + + return alloc_resources (dev, cp); +#endif +} /* find_card */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static struct capi_ctr * get_capi_ctr (int ctrl) { + int ix; + + assert (capi_card); + assert (capi_card->ctrl2 > 0); + ix = (capi_card->ctrl2 == ctrl) ? 1 : 0; + info (NULL != capi_controller[ix]); + return capi_controller[ix]; +} /* get_capi_ctr */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static int nbchans (struct capi_ctr * ctrl) { + per_ctrl_p C; + unsigned char * prf; + int temp = 2; + + assert (ctrl); + assert (ctrl->driverdata); + C = GET_CTRL (ctrl); + prf = (unsigned char *) C->string[6]; + if (prf != NULL) { + temp = prf[2] + 256 * prf[3]; + } + return temp; +} /* nbchans */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static struct sk_buff * make_0xfe_request (unsigned appl) { + unsigned char request[8]; + struct sk_buff * skb; + + if (NULL == (skb = alloc_skb (8, GFP_ATOMIC))) { + lprintf (KERN_ERR, "Unable to allocate message buffer.\n"); + } else { + request[0] = 8; + request[1] = 0; + request[2] = appl & 0xFF; + request[3] = (appl >> 8) & 0xFF; + request[4] = 0xFE; + request[5] = 0x80; + memcpy (skb_put (skb, 8), &request, 8); + } + return skb; +} /* make_0xfe_request */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void scan_version (struct capi_ctr * ctrl, const char * ver) { + int vlen, i; + char * vstr; + per_ctrl_p C; + + assert (ctrl); + assert (ctrl->driverdata); + C = GET_CTRL (ctrl); + + vlen = (unsigned char) ver[0]; + C->version = vstr = (char *) hmalloc (vlen); + if (NULL == vstr) { + log ("Could not allocate version buffer.\n"); + return; + } + memcpy (C->version, ver + 1, vlen); + i = 0; + for (i = 0; i < 8; i++) { + C->string[i] = vstr + 1; + vstr += 1 + *vstr; + } +#if defined (NDEBUG) + lprintf (KERN_INFO, "Stack version %s\n", C->string[0]); +#endif + log ("Library version: %s\n", C->string[0]); + log ("Card type: %s\n", C->string[1]); + log ("Capabilities: %s\n", C->string[4]); + log ("D-channel protocol: %s\n", C->string[5]); +} /* scan_version */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void copy_version (struct capi_ctr * ctrl) { + char * tmp; + per_ctrl_p C; + + assert (ctrl); + assert (ctrl->driverdata); + C = GET_CTRL (ctrl); + + if (NULL == (tmp = C->string[3])) { + lprintf (KERN_ERR, "Do not have version information...\n"); + return; + } + strncpy (ctrl->serial, tmp, CAPI_SERIAL_LEN); +#if defined (__fcdslsl__) + if (ctrl == capi_controller[0]) { + memset (&ctrl->profile, 0, sizeof (capi_profile)); + } else { + memcpy (&ctrl->profile, C->string[6], sizeof (capi_profile)); + } +#else + memcpy (&ctrl->profile, C->string[6], sizeof (capi_profile)); +#endif + strncpy (ctrl->manu, "AVM-GmbH", CAPI_MANUFACTURER_LEN); + ctrl->version.majorversion = 2; + ctrl->version.minorversion = 0; + tmp = C->string[0]; + ctrl->version.majormanuversion = (((tmp[0] - '0') & 15) << 4) + + ((tmp[2] - '0') & 15); + ctrl->version.minormanuversion = ((tmp[3] - '0') << 4) + + (tmp[5] - '0') * 10 + + ((tmp[6] - '0') & 15); +} /* copy_version */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void kill_version (struct capi_ctr * ctrl) { + int i; + per_ctrl_p C; + + assert (ctrl); + assert (ctrl->driverdata); + C = GET_CTRL (ctrl); + + for (i = 0; i < 8; i++) { + C->string[i] = NULL; + } + if (C->version != NULL) { + hfree (C->version); + C->version = NULL; + } +} /* kill_version */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void pprintf (char * page, int * len, const char * fmt, ...) { + va_list args; + + va_start (args, fmt); + *len += vsprintf (page + *len, fmt, args); + va_end (args); +} /* pprintf */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void stack_wait (unsigned msec) { + + log ("Stack wait request for %u msecs\n", msec); + assert (!in_interrupt ()); + mdelay (msec); +} /* stack_wait */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +unsigned get_timer (void) { + unsigned t = 0; + + if (!capi_card->code_access_ok) { + t = MINL (capi_card->code_base + timer_offset); + } + return t; +} /* get_timer */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void pc_acknowledge (unsigned char num) { + + assert (capi_lib != NULL); + assert (capi_lib->cc_link_version != NULL); + assert ((*capi_lib->cc_link_version) () > 3); +#if !defined (NDEBUG) && defined (LOG_LINK) + log ("ACK for buffer #%u\n", num); +#endif + MOUTL (capi_card->data_base + pc_ack_offset, num); + assert (MINL (capi_card->data_base + pc_ack_offset) == num); +} /* pc_acknowledge */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int __entry load_ware (struct capi_ctr * ctrl, capiloaddata * ware) { + card_p cp; + char * buffer; + int res; + ioaddr_p io; + + assert (ctrl != NULL); + assert (ware != NULL); + cp = GET_CARD(ctrl); + if (load_flag) { + log ("Firmware has already been loaded!\n"); + return 0; + } + assert (firmware_ptr == NULL); + if (NULL == (buffer = (char *) hmalloc (ware->firmware.len))) { + error ("Could not allocate firmware buffer.\n"); + return -EIO; + } + if (ware->firmware.user) { + if (copy_from_user (buffer, ware->firmware.data, ware->firmware.len)) { + error ("Error copying firmware data!\n"); + return -EIO; + } + } else { + memcpy (buffer, ware->firmware.data, ware->firmware.len); + } + log ("Loaded %d bytes of firmware.\n", ware->firmware.len); + firmware_ptr = buffer; + firmware_len = ware->firmware.len; + + if (NULL == (io = (ioaddr_p) hmalloc (3 * sizeof (ioaddr_t)))) { + log ("Could not claim memory for i/o structures.\n"); + return -ENOMEM; + } + cp->piowin = io; + +#define INIT_IO(x,n,f) x.virt_addr = (unsigned) cp->n##_base; \ + x.phys_addr = cp->addr_##n; \ + x.length = cp->len_##n; \ + x.inb = &(f##inb); \ + x.inw = &(f##inw); \ + x.inl = &(f##inl); \ + x.outb = &(f##outb); \ + x.outw = &(f##outw); \ + x.outl = &(f##outl); + + INIT_IO(io[0], data, m); + INIT_IO(io[1], code, m); + INIT_IO(io[2], mmio, p); + +#undef INIT_IO + + cp->c6205_ctx = fw_init ( + cp, + firmware_ptr, + firmware_len, + 3, io, + &res + ); + if ((NULL == cp->c6205_ctx) || (res != 0)) { + error ("Error while processing firmware (%d)!\n", res); + error1: + fw_exit (&cp->c6205_ctx); + hfree (firmware_ptr); + hfree (cp->piowin); + firmware_ptr = NULL; + cp->piowin = NULL; + return -EIO; + } + assert (capi_lib != NULL); + assert (capi_lib->cc_link_version != NULL); + assert ((*capi_lib->cc_link_version) () > 1); + if (!dif_init (cp, (*capi_lib->cc_link_version) () > 1, &get_timer, &pc_acknowledge)) { + error ("Error while setting up device structures!\n"); + error2: + goto error1; + } + assert (capi_lib->cc_timer_offset != NULL); + timer_offset = (*capi_lib->cc_timer_offset) (); + if ((*capi_lib->cc_link_version) () > 3) { + pc_ack_offset = (*capi_lib->cc_pc_ack_offset) (); + } + + fw_setup (cp->c6205_ctx); + if (!start_stack (cp)) { + error ("Error while starting protocoll stack!\n"); + /* error3: */ + dif_exit (); + goto error2; + } + assert (load_flag == FALSE); + load_flag = TRUE; + if (ctrl_context[0].ctrl != NULL) { + assert (capi_controller[0]->ready); + (*capi_controller[0]->ready) (capi_controller[0]); + } + assert (capi_controller[1]->ready); + (*capi_controller[1]->ready) (capi_controller[1]); + return 0; +} /* load_ware */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void init_ctrl (void) { + + ctrl_context[0].card = ctrl_context[1].card = NULL; + ctrl_context[0].ctrl = ctrl_context[1].ctrl = NULL; + capi_controller[0] = capi_controller[1] = NULL; +} /* init_ctrl */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static int setup_ctrl (card_p cp, int ix) { + int cix; + struct capi_ctr * cptr; + + assert ((0 < ix) && (ix < 3)); + cptr = (*capi_driver->attach_ctr) (&capi_interface, SHORT_LOGO, NULL); + if (NULL == cptr) { + free_resources (cp); + lprintf (KERN_INFO, "Error: Could not attach controller %d.\n", ix); + return -EBUSY; + } + if ((1 == ix) && (cptr->cnr != 1)) { + cix = ix; + } else { + cix = ix - 1; + } + log ("Controller %d (%d) --> %d\n", ix, cptr->cnr, cix); + capi_controller[cix] = cptr; + ctrl_context[cix].card = cp; + ctrl_context[cix].ctrl = &ctrl_params[cix]; + capi_controller[cix]->driverdata = (void *) &ctrl_context[cix]; + return 0; +} /* setup_ctrl */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int __entry add_card (struct capi_driver * drv, capicardparams * args) { + card_p cp; + int res = 0; + char * msg; + + UNUSED_ARG (drv); + UNUSED_ARG (args); + if (NULL != capi_card) { + lprintf (KERN_ERR, "Cannot handle two controllers!\n"); + return -EBUSY; + } + if (NULL == (cp = (card_p) hcalloc (sizeof (card_t)))) { + lprintf (KERN_ERR, "Card object allocation failed.\n"); + return -EIO; + } + capi_card = cp; + init_waitqueue_head (&wait); + + switch (find_card (cp)) { + + case PCI_OK: + break; + case PCI_NO_RESOURCE: + msg = "Could not claim required resources."; + res = -EBUSY; + break; + case PCI_NO_PCI_KERN: + msg = "No PCI kernel support available."; + res = -ESRCH; + break; + case PCI_NO_CARD: + msg = "Could not locate any " PRODUCT_LOGO "."; + res = -ESRCH; + break; + case PCI_NO_PCI: + msg = "No PCI busses available."; + res = -ESRCH; + break; + default: + msg = "Unknown PCI related problem..."; + res = -EINVAL; + break; + } + if (res != 0) { + msg_exit: + error ("Error: %s\n", msg); + hfree (cp); + return res; + } + if (!params_ok (cp)) { + free_resources (cp); + msg = "Error: Invalid parameters!"; + res = -EINVAL; + goto msg_exit; + } + inc_use_count (); + init_ctrl (); +#if defined (__fcdslsl__) + if (0 != (res = setup_ctrl (cp, 2))) { + dec_use_count (); + return res; + } +#else + if (0 != (res = setup_ctrl (cp, 1))) { + dec_use_count (); + return res; + } + if (ctrl_context[0].ctrl != NULL) { + if (0 != (res = setup_ctrl (cp, 2))) { + (*capi_driver->detach_ctr) (capi_controller[0]); + capi_controller[0] = NULL; + dec_use_count (); + return res; + } + } +#endif + cp->ctrl2 = capi_controller[1]->cnr; + cp->ctxp = NULL; + return res; +} /* add_card */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void __entry reset_ctrl (struct capi_ctr * ctrl) { + card_p cp; + appl_t * appp; + + assert (ctrl != NULL); + assert (ctrl->driverdata != NULL); + cp = GET_CARD (ctrl); + assert (cp != NULL); + if (0 != cp->count) { + lprintf (KERN_INFO, "Removing registered applications!\n"); + info (cp->appls); + if (cp->appls != NULL) { + appp = first_appl (cp->appls); + while (appp != NULL) { + free_ncci (appp->id, (unsigned) -1); + appp = next_appl (cp->appls, appp); + } + } + } + stop_stack (cp); + /* to do: remove marked buffers */ + reset_card (cp); + if (firmware_ptr != NULL) { + hfree (firmware_ptr); + firmware_ptr = NULL; + firmware_len = 0; + } + dif_exit (); + load_flag = FALSE; + if (ctrl_context[0].ctrl != NULL) { + assert (capi_controller[0]->reseted); + (*capi_controller[0]->reseted) (capi_controller[0]); + } + assert (capi_controller[1]->reseted); + (*capi_controller[1]->reseted) (capi_controller[1]); +} /* reset_ctrl */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void __entry remove_ctrl (struct capi_ctr * ctrl) { + card_p cp; + + assert (ctrl); + assert (ctrl->driverdata); + cp = GET_CARD (ctrl); + info (load_flag == FALSE); + if (load_flag) { + lprintf (KERN_ERR, "Remove controller w/o reset!\n"); + reset_card (cp); + } + free_resources (cp); + assert (capi_driver->detach_ctr); + if (ctrl_context[0].ctrl != NULL) { + (*capi_driver->detach_ctr) (capi_controller[0]); + } + (*capi_driver->detach_ctr) (capi_controller[1]); + dec_use_count (); + init_ctrl (); + hfree (capi_card); + capi_card = NULL; +} /* remove_ctrl */ + +/*---------------------------------------------------------------------------*\ +\*-L-------------------------------------------------------------------------*/ +void lock (void) { + unsigned long local_flags; + + info (!spin_is_locked (&qt_lock)); + spin_lock_irqsave (&qt_lock, local_flags); + qt_flags = local_flags; +} /* lock */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void unlock (void) { + unsigned long local_flags = qt_flags; + + spin_unlock_irqrestore (&qt_lock, local_flags); +} /* unlock */ + +/*---------------------------------------------------------------------------*\ +\*-C-------------------------------------------------------------------------*/ +static inline void check (void) { + unsigned long flags; + static spinlock_t chk_lock = SPIN_LOCK_UNLOCKED; + + if (atomic_xchg (&xfer_flag, 0)) { + spin_lock_irqsave (&chk_lock, flags); + xfer_handler (capi_card); + spin_unlock_irqrestore (&chk_lock, flags); + } +} /* check */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void enter_critical (void) { + + if (!atomic_read (&crit_count) && !in_interrupt ()) { + check (); + } + atomic_inc (&crit_count); +} /* enter_critical */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void leave_critical (void) { + + assert (in_critical ()); + atomic_dec (&crit_count); + if (!atomic_read (&crit_count) && !in_interrupt ()) { + check (); + } +} /* leave_critical */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void __entry register_appl ( + struct capi_ctr * ctrl, + u16 appl, + capi_register_params * args +) { + card_t * card; + appl_t * appp; + void * ptr; + unsigned nc; + + mlog ("REGISTER(ctrl:%d,appl:%u)\n", ctrl->cnr, appl); + assert (ctrl); + assert (ctrl->driverdata); + assert (args); + card = GET_CARD (ctrl); + if ((int) args->level3cnt < 0) { + nc = nbchans (ctrl) * -((int) args->level3cnt); + } else { + nc = args->level3cnt; + } + if (0 == nc) { + nc = nbchans (ctrl); + } + if (ctrl->cnr == card->ctrl2) { + appp = create_appl ( + card->appls, + appl, + nc, + args->datablkcnt, + args->datablklen + ); + if (NULL == appp) { + log ("Unable to create application record.\n"); + return; + } + ptr = hcalloc (card->length); + if (NULL == ptr) { + lprintf (KERN_ERR, "Not enough memory for application data.\n"); + remove_appl (card->appls, appp); + return; + } else { + inc_use_count (); + card->count++; + appp->data = ptr; + assert (card->reg_func); + (*card->reg_func) (ptr, appl); + } + } + assert (ctrl->appl_registered); + (*ctrl->appl_registered) (ctrl, appl); +} /* register_appl */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void __entry release_appl (struct capi_ctr * ctrl, u16 appl) { + card_t * card; + struct sk_buff * skb; + appl_t * appp; + + mlog ("RELEASE(ctrl:%d,appl:%u)\n", ctrl->cnr, appl); + assert (ctrl); + assert (ctrl->driverdata); + card = GET_CARD (ctrl); + if (ctrl->cnr == card->ctrl2) { + if (NULL == (appp = search_appl (card->appls, appl))) { + log ("Attempt to release unknown application (id #%u)\n", appl); + return; + } + skb = make_0xfe_request (appl); + handle_message (card->queue, appp, skb); + kick_scheduler (); + appp->dying = TRUE; + } +} /* release_appl */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void __entry send_msg (struct capi_ctr * ctrl, struct sk_buff * skb) { + card_t * card; + unsigned char * byte; + unsigned appl; + appl_t * appp; + + assert (ctrl != NULL); + assert (ctrl->driverdata != NULL); + assert (skb != NULL); + assert (skb->list == NULL); + card = GET_CARD (ctrl); + byte = skb->data; + appl = byte[2] + 256 * byte[3]; + appp = search_appl (card->appls, appl); + if ((NULL == appp) || appp->dying) { + log ("Message for unknown application (id %u).\n", appl); + return; + } + handle_message (card->queue, appp, skb); + kick_scheduler (); +} /* send_msg */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +char * __entry proc_info (struct capi_ctr * ctrl) { + card_p cp; + per_ctrl_p C; + static char text[80]; + + assert (ctrl); + assert (ctrl->driverdata); + cp = GET_CARD (ctrl); + C = GET_CTRL (ctrl); + if (load_flag) { + SNPRINTF ( + text, + sizeof (text), + "%s %s data %08lx code %08lx io %lx %u", + C->version ? C->string[1] : "A1", + C->version ? C->string[0] : "-", + cp->addr_code, cp->addr_data, cp->addr_mmio, + cp->irq + ); + } else { + SNPRINTF ( + text, + sizeof (text), + TARGET " device data %08lx code %08lx io %lx irq %u", + cp->addr_code, cp->addr_data, cp->addr_mmio, + cp->irq + ); + } + return text; +} /* proc_info */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int __entry ctr_info ( + char * page, + char ** start, + off_t ofs, + int count, + int * eof, + struct capi_ctr * ctrl +) { + card_p cp; + per_ctrl_p C; + char * temp; + unsigned char flag; + int len = 0; + + assert (ctrl); + assert (ctrl->driverdata); + cp = GET_CARD (ctrl); + C = GET_CTRL (ctrl); + pprintf (page, &len, "%-16s %s\n", "name", SHORT_LOGO); + pprintf (page, &len, "%-16s %d\n", "irq", cp->irq); + pprintf (page, &len, "%-16s %08lx\n", "data", cp->data_base); + pprintf (page, &len, "%-16s %08lx\n", "code", cp->code_base); + pprintf (page, &len, "%-16s %lx\n", "io", cp->mmio_base); + + if (load_flag) { + temp = C->version ? C->string[1] : "A1"; + pprintf (page, &len, "%-16s %s\n", "type", temp); + + temp = C->version ? C->string[0] : "-"; + pprintf (page, &len, "%-16s %s\n", "ver_driver", temp); + pprintf (page, &len, "%-16s %s\n", "ver_cardtype", SHORT_LOGO); + + flag = ((unsigned char *) (ctrl->profile.manu))[3]; + if (flag) { + pprintf(page, &len, "%-16s%s%s%s%s%s%s%s\n", "protocol", + (flag & 0x01) ? " DSS1" : "", + (flag & 0x02) ? " CT1" : "", + (flag & 0x04) ? " VN3" : "", + (flag & 0x08) ? " NI1" : "", + (flag & 0x10) ? " AUSTEL" : "", + (flag & 0x20) ? " ESS" : "", + (flag & 0x40) ? " 1TR6" : "" + ); + } + flag = ((unsigned char *) (ctrl->profile.manu))[5]; + if (flag) { + pprintf(page, &len, "%-16s%s%s%s%s\n", "linetype", + (flag & 0x01) ? " point to point" : "", + (flag & 0x02) ? " point to multipoint" : "", + (flag & 0x08) ? " leased line without D-channel" : "", + (flag & 0x04) ? " leased line with D-channel" : "" + ); + } + } + + if (len < ofs) { + return 0; + } + *eof = 1; + *start = page - ofs; + return ((count < len - ofs) ? count : len - ofs); +} /* ctr_info */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int __entry drv_info ( + char * page, + char ** start, + off_t ofs, + int count, + int * eof, + struct capi_driver * drv +) { + int len = 0; + + UNUSED_ARG (drv); + pprintf (page, &len, "%-16s %s\n", "name", TARGET); + pprintf (page, &len, "%-16s %s\n", "revision", capi_interface.revision); + if (len < ofs) { + return 0; + } + *eof = 1; + *start = page - ofs; + return ((count < len - ofs) ? count : len - ofs); +} /* drv_info */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void * data_by_id (unsigned appl_id) { + appl_t * appp; + + appp = search_appl (capi_card->appls, appl_id); + return (appp != NULL) ? appp->data : NULL; +} /* data_by_id */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +unsigned attr_by_id (unsigned appl_id) { + appl_t * appp; + + appp = search_appl (capi_card->appls, appl_id); + return (appp != NULL) ? appp->attr : 0; +} /* attr_by_id */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void * first_data (int * res) { + appl_t * appp; + + assert (res); + appp = first_appl (capi_card->appls); + *res = (appp != NULL) ? 0 : -1; + return (appp != NULL) ? appp->data : NULL; +} /* first_data */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void * next_data (int * res) { + appl_t * appp; + + assert (res); + if (NULL != (appp = get_appl (capi_card->appls, *res))) { + appp = next_appl (capi_card->appls, appp); + } + *res = (appp != NULL) ? 1 + *res : -1; + return (appp != NULL) ? appp->data : NULL; +} /* next_data */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int appl_profile (unsigned appl_id, unsigned * bs, unsigned * bc) { + appl_t * appp; + + appp = search_appl (capi_card->appls, appl_id); + if (NULL == appp) { + return 0; + } + *bs = appp->blk_size; + *bc = appp->blk_count; + return 1; +} /* appl_profile */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int msg2stack (unsigned char * msg) { + unsigned mlen; + unsigned appl; + unsigned nctr; + __u32 ncci; + unsigned hand; + unsigned char * mptr; + unsigned char * dptr; + struct sk_buff * skb; + unsigned temp; + int res = 0; + + assert (msg); + if (!queue_is_empty (capi_card->queue)) { + res = 1; + skb = queue_peek (capi_card->queue); + assert (skb); + mptr = (unsigned char *) skb->data; + mlen = mptr[0] + 256 * mptr[1]; + appl = mptr[2] + 256 * mptr[3]; + nctr = mptr[8] & 127; + + mlog ( + "PUT_MESSAGE(ctrl:%d,appl:%u,cmd:0x%02X,subcmd:0x%02X)\n", + nctr, + appl, + mptr[4], + mptr[5] + ); + + if ((0x86 == mptr[4]) && (0x80 == mptr[5])) { /* DATA_B3_REQ */ + ncci = mptr[8] + + 256 * (mptr[9] + + 256 * (mptr[10] + + 256 * mptr[11] + ) ); + hand = mptr[18] + 256 * mptr[19]; + temp = (unsigned) (mptr + mlen); + dptr = mptr + 12; + *dptr++ = temp & 0xFF; temp >>= 8; + *dptr++ = temp & 0xFF; temp >>= 8; + *dptr++ = temp & 0xFF; temp >>= 8; + *dptr++ = temp & 0xFF; + memcpy (msg, mptr, mlen); + queue_park (capi_card->queue, appl, ncci, hand); + } else { + memcpy (msg, mptr, mlen); + queue_drop (capi_card->queue); + } + } + return res; +} /* msg2stack */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void msg2capi (unsigned char * msg) { + unsigned mlen; + unsigned appl; + unsigned nctr; + __u32 ncci; + unsigned hand; + unsigned dlen; + unsigned char * dptr; + unsigned temp; + struct sk_buff * skb; + struct capi_ctr * ctrl; + + assert (msg); + mlen = msg[0] + 256 * msg[1]; + appl = msg[2] + 256 * msg[3]; + nctr = msg[8] & 127; + + mlog ( + "GET_MESSAGE(ctrl:%u,appl:%d,cmd:0x%02X,subcmd:0x%02X)\n", + nctr, + appl, + msg[4], + msg[5] + ); + if ((0x86 == msg[4]) && (0x81 == msg[5])) { /* DATA_B3_CONF */ + hand = msg[12] + 256 * msg[13]; + ncci = msg[8] + + 256 * (msg[9] + + 256 * (msg[10] + + 256 * msg[11] + ) ); + queue_conf (capi_card->queue, appl, ncci, hand); + } + if ((0x86 == msg[4]) && (0x82 == msg[5])) { /* DATA_B3_IND */ + dlen = msg[16] + 256 * msg[17]; + skb = alloc_skb ( + mlen + dlen + ((mlen < 30) ? (30 - mlen) : 0), + GFP_ATOMIC + ); + if (NULL == skb) { + lprintf ( + KERN_ERR, + "Unable to build CAPI message skb. Message lost.\n" + ); + return; + } + /* Messages are expected to come with 32 bit data pointers. + * The kernel CAPI works with extended (64 bit ready) message + * formats so that the incoming message needs to be fixed, + * i.e. the length gets adjusted and the required 64 bit data + * pointer is added. + */ + temp = msg[12] + 256 * (msg[13] + + 256 * (msg[14] + 256 * msg[15])); + dptr = (unsigned char *) temp; + if (mlen < 30) { + msg[0] = 30; + ncci = 0; + memcpy (skb_put (skb, mlen), msg, mlen); + memcpy (skb_put (skb, 4), &ncci, 4); + memcpy (skb_put (skb, 4), &ncci, 4); + } else { + memcpy (skb_put (skb, mlen), msg, mlen); + } + memcpy (skb_put (skb, dlen), dptr, dlen); + } else { + if (NULL == (skb = alloc_skb (mlen, GFP_ATOMIC))) { + lprintf ( + KERN_ERR, + "Unable to build CAPI message skb." + " Message lost.\n" + ); + return; + } + memcpy (skb_put (skb, mlen), msg, mlen); + } + ctrl = get_capi_ctr (nctr); + if (ctrl == NULL) { + lprintf (KERN_ERR, "Message to illegal controller #%u!\n", nctr); + ctrl = (NULL == capi_controller[0]) + ? capi_controller[1] + : capi_controller[0]; + } + assert (ctrl->handle_capimsg != NULL); + (*ctrl->handle_capimsg) (ctrl, appl, skb); +} /* msg2capi */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void new_ncci ( + unsigned appl_id, + __u32 ncci, + unsigned winsize, + unsigned blksize +) { + appl_t * appp; + ncci_t * nccip; + struct capi_ctr * ctrl; + unsigned nctr; + + nctr = ncci & 127; + mlog ("NEW NCCI(ctrl:%u,appl:%u,ncci:0x%08X)\n", nctr, appl_id, ncci); + if (NULL == (appp = search_appl (capi_card->appls, appl_id))) { + lprintf (KERN_ERR, invalid_msg, appl_id); + return; + } + nccip = create_ncci ( + capi_card->appls, + appp, + (NCCI_t) ncci, + winsize, + blksize + ); + if (NULL == nccip) { + log ("Cannot handle new NCCI...\n"); + return; + } + ctrl = get_capi_ctr (nctr); + assert (ctrl != NULL); + assert (ctrl->cnr == (int) nctr); + assert (ctrl->new_ncci != NULL); + (*ctrl->new_ncci) (ctrl, appl_id, ncci, winsize); +} /* new_ncci */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void free_ncci (unsigned appl_id, __u32 ncci) { + appl_t * appp; + ncci_t * nccip; + struct capi_ctr * ctrl; + unsigned nctr; + + appp = search_appl (capi_card->appls, appl_id); + if (NULL == appp) { + lprintf (KERN_ERR, invalid_msg, appl_id); + return; + } + if (0xFFFFFFFF == ncci) { /* 2nd phase RELEASE */ + assert (appp->dying); + dec_use_count (); + capi_card->count--; + mlog ("FREE APPL(appl:%u)\n", appl_id); + (*capi_card->rel_func) (appp->data); + remove_appl (capi_card->appls, appp); + if (ctrl_context[0].ctrl != NULL) { + assert (capi_controller[0]->appl_released); + (*capi_controller[0]->appl_released) (capi_controller[0], appl_id); + } + assert (capi_controller[1]->appl_released); + (*capi_controller[1]->appl_released) (capi_controller[1], appl_id); + } else if (NULL != (nccip = locate_ncci (appp, ncci))) { + nctr = ncci & 127; + ctrl = get_capi_ctr (nctr); + assert (ctrl); + assert (ctrl->cnr == (int) nctr); + mlog ("FREE NCCI(ctrl:%u, appl:%u,ncci:0x%08X)\n", nctr, appl_id, ncci); + (*ctrl->free_ncci) (ctrl, appl_id, ncci); + remove_ncci (capi_card->appls, appp, nccip); + } else { + lprintf (KERN_ERR, "Attempt to free unknown NCCI.\n"); + } +} /* free_ncci */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +unsigned char * data_block (unsigned appl_id, __u32 ncci, unsigned handle) { + appl_t * appp; + + appp = search_appl (capi_card->appls, appl_id); + if (NULL == appp) { + lprintf (KERN_ERR, invalid_msg, appl_id); + return NULL; + } + return ncci_data_buffer (capi_card->appls, appp, ncci, handle); +} /* data_block */ + +/*-S-------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static int sched_thread (void * arg) { + + UNUSED_ARG (arg); + daemonize (); + SNPRINTF (current->comm, 16, "%s_thread", TARGET); /* See: sched.h */ + log ("Starting kicker thread '%s'...\n", current->comm); + while (atomic_read (&thread_flag)) { + /* Start/stop logic */ + if (!atomic_read (&thread_capi_flag)) { + interruptible_sleep_on (&capi_wait); + } else { + if (atomic_read (&scheduler_enabled)) { + interruptible_sleep_on_timeout (&wait, TEN_MSECS); + } else { + interruptible_sleep_on (&wait); + } + } + assert (!in_critical ()); + /* Enable/disable logic */ + if (!atomic_read (&thread_flag)) { + info (atomic_read (&thread_flag)); + break; + } + if (!atomic_read (&thread_capi_flag)) { + info (atomic_read (&thread_capi_flag)); + continue; + } + if (!atomic_read (&scheduler_enabled)) { + info (atomic_read (&scheduler_enabled)); + continue; + } + /* Body of thread, invoke scheduler */ + if (spin_trylock (&stack_lock)) { + os_timer_poll (); + assert (capi_lib->cm_schedule); + if ((*capi_lib->cm_schedule) ()) { + scheduler_control (TRUE); + } + spin_unlock (&stack_lock); + } + } + log ("Scheduler thread stopped.\n"); + up (&thread_sync); + return 0; +} /* sched_thread */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static int make_thread (void) { + + if (-1 != thread_pid) { + log ("Thread[%d] already running.\n", thread_pid); + return thread_pid; + } + atomic_set (&thread_flag, 1); + atomic_set (&thread_capi_flag, 0); + init_waitqueue_head (&capi_wait); + thread_pid = kernel_thread (sched_thread, NULL, 0); + log ("Thread[%d] started.\n", thread_pid); + return thread_pid; +} /* make_thread */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void kill_thread (void) { + + atomic_set (&thread_flag, 0); + if (NULL == find_task_by_pid (thread_pid)) { + log ("Thread[%d] has died before!\n", thread_pid); + } else { + if (!atomic_read (&thread_capi_flag)) { + wake_up_interruptible (&capi_wait); + } else { + wake_up_interruptible (&wait); + } + log ("Thread signalled, waiting for termination...\n"); + down (&thread_sync); + log ("Thread[%d] terminated.\n", thread_pid); + } + thread_pid = -1; +} /* kill_thread */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void enable_thread (void) { + + info (!atomic_read (&thread_capi_flag)); + if (!atomic_read (&thread_capi_flag)) { + atomic_set (&thread_capi_flag, 1); + wake_up_interruptible (&capi_wait); + log ("Thread enabled.\n"); + } +} /* enable_thread */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void disable_thread (void) { + + info (atomic_read (&thread_capi_flag)); + if (atomic_read (&thread_capi_flag)) { + atomic_set (&thread_capi_flag, 0); + wake_up_interruptible (&wait); + log ("Thread disabled.\n"); + } +} /* disable_thread */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int irq_callback (void * arg) { + + assert ((card_p) arg == capi_card); + kick_scheduler (); + return TRUE; +} /* irq_callback */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void wakeup_control (unsigned enable_flag) { + + enable_flag = 0; +} /* wakeup_control */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void version_callback (char * vp) { + + assert (nvers < 2); + if ((0 == nvers) && (NULL == ctrl_context[0].ctrl)) { + ++nvers; + log ("Version string #0 rejected.\n"); + return; + } + log ("Version string #%d:\n", nvers); + scan_version (capi_controller[nvers], vp); + copy_version (capi_controller[nvers]); + ++nvers; +} /* version_callback */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static unsigned scheduler_suspend (unsigned long timeout) { + + timeout = 0; + return 0; +} /* scheduler_suspend */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static unsigned scheduler_resume (void) { + + return 0; +} /* scheduler_resume */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static unsigned controller_remove (void) { + + assert (0); + return 0; +} /* controller_remove */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static unsigned controller_add (void) { + + assert (0); + return 0; +} /* controller_add */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void kick_scheduler (void) { + + if ((thread_pid != -1) && (NULL != find_task_by_pid (thread_pid))) { + atomic_set (&scheduler_enabled, 1); + wake_up_interruptible (&wait); + } +} /* kick_scheduler */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void scheduler_control (unsigned ena) { + int enabled = (int) ena; + int changed; + + enter_critical (); + changed = (atomic_read (&scheduler_enabled) != enabled); + leave_critical (); + if (changed) { + if (enabled) { + kick_scheduler (); + } else { + atomic_set (&scheduler_enabled, 0); + wake_up_interruptible (&wait); + } + } +} /* scheduler_control */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void init ( + unsigned len, + void (* reg) (void *, unsigned), + void (* rel) (void *), + void (* dwn) (void) +) { + assert (reg); + assert (rel); + assert (dwn); + + capi_card->length = len; + capi_card->reg_func = reg; + capi_card->rel_func = rel; + capi_card->dwn_func = dwn; +} /* init */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int driver_init (void) { + + strncpy ( + capi_interface.revision, + REVISION, + sizeof (capi_interface.revision) + ); + return (NULL != (capi_lib = link_library (&capi_card))); +} /* driver_init */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void driver_exit (void) { + + assert (capi_lib); + free_library (); + capi_lib = NULL; +} /* driver_exit */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ + diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/driver.h linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/driver.h --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/driver.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/driver.h 2004-08-13 00:00:00.000000000 +0200 @@ -0,0 +1,202 @@ +/* + * driver.h + * Copyright (C) 2002, AVM GmbH. All rights reserved. + * + * This Software is free software. You can redistribute and/or + * modify such free software under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * The free software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this Software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or see + * http://www.opensource.org/licenses/lgpl-license.html + * + * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de + */ + +#ifndef __have_driver_h__ +#define __have_driver_h__ + +#include +#include +#include +#include +#include +#include "capilli.h" +#include "tables.h" +#include "queue.h" +#include "libdefs.h" +#include "common.h" + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +struct __card { + + /* Software */ + int ctrl2; + void * ctxp; + unsigned length; + unsigned count; + appltab_t * appls; + queue_t * queue; + void (* reg_func) (void *, unsigned); + void (* rel_func) (void *); + void (* dwn_func) (void); + + /* Hardware */ + + c6205_context c6205_ctx; + ioaddr_p piowin; + + unsigned long addr_data; + unsigned long len_data; + void * data_base; + int data_access_ok; + + unsigned long addr_code; + unsigned long len_code; + void * code_base; + int code_access_ok; + + unsigned long addr_mmio; + unsigned long len_mmio; + unsigned mmio_base; + int mmio_access_ok; + + int irq; + + /* TX */ + void * tx_dmabuf; + void * tx_dmabuf_b; + void * tx_base; + void * tx_buffer; + unsigned tx_length; + hw_completion_func_t tx_func; + void * tx_ctx; + + /* RX */ + void * rx_dmabuf; + void * rx_dmabuf_b; + void * rx_base; + void * rx_buffer; + unsigned rx_length; + hw_completion_func_t rx_func; + void * rx_ctx; +} ; + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +typedef struct __per_ctrl { +#if !defined (NDEBUG) + int cid; +#endif + char * version; + char * string[8]; + struct capi_ctr * kctrl; +} per_ctrl_t, * per_ctrl_p; + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +typedef struct __bundle { + + card_p card; + per_ctrl_p ctrl; +} bundle_t, * bundle_p; + +#define GET_CARD(ctr) (((bundle_p) (ctr)->driverdata)->card) +#define GET_CTRL(ctr) (((bundle_p) (ctr)->driverdata)->ctrl) + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +extern card_p capi_card; +extern lib_callback_t * capi_lib; +extern struct capi_driver_interface * capi_driver; +extern struct capi_driver capi_interface; +extern struct capi_ctr * capi_controller[2]; +extern atomic_t crit_count; +extern spinlock_t stack_lock; +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +extern int load_ware(struct capi_ctr * ctrl, capiloaddata * ware); +extern void reset_ctrl(struct capi_ctr * ctrl); +extern void remove_ctrl(struct capi_ctr * ctrl); +extern void register_appl(struct capi_ctr * ctrl, __u16 appl, + capi_register_params * args); +extern void release_appl(struct capi_ctr * ctrl, __u16 appl); +extern void send_msg(struct capi_ctr * ctrl, struct sk_buff * skb); +extern char * proc_info(struct capi_ctr * ctrl); +extern int ctr_info(char * page, char ** start, off_t ofs, int count, + int * eof, struct capi_ctr * ctr); +extern int drv_info(char * page, char ** start, off_t ofs, int count, + int * eof, struct capi_driver * drv); +extern int add_card(struct capi_driver * drv, capicardparams *args); + +extern void * data_by_id (unsigned appl_id); +extern unsigned attr_by_id (unsigned appl_id); +extern struct capi_ctr * card_by_id (unsigned appl_id); +extern void * first_data (int * res); +extern void * next_data (int * res); + +extern int appl_profile (unsigned appl_id, unsigned * blksize, + unsigned * blkcount); + +extern int msg2stack (unsigned char * msg); +extern void msg2capi (unsigned char * msg); + +extern void new_ncci (unsigned appl_id, __u32 ncci, unsigned winsize, + unsigned blksize); +extern void free_ncci (unsigned appl_id, __u32 ncci); + +extern unsigned char * data_block (unsigned appl_id, __u32 ncci, + unsigned handle); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +extern void stack_wait (unsigned); +extern unsigned get_timer (void); +extern void pc_acknowledge (unsigned char); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +extern void enter_critical (void); +extern void leave_critical (void); + +static inline int in_critical (void) { + + return (0 < atomic_read (&crit_count)); +} /* in_critical */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +extern void kick_scheduler (void); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +extern void lock (void); +extern void unlock (void); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +extern int install_card (card_p card); +extern void remove_card (card_p card); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +extern void init (unsigned len, + void (* reg) (void *, unsigned), + void (* rel) (void *), + void (* dwn) (void)); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +extern int driver_init (void); +extern void driver_exit (void); + +#endif + diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/fw.h linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/fw.h --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/fw.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/fw.h 2004-08-13 00:00:00.000000000 +0200 @@ -0,0 +1,55 @@ +/* + * fw.h + * Copyright (C) 2003, AVM GmbH. All rights reserved. + * + * This Software is free software. You can redistribute and/or + * modify such free software under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * The free software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this Software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or see + * http://www.opensource.org/licenses/lgpl-license.html + * + * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de + */ + +#ifndef __have_fw_h__ +#define __have_fw_h__ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#include "common.h" + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +extern ioaddr_p fw_get_window (unsigned index); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +extern c6205_context fw_init ( + card_p cp, + void * image_ptr, + unsigned image_len, + unsigned iolistlen, + ioaddr_p iolist, + int * status +); +extern void fw_exit (c6205_context * ctx); + +extern int fw_ready (void); +extern int fw_setup (c6205_context ctx); +extern int fw_send_reset (c6205_context ctx); +extern unsigned fw_get_timer_offset (c6205_context ctx); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ + +#endif + diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/lib.c linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/lib.c --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/lib.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/lib.c 2004-08-13 00:00:00.000000000 +0200 @@ -0,0 +1,623 @@ +/* + * lib.c + * Copyright (C) 2002, AVM GmbH. All rights reserved. + * + * This Software is free software. You can redistribute and/or + * modify such free software under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * The free software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this Software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or see + * http://www.opensource.org/licenses/lgpl-license.html + * + * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de + */ + +#include +#include +#include +#include +#include +#include +#include +#include "main.h" +#include "driver.h" +#include "devif.h" +#include "queue.h" +#include "defs.h" +#include "tools.h" +#include "libstub.h" +#include "lib.h" + +#define PRINTF_BUFFER_SIZE 256 /* see: os_debug_printf */ +#define CA_PRINTF_BUFFER_SIZE 1024 /* see: os_printf */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static unsigned long long j64 = 0; +static unsigned long j32 = 0; + +static DECLARE_WAIT_QUEUE_HEAD(delay); + +#define TEN_MSECS (HZ/100) +#define JIFF2MSEC (1000/HZ) + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void os__enter_critical (const char * f, int l) { + + f = (void *) l; + enter_critical (); +} /* os__enter_critical */ + +static void os__leave_critical (const char * f, int l) { + + f = (void *) l; + leave_critical (); +} /* os__leave_critical */ + +static void os_enter_critical (void) { enter_critical (); } + +static void os_leave_critical (void) { leave_critical (); } + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void os_enter_cache_sensitive_code (void) { /* NOP */ } + +static void os_leave_cache_sensitive_code (void) { /* NOP */ } + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void os_init (unsigned len, register_t reg, release_t rel, down_t down) { + + init (len, reg, rel, down); +} /* os_init */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static char * os_params (void) { + static char parmbuf[128]; + size_t parmlen = 0; + size_t n; + int i = 0; + + static struct { + char * name; + short * var; + } X[] = { + { "ATMVCC", &VCC }, + { "ATMVPI", &VPI }, + { "ATMVCI", &VCI }, + { NULL, NULL } + } ; + +#define GUARD(n) if ((parmlen + (n)) >= sizeof (parmbuf)) { \ + log ("Parameter buffer overflow!\n"); \ + return NULL; \ + } + + lprintf ( + KERN_INFO, + "Using VCC/VPI/VCI = 0x%x/0x%x/0x%x\n", + VCC, + VPI, + VCI + ); + while (X[i].name != NULL) { + GUARD(1); + parmbuf[parmlen++] = ':'; + n = strlen (X[i].name); + GUARD(n + 1) + memcpy (&parmbuf[parmlen], X[i].name, n); + parmlen += n; + parmbuf[parmlen++] = (char) 0; + GUARD (7); + n = sprintf (&parmbuf[parmlen], "\\x%04x", *X[i].var); + assert (n == 6); + parmlen += n; + parmbuf[parmlen++] = (char) 0; + ++i; + } + GUARD (1); + parmbuf[parmlen++] = (char) 0; + +#undef GUARD + + return parmbuf; +} /* os_params */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static int os_get_message (unsigned char * msg) { + int res; + + assert (msg); + res = msg2stack (msg); + return res; +} /* os_get_message */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void os_put_message (unsigned char * msg) { + + assert (msg); + msg2capi (msg); +} /* os_put_message */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static unsigned char * os_get_data_block ( + unsigned appl, + unsigned long ncci, + unsigned index +) { + char * res; + + res = data_block (appl, ncci, index); + return res; +} /* os_get_data_block */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void os_free_data_block (unsigned appl, unsigned char * data) { + + data = (void *) appl; /* Avoid "unused arg" warning */ +} /* os_free_data_block */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static int os_new_ncci ( + unsigned appl, + unsigned long ncci, + unsigned win_size, + unsigned blk_size +) { + + new_ncci (appl, ncci, win_size, blk_size); + return 1; +} /* os_new_ncci */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void os_free_ncci (unsigned appl, unsigned long ncci) { + + free_ncci (appl, ncci); +} /* os_free_ncci */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static unsigned os_block_size (unsigned appl) { + unsigned bs, dummy; + + appl_profile (appl, &bs, &dummy); + return bs; +} /* os_block_size */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static unsigned os_window_size (unsigned appl) { + unsigned bc, dummy; + + appl_profile (appl, &dummy, &bc); + return bc; +} /* os_window_size */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static unsigned os_card (void) { + + return 0; +} /* os_card */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void * os_appl_data (unsigned appl) { + void * res; + + res = data_by_id (appl); + return res; +} /* os_appl_data */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static unsigned os_appl_attr (unsigned appl) { + unsigned res; + + res = attr_by_id (appl); + return res; +} /* os_appl_attr */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static appldata_t * os_appl_1st_data (appldata_t * s) { + int num; + void * data; + static char e[10]; + + memset (&e, 0, 10); + data = first_data (&num); + s->num = num; + s->buffer = (NULL == data) ? e : data; + return s; +} /* os_appl_1st_data */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static appldata_t * os_appl_next_data (appldata_t * s) { + int num; + void * data; + static char e[10]; + + memset (&e, 0, 10); + if ((num = s->num) < 0) { + return NULL; + } + data = next_data (&num); + s->num = num; + s->buffer = (NULL == data) ? e : data; + return s; +} /* os_appl_next_data */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void * os_malloc (unsigned len) { + void * res; + + res = hcalloc (len); + return res; +} /* os_malloc */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void * os_malloc2 (unsigned len) { + void * res; + + assert (0); /* Not used */ + res = hcalloc_kernel (len); + return res; +} /* os_malloc2 */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void os_free (void * p) { + + assert (p != NULL); + hfree (p); +} /* os_free */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void update_j64 (void) { + static int run1 = 1; + unsigned long j; + long long diff; + + j = jiffies; + if (run1) { + j32 = j; + run1 = 0; + } + if ((diff = j - j32) < 0) { + diff = -diff; + } + assert (diff >= 0); + j32 = j; + j64 += diff; +} /* update_j64 */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static unsigned long long os_msec64 (void) { + unsigned long tmp; + + update_j64 (); + tmp = j64 * JIFF2MSEC; + return tmp; +} /* os_msec64 */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static unsigned long os_msec (void) { + unsigned long tmp; + + update_j64 (); + tmp = ((unsigned long) j64) * JIFF2MSEC; + return tmp; +} /* os_msec */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void os_delay (unsigned msec) { + + assert (!in_interrupt ()); + info (msec > 9); + msec = (msec > 9) ? (msec / 10) * TEN_MSECS : TEN_MSECS; + interruptible_sleep_on_timeout (&delay, msec); +} /* os_delay */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +typedef struct { + + unsigned long lstart; + unsigned long start; + unsigned long tics; + unsigned long arg; + timerfunc_t func; +} timer_rec_t; + +static volatile timer_rec_t * timer = 0; +static unsigned timer_count = 0; + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static int os_timer_new (unsigned ntimers) { + unsigned size; + + assert (ntimers > 0); + timer_count = ntimers; + size = sizeof (timer_rec_t) * ntimers; + timer = (timer_rec_t *) hcalloc (size); + info (timer != NULL); + if (NULL == timer) { + timer_count = 0; + } + return timer == NULL; +} /* os_timer_new */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void os_timer_delete (void) { + + + hfree ((void *) timer); + timer = NULL; + timer_count = 0; +} /* os_timer_delete */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static int os_timer_start ( + unsigned index, + unsigned long timeout, + unsigned long arg, + timerfunc_t func +) { + assert (index < timer_count); + if (index >= timer_count) { + return 1; + } + enter_critical (); + timer[index].start = os_msec (); + timer[index].tics = timeout + 1; + timer[index].arg = arg; + timer[index].func = func; + leave_critical (); + return 0; +} /* os_timer_start */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static int os_timer_stop (unsigned index) { + + assert (index < timer_count); + if (index >= timer_count) { + return 1; + } + enter_critical (); + timer[index].func = NULL; + leave_critical (); + return 0; +} /* os_timer_stop */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void os_timer_poll (void) { + unsigned i; + unsigned long msec; + restart_t flag; + + if (NULL == timer) { + return; + } + enter_critical (); + msec = os_msec (); + for (i = 0; i < timer_count; i++) { + if (timer[i].func != 0) { + if ((msec - timer[i].start) >= timer[i].tics) { + leave_critical (); + assert (timer[i].func != NULL); + flag = (*timer[i].func) (timer[i].arg); + enter_critical (); + switch (flag) { + + case timer_end: + timer[i].func = NULL; + break; + case timer_restart: + assert (timer[i].func != NULL); + timer[i].start = msec; + break; + case timer_renew: + assert (timer[i].func != NULL); + break; + default: + assert (0); + break; + } + } + } + } + leave_critical (); +} /* os_timer_poll */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static int os_gettimeofday (struct timeval * tv) { + + if (NULL != tv) { + do_gettimeofday (tv); + } + return 0; +} /* os_gettimeofday */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static int nl_needed = 0; + +static void os_printf (char * s, va_list args) { +#if !defined (NDEBUG) + char buffer[CA_PRINTF_BUFFER_SIZE]; + char * bufptr = buffer; + int count; + + if (nl_needed) { + nl_needed = 0; + printk ("\n"); + } + count = VSNPRINTF (bufptr, sizeof (buffer), s, args); + if ('\n' == buffer[0]) { + bufptr++; + } + if ('\n' != buffer[count - 1]) { + assert (count < (int) (sizeof (buffer) - 2)); + buffer[count++] = '\n'; + buffer[count] = (char) 0; + } + printk (KERN_INFO TARGET ": %s", bufptr); +#else + s = s; + args = args; +#endif +} /* os_printf */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void os_puts (char * str, ...) { + va_list dummy; + + va_start (dummy, str); + os_printf (str, dummy); + va_end (dummy); +} /* os_puts */ + +static void os_putl (long l) { + + nl_needed = 1; + lprintf (KERN_INFO, "%ld", l); +} /* os_putl */ + +static void os_puti (int i) { + + nl_needed = 1; + lprintf (KERN_INFO, "%d", i); +} /* os_puti */ + +static void os_putnl (void) { + + nl_needed = 0; + lprintf (KERN_INFO, "\n"); +} /* os_putnl */ + +static void os_putc (char c) { + char buffer[10]; + + nl_needed = 1; + if ((31 < c) && (c < 127)) { + sprintf (buffer, "'%c' (0x%02x)", c, (unsigned char) c); + } else { + sprintf (buffer, "0x%02x", (unsigned char) c); + } + lprintf (KERN_INFO, "%s", buffer); +} /* os_putc */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void os_debug_printf (const char * fmt, va_list args) { + char buffer [PRINTF_BUFFER_SIZE]; + + VSNPRINTF (buffer, sizeof (buffer), fmt, args); + printk (KERN_INFO TARGET ": %s", buffer); +} /* os_debug_printf */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static lib_callback_t * lib = NULL; +static lib_interface_t libif = { + + init: &os_init, + params: &os_params, + get_message: &os_get_message, + put_message: &os_put_message, + get_data_block: &os_get_data_block, + free_data_block: &os_free_data_block, + new_ncci: &os_new_ncci, + free_ncci: &os_free_ncci, + block_size: &os_block_size, + window_size: &os_window_size, + card: &os_card, + appl_data: &os_appl_data, + appl_attr: &os_appl_attr, + appl_1st_data: &os_appl_1st_data, + appl_next_data: &os_appl_next_data, + malloc: &os_malloc, + malloc2: &os_malloc2, + free: &os_free, + msec: &os_msec, + msec64: &os_msec64, + delay: &os_delay, + timer_new: &os_timer_new, + timer_delete: &os_timer_delete, + timer_start: &os_timer_start, + timer_stop: &os_timer_stop, + timer_poll: &os_timer_poll, + get_time: &os_gettimeofday, + printf: &os_debug_printf, + putf: &os_printf, + puts: (void (*) (char *)) &os_puts, + putl: &os_putl, + puti: &os_puti, + putc: &os_putc, + putnl: &os_putnl, + _enter_critical: &os__enter_critical, + _leave_critical: &os__leave_critical, + enter_critical: &os_enter_critical, + leave_critical: &os_leave_critical, + enter_cache_sensitive_code: &os_enter_cache_sensitive_code, + leave_cache_sensitive_code: &os_leave_cache_sensitive_code, + + xfer_req: &dif_xfer_requirements, + + name: TARGET, + udata: 0, + pdata: NULL +} ; + +lib_callback_t * get_library (void) { + + return lib; +} /* get_library */ + +lib_callback_t * link_library (void * context) { + + return (lib = avm_lib_attach (&libif, context)); +} /* link_library */ + +void free_library (void) { + + if (lib != NULL) { + lib = 0; + avm_lib_detach (&libif); + } +} /* free_library */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ + diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/lib.h linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/lib.h --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/lib.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/lib.h 2004-08-13 00:00:00.000000000 +0200 @@ -0,0 +1,34 @@ +/* + * lib.h + * Copyright (C) 2002, AVM GmbH. All rights reserved. + * + * This Software is free software. You can redistribute and/or + * modify such free software under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * The free software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this Software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or see + * http://www.opensource.org/licenses/lgpl-license.html + * + * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de + */ + +#ifndef __have_lib_h__ +#define __have_lib_h__ + +#include "libdefs.h" + +extern lib_callback_t * get_library (void); +extern lib_callback_t * link_library (void * context); +extern void free_library (void); + +extern void os_timer_poll (void); + +#endif diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/libdefs.h linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/libdefs.h --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/libdefs.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/libdefs.h 2004-08-13 00:00:00.000000000 +0200 @@ -0,0 +1,136 @@ +/* + * libdefs.h + * Copyright (C) 2002, AVM GmbH. All rights reserved. + * + * This Software is free software. You can redistribute and/or + * modify such free software under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * The free software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this Software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or see + * http://www.opensource.org/licenses/lgpl-license.html + * + * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de + */ + +#ifndef __have_libdefs_h__ +#define __have_libdefs_h__ + +#include +#include +#include "common.h" + +typedef void (* register_t) (void *, unsigned); +typedef void (* release_t) (void *); +typedef void (* down_t) (void); + +typedef enum { + + timer_end = 0, + timer_restart = 1, + timer_renew = 2 +} restart_t; + +typedef restart_t (* timerfunc_t) (unsigned long); + +typedef struct __data { + + unsigned num; + char * buffer; +} appldata_t; + +typedef struct __lib { + + void (* init) (unsigned, register_t, release_t, down_t); + char * (* params) (void); + int (* get_message) (unsigned char *); + void (* put_message) (unsigned char *); + unsigned char * (* get_data_block) (unsigned, unsigned long, unsigned); + void (* free_data_block) (unsigned, unsigned char *); + int (* new_ncci) (unsigned, unsigned long, unsigned, unsigned); + void (* free_ncci) (unsigned, unsigned long); + unsigned (* block_size) (unsigned); + unsigned (* window_size) (unsigned); + unsigned (* card) (void); + void * (* appl_data) (unsigned); + unsigned (* appl_attr) (unsigned); + appldata_t * (* appl_1st_data) (appldata_t *); + appldata_t * (* appl_next_data) (appldata_t *); + void * (* malloc) (unsigned); + void (* free) (void *); + void * (* malloc2) (unsigned); + void (* delay) (unsigned); + unsigned long (* msec) (void); + unsigned long long (* msec64) (void); + int (* timer_new) (unsigned); + void (* timer_delete) (void); + int (* timer_start) (unsigned, unsigned long, unsigned long, timerfunc_t); + int (* timer_stop) (unsigned); + void (* timer_poll) (void); + int (* get_time) (struct timeval *); + void (* printf) (const char *, va_list); + void (* putf) (char *, va_list); + void (* puts) (char *); + void (* putl) (long); + void (* puti) (int); + void (* putc) (char); + void (* putnl) (void); + void (* _enter_critical) (const char *, int); + void (* _leave_critical) (const char *, int); + void (* enter_critical) (void); + void (* leave_critical) (void); + void (* enter_cache_sensitive_code) (void); + void (* leave_cache_sensitive_code) (void); + + void (* xfer_req) (dif_require_p, unsigned); + + char * name; + unsigned udata; + void * pdata; +} lib_interface_t, * lib_interface_p; + +typedef struct __f { + + unsigned nfuncs; + void (* sched_ctrl) (unsigned); + void (* wakeup_ctrl) (unsigned); + void (* version_ind) (char *); + unsigned (* sched_suspend) (unsigned long); + unsigned (* sched_resume) (void); + unsigned (* ctrl_remove) (void); + unsigned (* ctrl_add) (void); +} functions_t, * functions_p; + +typedef struct __cb { + + unsigned (* cm_start) (void); + char * (* cm_init) (unsigned, unsigned); + int (* cm_activate) (void); + int (* cm_exit) (void); + unsigned (* cm_handle_events) (void); + int (* cm_schedule) (void); + void (* cm_timer_irq_control) (unsigned); + void (* cm_register_ca_functions) (functions_p); + + int (* cc_need_debug_buffer) (void); + void (* cc_init_debug) (void *, unsigned); + void (* cc_init_dma) (dma_list_t, unsigned, dma_list_t, unsigned); + unsigned (* cc_num_link_buffer) (int); + unsigned (* cc_link_version) (void); + unsigned (* cc_timer_offset) (void); + unsigned (* cc_pc_ack_offset) (void); + unsigned (* cc_buffer_params) (unsigned *, ioaddr_p *, unsigned *, unsigned *); + void (* cc_compress_code) (void); + int (* cc_status) (unsigned, void *, void *); + int (* cc_run) (void); +} lib_callback_t, * lib_callback_p; + +#endif + diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/libstub.h linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/libstub.h --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/libstub.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/libstub.h 2004-08-13 00:00:00.000000000 +0200 @@ -0,0 +1,37 @@ +/* + * libstub.h + * Copyright (C) 2002, AVM GmbH. All rights reserved. + * + * This Software is free software. You can redistribute and/or + * modify such free software under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * The free software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this Software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or see + * http://www.opensource.org/licenses/lgpl-license.html + * + * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de + */ + +#ifndef __have_libstub_h__ +#define __have_libstub_h__ + +#include "libdefs.h" + +#if defined (OSDEBUG) && defined (NDEBUG) +# undef NDEBUG +#endif + +extern lib_interface_p avm_get_interface (void); +extern lib_callback_p avm_lib_attach (lib_interface_p lif, void * ctx); +extern void avm_lib_detach (lib_interface_p lif); + +#endif + diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/main.c linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/main.c --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/main.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/main.c 2004-09-05 18:48:43.000000000 +0200 @@ -0,0 +1,205 @@ +/* + * main.c + * Copyright (C) 2002, AVM GmbH. All rights reserved. + * + * This Software is free software. You can redistribute and/or + * modify such free software under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * The free software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this Software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or see + * http://www.opensource.org/licenses/lgpl-license.html + * + * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de + */ + +#ifndef EXPORT_SYMTAB +# define EXPORT_SYMTAB +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "capilli.h" +#include "driver.h" +#include "tools.h" +#include "defs.h" + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static char * REVCONST = "$Revision: $"; +char REVISION[32]; + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + +static struct pci_device_id fcdslsl_id_table[] __initdata = { + + { PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_FCDSL2, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { /* Terminating entry */ } +} ; + +MODULE_DEVICE_TABLE (pci, fcdslsl_id_table); +#else +#define __exit +#endif + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +short int VCC = 0x01; +short int VPI = 0x01; +short int VCI = 0x20; + +MODULE_PARM (VCC, "h"); +MODULE_PARM (VPI, "h"); +MODULE_PARM (VCI, "h"); + +MODULE_PARM_DESC (VCC, "VCC - Virtual Channel Connection"); +MODULE_PARM_DESC (VPI, "VPI - Virtual Path Identifier"); +MODULE_PARM_DESC (VCI, "VCI - Virtual Channel Identifier"); + +#if defined (MODULE_LICENSE) +MODULE_LICENSE ("GPL"); +#endif +#if defined (MODULE_DESCRIPTION) +MODULE_DESCRIPTION ("CAPI4Linux: Driver for " PRODUCT_LOGO); +#endif +#if defined (MODULE_AUTHOR) +MODULE_AUTHOR("AVM GmbH"); +#endif + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#ifndef NDEBUG +static void base_address (void) { + + log ("Base address: %p\n", base_address); + log ("Compile time: %s\n", __TIME__); +} /* base_address */ +#endif + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static int __init auto_attach (void) { + + lprintf (KERN_INFO, "Auto-attaching...\n"); + return add_card (&capi_interface, NULL); +} /* auto_attach */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void inc_use_count (void) { MOD_INC_USE_COUNT; } +void dec_use_count (void) { MOD_DEC_USE_COUNT; } + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static int __init fcdsl_init (void) { + char * tmp; + +#define RETURN(x) MOD_DEC_USE_COUNT; return (x); + + EXPORT_NO_SYMBOLS; +#ifndef NDEBUG + base_address (); +#endif + if ((NULL != (tmp = strchr (REVCONST, ':'))) && isdigit (*(tmp + 2))) { + strncpy (REVISION, tmp + 1, sizeof (REVISION)); + tmp = strchr (REVISION, '$'); + *tmp = 0; + } else { + strcpy (REVISION, REV_DEFAULT); + } + lprintf (KERN_INFO, "%s, revision %s\n", DRIVER_LOGO, REVISION); + lprintf (KERN_INFO, "(%s built on %s at %s)\n", TARGET, __DATE__, __TIME__); + + /*-------------------------------------------------------------------*\ + * 64 bit CAPI is not supported yet. + \*-------------------------------------------------------------------*/ + if (sizeof (char *) > 4) { + lprintf (KERN_ERR, "Cannot deal with 64 bit CAPI messages!\n"); + return -ENOSYS; + } + + MOD_INC_USE_COUNT; /* Protect attachment procedure */ + lprintf (KERN_INFO, "Loading...\n"); + if (!driver_init ()) { + lprintf (KERN_INFO, "Error: Driver library not available.\n"); + lprintf (KERN_INFO, "Not loaded.\n"); + RETURN (-ENOSYS); + } + capi_driver = attach_capi_driver (&capi_interface); + if (NULL == capi_driver) { + lprintf (KERN_INFO, "Error: Could not attach the driver.\n"); + lprintf (KERN_INFO, "Not loaded.\n"); + driver_exit (); + RETURN (-EIO); + } + if (0 != auto_attach ()) { + lprintf (KERN_INFO, "Not loaded.\n"); + detach_capi_driver (&capi_interface); + driver_exit (); + RETURN (-EIO); + } + lprintf (KERN_INFO, "Loaded.\n"); + RETURN (0); + +#undef RETURN + +} /* fcdsl_init */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void __exit fcdsl_exit (void) { + +#if defined (__fcdsl__) + if (capi_controller[0] != NULL) { + lprintf (KERN_INFO, "Shutting down controller 0...\n"); + (*capi_driver->detach_ctr) (capi_controller[0]); + } +#endif + if (capi_controller[1] != NULL) { + lprintf (KERN_INFO, "Shutting down controller 1...\n"); + (*capi_driver->detach_ctr) (capi_controller[1]); + } + lprintf (KERN_INFO, "Removing...\n"); + detach_capi_driver (&capi_interface); + driver_exit (); +#ifndef NDEBUG + if (hallocated() != 0) { + lprintf (KERN_ERR, "%u bytes leaked.\n", hallocated()); + } +#endif + lprintf (KERN_INFO, "Removed.\n"); +} /* fcdsl_exit */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +module_init (fcdsl_init); +module_exit (fcdsl_exit); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ + diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/main.h linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/main.h --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/main.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/main.h 2004-08-13 00:00:00.000000000 +0200 @@ -0,0 +1,35 @@ +/* + * main.h + * Copyright (C) 2002, AVM GmbH. All rights reserved. + * + * This Software is free software. You can redistribute and/or + * modify such free software under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * The free software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this Software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or see + * http://www.opensource.org/licenses/lgpl-license.html + * + * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de + */ + +#ifndef __have_main_h__ +#define __have_main_h__ + +extern void inc_use_count (void); +extern void dec_use_count (void); + +extern char REVISION[]; + +extern short int VCC; +extern short int VPI; +extern short int VCI; + +#endif diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/makefile linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/makefile --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/makefile 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/makefile 2004-08-13 00:00:00.000000000 +0200 @@ -0,0 +1,48 @@ +SOURCES = main.c driver.c tables.c queue.c lib.c tools.c devif.c +OBJECTS = $(patsubst %.c,%.o,$(SOURCES)) +LIBRARY = ../lib/$(CARD)-lib.o + +CARD_PATH = /lib/modules/`uname -r`/misc +CS_PATH = /lib/modules/`uname -r`/pcmcia-external + +# As propsed by /usr/include/linux/version.h... +KRNLINCL = /lib/modules/`uname -r`/build/include +# KRNLINCL = /usr/src/linux/include + +DEFINES = -DMODULE -D__KERNEL__ -DNDEBUG \ + -D__$(CARD)__ -DTARGET=\"$(CARD)\" +CCFLAGS = -c $(DEFINES) -O2 -Wall -I $(KRNLINCL) +LDFLAGS = -r + +ifeq ($(CARD),fcpcmcia) +CS_MOD = fcpcmcia_cs.o +CS_SRC = fcpcmcia_cs.c +else +CS_MOD = +CS_SRC = +endif + +all: $(CARD).o $(LIBRARY) $(CS_MOD) + +install: $(CARD).o $(LIBRARY) $(CS_MOD) + mkdir -p $(CARD_PATH) + cp -f $(CARD).o $(CARD_PATH) +ifeq ($(CARD),fcpcmcia) + mkdir -p $(CS_PATH) + cp -f $(CS_MOD) $(CS_PATH) +endif + +clean: + $(RM) $(OBJECTS) $(CARD).o $(CS_MOD) + +$(CARD).o: $(OBJECTS) + $(LD) $(LDFLAGS) -o $@ $(OBJECTS) $(LIBRARY) + +$(OBJECTS): %.o: %.c + $(CC) $(CCFLAGS) $< -o $@ + +$(CS_MOD): $(CS_SRC) + $(CC) $(CCFLAGS) $< -o $@ + +# No dependencies yet... + diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/queue.c linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/queue.c --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/queue.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/queue.c 2004-08-13 00:00:00.000000000 +0200 @@ -0,0 +1,276 @@ +/* + * queue.c + * Copyright (C) 2002, AVM GmbH. All rights reserved. + * + * This Software is free software. You can redistribute and/or + * modify such free software under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * The free software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this Software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or see + * http://www.opensource.org/licenses/lgpl-license.html + * + * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de + */ + +#include "defs.h" +#include "driver.h" +#include "tools.h" +#include "tables.h" +#include "queue.h" + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#define MAKE_KEY(a,n,h) (((tag_t)(a)<<48)+((tag_t)(n)<<16)+((tag_t)(h))) + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static qitem_t * free_list = NULL; + +static inline qitem_t * alloc_item (void) { + qitem_t * item; + + if (free_list != NULL) { + item = free_list; + free_list = item->succ; + } else { + item = (qitem_t *) hmalloc (sizeof (qitem_t)); + } + info (item); + return item; +} /* alloc_item */ + +static inline void free_item (qitem_t * item) { + + assert (item); + item->succ = free_list; + free_list = item; +} /* free_item */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void queue_init (queue_t ** q) { + + if (NULL == (*q = (queue_t *) hmalloc (sizeof (queue_t)))) { + lprintf (KERN_ERR, "Not enough memory for queue struct.\n"); + } else { + (*q)->noconf = (*q)->put = (*q)->get = NULL; + (*q)->num = 0; + } + assert (free_list == NULL); +} /* queue_init */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void queue_exit (queue_t ** q) { + qitem_t * item; + + assert (q != NULL); + assert (*q != NULL); + while ((*q)->get != NULL) { + item = (*q)->get->succ; + KFREE_SKB ((*q)->get->msg); + hfree ((*q)->get); + (*q)->get = item; + } + while ((*q)->noconf != NULL) { + item = (*q)->noconf->succ; + KFREE_SKB ((*q)->noconf->msg); + hfree ((*q)->noconf); + (*q)->noconf = item; + } + while (free_list != NULL) { + item = free_list->succ; + hfree (free_list); + free_list = item; + } + hfree (*q); + *q = NULL; +} /* queue_exit */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static int enqueue (queue_t * q, struct sk_buff * msg) { + qitem_t * item; + + if (NULL == (item = alloc_item ())) { + lprintf (KERN_ERR, "Not enough memory for queue item.\n"); + lprintf (KERN_ERR, "Message lost.\n"); + return 0; + } + item->succ = NULL; + item->msg = msg; + item->key = 0; + assert (q != NULL); + if (q->num != 0) { + q->put->succ = item; + } else { + q->get = item; + } + q->put = item; + q->num++; + return 1; +} /* enqueue */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static struct sk_buff * dequeue (queue_t * q) { + struct sk_buff * res; + qitem_t * item; + qitem_t * tmp; + + assert (q != NULL); + assert (q->get != NULL); + res = q->get->msg; + item = q->get->succ; + tmp = q->get; + q->get = item; + q->num--; + free_item (tmp); + return res; +} /* dequeue */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int queue_put (queue_t * q, struct sk_buff * msg) { + int res; + + assert (q != NULL); + lock (); + res = enqueue (q, msg); + unlock (); + return res; +} /* queue_put */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +struct sk_buff * queue_peek (queue_t * q) { + struct sk_buff * tmp = NULL; + + assert (q != NULL); + lock (); + if (!queue_is_empty (q)) { + assert (q->get != NULL); + tmp = q->get->msg; + } else { + lprintf (KERN_ERR, "Queue underflow.\n"); + } + unlock (); + return tmp; +} /* queue_peek */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +struct sk_buff * queue_get (queue_t * q) { + struct sk_buff * tmp = NULL; + + assert (q != NULL); + lock (); + if (!queue_is_empty (q)) { + tmp = dequeue (q); + } else { + lprintf (KERN_ERR, "Cannot read empty queue.\n"); + } + unlock (); + return tmp; +} /* queue_get */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void queue_drop (queue_t * q) { + struct sk_buff * tmp; + + assert (q != NULL); + lock (); + if (!queue_is_empty (q)) { + tmp = dequeue (q); + KFREE_SKB (tmp); + } else { + lprintf (KERN_ERR, "Cannot read empty queue.\n"); + } + unlock (); +} /* queue_drop */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int queue_size (queue_t * q) { + + assert (q != NULL); + return (int) q->num; +} /* queue_size */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int queue_is_empty (queue_t * q) { + + assert (q != NULL); + return (q->num == 0) ? TRUE : FALSE; +} /* queue_is_empty */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void queue_park (queue_t * q, unsigned appl, NCCI_t ncci, unsigned hand) { + struct sk_buff * eoq; + qitem_t * item; + + assert (q != NULL); + if (NULL == (eoq = queue_get (q))) { + lprintf (KERN_ERR, "Cannot park from empty queue.\n"); + return; + } + if (NULL == (item = alloc_item ())) { + lprintf (KERN_ERR, "Not enough memory for queue item.\n"); + return; + } + item->key = MAKE_KEY (appl, ncci, hand); + item->msg = eoq; + item->pred = NULL; + lock (); + item->succ = q->noconf; + if (q->noconf != NULL) { + q->noconf->pred = item; + } + q->noconf = item; + unlock (); +} /* queue_park */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void queue_conf (queue_t * q, unsigned appl, NCCI_t ncci, unsigned hand) { + qitem_t * item; + tag_t key = MAKE_KEY (appl, ncci, hand); + + assert (q != NULL); + lock (); + item = q->noconf; + while ((item != NULL) && (item->key != key)) { + item = item->succ; + } + if (item != NULL) { + if (item->succ != NULL) { + item->succ->pred = item->pred; + } + if (item->pred != NULL) { + item->pred->succ = item->succ; + } else { + q->noconf = item->succ; + } + assert (item->msg); + KFREE_SKB (item->msg); + free_item (item); + } else { + log ("Tried to confirm unknown data b3 message.\n"); + } + unlock (); +} /* queue_conf */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ + diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/queue.h linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/queue.h --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/queue.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/queue.h 2004-08-13 00:00:00.000000000 +0200 @@ -0,0 +1,62 @@ +/* + * queue.h + * Copyright (C) 2002, AVM GmbH. All rights reserved. + * + * This Software is free software. You can redistribute and/or + * modify such free software under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * The free software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this Software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or see + * http://www.opensource.org/licenses/lgpl-license.html + * + * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de + */ + +#ifndef __have_queue_h__ +#define __have_queue_h__ + +#include + +typedef long long tag_t; +typedef __u32 NCCI_t; + +typedef struct __qitem { + + tag_t key; + struct sk_buff * msg; + struct __qitem * succ; + struct __qitem * pred; +} qitem_t; + +typedef struct __queue { + + qitem_t * put; + qitem_t * get; + qitem_t * noconf; + unsigned num; +} queue_t; + +extern void queue_init (queue_t ** q); +extern void queue_exit (queue_t ** q); + +extern int queue_put (queue_t * q, struct sk_buff * msg); +extern struct sk_buff * queue_peek (queue_t * q); +extern struct sk_buff * queue_get (queue_t * q); +extern void queue_drop (queue_t * q); + +extern int queue_size (queue_t * q); +extern int queue_is_empty (queue_t * q); + +extern void queue_park (queue_t * q, unsigned appl, NCCI_t ncci, unsigned hand); +extern void queue_conf (queue_t * q, unsigned appl, NCCI_t ncci, unsigned hand); + +#endif + diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/tables.c linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/tables.c --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/tables.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/tables.c 2004-08-13 00:00:00.000000000 +0200 @@ -0,0 +1,328 @@ +/* + * tables.c + * Copyright (C) 2002, AVM GmbH. All rights reserved. + * + * This Software is free software. You can redistribute and/or + * modify such free software under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * The free software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this Software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or see + * http://www.opensource.org/licenses/lgpl-license.html + * + * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de + */ + +#include +#include +#include +#include "defs.h" +#include "main.h" +#include "tools.h" +#include "driver.h" +#include "queue.h" +#include "tables.h" + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void table_init (appltab_t ** tab) { + + if (NULL != (*tab = (appltab_t *) hmalloc (sizeof (appltab_t)))) { + (*tab)->appl_root = NULL; + (*tab)->appl_count = 0; + } +} /* table_init */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void table_exit (appltab_t ** tab) { + appl_t * appp; + appl_t * tmp; + + assert (*tab); + appp = (*tab)->appl_root; + while (appp != NULL) { + tmp = appp->succ; + capi_card->count--; + remove_appl (*tab, appp); + if (appp->data != NULL) { + hfree (appp->data); + } + appp = tmp; + } + hfree (*tab); + *tab = NULL; +} /* table_exit */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +appl_t * create_appl ( + appltab_t * tab, + unsigned id, + unsigned ncount, + unsigned bcount, + unsigned bsize +) { + appl_t * appp; + + if (NULL == (appp = (appl_t *) hmalloc (sizeof (appl_t)))) { + lprintf (KERN_ERR, "Not enough memory for application record.\n"); + return NULL; + } + appp->id = id; + appp->ncci_count = ncount; + appp->blk_count = bcount; + appp->blk_size = bsize; + appp->data = NULL; + appp->attr = 0; + appp->dying = FALSE; + appp->nncci = 0; + appp->root = NULL; + appp->pred = NULL; + lock (); + appp->succ = tab->appl_root; + tab->appl_root = appp; + if (NULL != appp->succ) { + appp->succ->pred = appp; + } + tab->appl_count++; + unlock (); + return appp; +} /* create_appl */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void remove_appl (appltab_t * tab, appl_t * appp) { + ncci_t * nccip; + ncci_t * tmp; + + assert (appp); + lock (); + if (appp->pred != NULL) { + appp->pred->succ = appp->succ; + } else { + tab->appl_root = appp->succ; + } + if (appp->succ != NULL) { + appp->succ->pred = appp->pred; + } + if (appp->data != NULL) { + hfree (appp->data); + appp->data = NULL; + } + nccip = appp->root; + tab->appl_count--; + unlock (); + while (nccip != NULL) { + tmp = nccip->succ; + remove_ncci (tab, appp, nccip); + nccip = tmp; + } + hfree (appp); +} /* remove_appl */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +appl_t * search_appl (appltab_t * tab, unsigned id) { + appl_t * appp; + + lock (); + appp = tab->appl_root; + while (appp != NULL) { + if (appp->id == id) { + break; + } + appp = appp->succ; + } + unlock (); + info (appp); + return appp; +} /* search_appl */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +appl_t * get_appl (appltab_t * tab, unsigned ix) { + appl_t * appp = NULL; + + assert (ix < tab->appl_count); + lock (); + if (ix < tab->appl_count) { + appp = tab->appl_root; + while (ix > 0) { + appp = appp->succ; + --ix; + } + } + unlock (); + return appp; +} /* get_appl */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +appl_t * next_appl (appltab_t * tab, appl_t * appp) { + + UNUSED_ARG (tab); + assert (appp); + return appp->succ; +} /* next_appl */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +appl_t * first_appl (appltab_t * tab) { + + return tab->appl_root; +} /* first_appl */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int handle_message (queue_t * q, appl_t * appp, struct sk_buff * msg) { + int ok; + + UNUSED_ARG (appp); + assert (q != NULL); + assert (msg != NULL); + if (!(ok = queue_put (q, msg))) { + lprintf (KERN_ERR, "Message queue overflow. Message lost...\n"); + KFREE_SKB (msg); + } + return ok; +} /* handle_message */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +ncci_t * create_ncci ( + appltab_t * tab, + appl_t * appp, + NCCI_t ncci, + unsigned wsize, + unsigned bsize +) { + ncci_t * tmp; + unsigned char ** data; + + UNUSED_ARG (tab); +#if defined (LOG_NCCI) + log ("Creating new NCCI 0x%08x\n", ncci); +#endif + if (NULL == (tmp = (ncci_t *) hmalloc (sizeof (ncci_t)))) { + lprintf (KERN_ERR, "Failed to allocate NCCI record.\n"); + return NULL; + } + data = (unsigned char **) hcalloc (sizeof (unsigned char *) + * appp->blk_count); + if (NULL == data) { + lprintf (KERN_ERR, "Failed to allocate data buffer directory.\n"); + hfree (tmp); + return NULL; + } + tmp->ncci = ncci; + tmp->appl = appp->id; + tmp->win_size = wsize; + tmp->blk_size = bsize; + tmp->data = data; + tmp->pred = NULL; + lock (); + tmp->succ = appp->root; + appp->root = tmp; + if (NULL != tmp->succ) { + tmp->succ->pred = tmp; + } + appp->nncci++; + unlock (); + return tmp; +} /* create_ncci */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void remove_ncci (appltab_t * tab, appl_t * appp, ncci_t * nccip) { + unsigned i; + + UNUSED_ARG (tab); + assert (appp); + assert (nccip); + if (nccip != NULL) { +#if defined (LOG_NCCI) + log ("Removing NCCI 0x%08x\n", nccip->ncci); +#endif + lock (); + for (i = 0; i < appp->blk_count; i++) { + if (nccip->data[i] != NULL) { + hfree (nccip->data[i]); + } + } + hfree (nccip->data); + if (nccip->succ != NULL) { + nccip->succ->pred = nccip->pred; + } + if (nccip->pred != NULL) { + nccip->pred->succ = nccip->succ; + } else { + appp->root = nccip->succ; + } + hfree (nccip); + appp->nncci--; + unlock (); + } +} /* remove_ncci */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +unsigned char * ncci_data_buffer ( + appltab_t * tab, + appl_t * appp, + NCCI_t ncci, + unsigned index +) { + ncci_t * nccip; + + UNUSED_ARG (tab); + if (NULL == (nccip = locate_ncci (appp, ncci))) { + log ("Data buffer request failed. NCCI not found.\n"); + return NULL; + } + lock (); + if (index >= appp->blk_count) { + unlock (); + log ("Data buffer index out of range.\n"); + return NULL; + } + if (nccip->data[index] == NULL) { + if (NULL == (nccip->data[index] = (unsigned char *) hmalloc (appp->blk_size))) { + lprintf (KERN_ERR, "Not enough memory for data buffer.\n"); + } + } + unlock (); + return nccip->data[index]; +} /* ncci_data_buffer */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +ncci_t * locate_ncci (appl_t * appp, NCCI_t ncci) { + ncci_t * tmp; + + assert (appp); + lock (); + tmp = appp->root; + while ((tmp != NULL) && (tmp->ncci != ncci)) { + tmp = tmp->succ; + } + unlock (); +#if defined (LOG_NCCI) + if (tmp == NULL) { + log ("Failed to find NCCI 0x%08x\n", ncci); + } +#endif + info (tmp); + return tmp; +} /* locate_ncci */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ + diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/tables.h linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/tables.h --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/tables.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/tables.h 2004-08-13 00:00:00.000000000 +0200 @@ -0,0 +1,101 @@ +/* + * tables.h + * Copyright (C) 2002, AVM GmbH. All rights reserved. + * + * This Software is free software. You can redistribute and/or + * modify such free software under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * The free software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this Software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or see + * http://www.opensource.org/licenses/lgpl-license.html + * + * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de + */ + +#ifndef __have_tables_h__ +#define __have_tables_h__ + +#include +#include +#include +#include "queue.h" +#include "capilli.h" + +typedef struct __ncci { + + NCCI_t ncci; + unsigned appl; + unsigned win_size; + unsigned blk_size; + unsigned char ** data; + struct __ncci * pred; + struct __ncci * succ; +} ncci_t; + +typedef struct __appl { + + unsigned id; + unsigned dying; + void * data; + unsigned attr; + unsigned blk_size; + unsigned blk_count; + unsigned ncci_count; + unsigned nncci; + ncci_t * root; + struct __appl * pred; + struct __appl * succ; +} appl_t; + +typedef struct __appltab { + + appl_t * appl_root; + unsigned appl_count; +} appltab_t; + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +extern void table_init (appltab_t ** tab); +extern void table_exit (appltab_t ** tab); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +extern appl_t * create_appl (appltab_t * tab, + unsigned id, + unsigned ncount, + unsigned bcount, + unsigned bsize); +extern void remove_appl (appltab_t * tab, appl_t * appp); + +extern appl_t * search_appl (appltab_t * tab, unsigned id); +extern appl_t * get_appl (appltab_t * tab, unsigned ix); +extern appl_t * first_appl (appltab_t * tab); +extern appl_t * next_appl (appltab_t * tab, appl_t * appp); + +extern int handle_message (queue_t * q, appl_t * appp, struct sk_buff * msg); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +extern ncci_t * create_ncci (appltab_t * tab, + appl_t * appl, + NCCI_t ncci, + unsigned wsize, + unsigned bsize); +extern void remove_ncci (appltab_t * tab, appl_t * appp, ncci_t * nccip); + +extern unsigned char * ncci_data_buffer (appltab_t * tab, + appl_t * appl, + NCCI_t ncci, + unsigned index); + +extern ncci_t * locate_ncci (appl_t * appp, NCCI_t ncci); + +#endif diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/tools.c linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/tools.c --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/tools.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/tools.c 2004-08-13 00:00:00.000000000 +0200 @@ -0,0 +1,574 @@ +/* + * tools.c + * Copyright (C) 2002, AVM GmbH. All rights reserved. + * + * This Software is free software. You can redistribute and/or + * modify such free software under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * The free software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this Software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or see + * http://www.opensource.org/licenses/lgpl-license.html + * + * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de + */ + +#include +#include +#include +#include +#include "defs.h" +#include "tools.h" + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +struct __q { + + unsigned head, tail, mask; + unsigned size, free; + unsigned bnum, blen; + void ** item; + char * bptr; +} ; + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +typedef struct __header { + + unsigned type; +#if !defined (NDEBUG) + unsigned size; + unsigned from; + unsigned tag; +#endif +} header_t; + +#define TYPE_NONE '?' +#define TYPE_KMALLOCED 'k' +#define TYPE_VMALLOCED 'v' +#define KMALLOC_LIMIT 131072 + +static nomem_handler_t handler = NULL; + +#if !defined (NDEBUG) +#include + +#define FENCE_TAG 0xDEADBEEF +#define FENCE1_OK(h,m) ((h)->tag==FENCE_TAG) +#define FENCE2_OK(h,m) (*(unsigned *)(((char *) m)+(h)->size)==FENCE_TAG) + +static atomic_t alloc_count = ATOMIC_INIT (0); + +#if !defined (NDEBUG) && defined (LOG_TIMER) +static struct timeval zero_time; +#endif + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +unsigned hallocated (void) { + + return atomic_read (&alloc_count); +} /* hallocated */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +unsigned hallocator (void * mem) { + header_t * hdr; + + if (mem != NULL) { + hdr = ((header_t *) mem) - 1; + return FENCE1_OK(hdr, mem) ? 0 : hdr->from; + } else { + return 0; + } +} /* hallocator */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int hvalid (void * mem) { + header_t * hdr; + int flag = TRUE; + + if (mem != NULL) { + hdr = ((header_t *) mem) - 1; + flag = FENCE1_OK(hdr, mem) && FENCE2_OK(hdr, mem); + } + return flag; +} /* hvalid */ +#endif + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void * ALLOCATE (unsigned n, unsigned * t, int p) { + void * temp; + unsigned type; + + if (n <= KMALLOC_LIMIT) { + temp = kmalloc (n, p); + type = TYPE_KMALLOCED; + } else { + temp = vmalloc (n); + type = TYPE_VMALLOCED; + } + *t = (temp != NULL) ? type : TYPE_NONE; + return temp; +} /* ALLOCATE */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#if !defined (NDEBUG) +#define PATCH(n) sizeof(header_t)+sizeof(unsigned)+((n)?(n):1) +#else +#define PATCH(n) sizeof(header_t)+((n)?(n):1) +#endif + +static void * halloc (unsigned size, unsigned addr, int prio) { + unsigned n, t = TYPE_NONE; + void * mem; + header_t * hdr; + + n = PATCH(size); + if (NULL == (hdr = (header_t *) ALLOCATE (n, &t, prio))) { + log ("Memory request (%u/%u bytes) failed.\n", size, n); + mem = NULL; + if (handler != NULL) { + (*handler) (size); + } + } else { + mem = (void *) (hdr + 1); + hdr->type = t; +#if !defined (NDEBUG) + hdr->size = size ? size : 1; + hdr->from = addr; + hdr->tag = FENCE_TAG; + * (unsigned *) (((char *) mem) + size) = FENCE_TAG; + atomic_add (hdr->size, &alloc_count); +#if defined (LOG_ALLOC) + log ( + "malloc (%u[%u,%c]) = %p @ %08x\n", + hdr->size, + n, + hdr->type, + mem, + hdr->from + ); +#endif +#else + UNUSED_ARG (addr); +#endif + } + return mem; +} /* halloc */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void * hmalloc (unsigned size) { + + return halloc (size, *(((unsigned *) &size) - 1), GFP_ATOMIC); +} /* hmalloc */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void * hcalloc (unsigned size) { + void * mem; + + mem = halloc (size, *(((unsigned *) &size) - 1), GFP_ATOMIC); + if ((mem != NULL) && (size != 0)) { + memset (mem, 0, size); + } + return mem; +} /* hcalloc */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void * hmalloc_kernel (unsigned size) { + + return halloc (size, *(((unsigned *) &size) - 1), GFP_KERNEL); +} /* hmalloc */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void * hcalloc_kernel (unsigned size) { + void * mem; + + mem = halloc (size, *(((unsigned *) &size) - 1), GFP_KERNEL); + if ((mem != NULL) && (size != 0)) { + memset (mem, 0, size); + } + return mem; +} /* hcalloc */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void hfree (void * mem) { + header_t * hdr; + + if (mem != NULL) { + hdr = ((header_t *) mem) - 1; +#if !defined (NDEBUG) + if (!(FENCE1_OK(hdr, mem) && FENCE2_OK(hdr, mem))) { + log ( + "FENCE VIOLATED (%u/0x%08X)!\n", + hdr->size, + hdr->from + ); + return; /* Oops. */ + } + atomic_sub (hdr->size, &alloc_count); +#if defined (LOG_ALLOC) + log ( + "free (%p), %u bytes, alloc @ %08x\n", + mem, + hdr->size, + hdr->from + ); +#endif +#endif + assert ((hdr->type == TYPE_KMALLOCED) || (hdr->type == TYPE_VMALLOCED)); + switch (hdr->type) { + + case TYPE_KMALLOCED: + kfree (hdr); + break; + case TYPE_VMALLOCED: + vfree (hdr); + break; + default: + log ("Could not free memory @ %p.\n", mem); + } + } +} /* hfree */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +nomem_handler_t hset_handler (nomem_handler_t hndf) { + nomem_handler_t oldf = handler; + + handler = hndf; + return oldf; +} /* hset_handler */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ + +#if !defined (NDEBUG) && defined (LOG_TIMER) + +#include + +void setup_timer (dbg_timer * t, long dsec, long dusec) { + + assert (t != NULL); + memset (&t->t, 0, sizeof (t->t)); + t->d.tv_sec = dsec; + t->d.tv_usec = dusec; +} /* setup_timer */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int check_timer (dbg_timer * t) { + int res = 1; + struct timeval now; + struct timeval delta; + + assert (t != NULL); + do_gettimeofday (&now); + timeval_less (now, zero_time, &delta); + now = delta; + timeval_less (now, t->t, &delta); + if ((delta.tv_sec > t->d.tv_sec) + || ((delta.tv_sec == t->d.tv_sec) && (delta.tv_usec > t->d.tv_usec)) + ) { + lprintf ( + KERN_INFO, + "Timer '%s' exceeded: %ld s, %ld µs\n", + t->name, + delta.tv_sec, + delta.tv_usec + ); + res = 0; + } + return res; +} /* check_timer */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int check_timer_cb (dbg_timer * t, void (* callback) (dbg_timer *, struct timeval *)) { + int res = 1; + struct timeval now; + struct timeval delta; + + assert (t != NULL); + do_gettimeofday (&now); + timeval_less (now, zero_time, &delta); + now = delta; + timeval_less (now, t->t, &delta); + if ((delta.tv_sec > t->d.tv_sec) + || ((delta.tv_sec == t->d.tv_sec) && (delta.tv_usec > t->d.tv_usec)) + ) { + if (callback != NULL) { + (*callback) (t, &delta); + } + res = 0; + } + return res; +} /* check_timer_cb */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void touch_timer (dbg_timer * t) { + struct timeval temp, delta; + + assert (t != NULL); + do_gettimeofday (&temp); + timeval_less (temp, zero_time, &delta); + t->t = delta; +} /* touch_timer */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void start_watch (dbg_timer * w) { + struct timeval temp, delta; + + assert (w != NULL); + do_gettimeofday (&temp); + timeval_less (temp, zero_time, &delta); + w->t = delta; +} /* start_watch */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void stop_watch (dbg_timer * w) { + struct timeval temp, delta; + + assert (w != NULL); + do_gettimeofday (&temp); + timeval_less (temp, zero_time, &delta); + temp = delta; + timeval_less (temp, w->t, &delta); + w->t = delta; +} /* stop_watch */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int timers_start (void) { + + do_gettimeofday (&zero_time); + return 1; +} /* timers_start */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void timers_stop (void) { + +} /* timers_stop */ + +#endif /* !NDEBUG && LOG_TIMER */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void vlprintf (const char * level, const char * fmt, va_list args) { + char line[__BUFSIZE]; + + VSNPRINTF (line, sizeof (line), fmt, args); + printk ("%s%s: %s", level, TARGET, line); +} /* vlprintf */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void lprintf (const char * level, const char * fmt, ...) { + va_list args; + + va_start (args, fmt); + vlprintf (level, fmt, args); + va_end (args); +} /* lprintf */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +unsigned long atomic_xchg (volatile atomic_t * v, unsigned value) { + + return __xchg (value, &v->counter, sizeof (unsigned)); +} /* atomic_xchg */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +ptr_queue_p q_make (unsigned max) { + ptr_queue_p qp; + unsigned mask = 1; + + if (NULL == (qp = (ptr_queue_p) hmalloc (sizeof (ptr_queue_t)))) { + return NULL; + } + if (NULL == (qp->item = (void **) hmalloc (max * sizeof (void *)))) { + hfree (qp); + return NULL; + } + qp->bptr = NULL; + while (mask < max) { + mask <<= 1; + } + assert (mask == max); + --mask; + qp->head = 0; + qp->tail = 0; + qp->mask = mask; + qp->size = max; + qp->free = max; + return qp; +} /* q_make */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void q_remove (ptr_queue_p * qpp) { + ptr_queue_p qp; + + assert (qpp != NULL); + qp = *qpp; + assert (qp != NULL); + assert (qp->item != NULL); + if (qp->bptr != NULL) { + hfree (qp->bptr); + } + hfree (qp->item); + hfree (qp); + *qpp = NULL; +} /* q_remove */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void q_reset (ptr_queue_p qp) { + + assert (qp != NULL); + qp->head = qp->tail = 0; + qp->free = qp->size; +} /* q_reset */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int q_attach_mem (ptr_queue_p qp, unsigned n, unsigned len) { + void * buf; + + assert (qp != NULL); + assert (qp->bptr == 0); + assert ((n * len) != 0); + if (NULL == (buf = hmalloc (n * len))) { + return FALSE; + } + qp->bnum = n; + qp->blen = len; + qp->bptr = buf; + return TRUE; +} /* q_attach_mem */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int q_enqueue (ptr_queue_p qp, void * p) { + + assert (qp != NULL); + if (qp->free == 0) { + return FALSE; + } + assert (qp->head < qp->size); + qp->item[qp->head++] = p; + qp->head &= qp->mask; + assert (qp->head < qp->size); + qp->free--; + return TRUE; +} /* q_enqueue */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int q_enqueue_mem (ptr_queue_p qp, void * m, unsigned len) { + unsigned ix; + char * mp; + + assert (qp != NULL); + assert (qp->bptr != NULL); + assert (qp->blen >= len); + if (qp->free == 0) { + return FALSE; + } + assert (qp->head < qp->size); + ix = qp->head++; + qp->head &= qp->mask; + qp->item[ix] = mp = &qp->bptr[ix * len]; + assert (mp != NULL); + memcpy (mp, m, len); + assert (qp->head < qp->size); + qp->free--; + return TRUE; +} /* q_enqueue_mem */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int q_dequeue (ptr_queue_p qp, void ** pp) { + + assert (qp != NULL); + if (qp->free == qp->size) { + return FALSE; + } + assert (qp->tail < qp->size); + assert (pp != NULL); + *pp = qp->item[qp->tail++]; + qp->tail &= qp->mask; + assert (qp->tail < qp->size); + qp->free++; + return TRUE; +} /* q_dequeue */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int q_peek (ptr_queue_p qp, void ** pp) { + + assert (qp != NULL); + if (qp->free == qp->size) { + return FALSE; + } + assert (qp->tail < qp->size); + assert (pp != NULL); + *pp = qp->item[qp->tail]; + return TRUE; +} /* q_peek */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +unsigned q_get_count (ptr_queue_p qp) { + + assert (qp != NULL); + return qp->size - qp->free; +} /* q_get_count */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void memdump (const void * mem, unsigned len, unsigned start, const char * msg) { + unsigned max, min, idx; + unsigned char * data = (unsigned char *) mem; + char hex[50], chr[20]; + + lprintf (KERN_INFO, "Memory dump %s:\n", msg); + min = 0; + while (min < len) { + max = ((min + 16) > len ? len : min + 16); + idx = 0; + while ((min + idx) < max) { + sprintf (hex + 3 * idx, "%02x ", *data); + sprintf (chr + idx, "%c", ((' ' <= *data) && + (*data <= '~')) ? *data : '.'); + ++idx; + ++data; + } + while (idx < 16) { + strcpy (hex + 3 * idx++, " "); + } + lprintf (KERN_INFO, "%08x: %s %s\n", min + start, hex, chr); + min = max; + } +} /* memdump */ + diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/tools.h linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/tools.h --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-dsl/src.drv/tools.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-dsl/src.drv/tools.h 2004-08-13 00:00:00.000000000 +0200 @@ -0,0 +1,201 @@ +/* + * tools.h + * Copyright (C) 2002, AVM GmbH. All rights reserved. + * + * This Software is free software. You can redistribute and/or + * modify such free software under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * The free software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this Software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or see + * http://www.opensource.org/licenses/lgpl-license.html + * + * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de + */ + +#ifndef __have_tools_h__ +#define __have_tools_h__ + +#include +#include +#include +#include +#include "defs.h" + +#if defined (HERE) +#undef HERE +#endif + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,4) +#define VSNPRINTF(s,n,f,a) vsnprintf (s, n, f, a) +#define SNPRINTF(s,n,f,l...) snprintf (s, n, f, ##l) +#define __BUFSIZE 256 +#else +#define VSNPRINTF(s,n,f,a) vsprintf (s, f, a) +#define SNPRINTF(s,n,f,l...) sprintf (s, f, ##l) +#define __BUFSIZE 512 +#endif + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#define MINB(addr) readb(addr) +#define MINW(addr) readw(addr) +#define MINL(addr) readl(addr) +#define MOUTB(addr,v) writeb((v),(addr)) +#define MOUTW(addr,v) writew((v),(addr)) +#define MOUTL(addr,v) writel((v),(addr)) + +#define PINB(addr) inb(addr) +#define PINW(addr) inw(addr) +#define PINL(addr) inl(addr) +#define POUTB(addr,v) outb((v),(addr)) +#define POUTW(addr,v) outw((v),(addr)) +#define POUTL(addr,v) outl((v),(addr)) + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#ifndef NDEBUG +# define assert(x) (!(x)?lprintf(KERN_INFO,"%s(%d): assert (%s) " \ + "failed\n", __FILE__, __LINE__, #x):((void)0)) +# define info(x) (!(x)?lprintf(KERN_INFO,"%s(%d): info (%s) failed\n", \ + __FILE__, __LINE__, #x):((void)0)) +# define log(f,x...) lprintf(KERN_INFO, f, ##x) +#else +# define assert(x) +# define info(x) +# define log(f,x...) +#endif + +#define error(f,x...) lprintf(KERN_ERR, f, ##x) + +/*---------------------------------------------------------------------------* +\*---------------------------------------------------------------------------*/ +extern void lprintf (const char *, const char *, ...); +extern void vlprintf (const char *, const char *, va_list); + +/*---------------------------------------------------------------------------* +\*---------------------------------------------------------------------------*/ +extern unsigned long atomic_xchg (volatile atomic_t *, unsigned); + +/*---------------------------------------------------------------------------* +\*---------------------------------------------------------------------------*/ +typedef void (* nomem_handler_t) (unsigned); + +#ifndef NDEBUG +extern unsigned hallocated (void); +extern unsigned hallocator (void * mem); +extern int hvalid (void * mem); +#endif + +/*---------------------------------------------------------------------------* +\*---------------------------------------------------------------------------*/ +extern nomem_handler_t hset_handler (nomem_handler_t hndf); + +/*---------------------------------------------------------------------------* +\*---------------------------------------------------------------------------*/ +extern void * hmalloc (unsigned); +extern void * hcalloc (unsigned); +extern void * hmalloc_kernel (unsigned); +extern void * hcalloc_kernel (unsigned); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +extern void hfree (void *); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +extern void memdump (const void *, unsigned, unsigned, const char *); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#if !defined (NDEBUG) && defined (LOG_TIMER) + +#include + +typedef struct { + + const char * name; + struct timeval t; + struct timeval d; +} dbg_timer; + +#define PRINT_TIMER(x) log ( \ + "Timer '%s': %ld s, %ld µs\n", \ + (x)->name, \ + (x)->t.tv_sec, (x)->t.tv_usec \ + ) +#define PRINT_TIME_MSG(s,x) log ( \ + "%s: %ld s, %ld µs\n", \ + s, (x)->t.tv_sec, (x)->t.tv_usec \ + ) + +#define WATCH_DECL(id) dbg_timer id##_timer +#define WATCH_START(id) start_watch (&id##_timer) +#define WATCH_STOP(id) stop_watch (&id##_timer); \ + PRINT_TIME_MSG(#id,&id##_timer) + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +extern int timers_start (void); +extern void timers_stop (void); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +extern void setup_timer (dbg_timer *, long, long); +extern int check_timer (dbg_timer *); +extern int check_timer_cb (dbg_timer *, void (*) (dbg_timer *, struct timeval *)); +extern void touch_timer (dbg_timer *); + +extern void start_watch (dbg_timer *); +extern void stop_watch (dbg_timer *); +#else +#define PRINT_TIMER(t) +#define WATCH_DECL(name) +#define WATCH_START(name) +#define WATCH_STOP(name) +#endif + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +typedef struct __q ptr_queue_t, * ptr_queue_p; + +extern ptr_queue_p q_make (unsigned); +extern void q_remove (ptr_queue_p *); +extern void q_reset (ptr_queue_p); + +extern int q_attach_mem (ptr_queue_p, unsigned, unsigned); + +extern int q_dequeue (ptr_queue_p, void **); +extern int q_peek (ptr_queue_p, void **); +extern int q_enqueue (ptr_queue_p, void *); +extern int q_enqueue_mem (ptr_queue_p, void *, unsigned); + +extern unsigned q_get_count (ptr_queue_p); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#ifdef NEED_MEM_STR_PROTOS + +extern void * memcpy (void * d, const void * s, size_t n); +extern void * memmove (void * d, const void * s, size_t n); +extern void * memset (void * m, int x, size_t c); + +extern int memcmp (const void * s1, const void * s2, size_t n); + +extern char * strcpy (char * d, const char * s); +extern char * strncpy (char * d, const char * s, unsigned n); +extern char * strcat (char * d, const char * s); +extern int strcmp (const char * s1, const char * s2); +extern int strncmp (const char * s1, const char * s2, unsigned n); + +extern size_t strlen (const char * s); + +#endif +#endif diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/make.card linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/make.card --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/make.card 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/make.card 2003-07-08 00:02:00.000000000 +0200 @@ -0,0 +1,2 @@ +CARD=fcpci + diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/makefile linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/makefile --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/makefile 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/makefile 2003-07-08 00:02:00.000000000 +0200 @@ -0,0 +1,12 @@ +include make.card + +.PHONY: all clean install + +all: drv + +clean: ; (cd src.drv; make clean CARD=$(CARD)) + +install: ; (cd src.drv; make install CARD=$(CARD)) + +drv: ; (cd src.drv; make CARD=$(CARD)) + diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/src.drv/ca.h linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/src.drv/ca.h --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/src.drv/ca.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/src.drv/ca.h 2003-07-08 00:02:00.000000000 +0200 @@ -0,0 +1,114 @@ +/* + * ca.h + * Copyright (C) 2002, AVM GmbH. All rights reserved. + * + * This Software is free software. You can redistribute and/or + * modify such free software under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * The free software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this Software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or see + * http://www.opensource.org/licenses/lgpl-license.html + * + * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de + */ + +#ifndef __have_ca_h__ +#define __have_ca_h__ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void CA_INIT (unsigned Len, void (* Register) (void *adata, unsigned ApplId), + void (* Release) (void * adata), + void (* Down) (void)); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +char *CA_PARAMS (void); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int CA_GET_MESSAGE (unsigned char *Msg); +void CA_PUT_MESSAGE (unsigned char *Msg); + +unsigned char *CA_NEW_DATA_B3_IND (unsigned ApplId, unsigned long NCCI, + unsigned Index); +void CA_FREE_DATA_B3_REQ (unsigned ApplId, unsigned char *data); + +int CA_NEW_NCCI (unsigned ApplId, unsigned long NCCI, unsigned WindowSize, + unsigned BlockSize); +void CA_FREE_NCCI (unsigned ApplId, unsigned long NCCI); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void *CA_MALLOC (unsigned); +void CA_FREE (void *p); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#define MSEC_PER_SEC 1000l + +unsigned long CA_MSEC (void); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +unsigned CA_KARTE (void); +unsigned CA_BLOCKSIZE (unsigned ApplId); +unsigned CA_WINDOWSIZE (unsigned ApplId); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +typedef struct { + + unsigned Nr; + char *Buffer; +} __ApplsFirstNext, *_ApplsFirstNext; + +void *CA_APPLDATA (unsigned ApplId); +_ApplsFirstNext CA_APPLDATA_FIRST (_ApplsFirstNext s); +_ApplsFirstNext CA_APPLDATA_NEXT (_ApplsFirstNext s); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +typedef enum { + CA_TIMER_END = 0, + CA_TIMER_RESTART = 1 +} CA_RESTARTTIMER; + +int CA_TIMER_NEW (unsigned nTimers); +void CA_TIMER_DELETE (void); + +int CA_TIMER_START (unsigned index, + unsigned long TimeoutValue, + unsigned long param, + CA_RESTARTTIMER (*f)(unsigned long param)); +int CA_TIMER_STOP (unsigned index); + +void CA_TIMER_POLL (void); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void CA_PRINTF (char *s, ...); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#if !defined (NDEBUG) + +void CA_PUTS (char *); +void CA_PUTI (int); +void CA_PUTL (long); +void CA_PUTC (char); +void CA_PUTNL (void); + +#endif + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#endif diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/src.drv/capilli.h linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/src.drv/capilli.h --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/src.drv/capilli.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/src.drv/capilli.h 2003-07-08 00:02:00.000000000 +0200 @@ -0,0 +1,132 @@ +/* + * capilli.h + * Copyright (C) 2002, AVM GmbH. All rights reserved. + * + * This Software is free software. You can redistribute and/or + * modify such free software under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * The free software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this Software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or see + * http://www.opensource.org/licenses/lgpl-license.html + * + * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de + */ + +/* + * $Id: capilli.h,v 1.4 1999/07/23 08:51:05 calle Exp $ + * + * Kernel CAPI 2.0 Driver Interface for Linux + * + * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de) + * + */ +#ifndef __CAPILLI_H__ +#define __CAPILLI_H__ + +typedef struct capiloaddatapart { + int user; /* data in userspace ? */ + int len; + unsigned char *data; +} capiloaddatapart; + +typedef struct capiloaddata { + capiloaddatapart firmware; + capiloaddatapart configuration; +} capiloaddata; + +typedef struct capicardparams { + unsigned int port; + unsigned irq; + int cardtype; + int cardnr; + unsigned int membase; +} capicardparams; + +struct capi_driver; + +struct capi_ctr { + struct capi_ctr *next; /* next ctr of same driver */ + struct capi_driver *driver; + int cnr; /* controller number */ + char name[32]; /* name of controller */ + volatile unsigned short cardstate; /* controller state */ + volatile int blocked; /* output blocked */ + int traceflag; /* capi trace */ + + void *driverdata; /* driver specific */ + + /* filled before calling ready callback */ + __u8 manu[CAPI_MANUFACTURER_LEN]; /* CAPI_GET_MANUFACTURER */ + capi_version version; /* CAPI_GET_VERSION */ + capi_profile profile; /* CAPI_GET_PROFILE */ + __u8 serial[CAPI_SERIAL_LEN]; /* CAPI_GET_SERIAL */ + + /* functions */ + void (*ready)(struct capi_ctr * card); + void (*reseted)(struct capi_ctr * card); + void (*suspend_output)(struct capi_ctr * card); + void (*resume_output)(struct capi_ctr * card); + void (*handle_capimsg)(struct capi_ctr * card, + __u16 appl, struct sk_buff *skb); + void (*appl_registered)(struct capi_ctr * card, __u16 appl); + void (*appl_released)(struct capi_ctr * card, __u16 appl); + + void (*new_ncci)(struct capi_ctr * card, + __u16 appl, __u32 ncci, __u32 winsize); + void (*free_ncci)(struct capi_ctr * card, __u16 appl, __u32 ncci); + + /* management information for kcapi */ + + unsigned long nrecvctlpkt; + unsigned long nrecvdatapkt; + unsigned long nsentctlpkt; + unsigned long nsentdatapkt; + + struct proc_dir_entry *procent; + char procfn[128]; +}; + +struct capi_driver_interface { + struct capi_ctr *(*attach_ctr)(struct capi_driver *driver, char *name, void *data); + int (*detach_ctr)(struct capi_ctr *); +}; + +struct capi_driver { + char name[32]; /* driver name */ + char revision[32]; + int (*load_firmware)(struct capi_ctr *, capiloaddata *); + void (*reset_ctr)(struct capi_ctr *); + void (*remove_ctr)(struct capi_ctr *); + void (*register_appl)(struct capi_ctr *, __u16 appl, + capi_register_params *); + void (*release_appl)(struct capi_ctr *, __u16 appl); + void (*send_message)(struct capi_ctr *, struct sk_buff *skb); + + char *(*procinfo)(struct capi_ctr *); + int (*ctr_read_proc)(char *page, char **start, off_t off, + int count, int *eof, struct capi_ctr *card); + int (*driver_read_proc)(char *page, char **start, off_t off, + int count, int *eof, struct capi_driver *driver); + + int (*add_card)(struct capi_driver *driver, capicardparams *data); + + /* intitialized by kcapi */ + struct capi_ctr *controller; /* list of controllers */ + struct capi_driver *next; + int ncontroller; + struct proc_dir_entry *procent; + char procfn[128]; +}; + +struct capi_driver_interface *attach_capi_driver(struct capi_driver *driver); +void detach_capi_driver(struct capi_driver *driver); + +#endif /* __CAPILLI_H__ */ diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/src.drv/defs.h linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/src.drv/defs.h --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/src.drv/defs.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/src.drv/defs.h 2004-09-05 18:12:51.000000000 +0200 @@ -0,0 +1,89 @@ +/* + * defs.h + * Copyright (C) 2002, AVM GmbH. All rights reserved. + * + * This Software is free software. You can redistribute and/or + * modify such free software under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * The free software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this Software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or see + * http://www.opensource.org/licenses/lgpl-license.html + * + * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de + */ + +#ifndef __have_defs_h__ +#define __have_defs_h__ + +#ifndef LINUX_VERSION_CODE +# include +#endif + +#ifndef TRUE +# define TRUE (1==1) +# define FALSE (1==0) +#endif + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#if defined (__fcclassic__) +# define PRODUCT_LOGO "AVM FRITZ!Card Classic" +# define INTERFACE "isa" +#elif defined (__fcpnp__) +# define PRODUCT_LOGO "AVM FRITZ!Card PnP" +# define INTERFACE "pnp" +#elif defined (__fcpcmcia__) +# define PRODUCT_LOGO "AVM FRITZ!Card PCMCIA" +# define INTERFACE "pcmcia" +#elif defined (__fcpci__) +# define PRODUCT_LOGO "AVM FRITZ!Card PCI" +# define INTERFACE "pci" +#endif +#define DRIVER_LOGO PRODUCT_LOGO " driver" +#define SHORT_LOGO "fritz-" INTERFACE + +#define REV_DEFAULT "0.5.2" + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#if defined (OSDEBUG) && defined (NDEBUG) +# undef NDEBUG +#endif + +#define UNUSED_ARG(x) (x)=(x) + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#define KB 1024 +#define MIN_LIB_HEAP_SIZE (64 * KB) +#define MAX_LIB_HEAP_SIZE (600 * KB) + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 13) +# define GET_PCI_BASE(d, r) (d)->base_address[r] +#else +# define GET_PCI_BASE(d, r) (d)->resource[r].start +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 43) +# define KFREE_SKB(x) dev_kfree_skb(x) +#else +# include +# define KFREE_SKB(x) dev_kfree_skb_any(x) +#endif + +#if defined (CONFIG_ISAPNP_MODULE) && !defined (CONFIG_ISAPNP) +#define CONFIG_ISAPNP +#endif + +#endif + diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/src.drv/driver.c linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/src.drv/driver.c --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/src.drv/driver.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/src.drv/driver.c 2003-07-08 00:02:00.000000000 +0200 @@ -0,0 +1,1323 @@ +/* + * driver.c + * Copyright (C) 2002, AVM GmbH. All rights reserved. + * + * This Software is free software. You can redistribute and/or + * modify such free software under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * The free software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this Software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or see + * http://www.opensource.org/licenses/lgpl-license.html + * + * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ca.h" +#include "capilli.h" +#include "main.h" +#include "tables.h" +#include "queue.h" +#include "tools.h" +#include "defs.h" +#include "lib.h" +#include "driver.h" + +#if defined (LOG_MESSAGES) +# define mlog log +#else +# define mlog(f, a...) +#endif + +#define __entry + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) +#error This module depends on tasklets (introduced with kernel 2.4)! +#endif + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#if defined (__fcclassic__) +# define IO_RANGE 32 +#elif defined (__fcpcmcia__) +# define CARD_ID 1 +# define ID_OFFSET 6 +# define IO_RANGE 8 +#elif defined (__fcpnp__) +# include + +# define AVM_VENDOR_ID ISAPNP_VENDOR('A','V','M') +# define AVM_DEVICE_ID ISAPNP_DEVICE(0x0900) +# define PNP_NO_CARD 2 +# define PNP_ERROR 1 +# define PNP_OK 0 +# define CARD_ID 9 +# define ID_OFFSET 0 +# define IO_RANGE 32 +#elif defined (__fcpci__) +# include + +# define AVM_VENDOR_ID 0x1244 +# define AVM_DEVICE_ID 0x0A00 +# define AVM_DEVICE_ID2 0x0E00 +# define PCI_NO_PCI_KERN 3 +# define PCI_NO_CARD 2 +# define PCI_NO_PCI 1 +# define PCI_OK 0 +# define CARD_ID 10 +# define CARD_ID2 14 +# define ID_OFFSET 0 +# define IO_RANGE 32 +#else +# error You must define a card identifier... +#endif + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +card_t * capi_card = NULL; +lib_callback_t * capi_lib = NULL; + +static int irq; +static atomic_t timer_irq_enabled = ATOMIC_INIT (0); +static atomic_t dont_sched = ATOMIC_INIT (1); +static atomic_t crit_level = ATOMIC_INIT (0); +static atomic_t event_pending = ATOMIC_INIT (0); +static atomic_t scheduler_enabled = ATOMIC_INIT (0); +static atomic_t scheduler_id = ATOMIC_INIT (-1); +struct capi_driver_interface * capi_driver = NULL; +struct capi_ctr * capi_controller = NULL; +static spinlock_t sched_lock = SPIN_LOCK_UNLOCKED; +static spinlock_t qt_lock = SPIN_LOCK_UNLOCKED; +static unsigned long qt_flags; +#if !defined (__fcclassic__) +static int card_id = 0; +#endif + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void scheduler (unsigned long data); +static void scheduler_control (unsigned); +static void irq_handler (int irq, void * args, struct pt_regs * regs); +static void check_events (void); + +static DECLARE_TASKLET_DISABLED (scheduler_tasklet, scheduler, 0); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +struct capi_driver capi_interface = { + + TARGET, + REV_DEFAULT, + load_ware, + reset_ctrl, + remove_ctrl, + register_appl, + release_appl, + send_msg, + proc_info, + ctr_info, + drv_info, + add_card, + NULL, + NULL, + 0, + NULL, + "" +} ; + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static char * invalid_msg = "Invalid application id #%d.\n"; + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static functions_t cafuncs = { + + 1, + scheduler_control, + NULL +} ; + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static inline unsigned long atomic_xchg ( + volatile atomic_t * v, + unsigned value +) { + return __xchg (value, &v->counter, sizeof (unsigned)); +} /* atomic_xchg */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static int nbchans (struct capi_ctr * ctrl) { + card_t * card; + unsigned char * prf; + int temp = 2; + + assert (ctrl); + card = (card_t *) ctrl->driverdata; + prf = (unsigned char *) card->string[6]; + if (prf != NULL) { + temp = prf[2] + 256 * prf[3]; + } + return temp; +} /* nbchans */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static struct sk_buff * make_0xfe_request (unsigned appl) { + unsigned char request[8]; + struct sk_buff * skb; + + if (NULL == (skb = alloc_skb (8, GFP_ATOMIC))) { + lprintf (KERN_ERR, "Unable to allocate message buffer.\n"); + } else { + request[0] = 8; + request[1] = 0; + request[2] = appl & 0xFF; + request[3] = (appl >> 8) & 0xFF; + request[4] = 0xFE; + request[5] = 0x80; + memcpy (skb_put (skb, 8), &request, 8); + } + return skb; +} /* make_0xfe_request */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void scan_version (card_t * card, const char * ver) { + int vlen, i; + char * vstr; + + vlen = (unsigned char) ver[0]; + card->version = vstr = (char *) hmalloc (vlen); + if (NULL == card->version) { + log ("Could not allocate version buffer.\n"); + return; + } + memcpy (card->version, ver + 1, vlen); + i = 0; + for (i = 0; i < 8; i++) { + card->string[i] = vstr + 1; + vstr += 1 + *vstr; + } +#ifdef NDEBUG + lprintf (KERN_INFO, "Stack version %s\n", card->string[0]); +#endif + log ("Library version: %s\n", card->string[0]); + log ("Card type: %s\n", card->string[1]); + log ("Capabilities: %s\n", card->string[4]); + log ("D-channel protocol: %s\n", card->string[5]); +} /* scan_version */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void copy_version (struct capi_ctr * ctrl) { + char * tmp; + card_t * card; + + assert (ctrl); + card = (card_t *) ctrl->driverdata; + if (NULL == (tmp = card->string[3])) { + lprintf (KERN_ERR, "Do not have version information...\n"); + return; + } + strncpy (ctrl->serial, tmp, CAPI_SERIAL_LEN); + memcpy (&ctrl->profile, card->string[6], sizeof (capi_profile)); + strncpy (ctrl->manu, "AVM GmbH", CAPI_MANUFACTURER_LEN); + ctrl->version.majorversion = 2; + ctrl->version.minorversion = 0; + tmp = card->string[0]; + ctrl->version.majormanuversion = (((tmp[0] - '0') & 15) << 4) + + ((tmp[2] - '0') & 15); + ctrl->version.minormanuversion = ((tmp[3] - '0') << 4) + + (tmp[5] - '0') * 10 + + ((tmp[6] - '0') & 15); +} /* copy_version */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void kill_version (card_t * card) { + int i; + + for (i = 0; i < 8; i++) { + card->string[i] = NULL; + } + if (card->version != NULL) { + hfree (card->version); + card->version = NULL; + } +} /* kill_version */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void pprintf (char * page, int * len, const char * fmt, ...) { + va_list args; + + va_start (args, fmt); + *len += vsprintf (page + *len, fmt, args); + va_end (args); +} /* pprintf */ + +/*---------------------------------------------------------------------------*\ +\*-L-------------------------------------------------------------------------*/ +void lock (void) { + unsigned long local_flags; + + spin_lock_irqsave (&qt_lock, local_flags); + qt_flags = local_flags; +} /* lock */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void unlock (void) { + + spin_unlock_irqrestore (&qt_lock, qt_flags); +} /* unlock */ + +/*---------------------------------------------------------------------------*\ +\*-C-------------------------------------------------------------------------*/ +void enter_critical (void) { + + disable_irq (capi_card->irq); + if (!atomic_read (&crit_level)) { + check_events (); + } + atomic_inc (&crit_level); +} /* enter_critical */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void leave_critical (void) { + + assert (0 < atomic_read (&crit_level)); + atomic_dec (&crit_level); + if (!atomic_read (&crit_level)) { + check_events (); + } + enable_irq (capi_card->irq); +} /* leave_critical */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static inline int in_critical (void) { + + return (atomic_read (&crit_level) > 0); +} /* in_critical */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#if defined (__fcpci__) +static int find_card (unsigned * base, unsigned * irq) { +# ifndef CONFIG_PCI + return PCI_NO_PCI_KERN; +# else + struct pci_dev * dev = NULL; + if (!pci_present ()) { + return PCI_NO_PCI; + } + dev = pci_find_device (AVM_VENDOR_ID, AVM_DEVICE_ID, dev); + if (NULL == dev) { + dev = pci_find_device (AVM_VENDOR_ID, AVM_DEVICE_ID2, dev); + if (NULL == dev) { + return PCI_NO_CARD; + } + } +# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 3, 0) + if (0 != pci_enable_device (dev)) { + return PCI_NO_CARD; + } +# endif + *irq = dev->irq; + *base = GET_PCI_BASE (dev, 1) & PCI_BASE_ADDRESS_IO_MASK; + log ("PCI: dev %04x, irq %d, base %04x\n", dev->device, *irq, *base); + return PCI_OK; +# endif +} /* find_card */ +#endif + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#if defined (__fcpnp__) && defined (CONFIG_ISAPNP) +static int find_card (unsigned * base, unsigned * irq, struct pci_dev ** d) { + struct pci_dev * dev = NULL; + + dev = isapnp_find_dev (NULL, AVM_VENDOR_ID, AVM_DEVICE_ID, dev); + if (NULL == dev) { + return PNP_NO_CARD; + } else { + if (dev->active) { + lprintf (KERN_ERR, "PnP device is already in use.\n"); + return PNP_ERROR; + } + if ((*dev->prepare) (dev) < 0) { + lprintf (KERN_ERR, "PnP device preparation failed.\n"); + return PNP_ERROR; + } + if ((*dev->activate) (dev) < 0) { + lprintf (KERN_ERR, "PnP device activation failed.\n"); + return PNP_ERROR; + } + *base = dev->resource[0].start; + *irq = dev->irq_resource[0].start; + *d = dev; + return PNP_OK; + } +} /* find_card */ +#endif + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static inline void enable_scheduler (void) { + + log ("Enabling scheduler...\n"); + tasklet_enable (&scheduler_tasklet); + atomic_set (&scheduler_enabled, 1); +} /* enable_scheduler */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static inline void disable_scheduler (void) { + + log ("Disabling scheduler...\n"); + atomic_set (&scheduler_enabled, 0); + tasklet_disable (&scheduler_tasklet); +} /* disable_scheduler */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void kick_scheduler (void) { + + assert (atomic_read (&scheduler_enabled)); + if (atomic_dec_and_test (&dont_sched)) { + tasklet_schedule (&scheduler_tasklet); + } else { + atomic_set (&dont_sched, 0); + } +} /* kick_scheduler */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int install_card (card_t * card) { + int result = 4711; + + assert (card); +#if !defined (__fcpcmcia__) + request_region (card->base, IO_RANGE, TARGET); + log ( + "I/O range 0x%04x-0x%04x assigned to " TARGET " driver.\n", + card->base, + card->base + IO_RANGE - 1 + ); +#endif +#if !defined (__fcclassic__) + card_id = inb (card->base + ID_OFFSET); +#if defined (__fcpci__) + if ((CARD_ID != card_id) && (CARD_ID2 != card_id)) +#else + if (CARD_ID != card_id) +#endif + { + release_region (card->base, IO_RANGE); + lprintf (KERN_ERR, "Card identification test failed.\n"); + return FALSE; + } +#endif + card->data = (unsigned) &irq_handler; + irq = card->irq; + tasklet_init (&scheduler_tasklet, scheduler, 0); + disable_scheduler (); + result = request_irq ( + card->irq, + &irq_handler, +#if defined (__fcpci__) && defined (SHARED_IRQ) + SA_INTERRUPT | SA_SHIRQ, +#else + SA_INTERRUPT, +#endif + TARGET, + card + ); + if (result) { + release_region (card->base, IO_RANGE); + lprintf (KERN_ERR, "Could not install irq handler.\n"); + return FALSE; + } else { + log ("IRQ #%d assigned to " TARGET " driver.\n", card->irq); + } + return TRUE; +} /* install_card */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void remove_card (card_t * card) { + + log ("Releasing IRQ #%d...\n", card->irq); + free_irq (card->irq, card); + log ( + "Releasing I/O range 0x%04x-0x%04x...\n", + card->base, + card->base + IO_RANGE - 1 + ); +#if !defined (__fcpcmcia__) + release_region (card->base, IO_RANGE); +#endif +#if defined (__fcpnp__) && defined (CONFIG_ISAPNP) + (*card->dev->deactivate) (card->dev); +#endif +} /* remove_card */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static int start (card_t * card) { + char * version; + + card->count = 0; + table_init (&card->appls); + queue_init (&card->queue); + (*capi_lib->cm_register_ca_functions) (&cafuncs); + (*capi_lib->cm_start) (); + version = (*capi_lib->cm_init) (card->base, card->irq); + scan_version (card, version); + if (!install_card (card)) { + (*capi_lib->cm_exit) (); + return FALSE; + } + disable_irq (card->irq); + if ((*capi_lib->cm_activate) ()) { + log ("Activate failed.\n"); + remove_card (card); + return FALSE; + } + (*capi_lib->cm_handle_events) (); + enable_irq (card->irq); + enable_scheduler (); + kick_scheduler (); + return TRUE; +} /* start */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void stop (card_t * card) { + + disable_scheduler (); + log ("Killing scheduler...\n"); + tasklet_kill (&scheduler_tasklet); + (*capi_lib->cm_exit) (); + remove_card (card); + queue_exit (&card->queue); + table_exit (&card->appls); + kill_version (card); +} /* stop */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int __entry load_ware (struct capi_ctr * ctrl, capiloaddata * ware) { + + UNUSED_ARG (ctrl); + UNUSED_ARG (ware); + lprintf (KERN_ERR, "No firmware required!\n"); + return -EIO; +} /* load_ware */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void __entry reset_ctrl (struct capi_ctr * ctrl) { + card_t * card; + appl_t * appp; + + assert (ctrl); + card = (card_t *) ctrl->driverdata; + if (0 != card->count) { + lprintf (KERN_INFO, "Removing registered applications!\n"); + info (card->appls); + if (card->appls != NULL) { + appp = first_appl (card->appls); + while (appp != NULL) { + free_ncci (appp->id, (unsigned) -1); + appp = next_appl (card->appls, appp); + } + } + } + stop (card); + (*ctrl->reseted) (ctrl); +} /* reset_ctrl */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int __entry add_card (struct capi_driver * drv, capicardparams * args) { + card_t * card; + + UNUSED_ARG (drv); + if (NULL != capi_controller) { + lprintf (KERN_ERR, "Cannot handle two controllers!\n"); + return -EBUSY; + } + if (NULL == (card = (card_t *) hmalloc (sizeof (card_t)))) { + lprintf (KERN_ERR, "Card object allocation failed.\n"); + return -EIO; + } + capi_card = card; + + /*-------------------------------------------------------------------*\ + * Card-dependent handling of I/O and IRQ values... + \*-------------------------------------------------------------------*/ + +#if defined (__fcclassic__) || defined (__fcpcmcia__) + card->base = args->port; + card->irq = args->irq; +#elif defined (__fcpnp__) +# if !defined (CONFIG_ISAPNP) + card->base = args->port; + card->irq = args->irq; +# else + UNUSED_ARG (args); + switch (find_card (&card->base, &card->irq, &card->dev)) { + + case PNP_OK: + break; + case PNP_ERROR: + return -ESRCH; + case PNP_NO_CARD: + lprintf (KERN_ERR, "Could not locate any FRITZ!Card PnP.\n"); + return -ESRCH; + default: + lprintf (KERN_ERR, "Unknown PnP related problem...\n"); + return -EINVAL; + } +# endif +#else + UNUSED_ARG (args); + switch (find_card (&card->base, &card->irq)) { + + case PCI_OK: + break; + case PCI_NO_PCI_KERN: + lprintf (KERN_ERR, "No PCI kernel support available.\n"); + return -ESRCH; + case PCI_NO_CARD: + lprintf (KERN_ERR, "Could not locate any FRITZ!Card PCI.\n"); + return -ESRCH; + case PCI_NO_PCI: + lprintf (KERN_ERR, "No PCI busses available.\n"); + return -ESRCH; + default: + lprintf (KERN_ERR, "Unknown PCI related problem...\n"); + return -EINVAL; + } +#endif + + if (!params_ok (card)) { + lprintf ( + KERN_INFO, + "Error: Invalid parameters (base=0x%04x, irq=%d)\n", + card->base, + card->irq + ); + return -EINVAL; + } + inc_use_count (); + if (!start (card)) { + dec_use_count (); + lprintf (KERN_INFO, "Error: Initialization failed.\n"); + return -EIO; + } + capi_controller = (*capi_driver->attach_ctr) + (&capi_interface, SHORT_LOGO, NULL); + if (NULL == capi_controller) { + dec_use_count (); + stop (card); + lprintf (KERN_INFO, "Error: Could not attach controller.\n"); + return -EBUSY; + } + capi_controller->driverdata = (void *) card; + copy_version (capi_controller); + (*capi_controller->ready) (capi_controller); + return 0; +} /* add_card */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void __entry remove_ctrl (struct capi_ctr * ctrl) { + + UNUSED_ARG (ctrl); + assert (capi_controller != NULL); + (*capi_driver->detach_ctr) (capi_controller); + dec_use_count (); + ctrl->driverdata = NULL; + hfree (capi_card); + capi_controller = NULL; + capi_card = NULL; +} /* remove_ctrl */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void __entry register_appl ( + struct capi_ctr * ctrl, + u16 appl, + capi_register_params * args +) { + card_t * card; + appl_t * appp; + void * ptr; + unsigned nc; + + mlog ("REGISTER(appl:%u)\n", appl); + assert (ctrl); + assert (args); + card = (card_t *) ctrl->driverdata; + if ((int) args->level3cnt < 0) { + nc = nbchans (ctrl) * -((int) args->level3cnt); + } else { + nc = args->level3cnt; + } + if (0 == nc) { + nc = nbchans (ctrl); + } + appp = create_appl ( + card->appls, + appl, + nc, + args->datablkcnt, + args->datablklen + ); + if (NULL == appp) { + log ("Unable to create application record.\n"); + return; + } + ptr = hcalloc (card->length); + if (NULL == ptr) { + lprintf (KERN_ERR, "Not enough memory for application data.\n"); + remove_appl (card->appls, appp); + } else { + inc_use_count (); + lock (); + card->count++; + appp->data = ptr; + appp->ctrl = ctrl; + unlock (); + (*card->reg_func) (ptr, appl); + (*ctrl->appl_registered) (ctrl, appl); + } +} /* register_appl */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void __entry release_appl (struct capi_ctr * ctrl, u16 appl) { + card_t * card; + struct sk_buff * skb; + appl_t * appp; + + mlog ("RELEASE(appl:%u)\n", appl); + assert (ctrl); + card = (card_t *) ctrl->driverdata; + if (NULL == (appp = search_appl (card->appls, appl))) { + log ("Attempt to release unknown application (id #%u)\n", appl); + return; + } + skb = make_0xfe_request (appl); + handle_message (card->appls, appp, skb); + kick_scheduler (); + appp->dying = TRUE; +} /* release_appl */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void __entry send_msg (struct capi_ctr * ctrl, struct sk_buff * skb) { + card_t * card; + unsigned char * byte; + unsigned appl; + appl_t * appp; + + assert (ctrl); + assert (skb); + card = (card_t *) ctrl->driverdata; + byte = skb->data; + appl = byte[2] + 256 * byte[3]; + appp = search_appl (card->appls, appl); + if ((NULL == appp) || appp->dying) { + log ("Message for unknown application (id %u).\n", appl); + return; + } + handle_message (card->appls, appp, skb); + kick_scheduler (); +} /* send_msg */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +char * __entry proc_info (struct capi_ctr * ctrl) { + card_t * card; + static char text[80]; + + assert (ctrl); + card = (card_t *) ctrl->driverdata; + SNPRINTF ( + text, + sizeof (text), + "%s %s 0x%04x %u", + card->version ? card->string[1] : "A1", + card->version ? card->string[0] : "-", + card->base, card->irq + ); + return text; +} /* proc_info */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int __entry ctr_info ( + char * page, + char ** start, + off_t ofs, + int count, + int * eof, + struct capi_ctr * ctrl +) { + card_t * card; + char * temp; + unsigned char flag; + int len = 0; + + assert (ctrl); + card = (card_t *) ctrl->driverdata; + pprintf (page, &len, "%-16s %s\n", "name", SHORT_LOGO); + pprintf (page, &len, "%-16s 0x%04x\n", "io", card->base); + pprintf (page, &len, "%-16s %d\n", "irq", card->irq); + temp = card->version ? card->string[1] : "A1"; + pprintf (page, &len, "%-16s %s\n", "type", temp); + temp = card->version ? card->string[0] : "-"; +#if defined (__fcclassic__) || defined (__fcpcmcia__) + pprintf (page, &len, "%-16s 0x%04x\n", "revision", card->info); +#elif defined (__fcpci__) + pprintf (page, &len, "%-16s %d\n", "class", card_id); +#endif + pprintf (page, &len, "%-16s %s\n", "ver_driver", temp); + pprintf (page, &len, "%-16s %s\n", "ver_cardtype", SHORT_LOGO); + + flag = ((unsigned char *) (ctrl->profile.manu))[3]; + if (flag) { + pprintf(page, &len, "%-16s%s%s%s%s%s%s%s\n", "protocol", + (flag & 0x01) ? " DSS1" : "", + (flag & 0x02) ? " CT1" : "", + (flag & 0x04) ? " VN3" : "", + (flag & 0x08) ? " NI1" : "", + (flag & 0x10) ? " AUSTEL" : "", + (flag & 0x20) ? " ESS" : "", + (flag & 0x40) ? " 1TR6" : "" + ); + } + flag = ((unsigned char *) (ctrl->profile.manu))[5]; + if (flag) { + pprintf(page, &len, "%-16s%s%s%s%s\n", "linetype", + (flag & 0x01) ? " point to point" : "", + (flag & 0x02) ? " point to multipoint" : "", + (flag & 0x08) ? " leased line without D-channel" : "", + (flag & 0x04) ? " leased line with D-channel" : "" + ); + } + if (len < ofs) { + return 0; + } + *eof = 1; + *start = page - ofs; + return ((count < len - ofs) ? count : len - ofs); +} /* ctr_info */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int __entry drv_info ( + char * page, + char ** start, + off_t ofs, + int count, + int * eof, + struct capi_driver * drv +) { + int len = 0; + + UNUSED_ARG (drv); + pprintf (page, &len, "%-16s %s\n", "name", TARGET); + pprintf (page, &len, "%-16s %s\n", "revision", capi_interface.revision); + if (len < ofs) { + return 0; + } + *eof = 1; + *start = page - ofs; + return ((count < len - ofs) ? count : len - ofs); +} /* drv_info */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void * data_by_id (unsigned appl_id) { + appl_t * appp; + + appp = search_appl (capi_card->appls, appl_id); + return (appp != NULL) ? appp->data : NULL; +} /* data_by_id */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +struct capi_ctr * card_by_id (unsigned appl_id) { + appl_t * appp; + + appp = search_appl (capi_card->appls, appl_id); + return (appp != NULL) ? appp->ctrl : NULL; +} /* card_by_id */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void * first_data (int * res) { + appl_t * appp; + + assert (res); + appp = first_appl (capi_card->appls); + *res = (appp != NULL) ? 0 : -1; + return (appp != NULL) ? appp->data : NULL; +} /* first_data */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void * next_data (int * res) { + appl_t * appp; + + assert (res); + if (NULL != (appp = get_appl (capi_card->appls, *res))) { + appp = next_appl (capi_card->appls, appp); + } + *res = (appp != NULL) ? 1 + *res : -1; + return (appp != NULL) ? appp->data : NULL; +} /* next_data */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int appl_profile (unsigned appl_id, unsigned * bs, unsigned * bc) { + appl_t * appp; + + appp = search_appl (capi_card->appls, appl_id); + if (NULL == appp) { + return 0; + } + if (bs) { + *bs = appp->blk_size; + } + if (bc) { + *bc = appp->blk_count; + } + return 1; +} /* appl_profile */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int msg2stack (unsigned char * msg) { + unsigned mlen; + unsigned appl; + __u32 ncci; + unsigned hand; + unsigned char * mptr; + unsigned char * dptr; + struct sk_buff * skb; + unsigned temp; + int res = 0; + + assert (msg); + if (!queue_is_empty (capi_card->queue)) { + res = 1; + skb = queue_peek (capi_card->queue); + assert (skb); + mptr = (unsigned char *) skb->data; + mlen = mptr[0] + 256 * mptr[1]; + appl = mptr[2] + 256 * mptr[3]; + + mlog ( + "PUT_MESSAGE(appl:%u,cmd:0x%02X,subcmd:0x%02X)\n", + appl, + mptr[4], + mptr[5] + ); + + if ((0x86 == mptr[4]) && (0x80 == mptr[5])) { /* DATA_B3_REQ */ + ncci = mptr[8] + + 256 * (mptr[9] + + 256 * (mptr[10] + + 256 * mptr[11] + ) ); + hand = mptr[18] + 256 * mptr[19]; + temp = (unsigned) (mptr + mlen); + dptr = mptr + 12; + *dptr++ = temp & 0xFF; temp >>= 8; + *dptr++ = temp & 0xFF; temp >>= 8; + *dptr++ = temp & 0xFF; temp >>= 8; + *dptr++ = temp & 0xFF; + memcpy (msg, mptr, mlen); + queue_park (capi_card->queue, appl, ncci, hand); + } else { + memcpy (msg, mptr, mlen); + queue_drop (capi_card->queue); + } + } + return res; +} /* msg2stack */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void msg2capi (unsigned char * msg) { + unsigned mlen; + unsigned appl; + __u32 ncci; + unsigned hand; + unsigned dlen; + unsigned char * dptr; + unsigned temp; + struct sk_buff * skb; + struct capi_ctr * card; + + assert (msg); + mlen = msg[0] + 256 * msg[1]; + appl = msg[2] + 256 * msg[3]; + if ((0x86 == msg[4]) && (0x81 == msg[5])) { /* DATA_B3_CONF */ + hand = msg[12] + 256 * msg[13]; + ncci = msg[8] + + 256 * (msg[9] + + 256 * (msg[10] + + 256 * msg[11] + ) ); + queue_conf (capi_card->queue, appl, ncci, hand); + } + + if ((0x86 == msg[4]) && (0x82 == msg[5])) { /* DATA_B3_IND */ + dlen = msg[16] + 256 * msg[17]; + skb = alloc_skb ( + mlen + dlen + ((mlen < 30) ? (30 - mlen) : 0), + GFP_ATOMIC + ); + if (NULL == skb) { + lprintf ( + KERN_ERR, + "Unable to build CAPI message skb." + " Message lost.\n" + ); + return; + } + /* Messages are expected to come with 32 bit data pointers. + * The kernel CAPI works with extended (64 bit ready) message + * formats so that the incoming message needs to be fixed, + * i.e. the length gets adjusted and the required 64 bit data + * pointer is added. + */ + temp = msg[12] + 256 * (msg[13] + + 256 * (msg[14] + 256 * msg[15])); + dptr = (unsigned char *) temp; + if (mlen < 30) { + msg[0] = 30; + ncci = 0; + memcpy (skb_put (skb, mlen), msg, mlen); + memcpy (skb_put (skb, 4), &ncci, 4); + memcpy (skb_put (skb, 4), &ncci, 4); + } else { + memcpy (skb_put (skb, mlen), msg, mlen); + } + memcpy (skb_put (skb, dlen), dptr, dlen); + } else { + if (NULL == (skb = alloc_skb (mlen, GFP_ATOMIC))) { + lprintf ( + KERN_ERR, + "Unable to build CAPI message skb." + " Message lost.\n" + ); + return; + } + memcpy (skb_put (skb, mlen), msg, mlen); + } + mlog ( + "GET_MESSAGE(appl:%d,cmd:0x%02X,subcmd:0x%02X)\n", + appl, + msg[4], + msg[5] + ); + card = card_by_id (appl); + if (card != NULL) { + (*card->handle_capimsg) (card, appl, skb); + } +} /* msg2capi */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void new_ncci ( + unsigned appl_id, + __u32 ncci, + unsigned winsize, + unsigned blksize +) { + appl_t * appp; + ncci_t * nccip; + + mlog ("NEW NCCI(appl:%u,ncci:0x%08X)\n", appl_id, ncci); + if (NULL == (appp = search_appl (capi_card->appls, appl_id))) { + lprintf (KERN_ERR, invalid_msg, appl_id); + return; + } + nccip = create_ncci ( + capi_card->appls, + appp, + (NCCI_t) ncci, + winsize, + blksize + ); + if (NULL == nccip) { + log ("Cannot handle new NCCI...\n"); + return; + } + assert (appp->ctrl); + (*appp->ctrl->new_ncci) (appp->ctrl, appl_id, ncci, winsize); +} /* new_ncci */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void free_ncci (unsigned appl_id, __u32 ncci) { + appl_t * appp; + ncci_t * nccip; + + appp = search_appl (capi_card->appls, appl_id); + if (NULL == appp) { + lprintf (KERN_ERR, invalid_msg, appl_id); + return; + } + assert (appp->ctrl); + if (0xFFFFFFFF == ncci) { /* 2nd phase RELEASE */ + assert (appp->dying); + dec_use_count (); + capi_card->count--; + mlog ("FREE APPL(appl:%u)\n", appl_id); + (*appp->ctrl->appl_released) (appp->ctrl, appl_id); + (*capi_card->rel_func) (appp->data); + remove_appl (capi_card->appls, appp); + } else if (NULL != (nccip = locate_ncci (appp, ncci))) { + mlog ("FREE NCCI(appl:%u,ncci:0x%08X)\n", appl_id, ncci); + (*appp->ctrl->free_ncci) (appp->ctrl, appl_id, ncci); + remove_ncci (capi_card->appls, appp, nccip); + } else { + lprintf (KERN_ERR, "Attempt to free unknown NCCI.\n"); + } +} /* free_ncci */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +unsigned char * data_block (unsigned appl_id, __u32 ncci, unsigned handle) { + appl_t * appp; + + appp = search_appl (capi_card->appls, appl_id); + if (NULL == appp) { + lprintf (KERN_ERR, invalid_msg, appl_id); + return NULL; + } + return ncci_data_buffer (capi_card->appls, appp, ncci, handle); +} /* data_block */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int params_ok (card_t * card) { + int chk; + + assert (card); + if (0 == card->irq) { + lprintf ( + KERN_ERR, + "IRQ not assigned by BIOS. Please check BIOS" + "settings/manual for a proper PnP/PCI-Support.\n" + ); + return FALSE; + } + if (0 == card->base) { + lprintf (KERN_ERR, "Base address has not been set.\n"); + return FALSE; + } +#if defined (__fcclassic__) + switch (card->base) { + + case 0x200: case 0x240: case 0x300: case 0x340: + log ("Base address valid.\n"); + break; + default: + log ("Invalid base address.\n"); + return FALSE; + } +#endif +#if !defined (__fcpcmcia__) + if ((chk = check_region (card->base, IO_RANGE)) < 0) { + log ( + "I/O range 0x%04x-0x%04x busy. [%d]\n", + card->base, + card->base + IO_RANGE - 1, + chk + ); + return FALSE; + } +#endif + if (!(chk = (*capi_lib->check_controller) (card->base, &card->info))) { + return TRUE; + } else { + log ("Controller check failed.\n"); + return FALSE; + } +} /* params_ok */ + +/*---------------------------------------------------------------------------*\ +\*-S-------------------------------------------------------------------------*/ +static void scheduler_control (unsigned ena) { + int enabled = (int) ena; + int changed; + + enter_critical (); + changed = (atomic_read (&timer_irq_enabled) != enabled); + if (changed) { + atomic_set (&timer_irq_enabled, enabled); + (*capi_lib->cm_timer_irq_control) (enabled); + } + leave_critical (); +} /* scheduler_control */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static inline void handle_events (void) { + + if ((*capi_lib->cm_handle_events) ()) { + atomic_set (&dont_sched, 0); + if (atomic_read (&scheduler_enabled)) { + tasklet_schedule (&scheduler_tasklet); + } + } +} /* handle_events */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void check_events (void) { + + assert (!in_critical ()); + if (atomic_read (&event_pending)) { + handle_events (); + atomic_dec (&event_pending); + } +} /* check_events */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void scheduler (unsigned long data) { + + UNUSED_ARG (data); + atomic_set (&scheduler_id, smp_processor_id ()); + if (spin_trylock (&sched_lock)) { + while (!atomic_read (&dont_sched)) { + atomic_set (&dont_sched, 1); + os_timer_poll (); + if ((*capi_lib->cm_schedule) ()) { + scheduler_control (TRUE); + } + } + check_events (); + spin_unlock (&sched_lock); + } +} /* scheduler */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void irq_handler (int irq, void * args, struct pt_regs * regs) { + + UNUSED_ARG (irq); + UNUSED_ARG (regs); + if (args != NULL) { + if (spin_trylock (&sched_lock)) { + handle_events (); + spin_unlock (&sched_lock); + } else if (atomic_read (&scheduler_id) == smp_processor_id ()) { + handle_events (); + } else { + atomic_inc (&event_pending); + } + } +} /* irq_handler */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void init ( + unsigned len, + void (* reg) (void *, unsigned), + void (* rel) (void *), + void (* dwn) (void)) +{ + assert (reg); + assert (rel); + assert (dwn); + + capi_card->length = len; + capi_card->reg_func = reg; + capi_card->rel_func = rel; + capi_card->dwn_func = dwn; +} /* init */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#if defined (__fcpcmcia__) +int avm_a1pcmcia_addcard (unsigned int port, unsigned irq) { + capicardparams args; + + args.port = port; + args.irq = irq; + return add_card (&capi_interface, &args); +} /* avm_a1pcmcia_addcard */ + +int avm_a1pcmcia_delcard (unsigned int port, unsigned irq) { + + UNUSED_ARG (port); + UNUSED_ARG (irq); + if (NULL != capi_controller) { + reset_ctrl (capi_controller); + remove_ctrl (capi_controller); + } + return 0; +} /* avm_a1pcmcia_delcard */ +#endif + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int driver_init (void) { + + strncpy (capi_interface.revision, REVISION, + sizeof (capi_interface.revision)); + return (NULL != (capi_lib = link_library ())); +} /* driver_init */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void driver_exit (void) { + + assert (capi_lib); + free_library (); + capi_lib = NULL; +} /* driver_exit */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ + diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/src.drv/driver.h linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/src.drv/driver.h --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/src.drv/driver.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/src.drv/driver.h 2003-07-08 00:02:00.000000000 +0200 @@ -0,0 +1,140 @@ +/* + * driver.h + * Copyright (C) 2002, AVM GmbH. All rights reserved. + * + * This Software is free software. You can redistribute and/or + * modify such free software under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * The free software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this Software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or see + * http://www.opensource.org/licenses/lgpl-license.html + * + * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de + */ + +#ifndef __have_driver_h__ +#define __have_driver_h__ + +#include +#include +#include +#include "capilli.h" +#include "tables.h" +#include "queue.h" +#include "libdefs.h" + +#define SHARED_IRQ /* For PCI only... */ + +#if defined (CONFIG_ISAPNP) +# include +#endif + +typedef struct __irq { + + unsigned id; +} irq_t; + +typedef struct __card { + + unsigned base; + unsigned irq; + unsigned info; + unsigned data; + char * version; + char * string[8]; + unsigned count; + appltab_t * appls; + queue_t * queue; + unsigned length; + void (* reg_func) (void *, unsigned); + void (* rel_func) (void *); + void (* dwn_func) (void); +#if defined (CONFIG_ISAPNP) + struct pci_dev * dev; +#endif +} card_t; + +extern card_t * capi_card; +extern lib_callback_t * capi_lib; +extern struct capi_driver_interface * capi_driver; +extern struct capi_driver capi_interface; +extern struct capi_ctr * capi_controller; + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +extern int load_ware(struct capi_ctr * ctrl, capiloaddata * ware); +extern void reset_ctrl(struct capi_ctr * ctrl); +extern void remove_ctrl(struct capi_ctr * ctrl); +extern void register_appl(struct capi_ctr * ctrl, __u16 appl, + capi_register_params * args); +extern void release_appl(struct capi_ctr * ctrl, __u16 appl); +extern void send_msg(struct capi_ctr * ctrl, struct sk_buff * skb); +extern char * proc_info(struct capi_ctr * ctrl); +extern int ctr_info(char * page, char ** start, off_t ofs, int count, + int * eof, struct capi_ctr * ctr); +extern int drv_info(char * page, char ** start, off_t ofs, int count, + int * eof, struct capi_driver * drv); +extern int add_card(struct capi_driver * drv, capicardparams *args); + +extern void * data_by_id (unsigned appl_id); +extern struct capi_ctr * card_by_id (unsigned appl_id); +extern void * first_data (int * res); +extern void * next_data (int * res); + +extern int appl_profile (unsigned appl_id, unsigned * blksize, + unsigned * blkcount); + +extern int msg2stack (unsigned char * msg); +extern void msg2capi (unsigned char * msg); + +extern void new_ncci (unsigned appl_id, __u32 ncci, unsigned winsize, + unsigned blksize); +extern void free_ncci (unsigned appl_id, __u32 ncci); + +extern unsigned char * data_block (unsigned appl_id, __u32 ncci, + unsigned handle); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +extern void enter_critical (void); +extern void leave_critical (void); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +extern void lock (void); +extern void unlock (void); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +extern int params_ok (card_t * card); + +extern void stop (card_t * card); + +extern int install_card (card_t * card); +extern void remove_card (card_t * card); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +extern void init (unsigned len, + void (* reg) (void *, unsigned), + void (* rel) (void *), + void (* dwn) (void)); + +#if defined (__fcpcmcia__) +extern int avm_a1pcmcia_addcard (unsigned int port, unsigned irq); +extern int avm_a1pcmcia_delcard (unsigned int port, unsigned irq); +#endif + +extern int driver_init (void); +extern void driver_exit (void); + +#endif + diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/src.drv/fcpcmcia_cs.c linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/src.drv/fcpcmcia_cs.c --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/src.drv/fcpcmcia_cs.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/src.drv/fcpcmcia_cs.c 2003-07-08 00:02:00.000000000 +0200 @@ -0,0 +1,559 @@ +/* + * fcpcmcia_cs.c + * Copyright (C) 2002, AVM GmbH. All rights reserved. + * + * This Software is free software. You can redistribute and/or + * modify such free software under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * The free software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this Software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or see + * http://www.opensource.org/licenses/lgpl-license.html + * + * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de + */ + +/*---------------------------------------------------------------------------*\ + * + * Based on Carsten Paeth's PCMCIA client driver for AVM B1/M1/M2 + * +\*---------------------------------------------------------------------------*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +/*---------------------------------------------------------------------------*\ + * Interface to the main driver module +\*---------------------------------------------------------------------------*/ + +extern int avm_a1pcmcia_addcard (unsigned int, unsigned); +extern int avm_a1pcmcia_delcard (unsigned int, unsigned); + +/*---------------------------------------------------------------------------*\ + * All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If you do + * not define PCMCIA_DEBUG at all, all the debug code will be left out. If + * you compile with PCMCIA_DEBUG=0, the debug code will be present but + * disabled -- but it can then be enabled for specific modules at load time + * with a 'pc_debug=#' option to insmod. +\*---------------------------------------------------------------------------*/ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) +#define KFREE_S(a,n) kfree_s(a,n) +#else +#define KFREE_S(a,n) kfree(a) +#endif + +#ifdef PCMCIA_DEBUG +static int pc_debug = PCMCIA_DEBUG; +MODULE_PARM(pc_debug, "i"); +#define DEBUG(n, args...) if (pc_debug>(n)) \ + printk(KERN_DEBUG "fcpcmcia_cs: " args); +#else +#define DEBUG(n, args...) +#endif + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ + +/* Parameters that can be set with 'insmod' */ +/* This means pick from 15, 12, 11, 10, 9, 7, 5, 4, and 3 */ + +static int default_irq_list[10] = { 15, 12, 11, 10, 9, 7, 5, 4, 3, -1 }; +static int irq_list[10] = { -1 }; + +MODULE_PARM(irq_list, "1-10i"); + +/*---------------------------------------------------------------------------*\ + * The event() function is this driver's Card Services event handler. It will + * be called by Card Services when an appropriate card status event is + * received. The config() and release() entry points are used to configure + * or release a socket, in response to card insertion and ejection events. + * They are invoked from the skeleton event handler. +\*---------------------------------------------------------------------------*/ +static void fcpcmcia_config (dev_link_t * link); +static void fcpcmcia_release (u_long arg); +static int fcpcmcia_event (event_t event, int priority, + event_callback_args_t * args); + +/*---------------------------------------------------------------------------*\ + * The attach() and detach() entry points are used to create and destroy + * "instances" of the driver, where each instance represents everything + * needed to manage one actual PCMCIA card. +\*---------------------------------------------------------------------------*/ +static dev_link_t * fcpcmcia_attach (void); +static void fcpcmcia_detach (dev_link_t *); + +/*---------------------------------------------------------------------------*\ + * The dev_info variable is the "key" that is used to match up this device + * driver with appropriate cards, through the card configuration database. +\*---------------------------------------------------------------------------*/ +static dev_info_t dev_info = "fcpcmcia_cs"; + +/*---------------------------------------------------------------------------*\ + * A linked list of "instances" of the skeleton device. Each actual PCMCIA + * card corresponds to one device instance, and is described by one dev_link_t + * structure (defined in ds.h). + * + * You may not want to use a linked list for this -- for example, the memory + * card driver uses an array of dev_link_t pointers, where minor device + * numbers are used to derive the corresponding array index. +\*---------------------------------------------------------------------------*/ +static dev_link_t * dev_list = NULL; + +/*---------------------------------------------------------------------------*\ + * A dev_link_t structure has fields for most things that are needed to keep + * track of a socket, but there will usually be some device specific + * information that also needs to be kept track of. The 'priv' pointer in a + * dev_link_t structure can be used to point to a device-specific private data + * structure, like this. + * + * A driver needs to provide a dev_node_t structure for each device on a + * card. In some cases, there is only one device per card (for example, + * ethernet cards, modems). In other cases, there may be many actual or + * logical devices (SCSI adapters, memory cards with multiple partitions). + * The dev_node_t structures need to be kept in a linked list starting at the + * 'dev' field of a dev_link_t structure. We allocate them in the card's + * private data structure, because they generally can't be allocated + * dynamically. +\*---------------------------------------------------------------------------*/ +typedef struct local_info_t { + + dev_node_t node; +} local_info_t; + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void cs_error(client_handle_t handle, int func, int ret) { + error_info_t err = { func, ret }; + + CardServices (ReportError, handle, &err); +} /* cs_error */ + +/*---------------------------------------------------------------------------*\ + * fcpcmcia_attach() creates an "instance" of the driver, allocating local + * data structures for one device. The device is registered with Card + * Services. + * + * The dev_link structure is initialized, but we don't actually configure the + * card at this point -- we wait until we receive a card insertion event. +\*---------------------------------------------------------------------------*/ +static dev_link_t * fcpcmcia_attach(void) { + client_reg_t client_reg; + dev_link_t * link; + local_info_t * local; + int ret, i; + + DEBUG (0, "fcpcmcia_attach()\n"); + + /* Initialize the dev_link_t structure */ + link = kmalloc (sizeof (struct dev_link_t), GFP_KERNEL); + memset (link, 0, sizeof (struct dev_link_t)); + link->release.function = &fcpcmcia_release; + link->release.data = (u_long) link; + + /* The io structure describes IO port mapping */ + link->io.NumPorts1 = 16; + link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + link->io.NumPorts2 = 0; + + /* Interrupt setup */ + link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; + link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_FIRST_SHARED; + + link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID; + if (irq_list[0] != -1) { + for (i = 0; i < 10 && irq_list[i] > 0; i++) { + link->irq.IRQInfo2 |= 1 << irq_list[i]; + } + } else { + for (i = 0; i < 10 && default_irq_list[i] > 0; i++) { + link->irq.IRQInfo2 |= 1 << default_irq_list[i]; + } + } + + /* General socket configuration */ + link->conf.Attributes = CONF_ENABLE_IRQ; + link->conf.Vcc = 50; + link->conf.IntType = INT_MEMORY_AND_IO; + link->conf.ConfigIndex = 1; + link->conf.Present = PRESENT_OPTION; + + /* Allocate space for private device-specific data */ + local = kmalloc (sizeof (local_info_t), GFP_KERNEL); + memset (local, 0, sizeof (local_info_t)); + link->priv = local; + + /* Register with Card Services */ + link->next = dev_list; + dev_list = link; + client_reg.dev_info = &dev_info; + client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE; + client_reg.EventMask = + CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | + CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET | + CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME; + client_reg.event_handler = &fcpcmcia_event; + client_reg.Version = 0x0210; + client_reg.event_callback_args.client_data = link; + ret = CardServices (RegisterClient, &link->handle, &client_reg); + if (ret != 0) { + cs_error (link->handle, RegisterClient, ret); + fcpcmcia_detach (link); + return NULL; + } + + return link; +} /* fcpcmcia_attach */ + +/*---------------------------------------------------------------------------*\ + * This deletes a driver "instance". The device is de-registered with Card + * Services. If it has been released, all local data structures are freed. + * Otherwise, the structures will be freed when the device is released. +\*---------------------------------------------------------------------------*/ +static void fcpcmcia_detach (dev_link_t * link) +{ + dev_link_t ** linkp; + + DEBUG (0, "fcpcmcia_detach(0x%p)\n", link); + + /* Locate device structure */ + for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) { + if (*linkp == link) break; + } + if (*linkp == NULL) { + return; + } + + /*-----------------------------------------------------------------------*\ + * If the device is currently configured and active, we won't actually + * delete it yet. Instead, it is marked so that when the release() + * function is called, that will trigger a proper detach(). + \*-----------------------------------------------------------------------*/ + if (link->state & DEV_CONFIG) { +#ifdef PCMCIA_DEBUG + printk (KERN_DEBUG "fcpcmcia_cs: detach postponed, '%s' " + "still locked\n", link->dev->dev_name); +#endif + link->state |= DEV_STALE_LINK; + return; + } + + /* Break the link with Card Services */ + if (link->handle) { + CardServices (DeregisterClient, link->handle); + } + + /* Unlink device structure, free pieces */ + *linkp = link->next; + if (link->priv) { + KFREE_S (link->priv, sizeof(local_info_t)); + } + KFREE_S (link, sizeof(struct dev_link_t)); + +} /* fcpcmcia_detach */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static int get_tuple (int fn, client_handle_t handle, tuple_t * tuple, + cisparse_t *parse) +{ + int i; + + i = CardServices (fn, handle, tuple); + if (i != CS_SUCCESS) { + return i; + } + i = CardServices (GetTupleData, handle, tuple); + if (i != CS_SUCCESS) { + return i; + } + return CardServices (ParseTuple, handle, tuple, parse); +} /* get_tuple */ + +#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c) +#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c) + +/*---------------------------------------------------------------------------*\ + * fcpcmcia_config() is scheduled to run after a CARD_INSERTION event is + * received, to configure the PCMCIA socket, and to make the ISDN controller + * available to the system. +\*---------------------------------------------------------------------------*/ +static void fcpcmcia_config (dev_link_t * link) { + client_handle_t handle; + tuple_t tuple; + cisparse_t parse; + cistpl_cftable_entry_t * cf = &parse.cftable_entry; + local_info_t * dev; + int i; + u_char buf[64]; + char devname[128]; + int cardtype; + + handle = link->handle; + dev = link->priv; + + DEBUG (0, "fcpcmcia_config(0x%p)\n", link); + + /*-----------------------------------------------------------------------*\ + * Read the card's CONFIG tuple to find its configuration registers. + \*-----------------------------------------------------------------------*/ + do { + tuple.DesiredTuple = CISTPL_CONFIG; + i = CardServices (GetFirstTuple, handle, &tuple); + if (i != CS_SUCCESS) { + break; + } + tuple.TupleData = buf; + tuple.TupleDataMax = 64; + tuple.TupleOffset = 0; + i = CardServices (GetTupleData, handle, &tuple); + if (i != CS_SUCCESS) { + break; + } + i = CardServices (ParseTuple, handle, &tuple, &parse); + if (i != CS_SUCCESS) { + break; + } + link->conf.ConfigBase = parse.config.base; + } while (0); + if (i != CS_SUCCESS) { + cs_error (link->handle, ParseTuple, i); + link->state &= ~DEV_CONFIG_PENDING; + return; + } + + /* Configure card */ + link->state |= DEV_CONFIG; + + do { + tuple.Attributes = 0; + tuple.TupleData = buf; + tuple.TupleDataMax = 254; + tuple.TupleOffset = 0; + tuple.DesiredTuple = CISTPL_VERS_1; + + devname[0] = 0; + if (!first_tuple (handle, &tuple, &parse) && (parse.version_1.ns > 1)) { + strncpy (devname, parse.version_1.str + parse.version_1.ofs[1], + sizeof(devname)); + } + + /* find IO port */ + tuple.TupleData = (cisdata_t *) buf; + tuple.TupleOffset = 0; + tuple.TupleDataMax = 255; + tuple.Attributes = 0; + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + i = first_tuple (handle, &tuple, &parse); + while (i == CS_SUCCESS) { + if (cf->io.nwin > 0) { + link->conf.ConfigIndex = cf->index; + link->io.BasePort1 = cf->io.win[0].base; + link->io.NumPorts1 = cf->io.win[0].len; + link->io.NumPorts2 = 0; + printk (KERN_INFO "fcpcmcia_cs: testing i/o %#x-%#x\n", + link->io.BasePort1, + link->io.BasePort1 + link->io.NumPorts1 - 1); + i = CardServices (RequestIO, link->handle, &link->io); + if (i == CS_SUCCESS) { + goto found_port; + } + } + i = next_tuple (handle, &tuple, &parse); + } + + found_port: + if (i != CS_SUCCESS) { + cs_error (link->handle, RequestIO, i); + break; + } + + /* allocate an interrupt line */ + i = CardServices (RequestIRQ, link->handle, &link->irq); + if (i != CS_SUCCESS) { + cs_error (link->handle, RequestIRQ, i); + CardServices (ReleaseIO, link->handle, &link->io); + break; + } + + /* configure the PCMCIA socket */ + i = CardServices (RequestConfiguration, link->handle, &link->conf); + if (i != CS_SUCCESS) { + cs_error (link->handle, RequestConfiguration, i); + CardServices (ReleaseIO, link->handle, &link->io); + CardServices (ReleaseIRQ, link->handle, &link->irq); + break; + } + + } while (0); + + /*-----------------------------------------------------------------------*\ + * At this point, the dev_node_t structure(s) should be initialized and + * arranged in a linked list at link->dev. + \*-----------------------------------------------------------------------*/ + strcpy (dev->node.dev_name, "A1"); + dev->node.major = 45; /* <<<< */ + dev->node.minor = 0; /* <<<< */ + link->dev = &dev->node; + + link->state &= ~DEV_CONFIG_PENDING; + /* If any step failed, release any partially configured state */ + if (i != 0) { + fcpcmcia_release ((u_long) link); + return; + } + + if ((i = avm_a1pcmcia_addcard (link->io.BasePort1, link->irq.AssignedIRQ)) < 0) { + printk (KERN_ERR "fcpcmcia_cs: failed to add AVM-%s-Controller at" + " i/o %#x, irq %d\n", + dev->node.dev_name, link->io.BasePort1, link->irq.AssignedIRQ); + fcpcmcia_release ((u_long) link); + return; + } + dev->node.minor = i; + + printk (KERN_DEBUG "fcpcmcia_cs device loaded\n"); +} /* fcpcmcia_config */ + +/*---------------------------------------------------------------------------*\ + * After a card is removed, fcpcmcia_release() will unregister the net device, + * and release the PCMCIA configuration. If the device is still open, this + * will be postponed until it is closed. +\*---------------------------------------------------------------------------*/ + +static void fcpcmcia_release (u_long arg) { + dev_link_t * link = (dev_link_t *) arg; + + DEBUG (0, "fcpcmcia_release(0x%p)\n", link); + + /*-----------------------------------------------------------------------*\ + * If the device is currently in use, we won't release until it is + * actually closed. + \*-----------------------------------------------------------------------*/ + if (link->open) { + DEBUG (1, "fcpcmcia_cs: release postponed, '%s' still open\n", + link->dev->dev_name); + link->state |= DEV_STALE_CONFIG; + return; + } + + avm_a1pcmcia_delcard (link->io.BasePort1, link->irq.AssignedIRQ); + + /* Unlink the device chain */ + link->dev = NULL; + + /* Don't bother checking to see if these succeed or not */ + (void) CardServices (ReleaseConfiguration, link->handle); + (void) CardServices (ReleaseIO, link->handle, &link->io); + (void) CardServices (ReleaseIRQ, link->handle, &link->irq); + link->state &= ~DEV_CONFIG; + + if (link->state & DEV_STALE_LINK) + fcpcmcia_detach (link); + +} /* fcpcmcia_release */ + +/*---------------------------------------------------------------------------*\ + * The card status event handler. Mostly, this schedules other stuff to run + * after an event is received. A CARD_REMOVAL event also sets some flags to + * discourage the net drivers from trying to talk to the card any more. + * + * When a CARD_REMOVAL event is received, we immediately set a flag to block + * future accesses to this device. All the functions that actually access + * the device should check this flag to make sure the card is still present. +\*---------------------------------------------------------------------------*/ +static int fcpcmcia_event (event_t event, int priority, + event_callback_args_t * args) +{ + dev_link_t * link = args->client_data; + + DEBUG (1, "fcpcmcia_event(0x%06x)\n", event); + + switch (event) { + case CS_EVENT_CARD_REMOVAL: + link->state &= ~DEV_PRESENT; + if (link->state & DEV_CONFIG) { + link->release.expires = jiffies + (HZ/20); + add_timer (&link->release); + } + break; + case CS_EVENT_CARD_INSERTION: + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + fcpcmcia_config (link); + break; + case CS_EVENT_PM_SUSPEND: + link->state |= DEV_SUSPEND; + /* Fall through... */ + case CS_EVENT_RESET_PHYSICAL: + if (link->state & DEV_CONFIG) { + CardServices (ReleaseConfiguration, link->handle); + } + break; + case CS_EVENT_PM_RESUME: + link->state &= ~DEV_SUSPEND; + /* Fall through... */ + case CS_EVENT_CARD_RESET: + if (link->state & DEV_CONFIG) { + CardServices (RequestConfiguration, link->handle, &link->conf); + } + break; + } + return 0; +} /* fcpcmcia_event */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int init_module (void) { + servinfo_t serv; + + DEBUG (0, "%s\n", version); + CardServices (GetCardServicesInfo, &serv); + if (serv.Revision != CS_RELEASE_CODE) { + printk (KERN_NOTICE "fcpcmcia_cs: Card Services release " + "does not match!\n"); + return -1; + } + register_pcmcia_driver (&dev_info, &fcpcmcia_attach, &fcpcmcia_detach); + return 0; +} /* init_module */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void cleanup_module (void) { + + DEBUG (0, "fcpcmcia_cs: unloading\n"); + unregister_pcmcia_driver (&dev_info); + while (dev_list != NULL) { + if (dev_list->state & DEV_CONFIG) { + fcpcmcia_release ((u_long) dev_list); + } + fcpcmcia_detach (dev_list); + } +} /* cleanup_module */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ + diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/src.drv/io.c linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/src.drv/io.c --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/src.drv/io.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/src.drv/io.c 2003-07-08 00:02:00.000000000 +0200 @@ -0,0 +1,75 @@ +/* + * io.c + * Copyright (C) 2002, AVM GmbH. All rights reserved. + * + * This Software is free software. You can redistribute and/or + * modify such free software under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * The free software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this Software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or see + * http://www.opensource.org/licenses/lgpl-license.html + * + * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de + */ + +#include + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +unsigned char InpByte (unsigned port) { + + return inb (port); +} /* InpByte */ + +void OutpByte (unsigned port, unsigned char data) { + + outb (data, port); +} /* OutpByte */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +unsigned long InpDWord (unsigned port) { + + return inl (port); +} /* InpDWord */ + +void OutpDWord (unsigned port, unsigned long data) { + + outl (data, port); +} /* OutpDWord */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void InpByteBlock (unsigned port, unsigned char * buffer, unsigned length) { + + insb (port, buffer, length); +} /* InpByteBlock */ + +void OutpByteBlock (unsigned port, unsigned char * buffer, unsigned length) { + + outsb (port, buffer, length); +} /* OutpByteBlock */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void InpDWordBlock (unsigned port, unsigned char * buffer, unsigned length) { + + insl (port, buffer, (length + 3) / 4); +} /* InpDWordBlock */ + +void OutpDWordBlock (unsigned port, unsigned char * buffer, unsigned length) { + + outsl (port, buffer, (length + 3) / 4); +} /* OutpDWordBlock */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ + diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/src.drv/lib.c linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/src.drv/lib.c --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/src.drv/lib.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/src.drv/lib.c 2003-07-08 00:02:00.000000000 +0200 @@ -0,0 +1,520 @@ +/* + * lib.c + * Copyright (C) 2002, AVM GmbH. All rights reserved. + * + * This Software is free software. You can redistribute and/or + * modify such free software under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * The free software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this Software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or see + * http://www.opensource.org/licenses/lgpl-license.html + * + * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de + */ + +#include +#include +#include +#include +#include +#include +#include "driver.h" +#include "queue.h" +#include "defs.h" +#include "tools.h" +#include "libstub.h" +#include "lib.h" + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static unsigned long long j64 = 0; +static unsigned long j32 = 0; + +#define JIFF2MSEC (1000/HZ) + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void os__enter_critical (const char * f, int l) { + + f = (void *) l; + enter_critical (); +} /* os__enter_critical */ + +void os__leave_critical (const char * f, int l) { + + f = (void *) l; + leave_critical (); +} /* os__leave_critical */ + +void os_enter_critical (void) { enter_critical (); } + +void os_leave_critical (void) { leave_critical (); } + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void os_enter_cache_sensitive_code (void) { /* NOP */ } + +void os_leave_cache_sensitive_code (void) { /* NOP */ } + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void os_init (unsigned len, register_t reg, release_t rel, down_t down) { + + init (len, reg, rel, down); +} /* os_init */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +char * os_params (void) { + + return NULL; +} /* os_params */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int os_get_message (unsigned char * msg) { + int res; + + assert (msg); + res = msg2stack (msg); + return res; +} /* os_get_message */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void os_put_message (unsigned char * msg) { + + assert (msg); + msg2capi (msg); +} /* os_put_message */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +unsigned char * os_get_data_block ( + unsigned appl, + unsigned long ncci, + unsigned index) +{ + char * res; + + res = data_block (appl, ncci, index); + return res; +} /* os_get_data_block */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void os_free_data_block (unsigned appl, unsigned char * data) { + + data = (void *) appl; /* Avoid "unused arg" warning */ +} /* os_free_data_block */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int os_new_ncci ( + unsigned appl, + unsigned long ncci, + unsigned win_size, + unsigned blk_size +) { + + new_ncci (appl, ncci, win_size, blk_size); + return 1; +} /* os_new_ncci */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void os_free_ncci (unsigned appl, unsigned long ncci) { + + free_ncci (appl, ncci); +} /* os_free_ncci */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +unsigned os_block_size (unsigned appl) { + unsigned bs; + + appl_profile (appl, &bs, NULL); + return bs; +} /* os_block_size */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +unsigned os_window_size (unsigned appl) { + unsigned bc; + + appl_profile (appl, NULL, &bc); + return bc; +} /* os_window_size */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +unsigned os_card (void) { + + return 0; +} /* os_card */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void * os_appl_data (unsigned appl) { + void * res; + + res = data_by_id (appl); + return res; +} /* os_appl_data */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +appldata_t * os_appl_1st_data (appldata_t * s) { + int num; + void * data; + static char e[10]; + + memset (&e, 0, 10); + data = first_data (&num); + s->num = num; + s->buffer = (NULL == data) ? e : data; + return s; +} /* os_appl_1st_data */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +appldata_t * os_appl_next_data (appldata_t * s) { + int num; + void * data; + static char e[10]; + + memset (&e, 0, 10); + if ((num = s->num) < 0) { + + return NULL; + } + data = next_data (&num); + s->num = num; + s->buffer = (NULL == data) ? e : data; + return s; +} /* os_appl_next_data */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void * os_malloc (unsigned len) { + void * res; + + res = hcalloc (len); + return res; +} /* os_malloc */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void os_free (void * p) { + + assert (p); + hfree (p); +} /* os_free */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void update_j64 (void) { + static int run1 = 1; + unsigned long j; + long long diff; + + j = jiffies; + if (run1) { + j32 = j; + run1 = 0; + } + if ((diff = j - j32) < 0) { + diff = -diff; + } + assert (diff >= 0); + j32 = j; + j64 += diff; +} /* update_j64 */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +unsigned long long os_msec64 (void) { + unsigned long tmp; + + update_j64 (); + tmp = j64 * JIFF2MSEC; + return tmp; +} /* os_msec64 */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +unsigned long os_msec (void) { + unsigned long tmp; + + update_j64 (); + tmp = ((unsigned long) j64) * JIFF2MSEC; + return tmp; +} /* os_msec */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +typedef struct { + + unsigned long lstart; + unsigned long start; + unsigned long tics; + unsigned long arg; + timerfunc_t func; +} timer_rec_t; + +#define TIC_PER_SEC 250 +#define TIC_PER_MSEC 4 +#define Time() (avm_time_base * TIC_PER_MSEC) + +static volatile timer_rec_t * timer = 0; +static unsigned timer_count = 0; + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int os_timer_new (unsigned ntimers) { + unsigned size; + + assert (ntimers > 0); + + + timer_count = ntimers; + size = sizeof (timer_rec_t) * ntimers; + timer = (timer_rec_t *) hcalloc (size); + info (timer != NULL); + if (NULL == timer) { + timer_count = 0; + } + + return timer == NULL; +} /* os_timer_new */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void os_timer_delete (void) { + + + hfree ((void *) timer); + timer = NULL; + timer_count = 0; +} /* os_timer_delete */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int os_timer_start ( + unsigned index, + unsigned long timeout, + unsigned long arg, + timerfunc_t func +) { + assert (index < timer_count); + + if (index >= timer_count) { + return 1; + } + enter_critical (); + timer[index].start = avm_time_base; + timer[index].tics = (timeout + TIC_PER_MSEC) / TIC_PER_MSEC; + timer[index].arg = arg; + timer[index].func = func; + leave_critical (); + return 0; +} /* os_timer_start */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int os_timer_stop (unsigned index) { + + assert (index < timer_count); + + if (index >= timer_count) { + return 1; + } + enter_critical (); + timer[index].func = NULL; + leave_critical (); + return 0; +} /* os_timer_stop */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void os_timer_poll (void) { + unsigned i; + restart_t flag; + + if (NULL == timer) { + return; + } + enter_critical (); + for (i = 0; i < timer_count; i++) { + if (timer[i].func != 0) { + if ((avm_time_base - timer[i].start) >= timer[i].tics) { + leave_critical (); + assert (timer[i].func); + flag = (*timer[i].func) (timer[i].arg); + enter_critical (); + if (timer_restart == flag) { + timer[i].start = avm_time_base; + } else { + timer[i].func = 0; + } + } + } + } + leave_critical (); +} /* os_timer_poll */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static int nl_needed = 0; + +void os_printf (char * s, va_list args) { +#if !defined (NDEBUG) + char buffer[500]; + char * bufptr = buffer; + int count; + + if (nl_needed) { + nl_needed = 0; + printk ("\n"); + } + count = VSNPRINTF (bufptr, sizeof (buffer), s, args); + if ('\n' == buffer[0]) { + bufptr++; + } + if ('\n' != buffer[count - 1]) { + assert (count < 498); + buffer[count++] = '\n'; + buffer[count] = (char) 0; + } + lprintf (KERN_INFO, bufptr); +#else + s = s; + args = args; +#endif +} /* os_printf */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void os_puts (char * str, ...) { + va_list dummy; + + va_start (dummy, str); + os_printf (str, dummy); + va_end (dummy); +} /* os_puts */ + +void os_putl (long l) { + + nl_needed = 1; + lprintf (KERN_INFO, "%ld", l); +} /* os_putl */ + +void os_puti (int i) { + + nl_needed = 1; + lprintf (KERN_INFO, "%d", i); +} /* os_puti */ + +void os_putnl (void) { + + nl_needed = 0; + lprintf (KERN_INFO, "\n"); +} /* os_putnl */ + +void os_putc (char c) { + char buffer[10]; + + nl_needed = 1; + if ((31 < c) && (c < 127)) { + sprintf (buffer, "'%c' (0x%02x)", c, (unsigned char) c); + } else { + sprintf (buffer, "0x%02x", (unsigned char) c); + } + lprintf (KERN_INFO, "%s", buffer); +} /* os_putc */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static lib_callback_t * lib = NULL; +static lib_interface_t libif = { + + init: &os_init, + params: &os_params, + get_message: &os_get_message, + put_message: &os_put_message, + get_data_block: &os_get_data_block, + free_data_block: &os_free_data_block, + new_ncci: &os_new_ncci, + free_ncci: &os_free_ncci, + block_size: &os_block_size, + window_size: &os_window_size, + card: &os_card, + appl_data: &os_appl_data, + appl_1st_data: &os_appl_1st_data, + appl_next_data: &os_appl_next_data, + malloc: &os_malloc, + free: &os_free, + msec: &os_msec, + timer_new: &os_timer_new, + timer_delete: &os_timer_delete, + timer_start: &os_timer_start, + timer_stop: &os_timer_stop, + timer_poll: &os_timer_poll, + printf: &os_printf, + puts: (void (*) (char *)) &os_puts, + putl: &os_putl, + puti: &os_puti, + putc: &os_putc, + putnl: &os_putnl, + _enter_critical: &os__enter_critical, + _leave_critical: &os__leave_critical, + enter_critical: &os_enter_critical, + leave_critical: &os_leave_critical, + enter_cache_sensitive_code: &os_enter_cache_sensitive_code, + leave_cache_sensitive_code: &os_leave_cache_sensitive_code, + name: TARGET, + udata: 0, + pdata: NULL +} ; + +lib_callback_t * get_library (void) { + + return lib; +} /* get_library */ + +lib_callback_t * link_library (void) { + + return (lib = avm_lib_attach (&libif)); +} /* link_library */ + +void free_library (void) { + + if (lib != NULL) { + lib = 0; + avm_lib_detach (&libif); + } +} /* free_library */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void printl (char * fmt, ...) { + va_list args; + char buffer [80]; + + va_start (args, fmt); + VSNPRINTF (buffer, sizeof (buffer), fmt, args); + printk (buffer); + va_end (args); +} /* printl */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ + diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/src.drv/lib.h linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/src.drv/lib.h --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/src.drv/lib.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/src.drv/lib.h 2003-07-08 00:02:00.000000000 +0200 @@ -0,0 +1,36 @@ +/* + * lib.h + * Copyright (C) 2002, AVM GmbH. All rights reserved. + * + * This Software is free software. You can redistribute and/or + * modify such free software under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * The free software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this Software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or see + * http://www.opensource.org/licenses/lgpl-license.html + * + * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de + */ + +#ifndef __have_lib_h__ +#define __have_lib_h__ + +#include "libdefs.h" + +extern lib_callback_t * get_library (void); +extern lib_callback_t * link_library (void); +extern void free_library (void); + +extern void printl (char * fmt, ...); + +extern void os_timer_poll (void); + +#endif diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/src.drv/libdefs.h linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/src.drv/libdefs.h --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/src.drv/libdefs.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/src.drv/libdefs.h 2003-07-08 00:02:00.000000000 +0200 @@ -0,0 +1,114 @@ +/* + * libdefs.h + * Copyright (C) 2002, AVM GmbH. All rights reserved. + * + * This Software is free software. You can redistribute and/or + * modify such free software under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * The free software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this Software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or see + * http://www.opensource.org/licenses/lgpl-license.html + * + * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de + */ + +#ifndef __have_libdefs_h__ +#define __have_libdefs_h__ + +#include + +typedef void (* register_t) (void *, unsigned); +typedef void (* release_t) (void *); +typedef void (* down_t) (void); + +typedef enum { + + timer_end = 0, + timer_restart = 1 +} restart_t; + +typedef restart_t (* timerfunc_t) (unsigned long); + +typedef struct __data { + + unsigned num; + char * buffer; +} appldata_t; + +typedef struct __lib { + + void (* init) (unsigned, register_t, release_t, down_t); + char * (* params) (void); + int (* get_message) (unsigned char *); + void (* put_message) (unsigned char *); + unsigned char * (* get_data_block) (unsigned, unsigned long, unsigned); + void (* free_data_block) (unsigned, unsigned char *); + int (* new_ncci) (unsigned, unsigned long, unsigned, unsigned); + void (* free_ncci) (unsigned, unsigned long); + unsigned (* block_size) (unsigned); + unsigned (* window_size) (unsigned); + unsigned (* card) (void); + void * (* appl_data) (unsigned); + appldata_t * (* appl_1st_data) (appldata_t *); + appldata_t * (* appl_next_data) (appldata_t *); + void * (* malloc) (unsigned); + void (* free) (void *); + unsigned long (* msec) (void); + int (* timer_new) (unsigned); + void (* timer_delete) (void); + int (* timer_start) (unsigned, unsigned long, unsigned long, timerfunc_t); + int (* timer_stop) (unsigned); + void (* timer_poll) (void); + void (* printf) (char *, va_list); + void (* puts) (char *); + void (* putl) (long); + void (* puti) (int); + void (* putc) (char); + void (* putnl) (void); + void (* _enter_critical) (const char *, int); + void (* _leave_critical) (const char *, int); + void (* enter_critical) (void); + void (* leave_critical) (void); + void (* enter_cache_sensitive_code) (void); + void (* leave_cache_sensitive_code) (void); + + char * name; + unsigned udata; + void * pdata; +} lib_interface_t; + +typedef struct __f { + + unsigned nfuncs; + void (* sched_ctrl) (unsigned); + void (* wakeup_ctrl) (unsigned); +} functions_t, * functions_p; + +typedef struct __cb { + + unsigned (* cm_start) (void); + char * (* cm_init) (unsigned, unsigned); + int (* cm_activate) (void); + int (* cm_exit) (void); + unsigned (* cm_handle_events) (void); + int (* cm_schedule) (void); + void (* cm_timer_irq_control) (unsigned); + void (* cm_register_ca_functions) (functions_p); + unsigned (* check_controller) (unsigned, unsigned *); + + void * (* lib_heap_init) (void *, unsigned); + void (* lib_heap_exit) (void *); + void * (* lib_heap_alloc) (void *, unsigned); + void (* lib_heap_free) (void *, void *); +} lib_callback_t; + +#endif + diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/src.drv/libstub.h linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/src.drv/libstub.h --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/src.drv/libstub.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/src.drv/libstub.h 2003-07-08 00:02:00.000000000 +0200 @@ -0,0 +1,37 @@ +/* + * libstub.h + * Copyright (C) 2002, AVM GmbH. All rights reserved. + * + * This Software is free software. You can redistribute and/or + * modify such free software under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * The free software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this Software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or see + * http://www.opensource.org/licenses/lgpl-license.html + * + * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de + */ + +#ifndef __have_libstub_h__ +#define __have_libstub_h__ + +#include "libdefs.h" + +#if defined (OSDEBUG) && defined (NDEBUG) +# undef NDEBUG +#endif + +extern lib_callback_t * avm_lib_attach (lib_interface_t * lif); +extern void avm_lib_detach (lib_interface_t * lif); +extern volatile unsigned long avm_time_base; + +#endif + diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/src.drv/main.c linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/src.drv/main.c --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/src.drv/main.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/src.drv/main.c 2004-09-05 18:49:34.000000000 +0200 @@ -0,0 +1,212 @@ +/* + * main.c + * Copyright (C) 2002, AVM GmbH. All rights reserved. + * + * This Software is free software. You can redistribute and/or + * modify such free software under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * The free software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this Software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or see + * http://www.opensource.org/licenses/lgpl-license.html + * + * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de + */ + +#ifndef EXPORT_SYMTAB +# define EXPORT_SYMTAB +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined (__fcpci__) +#include +#elif defined (__fcpnp__) +#include +#endif + +#include "capilli.h" +#include "driver.h" +#include "tools.h" +#include "defs.h" + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static char * REVCONST = "$Revision: $"; +char REVISION[32]; + +#if defined (MODULE_LICENSE) +MODULE_LICENSE ("GPL"); +#endif +#if defined (MODULE_DESCRIPTION) +MODULE_DESCRIPTION ("CAPI4Linux: Driver for " PRODUCT_LOGO); +#endif +#if defined (MODULE_AUTHOR) +MODULE_AUTHOR("AVM GmbH"); +#endif + +#if defined (__fcpcmcia__) +EXPORT_SYMBOL (avm_a1pcmcia_addcard); +EXPORT_SYMBOL (avm_a1pcmcia_delcard); +#else +EXPORT_NO_SYMBOLS; +#endif + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) +#if defined (__fcpci__) +#define PCI_DEVICE_ID_FRITZ1 0x0A00 +#define PCI_DEVICE_ID_FRITZ2 0x0E00 + +static struct pci_device_id fcpci_id_table[] __initdata = { + { PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_FRITZ1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_FRITZ2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { /* Terminating entry */ } +} ; + +MODULE_DEVICE_TABLE (pci, fcpci_id_table); +#elif defined (__fcpnp__) +static struct isapnp_device_id fcpnp_id_table[] __initdata = { + { ISAPNP_VENDOR('A', 'V', 'M'), ISAPNP_FUNCTION(0x0900), + ISAPNP_VENDOR('A', 'V', 'M'), ISAPNP_FUNCTION(0x0900), 0 }, + { /* Terminating entry */ } +} ; + +MODULE_DEVICE_TABLE (isapnp, fcpnp_id_table); +#endif +#else +#define __exit +#endif + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#ifndef NDEBUG +static void base_address (void) { + + log ("Base address: %p\n", base_address); + log ("Compile time: %s\n", __TIME__); +} /* base_address */ +#endif + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#if defined (__fcpci__) || (defined (__fcpnp__) && defined (CONFIG_ISAPNP)) +static int auto_attach (void) { + struct capicardparams args; + + lprintf (KERN_INFO, "Auto-attaching...\n"); + return add_card (&capi_interface, &args); +} /* auto_attach */ +#endif + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void inc_use_count (void) { MOD_INC_USE_COUNT; } +void dec_use_count (void) { MOD_DEC_USE_COUNT; } + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static int __init fritz_init (void) { + char * tmp; + +#define RETURN(x) MOD_DEC_USE_COUNT; return (x); + +#ifndef NDEBUG + base_address (); +#endif + if ((NULL != (tmp = strchr (REVCONST, ':'))) && isdigit (*(tmp + 2))) { + strncpy (REVISION, tmp + 1, sizeof (REVISION)); + tmp = strchr (REVISION, '$'); + *tmp = 0; + } else { + strcpy (REVISION, REV_DEFAULT); + } + lprintf (KERN_INFO, "%s, revision %s\n", DRIVER_LOGO, REVISION); + lprintf (KERN_INFO, "(%s built on %s at %s)\n", TARGET, __DATE__, __TIME__); + + /*-------------------------------------------------------------------*\ + * 64 bit CAPI is not supported yet. + \*-------------------------------------------------------------------*/ + if (sizeof (char *) > 4) { + lprintf (KERN_ERR, "Cannot deal with 64 bit CAPI messages!\n"); + return -ENOSYS; + } + + MOD_INC_USE_COUNT; /* Protect attachment procedure */ + lprintf (KERN_INFO, "Loading...\n"); + if (!driver_init ()) { + lprintf (KERN_INFO, "Error: Driver library not available.\n"); + lprintf (KERN_INFO, "Not loaded.\n"); + RETURN (-ENOSYS); + } + capi_driver = attach_capi_driver (&capi_interface); + if (NULL == capi_driver) { + lprintf (KERN_INFO, "Error: Could not attach the driver.\n"); + lprintf (KERN_INFO, "Not loaded.\n"); + driver_exit (); + RETURN (-EIO); + } +#if defined (__fcpci__) || (defined (__fcpnp__) && defined (CONFIG_ISAPNP)) + if (0 != auto_attach ()) { + lprintf (KERN_INFO, "Not loaded.\n"); + detach_capi_driver (&capi_interface); + driver_exit (); + RETURN (-EIO); + } +#endif + libheap_init (MAX_LIB_HEAP_SIZE); + lprintf (KERN_INFO, "Loaded.\n"); + RETURN (0); + +#undef RETURN + +} /* fritz_init */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void __exit fritz_exit (void) { + + if (capi_controller != NULL) { + lprintf (KERN_INFO, "Shutting down controller...\n"); + stop (capi_card); + (*capi_driver->detach_ctr) (capi_controller); + } + lprintf (KERN_INFO, "Removing...\n"); + detach_capi_driver (&capi_interface); + libheap_exit (); + driver_exit (); +#ifndef NDEBUG + if (hallocated() != 0) { + lprintf (KERN_ERR, "%u bytes leaked.\n", hallocated()); + } +#endif + lprintf (KERN_INFO, "Removed.\n"); +} /* fritz_exit */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +module_init (fritz_init); +module_exit (fritz_exit); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ + diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/src.drv/main.h linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/src.drv/main.h --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/src.drv/main.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/src.drv/main.h 2003-07-08 00:02:00.000000000 +0200 @@ -0,0 +1,31 @@ +/* + * main.h + * Copyright (C) 2002, AVM GmbH. All rights reserved. + * + * This Software is free software. You can redistribute and/or + * modify such free software under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * The free software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this Software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or see + * http://www.opensource.org/licenses/lgpl-license.html + * + * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de + */ + +#ifndef __have_main_h__ +#define __have_main_h__ + +extern void inc_use_count (void); +extern void dec_use_count (void); + +extern char REVISION[]; + +#endif diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/src.drv/makefile linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/src.drv/makefile --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/src.drv/makefile 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/src.drv/makefile 2003-07-08 00:02:00.000000000 +0200 @@ -0,0 +1,48 @@ +SOURCES = main.c driver.c tables.c queue.c lib.c tools.c +OBJECTS = $(patsubst %.c,%.o,$(SOURCES)) +LIBRARY = ../lib/$(CARD)-lib.o + +CARD_PATH = /lib/modules/`uname -r`/misc +CS_PATH = /lib/modules/`uname -r`/pcmcia-external + +# As propsed by /usr/include/linux/version.h... +KRNLINCL = /lib/modules/`uname -r`/build/include +# KRNLINCL = /usr/src/linux/include + +DEFINES = -DMODULE -D__KERNEL__ -DNDEBUG \ + -D__$(CARD)__ -DTARGET=\"$(CARD)\" +CCFLAGS = -c $(DEFINES) -O2 -Wall -I $(KRNLINCL) +LDFLAGS = -r + +ifeq ($(CARD),fcpcmcia) +CS_MOD = fcpcmcia_cs.o +CS_SRC = fcpcmcia_cs.c +else +CS_MOD = +CS_SRC = +endif + +all: $(CARD).o $(LIBRARY) $(CS_MOD) + +install: $(CARD).o $(LIBRARY) $(CS_MOD) + mkdir -p $(CARD_PATH) + cp -f $(CARD).o $(CARD_PATH) +ifeq ($(CARD),fcpcmcia) + mkdir -p $(CS_PATH) + cp -f $(CS_MOD) $(CS_PATH) +endif + +clean: + $(RM) $(OBJECTS) $(CARD).o $(CS_MOD) + +$(CARD).o: $(OBJECTS) + $(LD) $(LDFLAGS) -o $@ $(OBJECTS) $(LIBRARY) + +$(OBJECTS): %.o: %.c + $(CC) $(CCFLAGS) $< -o $@ + +$(CS_MOD): $(CS_SRC) + $(CC) $(CCFLAGS) $< -o $@ + +# No dependencies yet... + diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/src.drv/queue.c linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/src.drv/queue.c --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/src.drv/queue.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/src.drv/queue.c 2003-07-08 00:02:00.000000000 +0200 @@ -0,0 +1,276 @@ +/* + * queue.c + * Copyright (C) 2002, AVM GmbH. All rights reserved. + * + * This Software is free software. You can redistribute and/or + * modify such free software under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * The free software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this Software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or see + * http://www.opensource.org/licenses/lgpl-license.html + * + * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de + */ + +#include "defs.h" +#include "driver.h" +#include "tools.h" +#include "tables.h" +#include "queue.h" + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#define MAKE_KEY(a,n,h) (((tag_t)(a)<<48)+((tag_t)(n)<<16)+((tag_t)(h))) + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static qitem_t * free_list = NULL; + +static inline qitem_t * alloc_item (void) { + qitem_t * item; + + if (free_list != NULL) { + item = free_list; + free_list = item->succ; + } else { + item = (qitem_t *) hmalloc (sizeof (qitem_t)); + } + info (item); + return item; +} /* alloc_item */ + +static inline void free_item (qitem_t * item) { + + assert (item); + item->succ = free_list; + free_list = item; +} /* free_item */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void queue_init (queue_t ** q) { + + if (NULL == (*q = (queue_t *) hmalloc (sizeof (queue_t)))) { + lprintf (KERN_ERR, "Not enough memory for queue struct.\n"); + } else { + (*q)->noconf = (*q)->put = (*q)->get = NULL; + (*q)->num = 0; + } + assert (free_list == NULL); +} /* queue_init */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void queue_exit (queue_t ** q) { + qitem_t * item; + + assert (q != NULL); + assert (*q != NULL); + while ((*q)->get != NULL) { + item = (*q)->get->succ; + KFREE_SKB ((*q)->get->msg); + hfree ((*q)->get); + (*q)->get = item; + } + while ((*q)->noconf != NULL) { + item = (*q)->noconf->succ; + KFREE_SKB ((*q)->noconf->msg); + hfree ((*q)->noconf); + (*q)->noconf = item; + } + while (free_list != NULL) { + item = free_list->succ; + hfree (free_list); + free_list = item; + } + hfree (*q); + *q = NULL; +} /* queue_exit */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static int enqueue (queue_t * q, struct sk_buff * msg) { + qitem_t * item; + + if (NULL == (item = alloc_item ())) { + lprintf (KERN_ERR, "Not enough memory for queue item.\n"); + lprintf (KERN_ERR, "Message lost.\n"); + return 0; + } + item->succ = NULL; + item->msg = msg; + item->key = 0; + assert (q != NULL); + if (q->num != 0) { + q->put->succ = item; + } else { + q->get = item; + } + q->put = item; + q->num++; + return 1; +} /* enqueue */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static struct sk_buff * dequeue (queue_t * q) { + struct sk_buff * res; + qitem_t * item; + qitem_t * tmp; + + assert (q != NULL); + assert (q->get != NULL); + res = q->get->msg; + item = q->get->succ; + tmp = q->get; + q->get = item; + q->num--; + free_item (tmp); + return res; +} /* dequeue */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int queue_put (queue_t * q, struct sk_buff * msg) { + int res; + + assert (q != NULL); + lock (); + res = enqueue (q, msg); + unlock (); + return res; +} /* queue_put */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +struct sk_buff * queue_peek (queue_t * q) { + struct sk_buff * tmp = NULL; + + assert (q != NULL); + lock (); + if (!queue_is_empty (q)) { + assert (q->get != NULL); + tmp = q->get->msg; + } else { + lprintf (KERN_ERR, "Queue underflow.\n"); + } + unlock (); + return tmp; +} /* queue_peek */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +struct sk_buff * queue_get (queue_t * q) { + struct sk_buff * tmp = NULL; + + assert (q != NULL); + lock (); + if (!queue_is_empty (q)) { + tmp = dequeue (q); + } else { + lprintf (KERN_ERR, "Cannot read empty queue.\n"); + } + unlock (); + return tmp; +} /* queue_get */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void queue_drop (queue_t * q) { + struct sk_buff * tmp; + + assert (q != NULL); + lock (); + if (!queue_is_empty (q)) { + tmp = dequeue (q); + KFREE_SKB (tmp); + } else { + lprintf (KERN_ERR, "Cannot read empty queue.\n"); + } + unlock (); +} /* queue_drop */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int queue_size (queue_t * q) { + + assert (q != NULL); + return (int) q->num; +} /* queue_size */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int queue_is_empty (queue_t * q) { + + assert (q != NULL); + return (q->num == 0) ? TRUE : FALSE; +} /* queue_is_empty */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void queue_park (queue_t * q, unsigned appl, NCCI_t ncci, unsigned hand) { + struct sk_buff * eoq; + qitem_t * item; + + assert (q != NULL); + if (NULL == (eoq = queue_get (q))) { + lprintf (KERN_ERR, "Cannot park from empty queue.\n"); + return; + } + if (NULL == (item = alloc_item ())) { + lprintf (KERN_ERR, "Not enough memory for queue item.\n"); + return; + } + item->key = MAKE_KEY (appl, ncci, hand); + item->msg = eoq; + item->pred = NULL; + lock (); + item->succ = q->noconf; + if (q->noconf != NULL) { + q->noconf->pred = item; + } + q->noconf = item; + unlock (); +} /* queue_park */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void queue_conf (queue_t * q, unsigned appl, NCCI_t ncci, unsigned hand) { + qitem_t * item; + tag_t key = MAKE_KEY (appl, ncci, hand); + + assert (q != NULL); + lock (); + item = q->noconf; + while ((item != NULL) && (item->key != key)) { + item = item->succ; + } + if (item != NULL) { + if (item->succ != NULL) { + item->succ->pred = item->pred; + } + if (item->pred != NULL) { + item->pred->succ = item->succ; + } else { + q->noconf = item->succ; + } + assert (item->msg); + KFREE_SKB (item->msg); + free_item (item); + } else { + log ("Tried to confirm unknown data b3 message.\n"); + } + unlock (); +} /* queue_conf */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ + diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/src.drv/queue.h linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/src.drv/queue.h --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/src.drv/queue.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/src.drv/queue.h 2003-07-08 00:02:00.000000000 +0200 @@ -0,0 +1,62 @@ +/* + * queue.h + * Copyright (C) 2002, AVM GmbH. All rights reserved. + * + * This Software is free software. You can redistribute and/or + * modify such free software under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * The free software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this Software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or see + * http://www.opensource.org/licenses/lgpl-license.html + * + * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de + */ + +#ifndef __have_queue_h__ +#define __have_queue_h__ + +#include + +typedef long long tag_t; +typedef __u32 NCCI_t; + +typedef struct __qitem { + + tag_t key; + struct sk_buff * msg; + struct __qitem * succ; + struct __qitem * pred; +} qitem_t; + +typedef struct __queue { + + qitem_t * put; + qitem_t * get; + qitem_t * noconf; + unsigned num; +} queue_t; + +extern void queue_init (queue_t ** q); +extern void queue_exit (queue_t ** q); + +extern int queue_put (queue_t * q, struct sk_buff * msg); +extern struct sk_buff * queue_peek (queue_t * q); +extern struct sk_buff * queue_get (queue_t * q); +extern void queue_drop (queue_t * q); + +extern int queue_size (queue_t * q); +extern int queue_is_empty (queue_t * q); + +extern void queue_park (queue_t * q, unsigned appl, NCCI_t ncci, unsigned hand); +extern void queue_conf (queue_t * q, unsigned appl, NCCI_t ncci, unsigned hand); + +#endif + diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/src.drv/tables.c linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/src.drv/tables.c --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/src.drv/tables.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/src.drv/tables.c 2003-07-08 00:02:00.000000000 +0200 @@ -0,0 +1,316 @@ +/* + * tables.c + * Copyright (C) 2002, AVM GmbH. All rights reserved. + * + * This Software is free software. You can redistribute and/or + * modify such free software under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * The free software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this Software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or see + * http://www.opensource.org/licenses/lgpl-license.html + * + * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de + */ + +#include +#include +#include +#include "defs.h" +#include "main.h" +#include "tools.h" +#include "driver.h" +#include "queue.h" +#include "tables.h" + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void table_init (appltab_t ** tab) { + + if (NULL != (*tab = (appltab_t *) hmalloc (sizeof (appltab_t)))) { + (*tab)->appl_root = NULL; + (*tab)->appl_count = 0; + } +} /* table_init */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void table_exit (appltab_t ** tab) { + appl_t * appp; + appl_t * tmp; + + assert (*tab); + appp = (*tab)->appl_root; + while (appp != NULL) { + tmp = appp->succ; + capi_card->count--; + remove_appl (*tab, appp); + if (appp->data != NULL) { + hfree (appp->data); + } + appp = tmp; + } + hfree (*tab); + *tab = NULL; +} /* table_exit */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +appl_t * create_appl ( + appltab_t * tab, + unsigned id, + unsigned ncount, + unsigned bcount, + unsigned bsize +) { + appl_t * appp; + + if (NULL == (appp = (appl_t *) hmalloc (sizeof (appl_t)))) { + lprintf (KERN_ERR, "Not enough memory for application record.\n"); + return NULL; + } + appp->id = id; + appp->ncci_count = ncount; + appp->blk_count = bcount; + appp->blk_size = bsize; + appp->data = NULL; + appp->dying = FALSE; + appp->nncci = 0; + appp->root = NULL; + appp->pred = NULL; + lock (); + appp->succ = tab->appl_root; + tab->appl_root = appp; + if (NULL != appp->succ) { + appp->succ->pred = appp; + } + tab->appl_count++; + unlock (); + return appp; +} /* create_appl */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void remove_appl (appltab_t * tab, appl_t * appp) { + ncci_t * nccip; + ncci_t * tmp; + + assert (appp); + lock (); + if (appp->pred != NULL) { + appp->pred->succ = appp->succ; + } else { + tab->appl_root = appp->succ; + } + if (appp->succ != NULL) { + appp->succ->pred = appp->pred; + } + if (appp->data != NULL) { + hfree (appp->data); + appp->data = NULL; + } + nccip = appp->root; + tab->appl_count--; + unlock (); + while (nccip != NULL) { + tmp = nccip->succ; + remove_ncci (tab, appp, nccip); + nccip = tmp; + } + hfree (appp); +} /* remove_appl */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +appl_t * search_appl (appltab_t * tab, unsigned id) { + appl_t * appp; + + lock (); + appp = tab->appl_root; + while (appp != NULL) { + if (appp->id == id) { + break; + } + appp = appp->succ; + } + unlock (); + info (appp); + return appp; +} /* search_appl */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +appl_t * get_appl (appltab_t * tab, unsigned ix) { + appl_t * appp = NULL; + + assert (ix < tab->appl_count); + lock (); + if (ix < tab->appl_count) { + appp = tab->appl_root; + while (ix > 0) { + appp = appp->succ; + --ix; + } + } + unlock (); + return appp; +} /* get_appl */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +appl_t * next_appl (appltab_t * tab, appl_t * appp) { + + UNUSED_ARG (tab); + assert (appp); + return appp->succ; +} /* next_appl */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +appl_t * first_appl (appltab_t * tab) { + + return tab->appl_root; +} /* first_appl */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int handle_message (appltab_t * tab, appl_t * appp, struct sk_buff * msg) { + int ok; + + UNUSED_ARG (tab); + UNUSED_ARG (appp); + assert (msg); + if (!(ok = queue_put (capi_card->queue, msg))) { + lprintf (KERN_ERR, "Message queue overflow. Message lost...\n"); + KFREE_SKB (msg); + } + return ok; +} /* handle_message */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +ncci_t * create_ncci ( + appltab_t * tab, + appl_t * appp, + NCCI_t ncci, + unsigned wsize, + unsigned bsize +) { + ncci_t * tmp; + unsigned char ** data; + + UNUSED_ARG (tab); + if (NULL == (tmp = (ncci_t *) hmalloc (sizeof (ncci_t)))) { + lprintf (KERN_ERR, "Failed to allocate NCCI record.\n"); + return NULL; + } + data = (unsigned char **) hcalloc (sizeof (unsigned char *) + * appp->blk_count); + if (NULL == data) { + lprintf (KERN_ERR, "Failed to allocate data buffer directory.\n"); + hfree (tmp); + return NULL; + } + tmp->ncci = ncci; + tmp->appl = appp->id; + tmp->win_size = wsize; + tmp->blk_size = bsize; + tmp->data = data; + tmp->pred = NULL; + lock (); + tmp->succ = appp->root; + appp->root = tmp; + if (NULL != tmp->succ) { + tmp->succ->pred = tmp; + } + appp->nncci++; + unlock (); + return tmp; +} /* create_ncci */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void remove_ncci (appltab_t * tab, appl_t * appp, ncci_t * nccip) { + unsigned i; + + UNUSED_ARG (tab); + assert (appp); + assert (nccip); + if (nccip != NULL) { + lock (); + for (i = 0; i < appp->blk_count; i++) { + if (nccip->data[i] != NULL) { + hfree (nccip->data[i]); + } + } + hfree (nccip->data); + if (nccip->succ != NULL) { + nccip->succ->pred = nccip->pred; + } + if (nccip->pred != NULL) { + nccip->pred->succ = nccip->succ; + } else { + appp->root = nccip->succ; + } + hfree (nccip); + appp->nncci--; + unlock (); + } +} /* remove_ncci */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +unsigned char * ncci_data_buffer ( + appltab_t * tab, + appl_t * appp, + NCCI_t ncci, + unsigned index +) { + ncci_t * nccip; + + UNUSED_ARG (tab); + if (NULL == (nccip = locate_ncci (appp, ncci))) { + log ("Data buffer request failed. NCCI not found.\n"); + return NULL; + } + lock (); + if (index >= appp->blk_count) { + unlock (); + log ("Data buffer index out of range.\n"); + return NULL; + } + if (nccip->data[index] == NULL) { + if (NULL == (nccip->data[index] = (unsigned char *) hmalloc (appp->blk_size))) { + lprintf (KERN_ERR, "Not enough memory for data buffer.\n"); + } + } + unlock (); + return nccip->data[index]; +} /* ncci_data_buffer */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +ncci_t * locate_ncci (appl_t * appp, NCCI_t ncci) { + ncci_t * tmp; + + assert (appp); + lock (); + tmp = appp->root; + while ((tmp != NULL) && (tmp->ncci != ncci)) { + tmp = tmp->succ; + } + unlock (); + info (tmp); + return tmp; +} /* locate_ncci */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ + diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/src.drv/tables.h linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/src.drv/tables.h --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/src.drv/tables.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/src.drv/tables.h 2003-07-08 00:02:00.000000000 +0200 @@ -0,0 +1,112 @@ +/* + * tables.h + * Copyright (C) 2002, AVM GmbH. All rights reserved. + * + * This Software is free software. You can redistribute and/or + * modify such free software under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * The free software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this Software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or see + * http://www.opensource.org/licenses/lgpl-license.html + * + * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de + */ + +#ifndef __have_tables_h__ +#define __have_tables_h__ + +#include +#include +#include +#include +#include "queue.h" +#include "capilli.h" + +typedef struct __ncci { + + NCCI_t ncci; + unsigned appl; + unsigned win_size; + unsigned blk_size; + unsigned char ** data; + struct __ncci * pred; + struct __ncci * succ; +} ncci_t; + +typedef struct __appl { + + unsigned id; + unsigned dying; + struct capi_ctr * ctrl; + void * data; + unsigned blk_size; + unsigned blk_count; + unsigned ncci_count; + unsigned nncci; + ncci_t * root; + struct __appl * pred; + struct __appl * succ; +} appl_t; + +typedef struct __appltab { + + appl_t * appl_root; + unsigned appl_count; +} appltab_t; + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +extern void table_init (appltab_t ** tab); +extern void table_exit (appltab_t ** tab); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +extern appl_t * create_appl ( + appltab_t * tab, + unsigned id, + unsigned ncount, + unsigned bcount, + unsigned bsize +); +extern void remove_appl (appltab_t * tab, appl_t * appp); + +extern appl_t * search_appl (appltab_t * tab, unsigned id); +extern appl_t * get_appl (appltab_t * tab, unsigned ix); +extern appl_t * first_appl (appltab_t * tab); +extern appl_t * next_appl (appltab_t * tab, appl_t * appp); + +extern int handle_message ( + appltab_t * tab, + appl_t * appp, + struct sk_buff * msg +); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +extern ncci_t * create_ncci ( + appltab_t * tab, + appl_t * appp, + NCCI_t ncci, + unsigned wsize, + unsigned bsize +); +extern void remove_ncci (appltab_t * tab, appl_t * appp, ncci_t * nccip); + +extern unsigned char * ncci_data_buffer ( + appltab_t * tab, + appl_t * appp, + NCCI_t ncci, + unsigned index +); +extern ncci_t * locate_ncci (appl_t * appp, NCCI_t ncci); +extern ncci_t * search_ncci (appltab_t * tab, unsigned appl, NCCI_t ncci); + +#endif diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/src.drv/tools.c linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/src.drv/tools.c --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/src.drv/tools.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/src.drv/tools.c 2003-07-08 00:02:00.000000000 +0200 @@ -0,0 +1,398 @@ +/* + * tools.c + * Copyright (C) 2002, AVM GmbH. All rights reserved. + * + * This Software is free software. You can redistribute and/or + * modify such free software under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * The free software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this Software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or see + * http://www.opensource.org/licenses/lgpl-license.html + * + * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de + */ + +#include +#include +#include +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,18) +#include +#else +#include +#endif + +#include "defs.h" +#include "libdefs.h" +#include "driver.h" +#include "tools.h" + +typedef struct __header { + + unsigned type; +#if !defined (NDEBUG) + unsigned size; + unsigned from; + unsigned tag; +#endif +} header_t; + +#define TYPE_NONE '?' +#define TYPE_KMALLOCED 'k' +#define TYPE_VMALLOCED 'v' +#define TYPE_SMALLOCED 's' + +#define ALLOC_NORMAL 0 +#define ALLOC_SPECIAL 1 + +#define PRIORITY GFP_ATOMIC + +static void * lib_heap_base = NULL; +static unsigned lib_heap_size = 0; + +#if !defined (NDEBUG) +#include + +#define FENCE_TAG 0xDEADBEEF +#define FENCE1_OK(h,m) ((h)->tag==FENCE_TAG) +#define FENCE2_OK(h,m) (*(unsigned *)(((char *) m)+(h)->size)==FENCE_TAG) + +static atomic_t alloc_count = ATOMIC_INIT (0); + +#if !defined (NDEBUG) && defined (LOG_TIMER) +static struct timeval zero_time; +#endif + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +unsigned hallocated (void) { + + return atomic_read (&alloc_count); +} /* hallocated */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +unsigned hallocator (void * mem) { + header_t * hdr; + + if (mem != NULL) { + hdr = ((header_t *) mem) - 1; + return FENCE1_OK(hdr, mem) ? 0 : hdr->from; + } else { + return 0; + } +} /* hallocator */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int hvalid (void * mem) { + header_t * hdr; + int flag = TRUE; + + if (mem != NULL) { + hdr = ((header_t *) mem) - 1; + flag = FENCE1_OK(hdr, mem) && FENCE2_OK(hdr, mem); + } + return flag; +} /* hvalid */ +#endif + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +static void * ALLOCATE (unsigned n, unsigned * t, unsigned m) { + void * temp; + unsigned type; + + temp = kmalloc (n, PRIORITY); + type = TYPE_KMALLOCED; + if (temp == NULL) { + if (ALLOC_NORMAL == m) { + assert (capi_lib->lib_heap_alloc != NULL); + info (lib_heap_base != NULL); + temp = (*capi_lib->lib_heap_alloc) (lib_heap_base, n); + type = TYPE_SMALLOCED; + } else { + temp = vmalloc (n); + type = TYPE_VMALLOCED; + } + } + info (temp != NULL); + *t = (temp != NULL) ? type : TYPE_NONE; +#if defined (LOG_ALLOC) + log ("ALLOC (%u,%u) = 0x%p, type %c\n", n, m, temp, (char) *t); +#endif + return temp; +} /* ALLOCATE */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#if !defined (NDEBUG) +#define PATCH(n) sizeof(header_t)+sizeof(unsigned)+((n)?(n):1) +#else +#define PATCH(n) sizeof(header_t)+((n)?(n):1) +#endif + +static void * halloc (unsigned size, unsigned addr, unsigned mode) { + unsigned n, t = TYPE_NONE; + void * mem; + header_t * hdr; + + n = PATCH(size); + if (NULL == (hdr = (header_t *) ALLOCATE (n, &t, mode))) { + log ( + "Memory request (%u/%u bytes) failed. (mode %u)\n", + size, + PATCH(size), + mode + ); + mem = NULL; + } else { + mem = (void *) (hdr + 1); + hdr->type = t; +#if !defined (NDEBUG) + hdr->size = size ? size : 1; + hdr->from = addr; + hdr->tag = FENCE_TAG; + * (unsigned *) (((char *) mem) + size) = FENCE_TAG; + atomic_add (size, &alloc_count); +#else + UNUSED_ARG (addr); +#endif + } + return mem; +} /* halloc */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +unsigned libheap_init (unsigned heap_size) { + void * heap_base = NULL; + + assert (lib_heap_base == NULL); + assert (heap_size > MIN_LIB_HEAP_SIZE); + do { + if (NULL != (heap_base = halloc (heap_size, (unsigned) &libheap_init, ALLOC_SPECIAL))) { + lib_heap_base = heap_base; + lib_heap_size = heap_size; + (*capi_lib->lib_heap_init) (heap_base, heap_size); + return heap_size; + } + heap_size /= 2; + } while (heap_size > 0); + return 0; +} /* libheap_init */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void libheap_exit (void) { + + assert (lib_heap_base != NULL); + (*capi_lib->lib_heap_exit) (lib_heap_base); + hfree (lib_heap_base); + lib_heap_base = NULL; + lib_heap_size = 0; +} /* libheap_exit */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void * hmalloc (unsigned size) { + + return halloc (size, *(((unsigned *) &size) - 1), ALLOC_NORMAL); +} /* hmalloc */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void * hcalloc (unsigned size) { + void * mem; + + mem = halloc (size, *(((unsigned *) &size) - 1), ALLOC_NORMAL); + if ((mem != NULL) && (size != 0)) { + memset (mem, 0, size); + } + return mem; +} /* hcalloc */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void hfree (void * mem) { + header_t * hdr; + + if (mem != NULL) { + hdr = ((header_t *) mem) - 1; +#if !defined (NDEBUG) + if (!(FENCE1_OK(hdr, mem) && FENCE2_OK(hdr, mem))) { + log ( + "FENCE VIOLATED (%u/0x%08X)!\n", + hdr->size, + hdr->from + ); + } + atomic_sub (hdr->size, &alloc_count); +#if defined (LOG_ALLOC) + log ("FREE (0x%p, %u), type %c\n", hdr, hdr->size, hdr->type); +#endif +#endif + switch (hdr->type) { + + case TYPE_KMALLOCED: + kfree (hdr); + break; + case TYPE_VMALLOCED: + vfree (hdr); + break; + case TYPE_SMALLOCED: + assert (capi_lib->lib_heap_free != NULL); + info (lib_heap_base != NULL); + (*capi_lib->lib_heap_free) (lib_heap_base, hdr); + break; + default: + assert (0); + break; + } + } +} /* hfree */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#if !defined (NDEBUG) && defined (LOG_TIMER) + +#include + +void setup_timer (dbg_timer * t, long dsec, long dusec) { + + assert (t != NULL); + memset (&t->t, 0, sizeof (t->t)); + t->d.tv_sec = dsec; + t->d.tv_usec = dusec; +} /* dbg_setup_timer */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int check_timer (dbg_timer * t) { + int res = 1; + struct timeval now; + struct timeval delta; + + assert (t != NULL); + do_gettimeofday (&now); + timeval_less (now, zero_time, &delta); + now = delta; + timeval_less (now, t->t, &delta); + if ((delta.tv_sec > t->d.tv_sec) + || ((delta.tv_sec == t->d.tv_sec) && (delta.tv_usec > t->d.tv_usec)) + ) { + lprintf ( + KERN_INFO, + "Timer '%s' exceeded: %ld s, %ld µs\n", + t->name, + delta.tv_sec, + delta.tv_usec + ); + res = 0; + } + return res; +} /* check_timer */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void touch_timer (dbg_timer * t) { + struct timeval temp, delta; + + assert (t != NULL); + do_gettimeofday (&temp); + timeval_less (temp, zero_time, &delta); + t->t = delta; +} /* touch_timer */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void start_watch (dbg_timer * w) { + struct timeval temp, delta; + + assert (w != NULL); + do_gettimeofday (&temp); + timeval_less (temp, zero_time, &delta); + w->t = delta; +} /* start_watch */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void stop_watch (dbg_timer * w) { + struct timeval temp, delta; + + assert (w != NULL); + do_gettimeofday (&temp); + timeval_less (temp, zero_time, &delta); + temp = delta; + timeval_less (temp, w->t, &delta); + w->t = delta; +} /* stop_watch */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +int timers_start (void) { + + do_gettimeofday (&zero_time); + return 1; +} /* timers_start */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void timers_stop (void) { + +} /* timers_stop */ + +#endif /* !NDEBUG && LOG_TIMER */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void vlprintf (const char * level, const char * fmt, va_list args) { + static char line[256]; + + VSNPRINTF (line, sizeof (line), fmt, args); + printk ("%s%s: %s", level, TARGET, line); +} /* vlprintf */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void lprintf (const char * level, const char * fmt, ...) { + va_list args; + + va_start (args, fmt); + vlprintf (level, fmt, args); + va_end (args); +} /* lprintf */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +void message (const char * fmt, ...) { + va_list args; + + va_start (args, fmt); + vlprintf (KERN_INFO, fmt, args); + va_end (args); +} /* message */ + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#ifndef NDEBUG +void _OSassert (void * exp, void * file, unsigned line) { + + message ("assert (%s) in %s(%u)\n", exp, file, line); +} /* _OSassert */ + +void _OSinfo (void * exp, void * file, unsigned line) { + + message ("info (%s) in %s(%u)\n", exp, file, line); +} /* _OSinfo */ +#endif + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ diff -Naurp linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/src.drv/tools.h linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/src.drv/tools.h --- linux-2.4.20-wolk4.15-fullkernel/3rdparty/avm-fritz-pci/src.drv/tools.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/3rdparty/avm-fritz-pci/src.drv/tools.h 2003-07-08 00:02:00.000000000 +0200 @@ -0,0 +1,144 @@ +/* + * tools.h + * Copyright (C) 2002, AVM GmbH. All rights reserved. + * + * This Software is free software. You can redistribute and/or + * modify such free software under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * The free software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this Software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or see + * http://www.opensource.org/licenses/lgpl-license.html + * + * Contact: AVM GmbH, Alt-Moabit 95, 10559 Berlin, Germany, email: info@avm.de + */ + +#ifndef __have_tools_h__ +#define __have_tools_h__ + +#include +#include +#include +#include +#include "defs.h" + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,4) +#define VSNPRINTF(s,n,f,a) vsnprintf (s, n, f, a) +#define SNPRINTF(s,n,f,l...) snprintf (s, n, f, ##l) +#else +#define VSNPRINTF(s,n,f,a) vsprintf (s, f, a) +#define SNPRINTF(s,n,f,l...) sprintf (s, f, ##l) +#endif + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#if !defined (NDEBUG) +# define assert(x) (!(x)?message("%s(%d): assert (%s) failed\n", \ + __FILE__, __LINE__, #x):((void)0)) +# define info(x) (!(x)?message("%s(%d): info (%s) failed\n", \ + __FILE__, __LINE__, #x):((void)0)) +# define log(f,x...) message (f, ##x) + +extern void message (const char * fmt, ...); +#else +# define assert(x) +# define info(x) +# define log(f,x...) +#endif + +extern void lprintf (const char * level, const char * fmt, ...); +extern void vlprintf (const char * level, const char * fmt, va_list args); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#if !defined (NDEBUG) +extern unsigned hallocated (void); +extern unsigned hallocator (void * mem); +extern int hvalid (void * mem); +#endif + +extern void * hmalloc (unsigned size); +extern void * hcalloc (unsigned size); + +extern void hfree (void * mem); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +extern unsigned libheap_init (unsigned heap_size); +extern void libheap_exit (void); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#if !defined (NDEBUG) && defined (LOG_TIMER) + +#include + +typedef struct { + + const char * name; + struct timeval t; + struct timeval d; +} dbg_timer; + +#define PRINT_TIMER(x) log ( \ + "Timer '%s': %ld s, %ld µs\n", \ + (x)->name, \ + (x)->t.tv_sec, (x)->t.tv_usec \ + ) +#define PRINT_TIME_MSG(s,x) log ( \ + "%s: %ld s, %ld µs\n", \ + s, (x)->t.tv_sec, (x)->t.tv_usec \ + ) + +#define WATCH_DECL(id) dbg_timer id##_timer +#define WATCH_START(id) start_watch (&id##_timer) +#define WATCH_STOP(id) stop_watch (&id##_timer); \ + PRINT_TIME_MSG(#id,&id##_timer) + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +extern int timers_start (void); +extern void timers_stop (void); + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +extern void setup_timer (dbg_timer * t, long dsec, long dusec); +extern int check_timer (dbg_timer * t); +extern void touch_timer (dbg_timer * t); + +extern void start_watch (dbg_timer * w); +extern void stop_watch (dbg_timer * w); +#else +#define PRINT_TIMER(t) +#define WATCH_DECL(name) +#define WATCH_START(name) +#define WATCH_STOP(name) +#endif + +/*---------------------------------------------------------------------------*\ +\*---------------------------------------------------------------------------*/ +#ifdef NEED_MEM_STR_PROTOS + +extern void * memcpy (void * d, const void * s, size_t n); +extern void * memmove (void * d, const void * s, size_t n); +extern void * memset (void * m, int x, size_t c); + +extern int memcmp (const void * s1, const void * s2, size_t n); + +extern char * strcpy (char * d, const char * s); +extern char * strcat (char * d, const char * s); +extern int strcmp (const char * s1, const char * s2); + +extern size_t strlen (const char * s); + +#endif +#endif diff -Naurp linux-2.4.20-wolk4.15-fullkernel/ADDON-patches/01_grsecurity-v2.0.1.patch linux-2.4.20-wolk4.16-fullkernel/ADDON-patches/01_grsecurity-v2.0.1.patch --- linux-2.4.20-wolk4.15-fullkernel/ADDON-patches/01_grsecurity-v2.0.1.patch 2004-06-29 13:28:10.000000000 +0200 +++ linux-2.4.20-wolk4.16-fullkernel/ADDON-patches/01_grsecurity-v2.0.1.patch 2004-09-05 17:09:24.000000000 +0200 @@ -1,411 +1,1143 @@ -diff -Naurp old/gradm2/Makefile new/gradm2/Makefile ---- old/gradm2/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ new/gradm2/Makefile 2004-06-29 13:10:03.000000000 +0200 -@@ -0,0 +1,131 @@ -+############################################################################## -+#gradm (c) 2002 Brad Spengler http://grsecurity.net# -+#---------------------------- ---------------------# -+#gradm is licensed under the GNU GPL http://www.gnu.org # -+############################################################################## +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/Documentation/Configure.help linux-2.4.20-wolk4.16-grsec2/Documentation/Configure.help +--- linux-2.4.20-wolk4.16-fullkernel/Documentation/Configure.help 2004-09-05 16:28:06.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/Documentation/Configure.help 2004-09-05 17:07:53.000000000 +0200 +@@ -27304,6 +27304,17 @@ CONFIG_GRKERNSEC_HIDESYM + useful protection against local and remote kernel exploitation of + overflows and arbitrary read/write vulnerabilities. + ++Deter exploit bruteforcing ++CONFIG_GRKERNSEC_BRUTE ++ If you say Y here, attempts to bruteforce exploits against forking ++ daemons such as apache or sshd will be deterred. When a child of a ++ forking daemon is killed by PaX or crashes due to an illegal ++ instruction, the parent process will be delayed 30 seconds upon every ++ subsequent fork until the administrator is able to assess the ++ situation and restart the daemon. It is recommended that you also ++ enable signal logging in the auditing section so that logs are ++ generated when a process performs an illegal instruction. ++ + /proc//ipaddr support + CONFIG_GRKERNSEC_PROC_IPADDR + If you say Y here, a new entry will be added to each /proc/ +@@ -27531,9 +27542,9 @@ CONFIG_GRKERNSEC_CHROOT_PIVOT + Deny double-chroots + CONFIG_GRKERNSEC_CHROOT_DOUBLE + If you say Y here, processes inside a chroot will not be able to chroot +- again. This is a widely used method of breaking out of a chroot jail +- and should not be allowed. If the sysctl option is enabled, a sysctl +- option with name "chroot_deny_chroot" is created. ++ again outside of the chroot. This is a widely used method of breaking ++ out of a chroot jail and should not be allowed. If the sysctl option ++ is enabled, a sysctl option with name "chroot_deny_chroot" is created. + + Deny fchdir outside of chroot + CONFIG_GRKERNSEC_CHROOT_FCHDIR +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/arch/i386/kernel/init_task.c linux-2.4.20-wolk4.16-grsec2/arch/i386/kernel/init_task.c +--- linux-2.4.20-wolk4.16-fullkernel/arch/i386/kernel/init_task.c 2004-09-05 15:45:59.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/arch/i386/kernel/init_task.c 2004-09-05 17:07:52.000000000 +0200 +@@ -30,5 +30,9 @@ union task_union init_task_union + * section. Since TSS's are completely CPU-local, we want them + * on exact cacheline boundaries, to eliminate cacheline ping-pong. + */ +-struct tss_struct init_tss[NR_CPUS] __cacheline_aligned = { [0 ... NR_CPUS-1] = INIT_TSS }; + ++#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC ++struct tss_struct init_tss[NR_CPUS] __attribute__((__aligned__(SMP_CACHE_BYTES), __section__(".rodata"))) = { [0 ... NR_CPUS-1] = INIT_TSS }; ++#else ++struct tss_struct init_tss[NR_CPUS] __cacheline_aligned = { [0 ... NR_CPUS-1] = INIT_TSS }; ++#endif +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/arch/i386/kernel/ioport.c linux-2.4.20-wolk4.16-grsec2/arch/i386/kernel/ioport.c +--- linux-2.4.20-wolk4.16-fullkernel/arch/i386/kernel/ioport.c 2004-09-05 16:05:40.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/arch/i386/kernel/ioport.c 2004-09-05 17:07:52.000000000 +0200 +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + + /* RSBAC */ + #ifdef CONFIG_RSBAC +@@ -63,6 +64,10 @@ asmlinkage int sys_ioperm(unsigned long + struct thread_struct * t = ¤t->thread; + struct tss_struct * tss; + ++#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC ++ unsigned long flags, cr3; ++#endif + -+GRADM_BIN=gradm -+GRSEC_DIR=/etc/grsec + /* RSBAC */ + #ifdef CONFIG_RSBAC + union rsbac_target_id_t rsbac_target_id; +@@ -126,6 +131,11 @@ asmlinkage int sys_ioperm(unsigned long + * do it in the per-thread copy and in the TSS ... + */ + set_bitmap(t->io_bitmap, from, num, !turn_on); + -+LEX=/usr/bin/lex -+FLEX=/usr/bin/flex -+LEXFLAGS=-B -+YACC=/usr/bin/yacc -+BYACC=/usr/bin/byacc -+BISON=/usr/bin/bison -+MKNOD=/bin/mknod -+#for dietlibc -+#CC=/usr/bin/diet /usr/bin/gcc -+CC=/usr/bin/gcc -+FIND=/usr/bin/find -+STRIP=/usr/bin/strip -+#for sparc64 -+#LIBS= -+LIBS=-lfl -+KERNVER=`uname -r | cut -d"." -f 2` -+#for 64-bit archs -+#OPT_FLAGS=-O2 -m64 -+OPT_FLAGS=-O2 -+CFLAGS=$(OPT_FLAGS) -DGRSEC_DIR=\"$(GRSEC_DIR)\" -DKERNVER=$(KERNVER) -+LDFLAGS= -+INSTALL = /usr/bin/install -c ++#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC ++ pax_open_kernel(flags, cr3); ++#endif + -+# FHS -+MANDIR=/usr/share/man -+# older MANDIR -+#MANDIR=/usr/man -+DESTDIR= + if (tss->bitmap == IO_BITMAP_OFFSET) { /* already active? */ + set_bitmap(tss->io_bitmap, from, num, !turn_on); + } else { +@@ -133,6 +143,10 @@ asmlinkage int sys_ioperm(unsigned long + tss->bitmap = IO_BITMAP_OFFSET; /* Activate it in the TSS */ + } + ++#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC ++ pax_close_kernel(flags, cr3); ++#endif + -+OBJECTS=gradm.tab.o lex.gradm.o learn_pass1.tab.o learn_pass2.tab.o \ -+ fulllearn_pass1.tab.o fulllearn_pass2.tab.o fulllearn_pass3.tab.o \ -+ gradm_misc.o gradm_parse.o gradm_arg.o gradm_pw.o gradm_opt.o \ -+ gradm_cap.o gradm_sha256.o gradm_adm.o gradm_analyze.o gradm_res.o \ -+ gradm_human.o gradm_learn.o gradm_net.o gradm_nest.o \ -+ gradm_sym.o gradm_newlearn.o gradm_fulllearn.o gradm_lib.o \ -+ lex.fulllearn_pass1.o lex.fulllearn_pass2.o \ -+ lex.fulllearn_pass3.o lex.learn_pass1.o lex.learn_pass2.o + preempt_enable(); + + return 0; +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/arch/i386/kernel/process.c linux-2.4.20-wolk4.16-grsec2/arch/i386/kernel/process.c +--- linux-2.4.20-wolk4.16-fullkernel/arch/i386/kernel/process.c 2004-09-05 16:08:39.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/arch/i386/kernel/process.c 2004-09-05 17:07:52.000000000 +0200 +@@ -1009,6 +1009,10 @@ void __switch_to(struct task_struct *pre + *next = &next_p->thread; + struct tss_struct *tss = init_tss + smp_processor_id(); + ++#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC ++ unsigned long flags, cr3; ++#endif + -+all: $(USE_YACC) $(USE_LEX) $(GRADM_BIN) grlearn + unlazy_fpu(prev_p); + + #ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC +@@ -1016,11 +1020,6 @@ void __switch_to(struct task_struct *pre + #endif + + /* +- * Reload esp0, LDT and the page table pointer: +- */ +- tss->esp0 = next->esp0; +- +- /* + * Save away %fs and %gs. No need to save %es and %ds, as + * those are always kernel segments while inside the kernel. + */ +@@ -1048,6 +1047,15 @@ void __switch_to(struct task_struct *pre + loaddebug(next, 7); + } + ++#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC ++ pax_open_kernel(flags, cr3); ++#endif + -+USE_YACC = $(shell if [ -x $(BYACC) ]; then echo $(BYACC); \ -+ else if [ -x $(BISON) ]; then echo $(BISON) -y; \ -+ else if [ -x $(YACC) ]; then echo $(YACC); \ -+ else \ -+ echo "Bison/(b)yacc needs to be installed to compile gradm."; \ -+ exit 1; \ -+ fi;fi;fi) ++ /* ++ * Reload esp0, LDT and the page table pointer: ++ */ ++ tss->esp0 = next->esp0; + -+USE_LEX = $(shell if [ -x $(FLEX) ]; then echo $(FLEX); \ -+ else if [ -x $(LEX) ]; then echo $(LEX); \ -+ else \ -+ echo "(f)Lex needs to be installed to compile gradm."; \ -+ exit 1; \ -+ fi;fi) + if (unlikely(prev->ioperm || next->ioperm)) { + if (next->ioperm) { + /* +@@ -1070,6 +1078,11 @@ void __switch_to(struct task_struct *pre + */ + tss->bitmap = INVALID_IO_BITMAP_OFFSET; + } + -+$(GRADM_BIN): $(OBJECTS) -+ $(CC) $(CFLAGS) -o $@ $(OBJECTS) $(LIBS) $(LDFLAGS) ++#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC ++ pax_close_kernel(flags, cr3); ++#endif + -+grlearn: grlearn.c gradm_lib.c -+ $(CC) $(CFLAGS) -o $@ grlearn.c gradm_lib.c $(LIBS) $(LDFLAGS) + } + + asmlinkage int sys_fork(struct pt_regs regs) +@@ -1164,6 +1177,10 @@ asmlinkage void pax_randomize_kstack(voi + struct tss_struct *tss = init_tss + smp_processor_id(); + unsigned long time; + ++#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC ++ unsigned long flags, cr3; ++#endif + + #ifdef CONFIG_GRKERNSEC_PAX_SOFTMODE + if (!pax_aslr) + return; +@@ -1180,7 +1197,16 @@ asmlinkage void pax_randomize_kstack(voi + time <<= 2; + #endif + ++#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC ++ pax_open_kernel(flags, cr3); ++#endif + -+gradm.tab.c: gradm.y -+ $(USE_YACC) -b gradm -p gradm -d ./gradm.y + tss->esp0 ^= time; + current->thread.esp0 = tss->esp0; + -+lex.gradm.c: gradm.l -+ $(USE_LEX) $(LEXFLAGS) -Pgradm ./gradm.l ++#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC ++ pax_close_kernel(flags, cr3); ++#endif + -+fulllearn_pass1.tab.c: gradm_fulllearn_pass1.y -+ $(USE_YACC) -b fulllearn_pass1 -p fulllearn_pass1 -d ./gradm_fulllearn_pass1.y -+fulllearn_pass2.tab.c: gradm_fulllearn_pass2.y -+ $(USE_YACC) -b fulllearn_pass2 -p fulllearn_pass2 -d ./gradm_fulllearn_pass2.y -+fulllearn_pass3.tab.c: gradm_fulllearn_pass3.y -+ $(USE_YACC) -b fulllearn_pass3 -p fulllearn_pass3 -d ./gradm_fulllearn_pass3.y + } + #endif +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/arch/i386/kernel/setup.c linux-2.4.20-wolk4.16-grsec2/arch/i386/kernel/setup.c +--- linux-2.4.20-wolk4.16-fullkernel/arch/i386/kernel/setup.c 2004-09-05 16:08:38.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/arch/i386/kernel/setup.c 2004-09-05 17:07:52.000000000 +0200 +@@ -177,7 +177,7 @@ unsigned char aux_device_present; + extern void mcheck_init(struct cpuinfo_x86 *c); + extern void dmi_scan_machine(void); + extern int root_mountflags; +-extern char _text, _etext, _edata, _end; ++extern char _text, _etext, _data, _edata, _end; + + static int have_cpuid_p(void) __init; + +@@ -1343,7 +1343,7 @@ void __init setup_arch(char **cmdline_p) + + code_resource.start = virt_to_bus(&_text); + code_resource.end = virt_to_bus(&_etext)-1; +- data_resource.start = virt_to_bus(&_etext); ++ data_resource.start = virt_to_bus(&_data); + data_resource.end = virt_to_bus(&_edata)-1; + + parse_cmdline_early(cmdline_p); +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/arch/i386/kernel/vm86.c linux-2.4.20-wolk4.16-grsec2/arch/i386/kernel/vm86.c +--- linux-2.4.20-wolk4.16-fullkernel/arch/i386/kernel/vm86.c 2004-09-05 16:04:41.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/arch/i386/kernel/vm86.c 2004-09-05 17:07:52.000000000 +0200 +@@ -45,6 +45,7 @@ + #include + #include + #include ++#include + + /* + * Known problems: +@@ -98,6 +99,10 @@ struct pt_regs * save_v86_state(struct k + struct pt_regs *ret; + unsigned long tmp; + ++#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC ++ unsigned long flags, cr3; ++#endif + -+lex.fulllearn_pass1.c: gradm_fulllearn_pass1.l -+ $(USE_LEX) $(LEXFLAGS) -Pfulllearn_pass1 ./gradm_fulllearn_pass1.l -+lex.fulllearn_pass2.c: gradm_fulllearn_pass2.l -+ $(USE_LEX) $(LEXFLAGS) -Pfulllearn_pass2 ./gradm_fulllearn_pass2.l -+lex.fulllearn_pass3.c: gradm_fulllearn_pass3.l -+ $(USE_LEX) $(LEXFLAGS) -Pfulllearn_pass3 ./gradm_fulllearn_pass3.l + if (!current->thread.vm86_info) { + printk("no vm86_info: BAD\n"); + do_exit(SIGSEGV); +@@ -112,7 +117,17 @@ struct pt_regs * save_v86_state(struct k + do_exit(SIGSEGV); + } + tss = init_tss + smp_processor_id(); + -+learn_pass1.tab.c: gradm_learn_pass1.y -+ $(USE_YACC) -b learn_pass1 -p learn_pass1 -d ./gradm_learn_pass1.y -+learn_pass2.tab.c: gradm_learn_pass2.y -+ $(USE_YACC) -b learn_pass2 -p learn_pass2 -d ./gradm_learn_pass2.y ++#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC ++ pax_open_kernel(flags, cr3); ++#endif + -+lex.learn_pass1.c: gradm_learn_pass1.l -+ $(USE_LEX) $(LEXFLAGS) -Plearn_pass1 ./gradm_learn_pass1.l -+lex.learn_pass2.c: gradm_learn_pass2.l -+ $(USE_LEX) $(LEXFLAGS) -Plearn_pass2 ./gradm_learn_pass2.l + tss->esp0 = current->thread.esp0 = current->thread.saved_esp0; + -+install: $(GRADM_BIN) gradm.8 acl grlearn -+ mkdir -p $(DESTDIR)/sbin -+ $(INSTALL) -m 0755 $(GRADM_BIN) $(DESTDIR)/sbin -+ $(STRIP) $(DESTDIR)/sbin/$(GRADM_BIN) -+ $(INSTALL) -m 0700 grlearn $(DESTDIR)/sbin -+ $(STRIP) $(DESTDIR)/sbin/grlearn -+ mkdir -p -m 700 $(DESTDIR)$(GRSEC_DIR) -+ @if [ ! -f $(DESTDIR)$(GRSEC_DIR)/acl ] ; then \ -+ $(INSTALL) -m 0600 acl $(DESTDIR)$(GRSEC_DIR) ; \ -+ fi -+ @if [ -z "`cut -d" " -f3 /proc/mounts | grep "^devfs"`" ] ; then \ -+ rm -f $(DESTDIR)/dev/grsec ; \ -+ if [ ! -e $(DESTDIR)/dev/grsec ] ; then \ -+ mkdir -p $(DESTDIR)/dev ; \ -+ $(MKNOD) -m 0622 $(DESTDIR)/dev/grsec c 1 11 ; \ -+ fi \ -+ fi -+ mkdir -p $(DESTDIR)$(MANDIR)/man8 -+ $(INSTALL) -m 0644 gradm.8 $(DESTDIR)$(MANDIR)/man8/$(GRADM_BIN).8 -+ @if [ -z $(DESTDIR) ] ; then \ -+ if [ -x /sbin/$(GRADM_BIN) ] ; then \ -+ $(FIND) $(GRSEC_DIR) -type f -name pw -size 48c -exec rm -f $(GRSEC_DIR)/pw \; ; \ -+ if [ ! -f $(GRSEC_DIR)/pw ] ; then \ -+ /sbin/$(GRADM_BIN) -P ; \ -+ fi \ -+ fi \ -+ fi ++#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC ++ pax_close_kernel(flags, cr3); ++#endif + -+clean: -+ rm -f core *.o $(GRADM_BIN) lex.*.c *.tab.c *.tab.h grlearn -diff -Naurp old/gradm2/acl new/gradm2/acl ---- old/gradm2/acl 1970-01-01 01:00:00.000000000 +0100 -+++ new/gradm2/acl 2004-04-03 18:03:13.000000000 +0200 -@@ -0,0 +1,179 @@ -+#sample default process acl for grsecurity -+# Role flags: -+# A -> This role is an administrative role, thus it has special privilege normal -+# roles do not have. In particular, this role bypasses the -+# additional ptrace restrictions -+# N -> Don't require authentication for this role. To access -+# the role, use gradm -n -+# s -> This role is a special role, meaning it does not belong to a -+# user or group, and does not fall under ACL enforcement -+# u -> This role is a user role -+# g -> This role is a group role -+# G -> This role can use gradm to authenticate to the kernel -+# An ACL for gradm will automatically be added to the role -+# T -> Enable TPE for this role -+# l -> Enable learning for this role -+# -+# a role can only be one of user, group, or special -+# -+# role_allow_ip IP/optional netmask -+# eg: role_allow_ip 192.168.1.0/24 -+# You can have as many of these per role as you want -+# They restrict the use of a role to a list of IPs. If a user -+# is on the system that would normally get the role does not -+# belong to those lists of IPs, the system falls back through -+# its method of determining a role for the user -+# -+# Role hierarchy -+# user -> group -> default -+# First a user role attempts to match, if one is not found, -+# a group role attempts to match, if one is not found, -+# the default role is used. -+# -+# role_transitions ... -+# eg: role_transitions www_admin dns_admin -+# -+# role transitions specify which special roles a given role is allowed -+# to authenticate to. This applies to special roles that do not -+# require password authentication as well. If a user tries to -+# authenticate to a role that is not within his transition table, he -+# will receive a permission denied error -+# -+# Nested subjects -+# subject /bin/su:/bin/bash:/bin/cat -+# / rwx -+# +CAP_ALL -+# grant privilege to specific processes if they are executed -+# within a trusted path. In this case, privilege is -+# granted if /bin/cat is executed from /bin/bash, which is -+# executed from /bin/su. -+# -+# Configuration inheritance on nested subjects -+# nested subjects inherit rules from their parents. In the -+# example above, the nested subject would inherit rules -+# from the nested subject for /bin/su:/bin/bash, -+# and the subject /bin/su -+# View the 1.9.x documentation for more information on -+# configuration inheritance -+# -+# new object modes: -+# m -> allow creation of setuid/setgid files/directories -+# and modification of files/directories to be setuid/setgid -+# M -> audit the setuid/setgid creation/modification -+# c -> allow creation of the file/directory -+# C -> audit the creation -+# d -> allow deletion of the file/directory -+# D -> audit the deletion -+# p -> reject all ptraces to this object -+# new subject modes: -+# r -> relax ptrace restrictions (allows process to ptrace processes -+# other than its own descendants) -+# -+# user/group transitions: -+# You may now specify what users and groups a given subject can -+# transition to. This can be done on an inclusive or exclusive basis. -+# Examples: -+# subject /bin/su -+# user_transition_allow root spender -+# group_transition_allow root spender -+# subject /bin/su -+# user_transition_deny evilhacker -+# subject /bin/su -+# group_transition_deny evilhacker1 evilhacker2 -+# -+# New learning system: -+# To learn on a given subject: add l (the letter l, not the number 1) -+# to the subject mode -+# To learn on a given role, add l to the role mode -+# For both of these, to enable learning, enable the system like: -+# gradm -L /etc/grsec/learning.logs -E -+# and then generate the rules after disabling the system after the -+# learning phase with: -+# gradm -L /etc/grsec/learning.logs -O /etc/grsec/acl -+# To use full system learning, enable the system like: -+# gradm -F -L /etc/grsec/learning.logs -+# and then generate the rules after disabling the system after the -+# learning phase with: -+# gradm -F -L /etc/grsec/learning.logs -O /etc/grsec/acl + current->thread.saved_esp0 = 0; + ret = KVM86->regs32; + return ret; +@@ -239,6 +254,11 @@ out: + static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk) + { + struct tss_struct *tss; + -+role admin sA -+subject / r -+ / rwcdmxi ++#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC ++ unsigned long flags, cr3; ++#endif + -+role default G -+role_transitions admin -+subject / -+ / r -+ /opt rx -+ /home rwxcd -+ /mnt rw -+ /dev -+ /dev/grsec h -+ /dev/urandom r -+ /dev/random r -+ /dev/zero rw -+ /dev/input rw -+ /dev/psaux rw -+ /dev/null rw -+ /dev/tty0 rw -+ /dev/tty1 rw -+ /dev/tty2 rw -+ /dev/tty3 rw -+ /dev/tty4 rw -+ /dev/tty5 rw -+ /dev/tty6 rw -+ /dev/tty7 rw -+ /dev/tty8 rw -+ /dev/console rw -+ /dev/tty rw -+ /dev/pts rw -+ /dev/ptmx rw -+ /dev/dsp rw -+ /dev/mixer rw -+ /dev/initctl rw -+ /dev/fd0 r -+ /dev/cdrom r -+ /dev/mem h -+ /dev/kmem h -+ /dev/port h -+ /bin rx -+ /sbin rx -+ /lib rx -+ /usr rx -+ /etc rx -+ /proc rwx -+ /proc/kcore h -+ /proc/sys r -+ /root r -+ /tmp rwcd -+ /var rwxcd -+ /var/tmp rwcd -+ /var/log r -+ /boot r -+ /etc/grsec h -+ /etc/ssh h -+ -+ -CAP_SYS_TTY_CONFIG -+ -CAP_LINUX_IMMUTABLE -+ -CAP_NET_RAW -+ -CAP_MKNOD -+ -CAP_SYS_ADMIN -+ -CAP_SYS_RAWIO -+ -CAP_SYS_MODULE -+ -CAP_SYS_PTRACE -+ -CAP_NET_ADMIN -+ -CAP_NET_BIND_SERVICE -+ -CAP_SYS_CHROOT + /* + * make sure the vm86() system call doesn't try to do anything silly + */ +@@ -280,8 +300,17 @@ static void do_sys_vm86(struct kernel_vm + info->regs32->eax = 0; + tsk->thread.saved_esp0 = tsk->thread.esp0; + tss = init_tss + smp_processor_id(); + -+# RES_AS 100M 100M ++#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC ++ pax_open_kernel(flags, cr3); ++#endif + -+# connect 192.168.1.0/24:22 stream tcp -+# bind 0.0.0.0 stream dgram tcp udp + tss->esp0 = tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0; + ++#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC ++ pax_close_kernel(flags, cr3); ++#endif + -+# the d flag protects /proc fd and mem entries for sshd -+subject /usr/sbin/sshd dp -+ /etc/ssh r -+ /dev/log rw -+ +CAP_SYS_TTY_CONFIG -+ +CAP_SYS_CHROOT + tsk->thread.screen_bitmap = info->screen_bitmap; + if (info->flags & VM86_SCREEN_BITMAP) + mark_screen_rdonly(tsk); +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/drivers/char/mem.c linux-2.4.20-wolk4.16-grsec2/drivers/char/mem.c +--- linux-2.4.20-wolk4.16-fullkernel/drivers/char/mem.c 2004-09-05 16:09:03.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/drivers/char/mem.c 2004-09-05 17:07:52.000000000 +0200 +@@ -41,7 +41,11 @@ extern void mda_console_init(void); + #if defined(CONFIG_S390_TAPE) && defined(CONFIG_S390_TAPE_CHAR) + extern void tapechar_init(void); + #endif +- + -diff -Naurp old/gradm2/gradm.8 new/gradm2/gradm.8 ---- old/gradm2/gradm.8 1970-01-01 01:00:00.000000000 +0100 -+++ new/gradm2/gradm.8 2003-08-20 13:33:45.000000000 +0200 -@@ -0,0 +1,136 @@ -+.TH GRADM 8 -+.SH NAME -+gradm \- Administration program for the grsecurity RBAC system -+.SH SYNOPSIS -+.B gradm -+[ -+.B \-E -+] -+[ -+.B \-R -+] -+[ -+.B \-F -+] -+[ -+.B \-L -+] -+[ -+.B \-O -+] -+[ -+.B \-M -+ -+] -+[ -+.B \-D -+] -+[ -+.B \-P [rolename] -+] -+[ -+.B \-a -+] -+[ -+.B \-n -+] -+[ -+.B \-u -+] -+[ -+.B \-h -+] -+[ -+.B \-v -+] ++#ifdef CONFIG_GRKERNSEC ++extern struct file_operations grsec_fops; ++#endif + -+.SH DESCRIPTION + /* RSBAC */ + #ifdef CONFIG_RSBAC + #include +@@ -770,6 +774,11 @@ static int memory_open(struct inode * in + case 10: + filp->f_op = &anon_file_operations; + break; ++#ifdef CONFIG_GRKERNSEC ++ case 12: ++ filp->f_op = &grsec_fops; ++ break; ++#endif + default: + return -ENXIO; + } +@@ -797,7 +806,10 @@ void __init memory_devfs_register (void) + {7, "full", S_IRUGO | S_IWUGO, &full_fops}, + {8, "random", S_IRUGO | S_IWUSR, &random_fops}, + {9, "urandom", S_IRUGO | S_IWUSR, &urandom_fops}, +- {10, "anon", S_IRUGO | S_IWUSR, &anon_file_operations} ++ {10, "anon", S_IRUGO | S_IWUSR, &anon_file_operations}, ++#ifdef CONFIG_GRKERNSEC ++ {12, "grsec", S_IRUSR | S_IWUGO, &grsec_fops} ++#endif + }; + int i; + +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/drivers/char/vt.c linux-2.4.20-wolk4.16-grsec2/drivers/char/vt.c +--- linux-2.4.20-wolk4.16-fullkernel/drivers/char/vt.c 2004-09-05 16:05:31.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/drivers/char/vt.c 2004-09-05 17:07:52.000000000 +0200 +@@ -179,6 +179,11 @@ do_kdsk_ioctl(int cmd, struct kbentry *u + case KDSKBENT: + if (!perm) + return -EPERM; ++#ifdef CONFIG_GRKERNSEC ++ if (!capable(CAP_SYS_TTY_CONFIG)) ++ return -EPERM; ++#endif + -+.I gradm -+is the userspace ACL parsing and authentication program for the -+.I grsecurity -+Access Control List System. + if (!i && v == K_NOSUCHMAP) { + /* disallocate map */ + key_map = key_maps[s]; +@@ -301,6 +306,11 @@ do_kdgkb_ioctl(int cmd, struct kbsentry + if (!perm) + return -EPERM; + ++#ifdef CONFIG_GRKERNSEC ++ if (!capable(CAP_SYS_TTY_CONFIG)) ++ return -EPERM; ++#endif + -+grsecurity aims to be a complete security system for Linux 2.4. gradm -+performs several tasks for the RBAC system including authenticated via a -+password to the kernel and parsing rules to be passed to the kernel. + q = func_table[i]; + first_free = funcbufptr + (funcbufsize - funcbufleft); + for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++) +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/fs/binfmt_elf.c linux-2.4.20-wolk4.16-grsec2/fs/binfmt_elf.c +--- linux-2.4.20-wolk4.16-fullkernel/fs/binfmt_elf.c 2004-09-05 16:08:32.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/fs/binfmt_elf.c 2004-09-05 17:07:53.000000000 +0200 +@@ -897,8 +897,6 @@ static int load_elf_binary(struct linux_ + } + #endif + +- gr_set_pax_flags(current); +- + elf_entry = (unsigned long) elf_ex.e_entry; + + /* Do this so that we can load the interpreter, if need be. We will +@@ -1079,7 +1077,7 @@ static int load_elf_binary(struct linux_ + #endif + + if (current->flags & PF_PAX_RANDMMAP) +- elf_brk += pax_delta_mask(get_random_long(), 4, PAGE_SHIFT); ++ elf_brk += PAGE_SIZE + pax_delta_mask(get_random_long(), 4, PAGE_SHIFT); + #undef pax_delta_mask + #endif + +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/fs/exec.c linux-2.4.20-wolk4.16-grsec2/fs/exec.c +--- linux-2.4.20-wolk4.16-fullkernel/fs/exec.c 2004-09-05 16:08:32.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/fs/exec.c 2004-09-05 17:07:52.000000000 +0200 +@@ -914,9 +914,6 @@ int prepare_binprm(struct linux_binprm * + cap_set_full(bprm->cap_effective); + } + +- if (gr_handle_ptrace_exec(bprm->file->f_dentry, bprm->file->f_vfsmnt)) +- return -EACCES; +- + memset(bprm->buf,0,BINPRM_BUF_SIZE); + return kernel_read(bprm->file,0,bprm->buf,BINPRM_BUF_SIZE); + } +@@ -979,8 +976,11 @@ void compute_creds(struct linux_binprm * + + /* AUD: Audit candidate if current->cap_effective is set */ + +- current->suid = current->euid = current->fsuid = bprm->e_uid; +- current->sgid = current->egid = current->fsgid = bprm->e_gid; ++ if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid)) ++ current->suid = current->euid = current->fsuid = bprm->e_uid; + -+.SH OPTIONS -+.TP ++ if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid)) ++ current->sgid = current->egid = current->fsgid = bprm->e_gid; + + gr_handle_chroot_caps(current); + +@@ -1248,7 +1248,9 @@ int do_execve(char * filename, char ** a + current->exec_file = file; + #endif + +- gr_set_proc_label(file->f_dentry, file->f_vfsmnt); ++ retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt); ++ if (retval < 0) ++ goto out_fail; + + retval = search_binary_handler(&bprm,regs); + if (retval >= 0) { +@@ -1284,6 +1286,7 @@ int do_execve(char * filename, char ** a + } + } + ++out_fail: + #ifdef CONFIG_GRKERNSEC + current->acl = old_acl; + memcpy(current->rlim, old_rlim, sizeof(old_rlim)); +@@ -1525,6 +1528,10 @@ int do_coredump(long signr, struct pt_re + if (!is_dumpable(current)) + goto fail; + current->mm->dumpable = 0; ++ ++ if (signr == SIGKILL || signr == SIGILL) ++ gr_handle_brute_attach(current); ++ + gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump, 1); + if (current->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump) + goto fail; +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/fs/fcntl.c linux-2.4.20-wolk4.16-grsec2/fs/fcntl.c +--- linux-2.4.20-wolk4.16-fullkernel/fs/fcntl.c 2004-09-05 16:05:23.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/fs/fcntl.c 2004-09-05 17:07:52.000000000 +0200 +@@ -65,10 +65,11 @@ static int locate_fd(struct files_struct + int error; + unsigned int start; + ++ gr_learn_resource(current, RLIMIT_NOFILE, orig_start, 0); + -+All options to gradm are mutually exclusive, except for -L and -O. -+.TP -+.B \-E -+Enable the RBAC system -+.TP + write_lock(&files->file_lock); + + error = -EINVAL; +- gr_learn_resource(current, RLIMIT_NOFILE, orig_start, 0); + if (orig_start >= current->rlim[RLIMIT_NOFILE].rlim_cur) + goto out; + +@@ -144,6 +145,8 @@ asmlinkage long sys_dup2(unsigned int ol + struct file * file, *tofree; + struct files_struct * files = current->files; + ++ gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0); + -+.B \-R -+Reload the RBAC system (only valid while in admin mode) -+.TP + write_lock(&files->file_lock); + if (!(file = fcheck(oldfd))) + goto out_unlock; +@@ -151,7 +154,6 @@ asmlinkage long sys_dup2(unsigned int ol + if (newfd == oldfd) + goto out_unlock; + err = -EBADF; +- gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0); + if (newfd >= current->rlim[RLIMIT_NOFILE].rlim_cur) + goto out_unlock; + get_file(file); /* We are now finished with oldfd */ +@@ -446,10 +448,6 @@ void send_sigio(struct fown_struct *fown + match = -p->pgrp; + if (pid != match) + continue; +- if (gr_check_protected_task(p)) +- continue; +- if (gr_pid_is_chrooted(p)) +- continue; + send_sigio_to_task(p, fown, fd, band); + } + out: +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/fs/namei.c linux-2.4.20-wolk4.16-grsec2/fs/namei.c +--- linux-2.4.20-wolk4.16-fullkernel/fs/namei.c 2004-09-05 16:06:25.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/fs/namei.c 2004-09-05 17:07:52.000000000 +0200 +@@ -1334,9 +1334,7 @@ int open_namei(const char * pathname, in + if (error) + return error; + +- if (gr_acl_is_enabled() && nd->dentry->d_inode && +- S_ISBLK(nd->dentry->d_inode->i_mode) && +- !capable(CAP_SYS_RAWIO)) { ++ if (gr_handle_rawio(nd->dentry->d_inode)) { + error = -EPERM; + goto exit; + } +@@ -1388,7 +1386,7 @@ do_last: + up(&dir->d_inode->i_sem); + goto exit_dput; + } +- if (!gr_acl_handle_creat(dentry, nd->dentry, nd->mnt, flag)) { ++ if (!gr_acl_handle_creat(dentry, nd->dentry, nd->mnt, flag, mode)) { + error = -EACCES; + up(&dir->d_inode->i_sem); + goto exit_dput; +@@ -1419,8 +1417,7 @@ do_last: + * It already exists. + */ + +- if (gr_acl_is_enabled() && S_ISBLK(dentry->d_inode->i_mode) && +- !capable(CAP_SYS_RAWIO)) { ++ if (gr_handle_rawio(dentry->d_inode)) { + error = -EPERM; + up(&dir->d_inode->i_sem); + goto exit_dput; +@@ -1874,7 +1871,7 @@ asmlinkage long sys_mknod(const char * f + goto out_dput; + } + +- if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt)) { ++ if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) { + error = -EACCES; + dput(dentry); + goto out_dput; +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/fs/open.c linux-2.4.20-wolk4.16-grsec2/fs/open.c +--- linux-2.4.20-wolk4.16-fullkernel/fs/open.c 2004-09-05 16:06:32.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/fs/open.c 2004-09-05 17:07:52.000000000 +0200 +@@ -726,7 +726,7 @@ asmlinkage long sys_fchmod(unsigned int + if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) + goto out_putf; + +- if (!gr_acl_handle_fchmod(dentry, file->f_vfsmnt)) { ++ if (!gr_acl_handle_fchmod(dentry, file->f_vfsmnt, mode)) { + err = -EACCES; + goto out_putf; + } +@@ -776,7 +776,7 @@ asmlinkage long sys_chmod(const char * f + if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) + goto dput_and_out; + +- if (!gr_acl_handle_chmod(nd.dentry, nd.mnt)) { ++ if (!gr_acl_handle_chmod(nd.dentry, nd.mnt, mode)) { + error = -EACCES; + goto dput_and_out; + } +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/fs/proc/base.c linux-2.4.20-wolk4.16-grsec2/fs/proc/base.c +--- linux-2.4.20-wolk4.16-fullkernel/fs/proc/base.c 2004-09-05 16:09:03.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/fs/proc/base.c 2004-09-05 17:07:52.000000000 +0200 +@@ -248,7 +248,8 @@ static int proc_root_link(struct inode * + #define MAY_PTRACE(task) \ + (task == current || \ + (task->p_pptr == current && \ +- (task->ptrace & PT_PTRACED) && task->state == TASK_STOPPED)) ++ (task->ptrace & PT_PTRACED) && task->state == TASK_STOPPED && \ ++ !gr_handle_proc_ptrace(task))) + + static int may_ptrace_attach(struct task_struct *task) + { +@@ -267,6 +268,8 @@ static int may_ptrace_attach(struct task + rmb(); + if (!is_dumpable(task) && !capable(CAP_SYS_PTRACE)) + goto out; ++ if (gr_handle_proc_ptrace(task)) ++ goto out; + + retval = 1; + +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/Makefile linux-2.4.20-wolk4.16-grsec2/gradm2/Makefile +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/Makefile 2004-09-05 17:07:53.000000000 +0200 +@@ -0,0 +1,131 @@ ++############################################################################## ++#gradm (c) 2002,2003,2004 Brad Spengler http://grsecurity.net# ++#-------------------------------------- ---------------------# ++#gradm is licensed under the GNU GPL http://www.gnu.org # ++############################################################################## + -+.B \-F -+Toggle full learning mode. -+If used only with -L, it enables the RBAC system in full learning -+mode. -+If used with -L and -O, it parses the full learning logs and -+generates a complete ruleset. -+.TP ++GRADM_BIN=gradm2 ++GRSEC_DIR=/etc/grsec2 + -+.B \-M -+Remove an execution ban on a given uid or filename that has been -+put in place by the RES_CRASH resource restriction of the RBAC system. -+.TP ++LEX=/usr/bin/lex ++FLEX=/usr/bin/flex ++LEXFLAGS=-B ++YACC=/usr/bin/yacc ++BYACC=/usr/bin/byacc ++BISON=/usr/bin/bison ++MKNOD=/bin/mknod ++#for dietlibc ++#CC=/usr/bin/diet /usr/bin/gcc ++CC=/usr/bin/gcc ++FIND=/usr/bin/find ++STRIP=/usr/bin/strip ++KERNVER=`uname -r | cut -d"." -f 2` ++LIBS = $(shell if [ "`uname -m`" != "sparc64" ]; then echo "-lfl" ; else echo "" ; fi) ++OPT_FLAGS = $(shell if [ "`uname -m`" != "sparc64" ]; then echo "-O2" ; else echo "-O2 -m64" ; fi) ++CFLAGS=$(OPT_FLAGS) -DGRSEC_DIR=\"$(GRSEC_DIR)\" -DKERNVER=$(KERNVER) ++LDFLAGS= ++INSTALL = /usr/bin/install -c + -+.B \-L -+Parses the learning logs. Accepts an argument which -+specifies the logfile to scan for the learning logs. ++# FHS ++MANDIR=/usr/share/man ++# older MANDIR ++#MANDIR=/usr/man ++DESTDIR= ++ ++OBJECTS=gradm.tab.o lex.gradm.o learn_pass1.tab.o learn_pass2.tab.o \ ++ fulllearn_pass1.tab.o fulllearn_pass2.tab.o fulllearn_pass3.tab.o \ ++ gradm_misc.o gradm_parse.o gradm_arg.o gradm_pw.o gradm_opt.o \ ++ gradm_cap.o gradm_sha256.o gradm_adm.o gradm_analyze.o gradm_res.o \ ++ gradm_human.o gradm_learn.o gradm_net.o gradm_nest.o \ ++ gradm_sym.o gradm_newlearn.o gradm_fulllearn.o gradm_lib.o \ ++ lex.fulllearn_pass1.o lex.fulllearn_pass2.o \ ++ lex.fulllearn_pass3.o lex.learn_pass1.o lex.learn_pass2.o ++ ++all: $(USE_YACC) $(USE_LEX) $(GRADM_BIN) grlearn ++ ++USE_YACC = $(shell if [ -x $(BYACC) ]; then echo $(BYACC); \ ++ else if [ -x $(BISON) ]; then echo $(BISON) -y; \ ++ else if [ -x $(YACC) ]; then echo $(YACC); \ ++ else \ ++ echo "Bison/(b)yacc needs to be installed to compile gradm."; \ ++ exit 1; \ ++ fi;fi;fi) ++ ++USE_LEX = $(shell if [ -x $(FLEX) ]; then echo $(FLEX); \ ++ else if [ -x $(LEX) ]; then echo $(LEX); \ ++ else \ ++ echo "(f)Lex needs to be installed to compile gradm."; \ ++ exit 1; \ ++ fi;fi) ++ ++$(GRADM_BIN): $(OBJECTS) ++ $(CC) $(CFLAGS) -o $@ $(OBJECTS) $(LIBS) $(LDFLAGS) ++ ++grlearn: grlearn.c gradm_lib.c ++ $(CC) $(CFLAGS) -o $@ grlearn.c gradm_lib.c $(LIBS) $(LDFLAGS) ++ ++ ++gradm.tab.c: gradm.y ++ $(USE_YACC) -b gradm -p gradm -d ./gradm.y ++ ++lex.gradm.c: gradm.l ++ $(USE_LEX) $(LEXFLAGS) -Pgradm ./gradm.l ++ ++fulllearn_pass1.tab.c: gradm_fulllearn_pass1.y ++ $(USE_YACC) -b fulllearn_pass1 -p fulllearn_pass1 -d ./gradm_fulllearn_pass1.y ++fulllearn_pass2.tab.c: gradm_fulllearn_pass2.y ++ $(USE_YACC) -b fulllearn_pass2 -p fulllearn_pass2 -d ./gradm_fulllearn_pass2.y ++fulllearn_pass3.tab.c: gradm_fulllearn_pass3.y ++ $(USE_YACC) -b fulllearn_pass3 -p fulllearn_pass3 -d ./gradm_fulllearn_pass3.y ++ ++lex.fulllearn_pass1.c: gradm_fulllearn_pass1.l ++ $(USE_LEX) $(LEXFLAGS) -Pfulllearn_pass1 ./gradm_fulllearn_pass1.l ++lex.fulllearn_pass2.c: gradm_fulllearn_pass2.l ++ $(USE_LEX) $(LEXFLAGS) -Pfulllearn_pass2 ./gradm_fulllearn_pass2.l ++lex.fulllearn_pass3.c: gradm_fulllearn_pass3.l ++ $(USE_LEX) $(LEXFLAGS) -Pfulllearn_pass3 ./gradm_fulllearn_pass3.l ++ ++learn_pass1.tab.c: gradm_learn_pass1.y ++ $(USE_YACC) -b learn_pass1 -p learn_pass1 -d ./gradm_learn_pass1.y ++learn_pass2.tab.c: gradm_learn_pass2.y ++ $(USE_YACC) -b learn_pass2 -p learn_pass2 -d ./gradm_learn_pass2.y ++ ++lex.learn_pass1.c: gradm_learn_pass1.l ++ $(USE_LEX) $(LEXFLAGS) -Plearn_pass1 ./gradm_learn_pass1.l ++lex.learn_pass2.c: gradm_learn_pass2.l ++ $(USE_LEX) $(LEXFLAGS) -Plearn_pass2 ./gradm_learn_pass2.l ++ ++install: $(GRADM_BIN) gradm.8 policy grlearn ++ mkdir -p $(DESTDIR)/sbin ++ $(INSTALL) -m 0755 $(GRADM_BIN) $(DESTDIR)/sbin ++ $(STRIP) $(DESTDIR)/sbin/$(GRADM_BIN) ++ $(INSTALL) -m 0700 grlearn $(DESTDIR)/sbin ++ $(STRIP) $(DESTDIR)/sbin/grlearn ++ mkdir -p -m 700 $(DESTDIR)$(GRSEC_DIR) ++ if [ -f $(DESTDIR)$(GRSEC_DIR)/acl ] ; then \ ++ if [ -f $(DESTDIR)$(GRSEC_DIR)/acl ] ; then \ ++ mv $(DESTDIR)$(GRSEC_DIR)/acl $(DESTDIR)$(GRSEC_DIR)/policy ; \ ++ else \ ++ $(INSTALL) -m 0600 policy $(DESTDIR)$(GRSEC_DIR) ; \ ++ fi \ ++ fi ++ @if [ -z "`cut -d" " -f3 /proc/mounts | grep "^devfs"`" ] ; then \ ++ rm -f $(DESTDIR)/dev/grsec ; \ ++ if [ ! -e $(DESTDIR)/dev/grsec ] ; then \ ++ mkdir -p $(DESTDIR)/dev ; \ ++ $(MKNOD) -m 0622 $(DESTDIR)/dev/grsec c 1 12 ; \ ++ fi \ ++ fi ++ mkdir -p $(DESTDIR)$(MANDIR)/man8 ++ $(INSTALL) -m 0644 gradm.8 $(DESTDIR)$(MANDIR)/man8/$(GRADM_BIN).8 ++ @if [ -z $(DESTDIR) ] ; then \ ++ if [ -x /sbin/$(GRADM_BIN) ] ; then \ ++ $(FIND) $(GRSEC_DIR) -type f -name pw -size 48c -exec rm -f $(GRSEC_DIR)/pw \; ; \ ++ if [ ! -f $(GRSEC_DIR)/pw ] ; then \ ++ /sbin/$(GRADM_BIN) -P ; \ ++ fi \ ++ fi \ ++ fi ++ ++clean: ++ rm -f core *.o $(GRADM_BIN) lex.*.c *.tab.c *.tab.h grlearn +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/debian/changelog linux-2.4.20-wolk4.16-grsec2/gradm2/debian/changelog +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/debian/changelog 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/debian/changelog 2004-09-05 17:07:53.000000000 +0200 +@@ -0,0 +1,20 @@ ++gradm2 (2.0.1-1) unstable; urgency=medium ++ ++ * New upstream release, grsec device is now 'c 1 12' and _not_ 'c 1 10'; ++ thus recreate it if it exists with the wrong minor number. ++ * Added Dutch Debconf translation, thanks to Luk Claes ++ ! ++ ++ -- László Böszörményi (GCS) Mon, 16 Aug 2004 23:01:54 +0000 ++ ++gradm2 (2.0-1) unstable; urgency=low ++ ++ * Initial release (closes: #244094). ++ * Changed binary name to gradm2 and config dir to /etc/gradm2 , not to ++ conflict with the gradm package, as one may need both on dual boot ++ setups. ++ * Renamed /etc/gradm2/acl to /etc/gradm2/policy as well, as now it is ++ required upstream. ++ * Backport amd64 compile fix from upstream CVS. ++ ++ -- László Böszörményi (GCS) Sat, 24 Apr 2004 19:19:02 +0000 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/debian/config linux-2.4.20-wolk4.16-grsec2/gradm2/debian/config +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/debian/config 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/debian/config 2004-09-05 17:07:53.000000000 +0200 +@@ -0,0 +1,13 @@ ++#!/bin/sh -e ++ ++. /usr/share/debconf/confmodule ++ ++# Check for configure time ++if [ "$1" = configure -o "$1" = reconfigure ]; then ++ db_version 2.0 ++ db_input medium gradm2/create_dev_grsec || true ++ db_go ++fi ++ ++ ++exit 0 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/debian/control linux-2.4.20-wolk4.16-grsec2/gradm2/debian/control +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/debian/control 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/debian/control 2004-09-05 17:07:53.000000000 +0200 +@@ -0,0 +1,16 @@ ++Source: gradm2 ++Section: admin ++Priority: optional ++Maintainer: László Böszörményi (GCS) ++Build-Depends: debhelper (>> 4.0.0), bison, flex ++Standards-Version: 3.6.1 ++ ++Package: gradm2 ++Architecture: any ++Suggests: kernel-patch-grsecurity2 ++Depends: ${misc:Depends} ++Description: Administration program for the grsecurity2 RBAC based ACL system ++ Used to manage the RBAC based ACL system of grsecurity2. Please note that you ++ will need a specially patched kernel for grsecurity to work (see the ++ kernel-patch-grsecurity2 Debian package). You can find more information ++ about grsecurity at http://www.grsecurity.net/ +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/debian/copyright linux-2.4.20-wolk4.16-grsec2/gradm2/debian/copyright +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/debian/copyright 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/debian/copyright 2004-09-05 17:07:53.000000000 +0200 +@@ -0,0 +1,23 @@ ++This package was debianized by LA¡szlA¶szA¶rmACnyi (GCS) on ++at, 24 Apr 2004 20:19:02 CET ++ ++It was downloaded from: http://www.grsecurity.net/download.php ++ ++Upstream Authors: Brad Spender ++ ++Copyright: ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ ++The complete license can be found at '/usr/share/common-licenses/GPL-2'. +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/debian/grlearn.8 linux-2.4.20-wolk4.16-grsec2/gradm2/debian/grlearn.8 +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/debian/grlearn.8 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/debian/grlearn.8 2004-09-05 17:07:53.000000000 +0200 +@@ -0,0 +1,26 @@ ++.TH GRLEARN 8 ++.SH NAME ++grlearn \- Automatic learning daemon for grsecurity RBAC system ++.SH SYNOPSIS ++.B grlearn ++[ ++.B logfile ++] ++ ++.SH DESCRIPTION ++.I grlearn ++is a daemon for automaticaly create minimalistic learnt access configuration ++for the grsecurity RBAC system. ++ ++.SH BUGS ++This package is by no means complete. ++ ++.SH REPORTING BUGS ++Please include as much information as possible(using any available debugging ++options) and send bug reports for gradm2 or the grsecurity RBAC system ++to ++.B dev@grsecurity.net. ++ ++.SH AUTHOR ++.B grsecurity and grlearn ++were created and are maintained by Brad Spengler +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/debian/lintian.overrides linux-2.4.20-wolk4.16-grsec2/gradm2/debian/lintian.overrides +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/debian/lintian.overrides 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/debian/lintian.overrides 2004-09-05 17:07:53.000000000 +0200 +@@ -0,0 +1 @@ ++gradm2: mknod-in-maintainer-script +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/debian/po/POTFILES.in linux-2.4.20-wolk4.16-grsec2/gradm2/debian/po/POTFILES.in +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/debian/po/POTFILES.in 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/debian/po/POTFILES.in 2004-09-05 17:07:53.000000000 +0200 +@@ -0,0 +1 @@ ++[type: gettext/rfc822deb] templates +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/debian/po/hu.po linux-2.4.20-wolk4.16-grsec2/gradm2/debian/po/hu.po +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/debian/po/hu.po 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/debian/po/hu.po 2004-09-05 17:07:53.000000000 +0200 +@@ -0,0 +1,42 @@ ++# ++# Translators, if you are not familiar with the PO format, gettext ++# documentation is worth reading, especially sections dedicated to ++# this format, e.g. by running: ++# info -n '(gettext)PO Files' ++# info -n '(gettext)Header Entry' ++# ++# Some information specific to po-debconf are available at ++# /usr/share/doc/po-debconf/README-trans ++# or http://www.debian.org/intl/l10n/po-debconf/README-trans ++# ++# Developers do not need to manually edit POT or PO files. ++# ++msgid "" ++msgstr "" ++"Project-Id-Version: PACKAGE VERSION\n" ++"Report-Msgid-Bugs-To: \n" ++"POT-Creation-Date: 2004-07-04 12:45+0000\n" ++"PO-Revision-Date: 2004-07-28 22:25+0100\n" ++"Last-Translator: László 'GCS' Böszörményi \n" ++"Language-Team: LANGUAGE \n" ++"MIME-Version: 1.0\n" ++"Content-Type: text/plain; charset=iso-8859-1\n" ++"Content-Transfer-Encoding: 8bit\n" ++ ++#. Type: note ++#. Description ++#: ../templates:3 ++msgid "gradm2 needs a device entry " ++msgstr "A gradm2-nek szüksége van egy eszközbejegyzésre" ++ ++#. Type: note ++#. Description ++#: ../templates:3 ++msgid "" ++"gradm2 needs a special entry, a device called /dev/grsec to communicate with " ++"the kernel. It will be created for you if you don't already have it and you " ++"don't have devfs or udev." ++msgstr "" ++"A gradm2-nek szükséges egy speciális bejegyzés, egy eszköz amit /dev/grsec -" ++"nek hívnak. Ez létre lesz hozva, ha még nem létezik, és nem devfs-t vagy " ++"udev-et használ." +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/debian/po/nl.po linux-2.4.20-wolk4.16-grsec2/gradm2/debian/po/nl.po +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/debian/po/nl.po 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/debian/po/nl.po 2004-09-05 17:07:53.000000000 +0200 +@@ -0,0 +1,39 @@ ++# info -n '(gettext)PO Files' ++# info -n '(gettext)Header Entry' ++# ++# Some information specific to po-debconf are available at ++# /usr/share/doc/po-debconf/README-trans ++# or http://www.debian.org/intl/l10n/po-debconf/README-trans ++# ++# Developers do not need to manually edit POT or PO files. ++# ++msgid "" ++msgstr "" ++"Project-Id-Version: gradm2 2.0-1\n" ++"Report-Msgid-Bugs-To: \n" ++"POT-Creation-Date: 2004-07-04 12:45+0000\n" ++"PO-Revision-Date: 2004-08-11 17:13+0100\n" ++"Last-Translator: Luk Claes \n" ++"Language-Team: Debian l10n Dutch \n" ++"MIME-Version: 1.0\n" ++"Content-Type: text/plain; charset=iso-8859-1\n" ++"Content-Transfer-Encoding: 8bit\n" ++ ++#. Type: note ++#. Description ++#: ../templates:3 ++msgid "gradm2 needs a device entry " ++msgstr "gradm2 heeft een apparaat (device) nodig" ++ ++#. Type: note ++#. Description ++#: ../templates:3 ++#, fuzzy ++msgid "" ++"gradm2 needs a special entry, a device called /dev/grsec to communicate with " ++"the kernel. It will be created for you if you don't already have it and you " ++"don't have devfs or udev." ++msgstr "" ++"gradm2 heeft een speciaal apparaat nodig, genaamd /dev/grsec, om te " ++"communiceren met de kernel. Het zal voor u worden aangemaakt als u het nog " ++"niet heeft en u geen devfs heeft." +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/debian/po/templates.pot linux-2.4.20-wolk4.16-grsec2/gradm2/debian/po/templates.pot +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/debian/po/templates.pot 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/debian/po/templates.pot 2004-09-05 17:07:53.000000000 +0200 +@@ -0,0 +1,40 @@ ++# ++# Translators, if you are not familiar with the PO format, gettext ++# documentation is worth reading, especially sections dedicated to ++# this format, e.g. by running: ++# info -n '(gettext)PO Files' ++# info -n '(gettext)Header Entry' ++# ++# Some information specific to po-debconf are available at ++# /usr/share/doc/po-debconf/README-trans ++# or http://www.debian.org/intl/l10n/po-debconf/README-trans ++# ++# Developers do not need to manually edit POT or PO files. ++# ++#, fuzzy ++msgid "" ++msgstr "" ++"Project-Id-Version: PACKAGE VERSION\n" ++"Report-Msgid-Bugs-To: \n" ++"POT-Creation-Date: 2004-07-04 12:45+0000\n" ++"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" ++"Last-Translator: FULL NAME \n" ++"Language-Team: LANGUAGE \n" ++"MIME-Version: 1.0\n" ++"Content-Type: text/plain; charset=CHARSET\n" ++"Content-Transfer-Encoding: 8bit\n" ++ ++#. Type: note ++#. Description ++#: ../templates:3 ++msgid "gradm2 needs a device entry " ++msgstr "" ++ ++#. Type: note ++#. Description ++#: ../templates:3 ++msgid "" ++"gradm2 needs a special entry, a device called /dev/grsec to communicate with " ++"the kernel. It will be created for you if you don't already have it and you " ++"don't have devfs or udev." ++msgstr "" +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/debian/postinst linux-2.4.20-wolk4.16-grsec2/gradm2/debian/postinst +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/debian/postinst 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/debian/postinst 2004-09-05 17:07:53.000000000 +0200 +@@ -0,0 +1,13 @@ ++#!/bin/sh -e ++ ++. /usr/share/debconf/confmodule ++ ++if [ "$1" = configure ]; then ++ if [ ! -c /dev/grsec ] && [ ! -c /dev/.devfsd ] && [ ! -f /dev/.udev.tdb ]; then ++ mknod -m 0622 /dev/grsec c 1 12 || true ++ fi ++fi ++ ++#DEBHELPER# ++ ++exit 0 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/debian/preinst linux-2.4.20-wolk4.16-grsec2/gradm2/debian/preinst +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/debian/preinst 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/debian/preinst 2004-09-05 17:07:53.000000000 +0200 +@@ -0,0 +1,13 @@ ++#!/bin/sh -e ++ ++. /usr/share/debconf/confmodule ++ ++if [ "$1" = install ] || [ "$1" = upgrade ]; then ++ if [ -c /dev/grsec ] && [ `ls -l /dev/grsec | tr -s ' ' | cut -f6 -d' '` = 10 ]; then ++ rm -f /dev/grsec ++ fi ++fi ++ ++#DEBHELPER# ++ ++exit 0 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/debian/rules linux-2.4.20-wolk4.16-grsec2/gradm2/debian/rules +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/debian/rules 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/debian/rules 2004-09-05 17:07:53.000000000 +0200 +@@ -0,0 +1,67 @@ ++#!/usr/bin/make -f ++# Uncomment this to turn on verbose mode. ++#export DH_VERBOSE=1 ++ ++export DH_COMPAT=4 ++ ++BUILDDIR=$(CURDIR)/debian/gradm2 ++ ++# These are used for cross-compiling and for saving the configure script ++# from having to guess our platform (since we know it already) ++DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) ++DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) ++ ++ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS))) ++ CFLAGS += -g ++endif ++ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS))) ++ INSTALL_PROGRAM += -s ++endif ++ ++debian/po/templates.pot: debian/templates ++ @debconf-updatepo ++ ++clean: debian/po/templates.pot ++ dh_testdir ++ ++ rm -f build-stamp install-stamp ++ $(MAKE) clean ++ dh_clean ++ ++build: build-stamp ++ ++build-stamp: ++ dh_testdir ++ ++ $(MAKE) ++ touch $@ ++ ++install: install-stamp ++ ++install-stamp: build ++ dh_testdir ++ ++ $(MAKE) install DESTDIR=$(BUILDDIR) ++ rm -rf $(BUILDDIR)/dev/ ++ install -d $(BUILDDIR)/usr/share/lintian/overrides/ ++ install -m0644 $(CURDIR)/debian/lintian.overrides $(BUILDDIR)/usr/share/lintian/overrides/gradm2 ++ touch $@ ++ ++binary-indep: build install ++ ++binary-arch: build install ++ dh_testdir ++ dh_installdebconf ++ dh_installdocs ++ dh_installman debian/grlearn.8 ++ dh_installchangelogs ++ dh_compress ++ dh_strip ++ dh_fixperms ++ dh_installdeb ++ dh_gencontrol ++ dh_md5sums ++ dh_builddeb ++ ++binary: binary-indep binary-arch ++.PHONY: clean build binary-indep binary-arch binary install +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/debian/templates linux-2.4.20-wolk4.16-grsec2/gradm2/debian/templates +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/debian/templates 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/debian/templates 2004-09-05 17:07:53.000000000 +0200 +@@ -0,0 +1,6 @@ ++Template: gradm2/create_dev_grsec ++Type: note ++_Description: gradm2 needs a device entry ++ gradm2 needs a special entry, a device called /dev/grsec to communicate with ++ the kernel. It will be created for you if you don't already have it and you ++ don't have devfs or udev. +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm.8 linux-2.4.20-wolk4.16-grsec2/gradm2/gradm.8 +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm.8 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/gradm.8 2004-09-05 17:07:53.000000000 +0200 +@@ -0,0 +1,135 @@ ++.TH GRADM 8 ++.SH NAME ++gradm \- Administration program for the grsecurity RBAC system ++.SH SYNOPSIS ++.B gradm ++[ ++.B \-E ++] ++[ ++.B \-R ++] ++[ ++.B \-F ++] ++[ ++.B \-L ++] ++[ ++.B \-O ++] ++[ ++.B \-M ++ ++] ++[ ++.B \-D ++] ++[ ++.B \-P [rolename] ++] ++[ ++.B \-a ++] ++[ ++.B \-n ++] ++[ ++.B \-u ++] ++[ ++.B \-h ++] ++[ ++.B \-v ++] ++ ++.SH DESCRIPTION ++ ++.I gradm ++is the userspace RBAC parsing and authentication program for ++.I grsecurity ++ ++grsecurity aims to be a complete security system for Linux 2.4. gradm ++performs several tasks for the RBAC system including authenticated via a ++password to the kernel and parsing rules to be passed to the kernel. ++ ++.SH OPTIONS ++.TP ++ ++All options to gradm are mutually exclusive, except for -L and -O. ++.TP ++.B \-E ++Enable the RBAC system ++.TP ++ ++.B \-R ++Reload the RBAC system (only valid while in admin mode) ++.TP ++ ++.B \-F ++Toggle full learning mode. ++If used only with -L, it enables the RBAC system in full learning ++mode. ++If used with -L and -O, it parses the full learning logs and ++generates a complete ruleset. ++.TP ++ ++.B \-M ++Remove an execution ban on a given uid or filename that has been ++put in place by the RES_CRASH resource restriction of the RBAC system. ++.TP ++ ++.B \-L ++Parses the learning logs. Accepts an argument which ++specifies the logfile to scan for the learning logs. +This option can be used with -E, -O, or -F. +.TP + @@ -456,9 +1188,9 @@ diff -Naurp old/gradm2/gradm.8 new/gradm +.SH AUTHOR +.B grsecurity and gradm +were created and are maintained by Brad Spengler -diff -Naurp old/gradm2/gradm.h new/gradm2/gradm.h ---- old/gradm2/gradm.h 1970-01-01 01:00:00.000000000 +0100 -+++ new/gradm2/gradm.h 2004-06-23 22:55:46.000000000 +0200 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm.h linux-2.4.20-wolk4.16-grsec2/gradm2/gradm.h +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/gradm.h 2004-09-05 17:07:53.000000000 +0200 @@ -0,0 +1,79 @@ +#ifndef GRADM_H +#define GRADM_H @@ -539,10 +1271,10 @@ diff -Naurp old/gradm2/gradm.h new/gradm +#include "gradm_func.h" + +#endif -diff -Naurp old/gradm2/gradm.l new/gradm2/gradm.l ---- old/gradm2/gradm.l 1970-01-01 01:00:00.000000000 +0100 -+++ new/gradm2/gradm.l 2004-06-18 03:51:29.000000000 +0200 -@@ -0,0 +1,405 @@ +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm.l linux-2.4.20-wolk4.16-grsec2/gradm2/gradm.l +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm.l 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/gradm.l 2004-09-05 17:07:53.000000000 +0200 +@@ -0,0 +1,511 @@ +%{ +#include "gradm.h" +#include "gradm.tab.h" @@ -557,11 +1289,20 @@ diff -Naurp old/gradm2/gradm.l new/gradm +int is_eof(void); +void add_include(char *includename); + -+int include_stack_ptr = 0; -+unsigned long lineno_stack[MAX_INCLUDE_DEPTH]; -+YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH]; -+FILE *include_in[MAX_INCLUDE_DEPTH]; -+char *current_acl[MAX_INCLUDE_DEPTH]; ++struct include_entry { ++ unsigned long lineno; ++ YY_BUFFER_STATE buffer; ++ FILE *file; ++ char *name; ++ struct include_entry *prev; ++ struct include_entry *next; ++ struct include_entry *parent; ++ struct include_entry **stack; ++ int sp; ++}; ++ ++struct include_entry include_stack; ++struct include_entry *current_stack; + +%} + @@ -571,7 +1312,8 @@ diff -Naurp old/gradm2/gradm.l new/gradm + +%x ROLE_STATE SUBJECT_STATE IP_STATE RES_STATE COMMENT_STATE ROLETYPE_STATE +%x INCLUDE_STATE IPNETMASK_STATE IPPORT_STATE ROLETRANS_STATE -+%x VAR_STATE VAR_OBJ_STATE IDTRANS_STATE ++%x VAR_STATE VAR_OBJ_STATE IDTRANS_STATE DOMAIN_STATE DOMAINTYPE_STATE ++%x DOMAINLIST_STATE + +%% + @@ -594,11 +1336,25 @@ diff -Naurp old/gradm2/gradm.l new/gradm + gradmlval.string = strdup(yytext); + return ROLE_TYPE; + } ++([ug]l?)|(l?[ug]) { ++ BEGIN(DOMAINLIST_STATE); ++ gradmlval.string = strdup(yytext); ++ return DOMAIN_TYPE; ++ } +[_a-zA-Z0-9-]{1,30} { + BEGIN(ROLETYPE_STATE); + gradmlval.string = strdup(yytext); + return ROLE_NAME; + } ++[_a-zA-Z0-9-]{1,30} { ++ BEGIN(DOMAINTYPE_STATE); ++ gradmlval.string = strdup(yytext); ++ return ROLE_NAME; ++ } ++[_a-zA-Z0-9-]{1,30} { ++ gradmlval.string = strdup(yytext); ++ return ROLE_NAME; ++ } +[_a-zA-Z0-9-]{1,30} { + gradmlval.string = strdup(yytext); + return ROLE_NAME; @@ -741,6 +1497,10 @@ diff -Naurp old/gradm2/gradm.l new/gradm + BEGIN(ROLE_STATE); + return ROLE; + } ++"domain" { ++ BEGIN(DOMAIN_STATE); ++ return DOMAIN; ++ } +"role_allow_ip" { + BEGIN(IP_STATE); + return ROLE_ALLOW_IP; @@ -819,18 +1579,70 @@ diff -Naurp old/gradm2/gradm.l new/gradm + struct stat fstat; + FILE *tmpfile; + -+ if (include_stack_ptr >= MAX_INCLUDE_DEPTH) { ++ if (current_stack->sp >= MAX_INCLUDE_DEPTH) { + fprintf(stderr, "Includes too deep while trying to process " + "%s\n", includename); + exit(EXIT_FAILURE); + } + ++ current_stack->stack = realloc(current_stack->stack, (1 + current_stack->sp) * sizeof(struct include_entry *)); ++ if (current_stack->stack == NULL) ++ failure("realloc"); ++ current_stack->stack[current_stack->sp] = calloc(1, sizeof(struct include_entry)); ++ if (current_stack->stack[current_stack->sp] == NULL) ++ failure("calloc"); ++ current_stack->stack[current_stack->sp]->lineno = lineno; ++ lineno = 1; ++ current_stack->stack[current_stack->sp]->file = yyin; ++ current_stack->stack[current_stack->sp]->name = current_acl_file; ++ current_stack->stack[current_stack->sp]->buffer = YY_CURRENT_BUFFER; ++ current_stack->stack[current_stack->sp]->parent = current_stack; ++ + if (!stat(includename, &fstat)) { + if (S_ISDIR(fstat.st_mode)) { -+ fprintf(stderr, "Error while including %s: " -+ "Directories cannot be specified by an " -+ "include directive.\n", includename); -+ exit(EXIT_FAILURE); ++ struct dirent **namelist; ++ struct include_entry *last = current_stack->stack[current_stack->sp]; ++ struct include_entry *tmp; ++ char *path; ++ int n; ++ ++ n = scandir(includename, &namelist, 0, alphasort); ++ if (n >= 3) { ++ while (n--) { ++ if (!strcmp(namelist[n]->d_name, ".") || !strcmp(namelist[n]->d_name, "..")) ++ continue; ++ tmp = calloc(1, sizeof(struct include_entry)); ++ if (tmp == NULL) ++ failure("calloc"); ++ ++ path = calloc(1, strlen(includename) + strlen(namelist[n]->d_name) + 2); ++ if (path == NULL) ++ failure("calloc"); ++ ++ sprintf(path, "%s/%s", includename, namelist[n]->d_name); ++ ++ tmp->name = path; ++ tmp->lineno = 1; ++ tmp->parent = current_stack; ++ ++ last->next = tmp; ++ tmp->prev = last; ++ last = tmp; ++ } ++ change_current_acl_file(tmp->name); ++ tmpfile = fopen(tmp->name, "r"); ++ ++ if (!tmpfile) { ++ fprintf(stderr, "Unable to open included file: %s\n", tmp->name); ++ exit(EXIT_FAILURE); ++ } ++ ++ yyin = tmpfile; ++ current_stack = tmp; ++ yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); ++ return; ++ } ++ return; + } + } + tmpfile = fopen(includename, "r"); @@ -841,12 +1653,8 @@ diff -Naurp old/gradm2/gradm.l new/gradm + exit(EXIT_FAILURE); + } + -+ lineno_stack[include_stack_ptr] = lineno; -+ lineno = 1; -+ include_in[include_stack_ptr] = yyin; -+ current_acl[include_stack_ptr] = current_acl_file; + change_current_acl_file(includename); -+ include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER; ++ current_stack->sp++; + yyin = tmpfile; + yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); + @@ -855,20 +1663,41 @@ diff -Naurp old/gradm2/gradm.l new/gradm + +int is_eof(void) +{ -+ if (include_stack_ptr) ++ if (current_stack->sp) + fclose(yyin); -+ if (--include_stack_ptr < 0) -+ { -+ include_stack_ptr = 0; -+ lineno = 1; -+ return 1; ++ current_stack->sp--; ++ if (current_stack->sp < 0) { ++ if (!current_stack->prev || !current_stack->prev->prev) { ++ if (current_stack->parent == NULL || current_stack->parent->name == NULL) { ++ current_stack->sp = 0; ++ lineno = 1; ++ return 1; ++ } else { ++ current_stack = current_stack->parent; ++ goto regular; ++ } ++ } else { ++ current_stack = current_stack->prev; ++ lineno = 1; ++ change_current_acl_file(current_stack->name); ++ yy_delete_buffer(YY_CURRENT_BUFFER); ++ yyin = fopen(current_stack->name, "r"); ++ if (yyin == NULL) { ++ fprintf(stderr, "Unable to open included file: %s\n", current_stack->name); ++ exit(EXIT_FAILURE); ++ } ++ yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); ++ return 0; ++ } + } + -+ change_current_acl_file(current_acl[include_stack_ptr]); ++regular: ++ change_current_acl_file(current_stack->stack[current_stack->sp]->name); + yy_delete_buffer(YY_CURRENT_BUFFER); -+ lineno = lineno_stack[include_stack_ptr]; -+ yyin = include_in[include_stack_ptr]; -+ yy_switch_to_buffer(include_stack[include_stack_ptr]); ++ lineno = current_stack->stack[current_stack->sp]->lineno; ++ yyin = current_stack->stack[current_stack->sp]->file; ++ yy_switch_to_buffer(current_stack->stack[current_stack->sp]->buffer); ++ + return 0; +} + @@ -897,30 +1726,15 @@ diff -Naurp old/gradm2/gradm.l new/gradm + return; +} + -+int main(int argc, char *argv[]) -+{ +#ifdef GRADM_DEBUG ++void show_policy(void) { + struct file_acl *filp; + struct proc_acl *proc; + struct role_acl *rolp; + struct role_transition *rolet; + extern struct rlimconv rlim_table[]; + int i; -+#endif -+ if (geteuid() != getuid()) { -+ fprintf(stderr, "gradm is not meant to run suid root.\n"); -+ exit(EXIT_FAILURE); -+ } -+ -+ special_role_uid = 0; -+ -+ no_coredump(); + -+ init_variables(); -+ -+ parse_args(argc, argv); -+ -+#ifdef GRADM_DEBUG + for (rolp = current_role;rolp;rolp=rolp->prev) { + printf("ROLE: %s type:%s uid/gid:%u\n", rolp->rolename, + rolp->roletype & GR_ROLE_SPECIAL ? "special" : @@ -936,7 +1750,7 @@ diff -Naurp old/gradm2/gradm.l new/gradm + printf("\tSUBJECT: %s dev:%d inode:%lu mode:%d c_raise:%x c_drop:%x\n", + proc->filename, proc->dev, proc->inode, proc->mode, ~proc->cap_drop, + proc->cap_drop); -+ if (!proc->ip_object) ++ if (!proc->ips) + printf("\t\tNo socket restrictions\n"); + for (filp = proc->hash->first;filp;filp=filp->prev) + printf("\t\tOBJECT: %s dev:%d inode:%lu mode:%d\n", filp->filename, filp->dev, filp->inode, filp->mode); @@ -945,13 +1759,37 @@ diff -Naurp old/gradm2/gradm.l new/gradm + printf("\t\t%s: soft: %lu hard: %lu\n", rlim_table[i].name, proc->res[i].rlim_cur, proc->res[i].rlim_max); + } + } ++} ++#endif ++ ++int main(int argc, char *argv[]) ++{ ++ if (geteuid() != getuid()) { ++ fprintf(stderr, "gradm is not meant to run suid root.\n"); ++ exit(EXIT_FAILURE); ++ } ++ ++ special_role_uid = 0; ++ ++ no_coredump(); ++ ++ current_stack = &include_stack; ++ memset(current_stack, 0, sizeof(struct include_entry)); ++ ++ init_variables(); ++ ++ parse_args(argc, argv); ++ ++#ifdef GRADM_DEBUG ++ show_policy(); +#endif + return 0; +} -diff -Naurp old/gradm2/gradm.y new/gradm2/gradm.y ---- old/gradm2/gradm.y 1970-01-01 01:00:00.000000000 +0100 -+++ new/gradm2/gradm.y 2004-03-08 01:22:08.000000000 +0100 -@@ -0,0 +1,337 @@ ++ +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm.y linux-2.4.20-wolk4.16-grsec2/gradm2/gradm.y +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm.y 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/gradm.y 2004-09-05 17:07:53.000000000 +0200 +@@ -0,0 +1,356 @@ +%{ +#include "gradm.h" + @@ -975,7 +1813,7 @@ diff -Naurp old/gradm2/gradm.y new/gradm +%token IPPROTO OBJ_MODE SUBJ_MODE IPNETMASK CAP_NAME ROLE_ALLOW_IP +%token ROLE_TRANSITION VARIABLE DEFINE DEFINE_NAME DISABLED +%token ID_NAME USER_TRANS_ALLOW GROUP_TRANS_ALLOW -+%token USER_TRANS_DENY GROUP_TRANS_DENY ++%token USER_TRANS_DENY GROUP_TRANS_DENY DOMAIN_TYPE DOMAIN +%type subj_mode obj_mode ip_netmask +%type role_type +%type variable_expression @@ -990,6 +1828,7 @@ diff -Naurp old/gradm2/gradm.y new/gradm + ; + +various_acls: role_label ++ | domain_label + | role_allow_ip + | role_transitions + | subject_label @@ -1057,6 +1896,24 @@ diff -Naurp old/gradm2/gradm.y new/gradm + } + ; + ++domain_label: DOMAIN ROLE_NAME DOMAIN_TYPE ++ { ++ if (!add_role_acl(¤t_role, $2, GR_ROLE_DOMAIN | role_mode_conv($3), 1)) ++ exit(EXIT_FAILURE); ++ } ++ domain_user_list ++ ; ++ ++domain_user_list: ROLE_NAME ++ { ++ add_domain_child(current_role, $1); ++ } ++ | domain_user_list ROLE_NAME ++ { ++ add_domain_child(current_role, $2); ++ } ++ ; ++ +role_label: ROLE ROLE_NAME role_type + { + if (!add_role_acl(¤t_role, $2, $3, 0)) @@ -1289,10 +2146,150 @@ diff -Naurp old/gradm2/gradm.y new/gradm + | ip_typeproto IPTYPE + { conv_name_to_type(&ip, $2); } + ; -diff -Naurp old/gradm2/gradm_adm.c new/gradm2/gradm_adm.c ---- old/gradm2/gradm_adm.c 1970-01-01 01:00:00.000000000 +0100 -+++ new/gradm2/gradm_adm.c 2004-06-23 22:55:46.000000000 +0200 -@@ -0,0 +1,246 @@ +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm2.8 linux-2.4.20-wolk4.16-grsec2/gradm2/gradm2.8 +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm2.8 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/gradm2.8 2004-09-05 17:07:53.000000000 +0200 +@@ -0,0 +1,136 @@ ++.TH GRADM2 8 ++.SH NAME ++gradm2 \- Administration program for the grsecurity RBAC system ++.SH SYNOPSIS ++.B gradm2 ++[ ++.B \-E ++] ++[ ++.B \-R ++] ++[ ++.B \-F ++] ++[ ++.B \-L ++] ++[ ++.B \-O ++] ++[ ++.B \-M ++ ++] ++[ ++.B \-D ++] ++[ ++.B \-P [rolename] ++] ++[ ++.B \-a ++] ++[ ++.B \-n ++] ++[ ++.B \-u ++] ++[ ++.B \-h ++] ++[ ++.B \-v ++] ++ ++.SH DESCRIPTION ++ ++.I gradm2 ++is the userspace ACL parsing and authentication program for the ++.I grsecurity ++Access Control List System. ++ ++grsecurity aims to be a complete security system for Linux 2.4. gradm2 ++performs several tasks for the RBAC system including authenticated via a ++password to the kernel and parsing rules to be passed to the kernel. ++ ++.SH OPTIONS ++.TP ++ ++All options to gradm2 are mutually exclusive, except for -L and -O. ++.TP ++.B \-E ++Enable the RBAC system ++.TP ++ ++.B \-R ++Reload the RBAC system (only valid while in admin mode) ++.TP ++ ++.B \-F ++Toggle full learning mode. ++If used only with -L, it enables the RBAC system in full learning ++mode. ++If used with -L and -O, it parses the full learning logs and ++generates a complete ruleset. ++.TP ++ ++.B \-M ++Remove an execution ban on a given uid or filename that has been ++put in place by the RES_CRASH resource restriction of the RBAC system. ++.TP ++ ++.B \-L ++Parses the learning logs. Accepts an argument which ++specifies the logfile to scan for the learning logs. ++This option can be used with -E, -O, or -F. ++.TP ++ ++.B \-O ++Specifies output mode. Requires a single argument that can be ++"stdout", "stderr", or a regular file. Only used with -L or -F. ++.TP ++ ++.B \-D ++Disable the RBAC system ++.TP ++ ++.B \-P [rolename] ++Without an argument, it sets the password for administering ++the RBAC system. With a role name as an argument, it sets ++the password for that given special role. ++.TP ++ ++.B \-a ++Authenticate to a special role that requires a password. ++.TP ++ ++.B \-n ++Authenticate to a special role that does not require a password. ++.TP ++ ++.B \-u ++Removes yourself from your current special role, reverting back ++to the normal role selection. To be used, for instance, for logging ++out of an admin role without exiting your shell. ++ ++.B \-h ++Display help information ++.TP ++ ++.B \-v ++Print version information and exit ++.TP ++ ++.BR ++ ++.SH REPORTING BUGS ++Please include as much information as possible(using any available debugging ++options) and send bug reports for gradm2 or the grsecurity RBAC system ++to ++.B dev@grsecurity.net. ++ ++.SH AUTHOR ++.B grsecurity and gradm2 ++were created and are maintained by Brad Spengler +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_adm.c linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_adm.c +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_adm.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_adm.c 2004-09-05 17:07:53.000000000 +0200 +@@ -0,0 +1,256 @@ +#include "gradm.h" + +int @@ -1389,6 +2386,10 @@ diff -Naurp old/gradm2/gradm_adm.c new/g + proc_object_mode_conv("r"), GR_FEXIST)) + exit(EXIT_FAILURE); + ++ if (!add_proc_object_acl(current_subject, "/etc/ld.so.preload", ++ proc_object_mode_conv("r"), GR_FEXIST)) ++ exit(EXIT_FAILURE); ++ + if (!add_proc_object_acl(current_subject, "/dev/urandom", + proc_object_mode_conv("r"), GR_FEXIST)) + exit(EXIT_FAILURE); @@ -1431,6 +2432,12 @@ diff -Naurp old/gradm2/gradm_adm.c new/g + (current_subject, "/", proc_object_mode_conv("rx"), GR_FEXIST)) + exit(EXIT_FAILURE); + if (!add_proc_object_acl ++ (current_subject, "/dev/tty", proc_object_mode_conv("rw"), GR_FEXIST)) ++ exit(EXIT_FAILURE); ++ if (!add_proc_object_acl ++ (current_subject, "/dev/null", proc_object_mode_conv("rw"), GR_FEXIST)) ++ exit(EXIT_FAILURE); ++ if (!add_proc_object_acl + (current_subject, "/etc/grsec", proc_object_mode_conv("h"), + GR_FEXIST)) + exit(EXIT_FAILURE); @@ -1539,9 +2546,9 @@ diff -Naurp old/gradm2/gradm_adm.c new/g + + return; +} -diff -Naurp old/gradm2/gradm_analyze.c new/gradm2/gradm_analyze.c ---- old/gradm2/gradm_analyze.c 1970-01-01 01:00:00.000000000 +0100 -+++ new/gradm2/gradm_analyze.c 2004-05-31 17:03:56.000000000 +0200 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_analyze.c linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_analyze.c +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_analyze.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_analyze.c 2004-09-05 17:07:53.000000000 +0200 @@ -0,0 +1,564 @@ +#include "gradm.h" + @@ -1628,7 +2635,7 @@ diff -Naurp old/gradm2/gradm_analyze.c n + if (!check_permission(role, def_acl, tmp->filename, &chk)) + fprintf(stderr, + "Warning: write access is allowed to your " -+ "subject ACL for %s in role %s. Please ensure that the subject is running with less privilege than the default subject.\n", ++ "subject for %s in role %s. Please ensure that the subject is running with less privilege than the default subject.\n", + tmp->filename, role->rolename); + + return errs_found; @@ -1913,7 +2920,7 @@ diff -Naurp old/gradm2/gradm_analyze.c n + if (!check_permission(role, def_acl, GRSEC_DIR, &chk)) { + fprintf(stderr, + "Viewing access is allowed by role %s to %s, the directory which " -+ "holds ACL and ACL password information.\n\n", ++ "stores RBAC policies and RBAC password information.\n\n", + role->rolename, GRSEC_DIR); + errs_found++; + } @@ -2048,7 +3055,7 @@ diff -Naurp old/gradm2/gradm_analyze.c n + if (!check_permission(role, def_acl, "", &chk)) { + fprintf(stderr, "CAP_SYS_ADMIN is not " + "removed in role %s. This would allow an " -+ "attacker to mount filesystems to bypass ACLs\n\n", ++ "attacker to mount filesystems to bypass your policies\n\n", + role->rolename); + errs_found++; + } @@ -2107,9 +3114,9 @@ diff -Naurp old/gradm2/gradm_analyze.c n + + return; +} -diff -Naurp old/gradm2/gradm_arg.c new/gradm2/gradm_arg.c ---- old/gradm2/gradm_arg.c 1970-01-01 01:00:00.000000000 +0100 -+++ new/gradm2/gradm_arg.c 2004-06-23 23:19:53.000000000 +0200 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_arg.c linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_arg.c +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_arg.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_arg.c 2004-09-05 17:07:53.000000000 +0200 @@ -0,0 +1,316 @@ +#include "gradm.h" + @@ -2143,7 +3150,7 @@ diff -Naurp old/gradm2/gradm_arg.c new/g + " -L , --learn\n" + " Specify the pathname for learning logs\n" + " -O , --output\n" -+ " Specify where to place ACLs generated from learning mode\n" ++ " Specify where to place policies generated from learning mode\n" + " -M , --modsegv\n" + " Remove a ban on a specific file or UID\n" + " -a , --auth\n" @@ -2188,7 +3195,7 @@ diff -Naurp old/gradm2/gradm_arg.c new/g + int gr_enable = 0; + int gr_fulllearn = 0; + struct gr_pw_entry entry; -+ struct gr_arg *grarg; ++ struct gr_arg_wrapper *grarg; + char cwd[PATH_MAX]; + const char *const short_opts = "SEFuDP::RL:O:M:a:n:hv"; + const struct option long_opts[] = { @@ -2266,8 +3273,8 @@ diff -Naurp old/gradm2/gradm_arg.c new/g + expand_acls(); + analyze_acls(); + grarg = conv_user_to_kernel(&entry); -+ read_saltandpass(entry.rolename, grarg->salt, -+ grarg->sum); ++ read_saltandpass(entry.rolename, grarg->arg->salt, ++ grarg->arg->sum); + transmit_to_kernel(grarg); + break; + case 'M': @@ -2398,8 +3405,8 @@ diff -Naurp old/gradm2/gradm_arg.c new/g + if (gr_learn) + start_grlearn(learn_log); + grarg = conv_user_to_kernel(&entry); -+ read_saltandpass(entry.rolename, grarg->salt, -+ grarg->sum); ++ read_saltandpass(entry.rolename, grarg->arg->salt, ++ grarg->arg->sum); + transmit_to_kernel(grarg); + } else if (gr_learn && gr_output) { + FILE *stream; @@ -2427,9 +3434,9 @@ diff -Naurp old/gradm2/gradm_arg.c new/g + } + return; +} -diff -Naurp old/gradm2/gradm_cap.c new/gradm2/gradm_cap.c ---- old/gradm2/gradm_cap.c 1970-01-01 01:00:00.000000000 +0100 -+++ new/gradm2/gradm_cap.c 2004-03-31 03:20:18.000000000 +0200 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_cap.c linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_cap.c +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_cap.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_cap.c 2004-09-05 17:07:53.000000000 +0200 @@ -0,0 +1,90 @@ +#include "gradm.h" + @@ -2521,19 +3528,20 @@ diff -Naurp old/gradm2/gradm_cap.c new/g + + return; +} -diff -Naurp old/gradm2/gradm_defs.h new/gradm2/gradm_defs.h ---- old/gradm2/gradm_defs.h 1970-01-01 01:00:00.000000000 +0100 -+++ new/gradm2/gradm_defs.h 2004-06-25 19:04:25.000000000 +0200 -@@ -0,0 +1,390 @@ +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_defs.h linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_defs.h +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_defs.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_defs.h 2004-09-05 17:07:53.000000000 +0200 +@@ -0,0 +1,403 @@ +#ifndef GRSEC_DIR -+#define GRSEC_DIR "/etc/grsec" ++#define GRSEC_DIR "/etc/grsec2" +#endif +#define GRLEARN_PATH "/sbin/grlearn" +#define GRDEV_PATH "/dev/grsec" -+#define GR_ACL_PATH GRSEC_DIR "/acl" ++#define GR_POLICY_PATH GRSEC_DIR "/policy" +#define GR_PW_PATH GRSEC_DIR "/pw" + +#define GR_VERSION "2.0.1" ++#define GRADM_VERSION 0x201 + +#define GR_PWONLY 0 +#define GR_PWANDSUM 1 @@ -2619,7 +3627,8 @@ diff -Naurp old/gradm2/gradm_defs.h new/ + GR_ROLE_NOPW = 0x0020, + GR_ROLE_GOD = 0x0040, + GR_ROLE_LEARN = 0x0080, -+ GR_ROLE_TPE = 0x0100 ++ GR_ROLE_TPE = 0x0100, ++ GR_ROLE_DOMAIN = 0x0200 +}; + +enum { @@ -2733,6 +3742,8 @@ diff -Naurp old/gradm2/gradm_defs.h new/ + + struct role_transition *transitions; + struct role_allowed_ip *allowed_ips; ++ uid_t *domain_children; ++ __u16 domain_child_num; + + struct proc_acl **subj_hash; + __u32 subj_hash_size; @@ -2766,7 +3777,6 @@ diff -Naurp old/gradm2/gradm_defs.h new/ + + struct proc_acl *parent_subject; + struct gr_hash_struct *hash; -+ struct ip_acl *ip_object; + struct proc_acl *prev; + struct proc_acl *next; + @@ -2882,13 +3892,11 @@ diff -Naurp old/gradm2/gradm_defs.h new/ + +struct user_acl_role_db { + struct role_acl **r_table; -+ __u32 r_entries; /* Number of entries in table */ -+ __u32 s_entries; /* total number of subject acls */ -+ __u32 i_entries; /* total number of ip acls */ -+ __u32 o_entries; /* Total number of object acls */ -+ __u32 g_entries; /* total number of globbed objects */ -+ __u32 a_entries; /* total number of allowed role ips */ -+ __u32 t_entries; /* total number of transitions */ ++ __u32 num_pointers; /* Number of allocations to track */ ++ __u32 num_roles; /* Number of roles */ ++ __u32 num_domain_children; /* Number of domain children */ ++ __u32 num_subjects; /* Number of subjects */ ++ __u32 num_objects; /* Number of objects */ +}; + +struct sprole_pw { @@ -2911,13 +3919,25 @@ diff -Naurp old/gradm2/gradm_defs.h new/ + __u16 mode; +}; + ++struct gr_arg_wrapper { ++ struct gr_arg *arg; ++ __u32 version; ++ __u32 size; ++}; ++ +struct capability_set capability_list[30]; +struct rlimconv rlim_table[12]; + +uid_t special_role_uid; -diff -Naurp old/gradm2/gradm_fulllearn.c new/gradm2/gradm_fulllearn.c ---- old/gradm2/gradm_fulllearn.c 1970-01-01 01:00:00.000000000 +0100 -+++ new/gradm2/gradm_fulllearn.c 2004-03-04 06:30:05.000000000 +0100 ++ ++__u32 num_subjects; ++__u32 num_roles; ++__u32 num_objects; ++__u32 num_pointers; ++__u32 num_domain_children; +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_fulllearn.c linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_fulllearn.c +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_fulllearn.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_fulllearn.c 2004-09-05 17:07:53.000000000 +0200 @@ -0,0 +1,275 @@ +#include "gradm.h" + @@ -3194,9 +4214,9 @@ diff -Naurp old/gradm2/gradm_fulllearn.c + + return; +} -diff -Naurp old/gradm2/gradm_fulllearn_pass1.l new/gradm2/gradm_fulllearn_pass1.l ---- old/gradm2/gradm_fulllearn_pass1.l 1970-01-01 01:00:00.000000000 +0100 -+++ new/gradm2/gradm_fulllearn_pass1.l 2003-06-25 21:01:10.000000000 +0200 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_fulllearn_pass1.l linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_fulllearn_pass1.l +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_fulllearn_pass1.l 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_fulllearn_pass1.l 2004-09-05 17:07:53.000000000 +0200 @@ -0,0 +1,41 @@ +%{ +#include "gradm.h" @@ -3239,9 +4259,9 @@ diff -Naurp old/gradm2/gradm_fulllearn_p + +void fulllearn_pass1error(const char *s) { return; } +int fulllearn_pass1wrap(void) { return 1; } -diff -Naurp old/gradm2/gradm_fulllearn_pass1.y new/gradm2/gradm_fulllearn_pass1.y ---- old/gradm2/gradm_fulllearn_pass1.y 1970-01-01 01:00:00.000000000 +0100 -+++ new/gradm2/gradm_fulllearn_pass1.y 2003-06-22 23:30:29.000000000 +0200 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_fulllearn_pass1.y linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_fulllearn_pass1.y +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_fulllearn_pass1.y 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_fulllearn_pass1.y 2004-09-05 17:07:53.000000000 +0200 @@ -0,0 +1,64 @@ +%{ +#include "gradm.h" @@ -3307,9 +4327,9 @@ diff -Naurp old/gradm2/gradm_fulllearn_p + } + ; +%% -diff -Naurp old/gradm2/gradm_fulllearn_pass2.l new/gradm2/gradm_fulllearn_pass2.l ---- old/gradm2/gradm_fulllearn_pass2.l 1970-01-01 01:00:00.000000000 +0100 -+++ new/gradm2/gradm_fulllearn_pass2.l 2003-06-25 21:01:10.000000000 +0200 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_fulllearn_pass2.l linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_fulllearn_pass2.l +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_fulllearn_pass2.l 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_fulllearn_pass2.l 2004-09-05 17:07:53.000000000 +0200 @@ -0,0 +1,41 @@ +%{ +#include "gradm.h" @@ -3352,9 +4372,9 @@ diff -Naurp old/gradm2/gradm_fulllearn_p + +void fulllearn_pass2error(const char *s) { return; } +int fulllearn_pass2wrap(void) { return 1; } -diff -Naurp old/gradm2/gradm_fulllearn_pass2.y new/gradm2/gradm_fulllearn_pass2.y ---- old/gradm2/gradm_fulllearn_pass2.y 1970-01-01 01:00:00.000000000 +0100 -+++ new/gradm2/gradm_fulllearn_pass2.y 2004-03-04 05:17:04.000000000 +0100 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_fulllearn_pass2.y linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_fulllearn_pass2.y +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_fulllearn_pass2.y 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_fulllearn_pass2.y 2004-09-05 17:07:53.000000000 +0200 @@ -0,0 +1,91 @@ +%{ +#include "gradm.h" @@ -3447,9 +4467,9 @@ diff -Naurp old/gradm2/gradm_fulllearn_p + } + ; +%% -diff -Naurp old/gradm2/gradm_fulllearn_pass3.l new/gradm2/gradm_fulllearn_pass3.l ---- old/gradm2/gradm_fulllearn_pass3.l 1970-01-01 01:00:00.000000000 +0100 -+++ new/gradm2/gradm_fulllearn_pass3.l 2003-06-25 21:01:10.000000000 +0200 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_fulllearn_pass3.l linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_fulllearn_pass3.l +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_fulllearn_pass3.l 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_fulllearn_pass3.l 2004-09-05 17:07:53.000000000 +0200 @@ -0,0 +1,41 @@ +%{ +#include "gradm.h" @@ -3492,9 +4512,9 @@ diff -Naurp old/gradm2/gradm_fulllearn_p + +void fulllearn_pass3error(const char *s) { return; } +int fulllearn_pass3wrap(void) { return 1; } -diff -Naurp old/gradm2/gradm_fulllearn_pass3.y new/gradm2/gradm_fulllearn_pass3.y ---- old/gradm2/gradm_fulllearn_pass3.y 1970-01-01 01:00:00.000000000 +0100 -+++ new/gradm2/gradm_fulllearn_pass3.y 2004-03-04 05:05:42.000000000 +0100 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_fulllearn_pass3.y linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_fulllearn_pass3.y +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_fulllearn_pass3.y 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_fulllearn_pass3.y 2004-09-05 17:07:53.000000000 +0200 @@ -0,0 +1,108 @@ +%{ +#include "gradm.h" @@ -3604,14 +4624,14 @@ diff -Naurp old/gradm2/gradm_fulllearn_p + } + ; +%% -diff -Naurp old/gradm2/gradm_func.h new/gradm2/gradm_func.h ---- old/gradm2/gradm_func.h 1970-01-01 01:00:00.000000000 +0100 -+++ new/gradm2/gradm_func.h 2004-06-18 03:50:57.000000000 +0200 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_func.h linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_func.h +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_func.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_func.h 2004-09-05 17:07:53.000000000 +0200 @@ -0,0 +1,129 @@ +void yyerror(const char *s); +FILE *open_acl_file(const char *filename); +void get_user_passwd(struct gr_pw_entry *entry, int mode); -+int transmit_to_kernel(struct gr_arg *buf); ++int transmit_to_kernel(struct gr_arg_wrapper *buf); +void generate_salt(struct gr_pw_entry *entry); +void write_user_passwd(struct gr_pw_entry *entry); +void parse_acls(void); @@ -3630,7 +4650,7 @@ diff -Naurp old/gradm2/gradm_func.h new/ +void add_gradm_acl(struct role_acl *role); +void add_grlearn_acl(struct role_acl *role); +void change_current_acl_file(const char *filename); -+struct gr_arg *conv_user_to_kernel(struct gr_pw_entry *entry); ++struct gr_arg_wrapper *conv_user_to_kernel(struct gr_pw_entry *entry); +int parent_dir(const char *filename, char *parent_dirent[]); +void rem_proc_object_acl(struct proc_acl *proc, struct file_acl *filp); +void expand_acls(void); @@ -3737,9 +4757,9 @@ diff -Naurp old/gradm2/gradm_func.h new/ +void insert_acl_subject(struct role_acl *role, struct proc_acl *subject); + +void insert_nested_acl_subject(struct proc_acl *subject); -diff -Naurp old/gradm2/gradm_human.c new/gradm2/gradm_human.c ---- old/gradm2/gradm_human.c 1970-01-01 01:00:00.000000000 +0100 -+++ new/gradm2/gradm_human.c 2004-04-03 18:22:57.000000000 +0200 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_human.c linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_human.c +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_human.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_human.c 2004-09-05 17:07:53.000000000 +0200 @@ -0,0 +1,161 @@ +#include "gradm.h" + @@ -3902,10 +4922,10 @@ diff -Naurp old/gradm2/gradm_human.c new + + return; +} -diff -Naurp old/gradm2/gradm_learn.c new/gradm2/gradm_learn.c ---- old/gradm2/gradm_learn.c 1970-01-01 01:00:00.000000000 +0100 -+++ new/gradm2/gradm_learn.c 2004-06-18 04:50:52.000000000 +0200 -@@ -0,0 +1,324 @@ +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_learn.c linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_learn.c +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_learn.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_learn.c 2004-09-05 17:07:53.000000000 +0200 +@@ -0,0 +1,325 @@ +#include "gradm.h" + +struct gr_learn_role_entry *default_role_entry; @@ -4046,7 +5066,8 @@ diff -Naurp old/gradm2/gradm_learn.c new + for_each_object(object, subject) { + insert_learn_object(matchsubj, conv_filename_to_struct(object->filename, object->mode)); + } -+ for (ipp = subject->ip_object; ipp; ipp = ipp->prev) { ++ for (i = 0; i < subject->ip_num; i++) { ++ ipp = subject->ips[i]; + if (ipp->mode == GR_IP_CONNECT) { + for (i = ipp->low; i <= ipp->high; i++) + for (x = 0; x < 5; x++) @@ -4230,9 +5251,9 @@ diff -Naurp old/gradm2/gradm_learn.c new + + return; +} -diff -Naurp old/gradm2/gradm_learn_pass1.l new/gradm2/gradm_learn_pass1.l ---- old/gradm2/gradm_learn_pass1.l 1970-01-01 01:00:00.000000000 +0100 -+++ new/gradm2/gradm_learn_pass1.l 2003-06-25 21:01:10.000000000 +0200 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_learn_pass1.l linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_learn_pass1.l +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_learn_pass1.l 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_learn_pass1.l 2004-09-05 17:07:53.000000000 +0200 @@ -0,0 +1,41 @@ +%{ +#include "gradm.h" @@ -4275,9 +5296,9 @@ diff -Naurp old/gradm2/gradm_learn_pass1 + +void learn_pass1error(const char *s) { return; } +int learn_pass1wrap(void) { return 1; } -diff -Naurp old/gradm2/gradm_learn_pass1.y new/gradm2/gradm_learn_pass1.y ---- old/gradm2/gradm_learn_pass1.y 1970-01-01 01:00:00.000000000 +0100 -+++ new/gradm2/gradm_learn_pass1.y 2004-03-04 05:05:42.000000000 +0100 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_learn_pass1.y linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_learn_pass1.y +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_learn_pass1.y 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_learn_pass1.y 2004-09-05 17:07:53.000000000 +0200 @@ -0,0 +1,112 @@ +%{ +#include "gradm.h" @@ -4391,9 +5412,9 @@ diff -Naurp old/gradm2/gradm_learn_pass1 + } + ; +%% -diff -Naurp old/gradm2/gradm_learn_pass2.l new/gradm2/gradm_learn_pass2.l ---- old/gradm2/gradm_learn_pass2.l 1970-01-01 01:00:00.000000000 +0100 -+++ new/gradm2/gradm_learn_pass2.l 2003-06-25 21:01:10.000000000 +0200 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_learn_pass2.l linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_learn_pass2.l +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_learn_pass2.l 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_learn_pass2.l 2004-09-05 17:07:53.000000000 +0200 @@ -0,0 +1,41 @@ +%{ +#include "gradm.h" @@ -4436,9 +5457,9 @@ diff -Naurp old/gradm2/gradm_learn_pass2 + +void learn_pass2error(const char *s) { return; } +int learn_pass2wrap(void) { return 1; } -diff -Naurp old/gradm2/gradm_learn_pass2.y new/gradm2/gradm_learn_pass2.y ---- old/gradm2/gradm_learn_pass2.y 1970-01-01 01:00:00.000000000 +0100 -+++ new/gradm2/gradm_learn_pass2.y 2004-03-04 05:05:42.000000000 +0100 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_learn_pass2.y linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_learn_pass2.y +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_learn_pass2.y 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_learn_pass2.y 2004-09-05 17:07:53.000000000 +0200 @@ -0,0 +1,123 @@ +%{ +#include "gradm.h" @@ -4563,9 +5584,9 @@ diff -Naurp old/gradm2/gradm_learn_pass2 + } + ; +%% -diff -Naurp old/gradm2/gradm_lib.c new/gradm2/gradm_lib.c ---- old/gradm2/gradm_lib.c 1970-01-01 01:00:00.000000000 +0100 -+++ new/gradm2/gradm_lib.c 2004-06-18 03:50:57.000000000 +0200 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_lib.c linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_lib.c +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_lib.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_lib.c 2004-09-05 17:07:53.000000000 +0200 @@ -0,0 +1,561 @@ +#include "gradm.h" + @@ -5128,10 +6149,10 @@ diff -Naurp old/gradm2/gradm_lib.c new/g + subject->hash = create_hash_table(GR_HASH_OBJECT); + return; +} -diff -Naurp old/gradm2/gradm_misc.c new/gradm2/gradm_misc.c ---- old/gradm2/gradm_misc.c 1970-01-01 01:00:00.000000000 +0100 -+++ new/gradm2/gradm_misc.c 2004-06-23 23:19:53.000000000 +0200 -@@ -0,0 +1,171 @@ +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_misc.c linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_misc.c +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_misc.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_misc.c 2004-09-05 17:07:53.000000000 +0200 +@@ -0,0 +1,177 @@ +#include "gradm.h" + +FILE * @@ -5148,18 +6169,17 @@ diff -Naurp old/gradm2/gradm_misc.c new/ +} + +int -+transmit_to_kernel(struct gr_arg *buf) ++transmit_to_kernel(struct gr_arg_wrapper *buf) +{ + int fd; + int err = 0; -+ void *pbuf = buf; + + if ((fd = open(GRDEV_PATH, O_WRONLY)) < 0) { + fprintf(stderr, "Could not open %s.\n", GRDEV_PATH); + failure("open"); + } + -+ if (write(fd, &pbuf, sizeof(struct gr_arg *)) != sizeof(struct gr_arg *)) { ++ if (write(fd, buf, sizeof(struct gr_arg_wrapper)) != sizeof(struct gr_arg_wrapper)) { + err = 1; + switch (errno) { + case EFAULT: @@ -5191,12 +6211,12 @@ diff -Naurp old/gradm2/gradm_misc.c new/ + } + + close(fd); -+ if (buf->mode != GRADM_DISABLE) { -+ memset(buf, 0, sizeof(struct gr_arg)); ++ if (buf->arg->mode != GRADM_DISABLE) { ++ memset(buf->arg, 0, sizeof(struct gr_arg)); + if (err) + exit(EXIT_FAILURE); + } else { -+ memset(buf, 0, sizeof(struct gr_arg)); ++ memset(buf->arg, 0, sizeof(struct gr_arg)); + if (err) + exit(EXIT_FAILURE); + else @@ -5211,8 +6231,11 @@ diff -Naurp old/gradm2/gradm_misc.c new/ + int fd; + int retval; + struct gr_arg arg; -+ struct gr_arg *parg = &arg; ++ struct gr_arg_wrapper wrapper; + ++ wrapper.version = GRADM_VERSION; ++ wrapper.size = sizeof(struct gr_arg); ++ wrapper.arg = &arg; + arg.mode = GRADM_STATUS; + + if ((fd = open(GRDEV_PATH, O_WRONLY)) < 0) { @@ -5220,7 +6243,7 @@ diff -Naurp old/gradm2/gradm_misc.c new/ + failure("open"); + } + -+ retval = write(fd, &parg, sizeof(struct gr_arg *)); ++ retval = write(fd, &wrapper, sizeof(struct gr_arg_wrapper)); + close(fd); + + switch (reqmode) { @@ -5265,6 +6288,10 @@ diff -Naurp old/gradm2/gradm_misc.c new/ + current_acl_file = NULL; + current_role = NULL; + current_subject = NULL; ++ num_roles = 0; ++ num_subjects = 0; ++ num_objects = 0; ++ num_pointers = 0; + + memset(&ip, 0, sizeof (ip)); + @@ -5303,10 +6330,10 @@ diff -Naurp old/gradm2/gradm_misc.c new/ + + return 0; +} -diff -Naurp old/gradm2/gradm_nest.c new/gradm2/gradm_nest.c ---- old/gradm2/gradm_nest.c 1970-01-01 01:00:00.000000000 +0100 -+++ new/gradm2/gradm_nest.c 2004-02-29 16:05:11.000000000 +0100 -@@ -0,0 +1,94 @@ +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_nest.c linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_nest.c +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_nest.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_nest.c 2004-09-05 17:07:53.000000000 +0200 +@@ -0,0 +1,89 @@ +#include "gradm.h" + +void @@ -5390,21 +6417,16 @@ diff -Naurp old/gradm2/gradm_nest.c new/ + current_subject->mode |= GR_NESTED; + + if (!stat(nestednames[i - 1], &fstat) && S_ISREG(fstat.st_mode)) { -+ if (is_valid_elf_binary(nestednames[i - 1])) { -+ if (!add_proc_object_acl(current_subject, nestednames[i - 1], proc_object_mode_conv("x"), GR_FLEARN)) -+ exit(EXIT_FAILURE); -+ } else { -+ if (!add_proc_object_acl(current_subject, nestednames[i - 1], proc_object_mode_conv("rx"), GR_FLEARN)) -+ exit(EXIT_FAILURE); -+ } ++ if (!add_proc_object_acl(current_subject, nestednames[i - 1], proc_object_mode_conv("rx"), GR_FLEARN)) ++ exit(EXIT_FAILURE); + } + + return; +} -diff -Naurp old/gradm2/gradm_net.c new/gradm2/gradm_net.c ---- old/gradm2/gradm_net.c 1970-01-01 01:00:00.000000000 +0100 -+++ new/gradm2/gradm_net.c 2003-05-16 23:59:28.000000000 +0200 -@@ -0,0 +1,123 @@ +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_net.c linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_net.c +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_net.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_net.c 2004-09-05 17:07:53.000000000 +0200 +@@ -0,0 +1,126 @@ +#include "gradm.h" + +void @@ -5413,6 +6435,8 @@ diff -Naurp old/gradm2/gradm_net.c new/g + struct role_allowed_ip **roleipp; + struct role_allowed_ip *roleip; + ++ num_pointers++; ++ + roleip = + (struct role_allowed_ip *) calloc(1, + sizeof (struct role_allowed_ip)); @@ -5437,29 +6461,32 @@ diff -Naurp old/gradm2/gradm_net.c new/g +void +add_ip_acl(struct proc_acl *subject, __u8 mode, struct ip_acl *acl_tmp) +{ -+ struct ip_acl **ipp; + struct ip_acl *p; + int i; + + if (!subject) { + fprintf(stderr, "Error on line %lu of %s.\n Definition " -+ "of an IP ACL without a subject definition.\n" ++ "of an IP policy without a subject definition.\n" + "The RBAC system will not be allowed to be " + "enabled until this problem is fixed.\n", + lineno, current_acl_file); + exit(EXIT_FAILURE); + } + -+ ipp = &(subject->ip_object); ++ /* add one for the pointer to array of pointers */ ++ if (subject->ips == NULL) ++ num_pointers++; ++ ++ num_pointers++; ++ ++ subject->ip_num++; ++ subject->ips = gr_dyn_realloc(subject->ips, subject->ip_num * sizeof(struct ip_acl *)); + + p = (struct ip_acl *) calloc(1, sizeof (struct ip_acl)); + if (!p) + failure("calloc"); + -+ if (*ipp) -+ (*ipp)->next = p; -+ -+ p->prev = *ipp; ++ *(subject->ips + subject->ip_num - 1) = p; + + p->mode = mode; + p->addr = acl_tmp->addr; @@ -5473,8 +6500,6 @@ diff -Naurp old/gradm2/gradm_net.c new/g + subject->ip_proto[i] |= p->proto[i]; + subject->ip_type |= p->type; + -+ *ipp = p; -+ + return; +} + @@ -5528,9 +6553,9 @@ diff -Naurp old/gradm2/gradm_net.c new/g + } + return; +} -diff -Naurp old/gradm2/gradm_newlearn.c new/gradm2/gradm_newlearn.c ---- old/gradm2/gradm_newlearn.c 1970-01-01 01:00:00.000000000 +0100 -+++ new/gradm2/gradm_newlearn.c 2004-06-18 04:50:20.000000000 +0200 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_newlearn.c linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_newlearn.c +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_newlearn.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_newlearn.c 2004-09-05 17:07:53.000000000 +0200 @@ -0,0 +1,1675 @@ +#include "gradm.h" + @@ -7207,10 +8232,10 @@ diff -Naurp old/gradm2/gradm_newlearn.c + return NULL; +} + -diff -Naurp old/gradm2/gradm_opt.c new/gradm2/gradm_opt.c ---- old/gradm2/gradm_opt.c 1970-01-01 01:00:00.000000000 +0100 -+++ new/gradm2/gradm_opt.c 2004-05-08 21:26:47.000000000 +0200 -@@ -0,0 +1,48 @@ +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_opt.c linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_opt.c +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_opt.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_opt.c 2004-09-05 17:07:53.000000000 +0200 +@@ -0,0 +1,43 @@ +#include "gradm.h" + +static void @@ -7243,13 +8268,8 @@ diff -Naurp old/gradm2/gradm_opt.c new/g + for_each_role(role, current_role) { + for_each_subject(proc, role) { + if (!stat(proc->filename, &fstat) && S_ISREG(fstat.st_mode)) { -+ if (is_valid_elf_binary(proc->filename)) { -+ if (!add_proc_object_acl(proc, proc->filename, proc_object_mode_conv("x"), GR_FLEARN)) -+ exit(EXIT_FAILURE); -+ } else { -+ if (!add_proc_object_acl(proc, proc->filename, proc_object_mode_conv("rx"), GR_FLEARN)) -+ exit(EXIT_FAILURE); -+ } ++ if (!add_proc_object_acl(proc, proc->filename, proc_object_mode_conv("rx"), GR_FLEARN)) ++ exit(EXIT_FAILURE); + } + /* if we're not nested and not /, set parent subject */ + if (!(proc->mode & GR_OVERRIDE) && !(proc->mode & GR_NESTED) && strcmp(proc->filename, "/")) @@ -7259,10 +8279,10 @@ diff -Naurp old/gradm2/gradm_opt.c new/g + + return; +} -diff -Naurp old/gradm2/gradm_parse.c new/gradm2/gradm_parse.c ---- old/gradm2/gradm_parse.c 1970-01-01 01:00:00.000000000 +0100 -+++ new/gradm2/gradm_parse.c 2004-06-18 03:50:57.000000000 +0200 -@@ -0,0 +1,1021 @@ +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_parse.c linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_parse.c +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_parse.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_parse.c 2004-09-05 17:07:53.000000000 +0200 +@@ -0,0 +1,1094 @@ +#include "gradm.h" + +extern FILE *gradmin; @@ -7306,8 +8326,12 @@ diff -Naurp old/gradm2/gradm_parse.c new + exit(EXIT_FAILURE); + } + ++ /* increment pointer count upon allocation of user transition list */ ++ if (subject->user_transitions == NULL) ++ num_pointers++; ++ + subject->user_trans_num++; -+ subject->user_transitions = gr_dyn_realloc(subject->user_transitions, subject->user_trans_num); ++ subject->user_transitions = gr_dyn_realloc(subject->user_transitions, subject->user_trans_num * sizeof(uid_t)); + *(subject->user_transitions + subject->user_trans_num - 1) = pwd->pw_uid; + } else if (usergroup == GR_ID_GROUP) { + if (allowdeny == GR_ID_ALLOW) { @@ -7341,8 +8365,12 @@ diff -Naurp old/gradm2/gradm_parse.c new + exit(EXIT_FAILURE); + } + ++ /* increment pointer count upon allocation of group transition list */ ++ if (subject->group_transitions == NULL) ++ num_pointers++; ++ + subject->group_trans_num++; -+ subject->group_transitions = gr_dyn_realloc(subject->group_transitions, subject->group_trans_num); ++ subject->group_transitions = gr_dyn_realloc(subject->group_transitions, subject->group_trans_num * sizeof(gid_t)); + *(subject->group_transitions + subject->group_trans_num - 1) = grp->gr_gid; + } + @@ -7350,11 +8378,70 @@ diff -Naurp old/gradm2/gradm_parse.c new +} + +void ++add_domain_child(struct role_acl *role, char *idname) ++{ ++ struct passwd *pwd; ++ struct group *grp; ++ ++ /* reason for this is that in the kernel, the hash table which is keyed by UID/GID ++ has a size dependent on the number of roles. Since we want to fake a domain ++ as being a real role for each of those users/groups by providing a pointer ++ to the domain for each user/group, we need to count each of these against the ++ role count */ ++ num_domain_children++; ++ ++ /* increment pointer count upon allocation of domain list */ ++ if (role->domain_children == NULL) ++ num_pointers++; ++ ++ if (role->roletype & GR_ROLE_USER) { ++ pwd = getpwnam(idname); ++ ++ if (!pwd) { ++ fprintf(stderr, "User %s on line %lu of %s " ++ "does not exist.\nThe RBAC system will " ++ "not be allowed to be enabled until " ++ "this error is fixed.\n", idname, ++ lineno, current_acl_file); ++ exit(EXIT_FAILURE); ++ } ++ ++ role->domain_child_num++; ++ role->domain_children = gr_dyn_realloc(role->domain_children, role->domain_child_num * sizeof(uid_t)); ++ *(role->domain_children + role->domain_child_num - 1) = pwd->pw_uid; ++ } else if (role->roletype & GR_ROLE_GROUP) { ++ grp = getgrnam(idname); ++ ++ if (!grp) { ++ fprintf(stderr, "Group %s on line %lu of %s " ++ "does not exist.\nThe RBAC system will " ++ "not be allowed to be enabled until " ++ "this error is fixed.\n", idname, ++ lineno, current_acl_file); ++ exit(EXIT_FAILURE); ++ } ++ ++ role->domain_child_num++; ++ role->domain_children = gr_dyn_realloc(role->domain_children, role->domain_child_num * sizeof(uid_t)); ++ *(role->domain_children + role->domain_child_num - 1) = grp->gr_gid; ++ } else { ++ // should never get here ++ fprintf(stderr, "Unhandled exception 1.\n"); ++ exit(EXIT_FAILURE); ++ } ++ ++ return; ++} ++ ++void +add_role_transition(struct role_acl *role, char *rolename) +{ + struct role_transition **roletpp; + struct role_transition *roletp; + ++ /* one for transition, one for name */ ++ num_pointers += 2; ++ + roletp = + (struct role_transition *) calloc(1, + sizeof (struct role_transition)); @@ -7471,6 +8558,11 @@ diff -Naurp old/gradm2/gradm_parse.c new + struct passwd *pwd; + struct group *grp; + ++ num_roles++; ++ ++ /* one for role, one for name */ ++ num_pointers += 2; ++ + if (!rolename) { + fprintf(stderr, "Out of memory.\n"); + exit(EXIT_FAILURE); @@ -7553,6 +8645,18 @@ diff -Naurp old/gradm2/gradm_parse.c new + return 1; +} + ++int count_slashes(char *str) ++{ ++ int i = 0; ++ while (*str) { ++ if (*str == '/') ++ i++; ++ str++; ++ } ++ ++ return i; ++} ++ +static int +add_globbing_file(struct proc_acl *subject, char *filename, + __u32 mode, int type) @@ -7561,6 +8665,10 @@ diff -Naurp old/gradm2/gradm_parse.c new + char *p, *p2; + struct file_acl *anchor; + struct file_acl *glob, *glob2; ++ int lnum, onum; ++ ++ /* one for the object itself, one for the filename */ ++ num_pointers += 2; + + if (!basepoint) + failure("strdup"); @@ -7570,7 +8678,7 @@ diff -Naurp old/gradm2/gradm_parse.c new + while (*p != '\0') { + if (*p == '/') + p2 = p; -+ if (*p == '?' || *p == '*') ++ if (*p == '?' || *p == '*' || *p == '[') + break; + p++; + } @@ -7591,11 +8699,32 @@ diff -Naurp old/gradm2/gradm_parse.c new + + if (anchor->globbed) { + glob = anchor->globbed; -+ while (glob->next) -+ glob = glob->next; + glob2 = calloc(1, sizeof(struct file_acl)); + if (!glob2) + failure("calloc"); ++ onum = count_slashes(filename); ++ lnum = count_slashes(glob->filename); ++ if (onum > lnum) { ++ glob2->next = glob; ++ anchor->globbed = glob2; ++ glob2->filename = filename; ++ glob2->mode = mode; ++ glob->prev = glob2; ++ return 1; ++ } ++ while (glob->next) { ++ lnum = count_slashes(glob->next->filename); ++ if (onum > lnum) { ++ glob2->next = glob->next; ++ glob->next = glob2; ++ glob2->filename = filename; ++ glob2->mode = mode; ++ glob2->prev = glob; ++ glob->next->prev = glob2; ++ return 1; ++ } ++ glob = glob->next; ++ } + glob2->filename = filename; + glob2->mode = mode; + glob2->prev = glob; @@ -7675,6 +8804,7 @@ diff -Naurp old/gradm2/gradm_parse.c new + struct stat fstat; + struct deleted_file *dfile; + unsigned int file_len; ++ char *str; + + if (!subject) { + fprintf(stderr, "Error on line %lu of %s. Attempt to " @@ -7692,10 +8822,28 @@ diff -Naurp old/gradm2/gradm_parse.c new + if (!strncmp(filename, "$HOME", 5)) + filename = parse_homedir(filename); + -+ file_len = strlen(filename) + 1; ++ str = filename; ++ file_len = 0; ++ while (*str) { ++ file_len++; ++ if (*str == '?' || *str == '*') ++ return add_globbing_file(subject, filename, mode, type); ++ if (*str == '[') { ++ char *str2 = str; ++ while (*str2) { ++ if (*str2 == ']') ++ return add_globbing_file(subject, filename, mode, type); ++ str2++; ++ } ++ } ++ str++; ++ } ++ ++ file_len++; + -+ if (strchr(filename, '?') || strchr(filename, '*')) -+ return add_globbing_file(subject, filename, mode, type); ++ num_objects++; ++ /* one for the object, one for the filename, one for the name entry struct in the kernel*/ ++ num_pointers += 3; + + if (lstat(filename, &fstat)) { + dfile = add_deleted_file(filename); @@ -7771,6 +8919,10 @@ diff -Naurp old/gradm2/gradm_parse.c new + struct stat fstat; + unsigned int file_len; + ++ num_subjects++; ++ /* one for the subject, one for the filename */ ++ num_pointers += 2; ++ + if (!role) { + fprintf(stderr, "Error on line %lu of %s. Attempt to " + "add a subject without a role declaration.\n" @@ -8081,8 +9233,8 @@ diff -Naurp old/gradm2/gradm_parse.c new + exit(EXIT_FAILURE); + } + -+ gradmin = open_acl_file(GR_ACL_PATH); -+ change_current_acl_file(GR_ACL_PATH); ++ gradmin = open_acl_file(GR_POLICY_PATH); ++ change_current_acl_file(GR_POLICY_PATH); + gradmparse(); + fclose(gradmin); + @@ -8134,30 +9286,16 @@ diff -Naurp old/gradm2/gradm_parse.c new + return; +} + -+struct gr_arg * ++struct gr_arg_wrapper * +conv_user_to_kernel(struct gr_pw_entry *entry) +{ ++ struct gr_arg_wrapper *wrapper; + struct gr_arg *retarg; + struct user_acl_role_db *role_db; + struct role_acl *rtmp = NULL; -+ struct proc_acl *tmp = NULL; -+ struct file_acl *tmpf = NULL; -+ struct file_acl *tmpg = NULL; -+ struct role_allowed_ip *atmp = NULL; -+ struct role_transition *trtmp = NULL; -+ struct ip_acl *tmpi = NULL; -+ struct ip_acl *i_tmp = NULL; + struct role_acl **r_tmp = NULL; -+ struct ip_acl **i_table = NULL; -+ unsigned long facls = 0; -+ unsigned long gacls = 0; -+ unsigned long tpacls = 0; -+ unsigned long racls = 0; -+ unsigned long iacls = 0; -+ unsigned long tiacls = 0; -+ unsigned long aacls = 0; -+ unsigned long tracls = 0; + unsigned long i = 0; ++ unsigned long racls = 0; + __u16 sproles = 0; + int err; + @@ -8166,35 +9304,26 @@ diff -Naurp old/gradm2/gradm_parse.c new + if (rtmp->roletype & GR_ROLE_SPECIAL && + !(rtmp->roletype & GR_ROLE_NOPW)) + sproles++; -+ -+ for_each_allowed_ip(atmp, rtmp->allowed_ips) -+ aacls++; -+ -+ for_each_transition(trtmp, rtmp->transitions) -+ tracls++; -+ -+ for_each_subject(tmp, rtmp) { -+ tpacls++; -+ for (tmpi = tmp->ip_object; tmpi; tmpi = tmpi->prev) -+ tiacls++; -+ for_each_object(tmpf, tmp) { -+ facls++; -+ for_each_globbed(tmpg, tmpf) -+ gacls++; -+ } -+ } -+ } ++ } + + if ((retarg = + (struct gr_arg *) calloc(1, sizeof (struct gr_arg))) == NULL) + failure("calloc"); + ++ if ((wrapper = ++ (struct gr_arg_wrapper *) calloc(1, sizeof (struct gr_arg_wrapper))) == NULL) ++ failure("calloc"); ++ ++ wrapper->version = GRADM_VERSION; ++ wrapper->size = sizeof(struct gr_arg); ++ wrapper->arg = retarg; ++ + err = mlock(retarg, sizeof (struct gr_arg)); + if (err && !getuid()) + fprintf(stderr, "Warning, unable to lock authentication " + "structure in physical memory.\n"); + -+ if (!racls && !tpacls && !facls) // we are disabling, don't want to calloc 0 ++ if (!racls) // we are disabling, don't want to calloc 0 + goto set_pw; + + if ((retarg->sprole_pws = @@ -8211,20 +9340,15 @@ diff -Naurp old/gradm2/gradm_parse.c new + + retarg->num_sprole_pws = sproles; + -+ if ((role_db = -+ (struct user_acl_role_db *) calloc(1, -+ sizeof (struct -+ user_acl_role_db))) == -+ NULL) ++ role_db = (struct user_acl_role_db *) calloc(1, sizeof (struct user_acl_role_db)); ++ if (role_db == NULL) + failure("calloc"); + -+ role_db->r_entries = racls; -+ role_db->s_entries = tpacls; -+ role_db->i_entries = tiacls; -+ role_db->o_entries = facls; -+ role_db->g_entries = gacls; -+ role_db->a_entries = aacls; -+ role_db->t_entries = tracls; ++ role_db->num_pointers = num_pointers; ++ role_db->num_roles = num_roles; ++ role_db->num_domain_children = num_domain_children; ++ role_db->num_subjects = num_subjects; ++ role_db->num_objects = num_objects; + + if ((r_tmp = role_db->r_table = + (struct role_acl **) calloc(racls, @@ -8233,37 +9357,6 @@ diff -Naurp old/gradm2/gradm_parse.c new + + for_each_role(rtmp, current_role) { + *r_tmp = rtmp; -+ for_each_subject(tmp, rtmp) { -+ iacls = 0; -+ for (tmpi = tmp->ip_object; tmpi; tmpi = tmpi->prev) -+ iacls++; -+ if (iacls) { -+ i_table = -+ (struct ip_acl **) calloc(iacls, -+ sizeof (struct -+ ip_acl -+ *)); -+ if (!i_table) -+ failure("calloc"); -+ i = 0; -+ for (tmpi = tmp->ip_object; tmpi; tmpi = tmpi->prev) { -+ i_tmp = -+ (struct ip_acl *) calloc(1, -+ sizeof -+ (struct -+ ip_acl)); -+ memcpy(i_tmp, tmpi, -+ sizeof (struct ip_acl)); -+ *(i_table + i) = i_tmp; -+ i++; -+ } -+ tmp->ips = i_table; -+ tmp->ip_num = iacls; -+ } else { -+ tmp->ips = NULL; -+ tmp->ip_num = 0; -+ } -+ } + r_tmp++; + } + @@ -8282,11 +9375,11 @@ diff -Naurp old/gradm2/gradm_parse.c new + + memset(entry, 0, sizeof (struct gr_pw_entry)); + -+ return retarg; ++ return wrapper; +} -diff -Naurp old/gradm2/gradm_pw.c new/gradm2/gradm_pw.c ---- old/gradm2/gradm_pw.c 1970-01-01 01:00:00.000000000 +0100 -+++ new/gradm2/gradm_pw.c 2003-04-06 05:13:14.000000000 +0200 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_pw.c linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_pw.c +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_pw.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_pw.c 2004-09-05 17:07:53.000000000 +0200 @@ -0,0 +1,189 @@ +#include "gradm.h" + @@ -8477,9 +9570,9 @@ diff -Naurp old/gradm2/gradm_pw.c new/gr + + return 1; +} -diff -Naurp old/gradm2/gradm_res.c new/gradm2/gradm_res.c ---- old/gradm2/gradm_res.c 1970-01-01 01:00:00.000000000 +0100 -+++ new/gradm2/gradm_res.c 2004-02-18 15:37:17.000000000 +0100 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_res.c linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_res.c +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_res.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_res.c 2004-09-05 17:07:53.000000000 +0200 @@ -0,0 +1,158 @@ +#include "gradm.h" + @@ -8639,9 +9732,9 @@ diff -Naurp old/gradm2/gradm_res.c new/g + + return; +} -diff -Naurp old/gradm2/gradm_sha256.c new/gradm2/gradm_sha256.c ---- old/gradm2/gradm_sha256.c 1970-01-01 01:00:00.000000000 +0100 -+++ new/gradm2/gradm_sha256.c 2003-04-06 05:13:14.000000000 +0200 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_sha256.c linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_sha256.c +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_sha256.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_sha256.c 2004-09-05 17:07:53.000000000 +0200 @@ -0,0 +1,288 @@ +#include "gradm.h" + @@ -8931,9 +10024,9 @@ diff -Naurp old/gradm2/gradm_sha256.c ne + + return; +} -diff -Naurp old/gradm2/gradm_sym.c new/gradm2/gradm_sym.c ---- old/gradm2/gradm_sym.c 1970-01-01 01:00:00.000000000 +0100 -+++ new/gradm2/gradm_sym.c 2003-05-03 16:33:48.000000000 +0200 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_sym.c linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_sym.c +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/gradm_sym.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/gradm_sym.c 2004-09-05 17:07:53.000000000 +0200 @@ -0,0 +1,148 @@ +#include "gradm.h" + @@ -9083,13 +10176,13 @@ diff -Naurp old/gradm2/gradm_sym.c new/g + + return; +} -diff -Naurp old/gradm2/grlearn.c new/gradm2/grlearn.c ---- old/gradm2/grlearn.c 1970-01-01 01:00:00.000000000 +0100 -+++ new/gradm2/grlearn.c 2004-04-06 05:10:05.000000000 +0200 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/grlearn.c linux-2.4.20-wolk4.16-grsec2/gradm2/grlearn.c +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/grlearn.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/grlearn.c 2004-09-05 17:07:53.000000000 +0200 @@ -0,0 +1,279 @@ +#include "gradm.h" + -+#define GR_LEARN_PID_PATH "/etc/grsec/.grlearn.pid" ++#define GR_LEARN_PID_PATH "/etc/grsec2/.grlearn.pid" +#define LEARN_BUFFER_SIZE (1024 * 1024) +#define MAX_ENTRY_SIZE 16384 + @@ -9366,501 +10459,256 @@ diff -Naurp old/gradm2/grlearn.c new/gra + + return 0; +} -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/Documentation/Configure.help linux-2.4.20-wolk4.15-grsec2/Documentation/Configure.help ---- linux-2.4.20-wolk4.15-fullkernel/Documentation/Configure.help 2004-06-29 11:35:50.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/Documentation/Configure.help 2004-06-29 13:00:43.000000000 +0200 -@@ -27371,9 +27371,9 @@ CONFIG_GRKERNSEC_CHROOT_PIVOT - Deny double-chroots - CONFIG_GRKERNSEC_CHROOT_DOUBLE - If you say Y here, processes inside a chroot will not be able to chroot -- again. This is a widely used method of breaking out of a chroot jail -- and should not be allowed. If the sysctl option is enabled, a sysctl -- option with name "chroot_deny_chroot" is created. -+ again outside of the chroot. This is a widely used method of breaking -+ out of a chroot jail and should not be allowed. If the sysctl option -+ is enabled, a sysctl option with name "chroot_deny_chroot" is created. - - Deny fchdir outside of chroot - CONFIG_GRKERNSEC_CHROOT_FCHDIR -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/arch/i386/kernel/init_task.c linux-2.4.20-wolk4.15-grsec2/arch/i386/kernel/init_task.c ---- linux-2.4.20-wolk4.15-fullkernel/arch/i386/kernel/init_task.c 2004-06-29 11:23:10.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/arch/i386/kernel/init_task.c 2004-06-29 13:00:30.000000000 +0200 -@@ -30,5 +30,9 @@ union task_union init_task_union - * section. Since TSS's are completely CPU-local, we want them - * on exact cacheline boundaries, to eliminate cacheline ping-pong. - */ --struct tss_struct init_tss[NR_CPUS] __cacheline_aligned = { [0 ... NR_CPUS-1] = INIT_TSS }; - -+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC -+struct tss_struct init_tss[NR_CPUS] __attribute__((__aligned__(SMP_CACHE_BYTES), __section__(".rodata"))) = { [0 ... NR_CPUS-1] = INIT_TSS }; -+#else -+struct tss_struct init_tss[NR_CPUS] __cacheline_aligned = { [0 ... NR_CPUS-1] = INIT_TSS }; -+#endif -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/arch/i386/kernel/ioport.c linux-2.4.20-wolk4.15-grsec2/arch/i386/kernel/ioport.c ---- linux-2.4.20-wolk4.15-fullkernel/arch/i386/kernel/ioport.c 2004-06-29 11:31:07.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/arch/i386/kernel/ioport.c 2004-06-29 13:00:30.000000000 +0200 -@@ -15,6 +15,7 @@ - #include - #include - #include -+#include - - /* RSBAC */ - #ifdef CONFIG_RSBAC -@@ -63,6 +64,10 @@ asmlinkage int sys_ioperm(unsigned long - struct thread_struct * t = ¤t->thread; - struct tss_struct * tss; - -+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC -+ unsigned long flags, cr3; -+#endif -+ - /* RSBAC */ - #ifdef CONFIG_RSBAC - union rsbac_target_id_t rsbac_target_id; -@@ -126,6 +131,11 @@ asmlinkage int sys_ioperm(unsigned long - * do it in the per-thread copy and in the TSS ... - */ - set_bitmap(t->io_bitmap, from, num, !turn_on); -+ -+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC -+ pax_open_kernel(flags, cr3); -+#endif -+ - if (tss->bitmap == IO_BITMAP_OFFSET) { /* already active? */ - set_bitmap(tss->io_bitmap, from, num, !turn_on); - } else { -@@ -133,6 +143,10 @@ asmlinkage int sys_ioperm(unsigned long - tss->bitmap = IO_BITMAP_OFFSET; /* Activate it in the TSS */ - } - -+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC -+ pax_close_kernel(flags, cr3); -+#endif -+ - preempt_enable(); - - return 0; -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/arch/i386/kernel/process.c linux-2.4.20-wolk4.15-grsec2/arch/i386/kernel/process.c ---- linux-2.4.20-wolk4.15-fullkernel/arch/i386/kernel/process.c 2004-06-29 11:31:29.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/arch/i386/kernel/process.c 2004-06-29 13:00:30.000000000 +0200 -@@ -1008,6 +1008,10 @@ void __switch_to(struct task_struct *pre - *next = &next_p->thread; - struct tss_struct *tss = init_tss + smp_processor_id(); - -+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC -+ unsigned long flags, cr3; -+#endif -+ - unlazy_fpu(prev_p); - - #ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC -@@ -1015,11 +1019,6 @@ void __switch_to(struct task_struct *pre - #endif - - /* -- * Reload esp0, LDT and the page table pointer: -- */ -- tss->esp0 = next->esp0; -- -- /* - * Save away %fs and %gs. No need to save %es and %ds, as - * those are always kernel segments while inside the kernel. - */ -@@ -1047,6 +1046,15 @@ void __switch_to(struct task_struct *pre - loaddebug(next, 7); - } - -+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC -+ pax_open_kernel(flags, cr3); -+#endif -+ -+ /* -+ * Reload esp0, LDT and the page table pointer: -+ */ -+ tss->esp0 = next->esp0; -+ - if (unlikely(prev->ioperm || next->ioperm)) { - if (next->ioperm) { - /* -@@ -1069,6 +1077,11 @@ void __switch_to(struct task_struct *pre - */ - tss->bitmap = INVALID_IO_BITMAP_OFFSET; - } -+ -+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC -+ pax_close_kernel(flags, cr3); -+#endif -+ - } - - asmlinkage int sys_fork(struct pt_regs regs) -@@ -1163,6 +1176,10 @@ asmlinkage void pax_randomize_kstack(voi - struct tss_struct *tss = init_tss + smp_processor_id(); - unsigned long time; - -+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC -+ unsigned long flags, cr3; -+#endif -+ - #ifdef CONFIG_GRKERNSEC_PAX_SOFTMODE - if (!pax_aslr) - return; -@@ -1179,7 +1196,16 @@ asmlinkage void pax_randomize_kstack(voi - time <<= 2; - #endif - -+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC -+ pax_open_kernel(flags, cr3); -+#endif -+ - tss->esp0 ^= time; - current->thread.esp0 = tss->esp0; -+ -+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC -+ pax_close_kernel(flags, cr3); -+#endif -+ - } - #endif -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/arch/i386/kernel/setup.c linux-2.4.20-wolk4.15-grsec2/arch/i386/kernel/setup.c ---- linux-2.4.20-wolk4.15-fullkernel/arch/i386/kernel/setup.c 2004-06-29 11:31:38.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/arch/i386/kernel/setup.c 2004-06-29 13:00:30.000000000 +0200 -@@ -177,7 +177,7 @@ unsigned char aux_device_present; - extern void mcheck_init(struct cpuinfo_x86 *c); - extern void dmi_scan_machine(void); - extern int root_mountflags; --extern char _text, _etext, _edata, _end; -+extern char _text, _etext, _data, _edata, _end; - - static int have_cpuid_p(void) __init; - -@@ -1341,7 +1341,7 @@ void __init setup_arch(char **cmdline_p) - - code_resource.start = virt_to_bus(&_text); - code_resource.end = virt_to_bus(&_etext)-1; -- data_resource.start = virt_to_bus(&_etext); -+ data_resource.start = virt_to_bus(&_data); - data_resource.end = virt_to_bus(&_edata)-1; - - parse_cmdline_early(cmdline_p); -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/arch/i386/kernel/vm86.c linux-2.4.20-wolk4.15-grsec2/arch/i386/kernel/vm86.c ---- linux-2.4.20-wolk4.15-fullkernel/arch/i386/kernel/vm86.c 2004-06-29 11:26:14.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/arch/i386/kernel/vm86.c 2004-06-29 13:00:30.000000000 +0200 -@@ -45,6 +45,7 @@ - #include - #include - #include -+#include - - /* - * Known problems: -@@ -98,6 +99,10 @@ struct pt_regs * save_v86_state(struct k - struct pt_regs *ret; - unsigned long tmp; - -+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC -+ unsigned long flags, cr3; -+#endif -+ - if (!current->thread.vm86_info) { - printk("no vm86_info: BAD\n"); - do_exit(SIGSEGV); -@@ -112,7 +117,17 @@ struct pt_regs * save_v86_state(struct k - do_exit(SIGSEGV); - } - tss = init_tss + smp_processor_id(); -+ -+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC -+ pax_open_kernel(flags, cr3); -+#endif -+ - tss->esp0 = current->thread.esp0 = current->thread.saved_esp0; -+ -+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC -+ pax_close_kernel(flags, cr3); -+#endif -+ - current->thread.saved_esp0 = 0; - ret = KVM86->regs32; - return ret; -@@ -239,6 +254,11 @@ out: - static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk) - { - struct tss_struct *tss; -+ -+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC -+ unsigned long flags, cr3; -+#endif -+ - /* - * make sure the vm86() system call doesn't try to do anything silly - */ -@@ -280,8 +300,17 @@ static void do_sys_vm86(struct kernel_vm - info->regs32->eax = 0; - tsk->thread.saved_esp0 = tsk->thread.esp0; - tss = init_tss + smp_processor_id(); -+ -+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC -+ pax_open_kernel(flags, cr3); -+#endif -+ - tss->esp0 = tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0; - -+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC -+ pax_close_kernel(flags, cr3); -+#endif -+ - tsk->thread.screen_bitmap = info->screen_bitmap; - if (info->flags & VM86_SCREEN_BITMAP) - mark_screen_rdonly(tsk); -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/drivers/char/mem.c linux-2.4.20-wolk4.15-grsec2/drivers/char/mem.c ---- linux-2.4.20-wolk4.15-fullkernel/drivers/char/mem.c 2004-06-29 11:31:48.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/drivers/char/mem.c 2004-06-29 13:00:19.000000000 +0200 -@@ -42,7 +42,11 @@ extern void mda_console_init(void); - #if defined(CONFIG_S390_TAPE) && defined(CONFIG_S390_TAPE_CHAR) - extern void tapechar_init(void); - #endif -- -+ -+#ifdef CONFIG_GRKERNSEC -+extern struct file_operations grsec_fops; -+#endif -+ - /* RSBAC */ - #ifdef CONFIG_RSBAC - #include -@@ -769,6 +773,11 @@ static int memory_open(struct inode * in - case 10: - filp->f_op = &anon_file_operations; - break; -+#ifdef CONFIG_GRKERNSEC -+ case 11: -+ filp->f_op = &grsec_fops; -+ break; -+#endif - default: - return -ENXIO; - } -@@ -796,7 +805,10 @@ void __init memory_devfs_register (void) - {7, "full", S_IRUGO | S_IWUGO, &full_fops}, - {8, "random", S_IRUGO | S_IWUSR, &random_fops}, - {9, "urandom", S_IRUGO | S_IWUSR, &urandom_fops}, -- {10, "anon", S_IRUGO | S_IWUSR, &anon_file_operations} -+ {10, "anon", S_IRUGO | S_IWUSR, &anon_file_operations}, -+#ifdef CONFIG_GRKERNSEC -+ {11, "grsec", S_IRUSR | S_IWUGO, &grsec_fops} -+#endif - }; - int i; - -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/drivers/char/vt.c linux-2.4.20-wolk4.15-grsec2/drivers/char/vt.c ---- linux-2.4.20-wolk4.15-fullkernel/drivers/char/vt.c 2004-06-29 11:31:00.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/drivers/char/vt.c 2004-06-29 13:00:19.000000000 +0200 -@@ -179,6 +179,11 @@ do_kdsk_ioctl(int cmd, struct kbentry *u - case KDSKBENT: - if (!perm) - return -EPERM; -+#ifdef CONFIG_GRKERNSEC -+ if (!capable(CAP_SYS_TTY_CONFIG)) -+ return -EPERM; -+#endif +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/gradm2/policy linux-2.4.20-wolk4.16-grsec2/gradm2/policy +--- linux-2.4.20-wolk4.16-fullkernel/gradm2/policy 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/gradm2/policy 2004-09-05 17:07:53.000000000 +0200 +@@ -0,0 +1,234 @@ ++#sample default policy for grsecurity ++# ++# Role flags: ++# A -> This role is an administrative role, thus it has special privilege normal ++# roles do not have. In particular, this role bypasses the ++# additional ptrace restrictions ++# N -> Don't require authentication for this role. To access ++# the role, use gradm2 -n ++# s -> This role is a special role, meaning it does not belong to a ++# user or group, and does not require an enforced secure policy ++# base to be included in the ruleset ++# u -> This role is a user role ++# g -> This role is a group role ++# G -> This role can use gradm2 to authenticate to the kernel ++# A polciy for gradm2 will automatically be added to the role ++# T -> Enable TPE for this role ++# l -> Enable learning for this role ++# ++# a role can only be one of user, group, or special ++# ++# role_allow_ip IP/optional netmask ++# eg: role_allow_ip 192.168.1.0/24 ++# You can have as many of these per role as you want ++# They restrict the use of a role to a list of IPs. If a user ++# is on the system that would normally get the role does not ++# belong to those lists of IPs, the system falls back through ++# its method of determining a role for the user ++# ++# Role hierarchy ++# user -> group -> default ++# First a user role attempts to match, if one is not found, ++# a group role attempts to match, if one is not found, ++# the default role is used. ++# ++# role_transitions ... ++# eg: role_transitions www_admin dns_admin ++# ++# role transitions specify which special roles a given role is allowed ++# to authenticate to. This applies to special roles that do not ++# require password authentication as well. If a user tries to ++# authenticate to a role that is not within his transition table, he ++# will receive a permission denied error ++# ++# Nested subjects ++# subject /bin/su:/bin/bash:/bin/cat ++# / rwx ++# +CAP_ALL ++# grant privilege to specific processes if they are executed ++# within a trusted path. In this case, privilege is ++# granted if /bin/cat is executed from /bin/bash, which is ++# executed from /bin/su. ++# ++# Configuration inheritance on nested subjects ++# nested subjects inherit rules from their parents. In the ++# example above, the nested subject would inherit rules ++# from the nested subject for /bin/su:/bin/bash, ++# and the subject /bin/su ++# View the 1.9.x documentation for more information on ++# configuration inheritance ++# ++# new object modes: ++# m -> allow creation of setuid/setgid files/directories ++# and modification of files/directories to be setuid/setgid ++# M -> audit the setuid/setgid creation/modification ++# c -> allow creation of the file/directory ++# C -> audit the creation ++# d -> allow deletion of the file/directory ++# D -> audit the deletion ++# p -> reject all ptraces to this object ++# new subject modes: ++# r -> relax ptrace restrictions (allows process to ptrace processes ++# other than its own descendants) ++# ++# user/group transitions: ++# You may now specify what users and groups a given subject can ++# transition to. This can be done on an inclusive or exclusive basis. ++# Examples: ++# subject /bin/su ++# user_transition_allow root spender ++# group_transition_allow root spender ++# subject /bin/su ++# user_transition_deny evilhacker ++# subject /bin/su ++# group_transition_deny evilhacker1 evilhacker2 ++# ++# Domains: ++# With domains you can combine users that don't share a common ++# GID as well as groups so that they share a single policy ++# Domains work just like roles, with the only exception being that ++# the line starting with "role" is replaced with one of the following: ++# domain somedomainname u user1 user2 user3 user4 ... usern ++# domain somedomainname g group1 group2 group3 group4 ... groupn ++# ++# New learning system: ++# To learn on a given subject: add l (the letter l, not the number 1) ++# to the subject mode ++# To learn on a given role, add l to the role mode ++# For both of these, to enable learning, enable the system like: ++# gradm2 -L /etc/grsec2/learning.logs -E ++# and then generate the rules after disabling the system after the ++# learning phase with: ++# gradm2 -L /etc/grsec2/learning.logs -O /etc/grsec2/policy ++# To use full system learning, enable the system like: ++# gradm2 -F -L /etc/grsec2/learning.logs ++# and then generate the rules after disabling the system after the ++# learning phase with: ++# gradm2 -F -L /etc/grsec2/learning.logs -O /etc/grsec2/policy + - if (!i && v == K_NOSUCHMAP) { - /* disallocate map */ - key_map = key_maps[s]; -@@ -301,6 +306,11 @@ do_kdgkb_ioctl(int cmd, struct kbsentry - if (!perm) - return -EPERM; - -+#ifdef CONFIG_GRKERNSEC -+ if (!capable(CAP_SYS_TTY_CONFIG)) -+ return -EPERM; -+#endif ++role admin sA ++subject / r ++ / rwcdmxi + - q = func_table[i]; - first_free = funcbufptr + (funcbufsize - funcbufleft); - for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++) -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/fs/binfmt_elf.c linux-2.4.20-wolk4.15-grsec2/fs/binfmt_elf.c ---- linux-2.4.20-wolk4.15-fullkernel/fs/binfmt_elf.c 2004-06-29 11:31:52.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/fs/binfmt_elf.c 2004-06-29 13:00:30.000000000 +0200 -@@ -1079,7 +1079,7 @@ static int load_elf_binary(struct linux_ - #endif - - if (current->flags & PF_PAX_RANDMMAP) -- elf_brk += pax_delta_mask(get_random_long(), 4, PAGE_SHIFT); -+ elf_brk += PAGE_SIZE + pax_delta_mask(get_random_long(), 4, PAGE_SHIFT); - #undef pax_delta_mask - #endif - -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/fs/exec.c linux-2.4.20-wolk4.15-grsec2/fs/exec.c ---- linux-2.4.20-wolk4.15-fullkernel/fs/exec.c 2004-06-29 11:31:52.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/fs/exec.c 2004-06-29 13:00:30.000000000 +0200 -@@ -914,9 +914,6 @@ int prepare_binprm(struct linux_binprm * - cap_set_full(bprm->cap_effective); - } - -- if (gr_handle_ptrace_exec(bprm->file->f_dentry, bprm->file->f_vfsmnt)) -- return -EACCES; -- - memset(bprm->buf,0,BINPRM_BUF_SIZE); - return kernel_read(bprm->file,0,bprm->buf,BINPRM_BUF_SIZE); - } -@@ -979,8 +976,11 @@ void compute_creds(struct linux_binprm * - - /* AUD: Audit candidate if current->cap_effective is set */ - -- current->suid = current->euid = current->fsuid = bprm->e_uid; -- current->sgid = current->egid = current->fsgid = bprm->e_gid; -+ if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid)) -+ current->suid = current->euid = current->fsuid = bprm->e_uid; ++role default G ++role_transitions admin ++subject / ++ / r ++ /opt rx ++ /home rwxcd ++ /mnt rw ++ /dev ++ /dev/grsec h ++ /dev/urandom r ++ /dev/random r ++ /dev/zero rw ++ /dev/input rw ++ /dev/psaux rw ++ /dev/null rw ++ /dev/tty0 rw ++ /dev/tty1 rw ++ /dev/tty2 rw ++ /dev/tty3 rw ++ /dev/tty4 rw ++ /dev/tty5 rw ++ /dev/tty6 rw ++ /dev/tty7 rw ++ /dev/tty8 rw ++ /dev/console rw ++ /dev/tty rw ++ /dev/pts rw ++ /dev/ptmx rw ++ /dev/dsp rw ++ /dev/mixer rw ++ /dev/initctl rw ++ /dev/fd0 r ++ /dev/cdrom r ++ /dev/mem h ++ /dev/kmem h ++ /dev/port h ++ /bin rx ++ /sbin rx ++ /lib rx ++ /usr rx ++ /etc rx ++ /proc rwx ++ /proc/kcore h ++ /proc/sys r ++ /root r ++ /tmp rwcd ++ /var rwxcd ++ /var/tmp rwcd ++ /var/log r ++ /boot r ++ /etc/grsec2 h ++ /etc/ssh h + -+ if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid)) -+ current->sgid = current->egid = current->fsgid = bprm->e_gid; - - gr_handle_chroot_caps(current); - -@@ -1248,7 +1248,9 @@ int do_execve(char * filename, char ** a - current->exec_file = file; - #endif - -- gr_set_proc_label(file->f_dentry, file->f_vfsmnt); -+ retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt); -+ if (retval < 0) -+ goto out_fail; - - retval = search_binary_handler(&bprm,regs); - if (retval >= 0) { -@@ -1284,6 +1286,7 @@ int do_execve(char * filename, char ** a - } - } - -+out_fail: - #ifdef CONFIG_GRKERNSEC - current->acl = old_acl; - memcpy(current->rlim, old_rlim, sizeof(old_rlim)); -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/fs/fcntl.c linux-2.4.20-wolk4.15-grsec2/fs/fcntl.c ---- linux-2.4.20-wolk4.15-fullkernel/fs/fcntl.c 2004-06-29 11:30:55.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/fs/fcntl.c 2004-06-29 13:00:19.000000000 +0200 -@@ -65,10 +65,11 @@ static int locate_fd(struct files_struct - int error; - unsigned int start; - -+ gr_learn_resource(current, RLIMIT_NOFILE, orig_start, 0); ++# if sshd needs to be restarted, it can be done through the admin role ++ /usr/sbin/sshd ++ ++ -CAP_KILL ++ -CAP_SYS_TTY_CONFIG ++ -CAP_LINUX_IMMUTABLE ++ -CAP_NET_RAW ++ -CAP_MKNOD ++ -CAP_SYS_ADMIN ++ -CAP_SYS_RAWIO ++ -CAP_SYS_MODULE ++ -CAP_SYS_PTRACE ++ -CAP_NET_ADMIN ++ -CAP_NET_BIND_SERVICE ++ -CAP_SYS_CHROOT + - write_lock(&files->file_lock); - - error = -EINVAL; -- gr_learn_resource(current, RLIMIT_NOFILE, orig_start, 0); - if (orig_start >= current->rlim[RLIMIT_NOFILE].rlim_cur) - goto out; - -@@ -144,6 +145,8 @@ asmlinkage long sys_dup2(unsigned int ol - struct file * file, *tofree; - struct files_struct * files = current->files; - -+ gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0); ++# RES_AS 100M 100M + - write_lock(&files->file_lock); - if (!(file = fcheck(oldfd))) - goto out_unlock; -@@ -151,7 +154,6 @@ asmlinkage long sys_dup2(unsigned int ol - if (newfd == oldfd) - goto out_unlock; - err = -EBADF; -- gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0); - if (newfd >= current->rlim[RLIMIT_NOFILE].rlim_cur) - goto out_unlock; - get_file(file); /* We are now finished with oldfd */ -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/fs/namei.c linux-2.4.20-wolk4.15-grsec2/fs/namei.c ---- linux-2.4.20-wolk4.15-fullkernel/fs/namei.c 2004-06-29 11:31:21.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/fs/namei.c 2004-06-29 13:00:19.000000000 +0200 -@@ -1331,9 +1331,7 @@ int open_namei(const char * pathname, in - if (error) - return error; - -- if (gr_acl_is_enabled() && nd->dentry->d_inode && -- S_ISBLK(nd->dentry->d_inode->i_mode) && -- !capable(CAP_SYS_RAWIO)) { -+ if (gr_handle_rawio(nd->dentry->d_inode)) { - error = -EPERM; - goto exit; - } -@@ -1385,7 +1383,7 @@ do_last: - up(&dir->d_inode->i_sem); - goto exit_dput; - } -- if (!gr_acl_handle_creat(dentry, nd->dentry, nd->mnt, flag)) { -+ if (!gr_acl_handle_creat(dentry, nd->dentry, nd->mnt, flag, mode)) { - error = -EACCES; - up(&dir->d_inode->i_sem); - goto exit_dput; -@@ -1416,8 +1414,7 @@ do_last: - * It already exists. - */ - -- if (gr_acl_is_enabled() && S_ISBLK(dentry->d_inode->i_mode) && -- !capable(CAP_SYS_RAWIO)) { -+ if (gr_handle_rawio(dentry->d_inode)) { - error = -EPERM; - up(&dir->d_inode->i_sem); - goto exit_dput; -@@ -1871,7 +1868,7 @@ asmlinkage long sys_mknod(const char * f - goto out_dput; - } - -- if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt)) { -+ if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) { - error = -EACCES; - dput(dentry); - goto out_dput; -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/fs/open.c linux-2.4.20-wolk4.15-grsec2/fs/open.c ---- linux-2.4.20-wolk4.15-fullkernel/fs/open.c 2004-06-29 11:31:27.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/fs/open.c 2004-06-29 13:00:19.000000000 +0200 -@@ -726,7 +726,7 @@ asmlinkage long sys_fchmod(unsigned int - if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) - goto out_putf; - -- if (!gr_acl_handle_fchmod(dentry, file->f_vfsmnt)) { -+ if (!gr_acl_handle_fchmod(dentry, file->f_vfsmnt, mode)) { - err = -EACCES; - goto out_putf; - } -@@ -776,7 +776,7 @@ asmlinkage long sys_chmod(const char * f - if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) - goto dput_and_out; - -- if (!gr_acl_handle_chmod(nd.dentry, nd.mnt)) { -+ if (!gr_acl_handle_chmod(nd.dentry, nd.mnt, mode)) { - error = -EACCES; - goto dput_and_out; - } -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/fs/proc/base.c linux-2.4.20-wolk4.15-grsec2/fs/proc/base.c ---- linux-2.4.20-wolk4.15-fullkernel/fs/proc/base.c 2004-06-29 11:32:31.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/fs/proc/base.c 2004-06-29 13:00:19.000000000 +0200 -@@ -248,7 +248,8 @@ static int proc_root_link(struct inode * - #define MAY_PTRACE(task) \ - (task == current || \ - (task->p_pptr == current && \ -- (task->ptrace & PT_PTRACED) && task->state == TASK_STOPPED)) -+ (task->ptrace & PT_PTRACED) && task->state == TASK_STOPPED && \ -+ !gr_handle_proc_ptrace(task))) - - static int may_ptrace_attach(struct task_struct *task) - { -@@ -267,6 +268,8 @@ static int may_ptrace_attach(struct task - rmb(); - if (!is_dumpable(task) && !capable(CAP_SYS_PTRACE)) - goto out; -+ if (gr_handle_proc_ptrace(task)) -+ goto out; - - retval = 1; - -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/grsecurity/Config.in linux-2.4.20-wolk4.15-grsec2/grsecurity/Config.in ---- linux-2.4.20-wolk4.15-fullkernel/grsecurity/Config.in 2004-06-29 11:31:06.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/grsecurity/Config.in 2004-06-29 13:00:19.000000000 +0200 -@@ -110,8 +110,8 @@ define_int CONFIG_GRKERNSEC_ACL_TIMEOUT ++# connect 192.168.1.0/24:22 stream tcp ++# bind 0.0.0.0 stream dgram tcp udp ++ ++# the d flag protects /proc fd and mem entries for sshd ++# all daemons should have 'p' in their subject mode to prevent ++# an attacker from killing the service (and restarting it with trojaned ++# config file or taking the port it reserved to run a trojaned service) ++ ++subject /usr/sbin/sshd dpo ++ / h ++ /bin/bash x ++ /dev h ++ /dev/log rw ++ /dev/null r ++ /dev/ptmx rw ++ /dev/pts rw ++ /dev/tty rw ++ /dev/tty? rw ++ /etc r ++ /etc/grsec2 h ++ /home ++ /lib rx ++ /root ++ /proc ++ /proc/kcore h ++ /proc/sys h ++ /usr/lib rx ++ /var/log ++ /var/mail ++ /var/log/lastlog rw ++ /var/log/wtmp w ++ /var/run/sshd ++ /var/run/utmp rw ++ ++ -CAP_ALL ++ +CAP_CHOWN ++ +CAP_SETGID ++ +CAP_SETUID ++ +CAP_SYS_CHROOT ++ +CAP_SYS_RESOURCE ++ +CAP_SYS_TTY_CONFIG ++ ++subject /usr/X11R6/bin/XFree86 ++ /dev/mem rw ++ ++ +CAP_SYS_ADMIN ++ +CAP_SYS_TTY_CONFIG ++ +CAP_SYS_RAWIO ++ ++subject /usr/bin/ssh ++ /etc/ssh/ssh_config r +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/grsecurity/Config.in linux-2.4.20-wolk4.16-grsec2/grsecurity/Config.in +--- linux-2.4.20-wolk4.16-fullkernel/grsecurity/Config.in 2004-09-05 16:05:39.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/grsecurity/Config.in 2004-09-05 17:07:53.000000000 +0200 +@@ -28,6 +28,7 @@ define_bool CONFIG_GRKERNSEC_PROC n + define_bool CONFIG_GRKERNSEC_PROC_IPADDR n + define_bool CONFIG_GRKERNSEC_PROC_MEMMAP n + define_bool CONFIG_GRKERNSEC_HIDESYM n ++define_bool CONFIG_GRKERNSEC_BRUTE n + define_bool CONFIG_GRKERNSEC_CHROOT_CAPS n + define_bool CONFIG_GRKERNSEC_CHROOT_SYSCTL n + define_bool CONFIG_GRKERNSEC_PROC_USERGROUP n +@@ -110,8 +111,8 @@ define_int CONFIG_GRKERNSEC_ACL_TIMEOUT define_int CONFIG_GRKERNSEC_FLOODTIME 10 define_int CONFIG_GRKERNSEC_FLOODBURST 4 @@ -9870,7 +10718,36 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke define_bool CONFIG_GRKERNSEC_LINK y define_bool CONFIG_GRKERNSEC_FIFO y define_bool CONFIG_GRKERNSEC_RANDPID y -@@ -307,7 +307,7 @@ bool 'Remove addresses from /proc/pid/[m +@@ -143,6 +144,7 @@ define_bool CONFIG_GRKERNSEC_PAX_RANDKST + define_bool CONFIG_GRKERNSEC_PAX_KERNEXEC n + define_bool CONFIG_GRKERNSEC_PAX_ASLR y + define_bool CONFIG_GRKERNSEC_PAX_RANDMMAP y ++define_bool CONFIG_GRKERNSEC_BRUTE n + fi + if [ "$CONFIG_GRKERNSEC_HI" = "y" ]; then + define_int CONFIG_GRKERNSEC_FLOODTIME 10 +@@ -175,6 +177,7 @@ define_bool CONFIG_GRKERNSEC_PROC y + define_bool CONFIG_GRKERNSEC_PROC_IPADDR n + define_bool CONFIG_GRKERNSEC_PROC_MEMMAP y + define_bool CONFIG_GRKERNSEC_HIDESYM y ++define_bool CONFIG_GRKERNSEC_BRUTE y + define_bool CONFIG_GRKERNSEC_PROC_USERGROUP y + define_int CONFIG_GRKERNSEC_PROC_GID 10 + define_bool CONFIG_GRKERNSEC_KMEM y +@@ -228,7 +231,7 @@ bool 'Use ELF program header marking' CO + choice 'MAC system integration' \ + "none CONFIG_GRKERNSEC_PAX_NO_ACL_FLAGS \ + direct CONFIG_GRKERNSEC_PAX_HAVE_ACL_FLAGS \ +- hook CONFIG_GRKERNSEC_PAX_HOOK_ACL_FLAGS" none ++ hook CONFIG_GRKERNSEC_PAX_HOOK_ACL_FLAGS" direct + endmenu + mainmenu_option next_comment + comment 'Address Space Protection' +@@ -304,10 +307,11 @@ if [ "$CONFIG_X86" = "y" ]; then + fi + fi + bool 'Remove addresses from /proc/pid/[maps|stat]' CONFIG_GRKERNSEC_PROC_MEMMAP ++bool 'Deter exploit bruteforcing' CONFIG_GRKERNSEC_BRUTE bool 'Hide kernel symbols' CONFIG_GRKERNSEC_HIDESYM endmenu mainmenu_option next_comment @@ -9879,9 +10756,9 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke bool 'Hide kernel processes' CONFIG_GRKERNSEC_ACL_HIDEKERN int 'Maximum tries before password lockout' CONFIG_GRKERNSEC_ACL_MAXTRIES 3 int 'Time to wait after max password tries, in seconds' CONFIG_GRKERNSEC_ACL_TIMEOUT 30 -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/grsecurity/Makefile linux-2.4.20-wolk4.15-grsec2/grsecurity/Makefile ---- linux-2.4.20-wolk4.15-fullkernel/grsecurity/Makefile 2004-06-29 11:31:05.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/grsecurity/Makefile 2004-06-29 13:00:19.000000000 +0200 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/grsecurity/Makefile linux-2.4.20-wolk4.16-grsec2/grsecurity/Makefile +--- linux-2.4.20-wolk4.16-fullkernel/grsecurity/Makefile 2004-09-05 16:05:37.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/grsecurity/Makefile 2004-09-05 17:07:52.000000000 +0200 @@ -15,7 +15,7 @@ obj-y = grsec_chdir.o grsec_chroot.o grs ifeq ($(CONFIG_GRKERNSEC),y) obj-y += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o obsd_rand.o \ @@ -9891,10 +10768,10 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o else obj-y += grsec_disabled.o -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/grsecurity/gracl.c linux-2.4.20-wolk4.15-grsec2/grsecurity/gracl.c ---- linux-2.4.20-wolk4.15-fullkernel/grsecurity/gracl.c 2004-06-29 11:31:05.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/grsecurity/gracl.c 2004-06-29 13:00:37.000000000 +0200 -@@ -26,34 +26,44 @@ +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/grsecurity/gracl.c linux-2.4.20-wolk4.16-grsec2/grsecurity/gracl.c +--- linux-2.4.20-wolk4.16-fullkernel/grsecurity/gracl.c 2004-09-05 16:05:37.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/grsecurity/gracl.c 2004-09-05 17:07:53.000000000 +0200 +@@ -26,34 +26,48 @@ #include #include @@ -9910,9 +10787,13 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke +/* for keeping track of userspace pointers used for subjects, so we + can share references in the kernel as well +*/ -+static struct acl_subj_map_db subj_map_set; -static DECLARE_MUTEX(gr_proc_sem); ++static struct dentry *real_root; ++static struct vfsmount *real_root_mnt; ++ ++static struct acl_subj_map_db subj_map_set; ++ + +static struct acl_role_label *default_role; + @@ -9953,7 +10834,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke /* The following are used to keep a place held in the hash table when we move entries around. They can be replaced during insert. */ -@@ -62,6 +72,15 @@ static struct acl_subject_label *deleted +@@ -62,6 +76,15 @@ static struct acl_subject_label *deleted static struct acl_object_label *deleted_object; static struct name_entry *deleted_inodev; @@ -9969,10 +10850,11 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke extern int gr_init_uidset(void); extern void gr_free_uidset(void); extern void gr_remove_uid(uid_t uid); -@@ -73,6 +92,85 @@ gr_acl_is_enabled(void) +@@ -73,26 +96,100 @@ gr_acl_is_enabled(void) return (gr_status & GR_READY); } +-static __inline__ char * +char gr_roletype_to_char(void) +{ + switch (current->role->roletype & @@ -10005,13 +10887,12 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke +int +gr_handle_rawio(const struct inode *inode) +{ -+ if (inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO) && -+ ((gr_status & GR_READY) +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS -+ || (grsec_enable_chroot_caps && proc_is_chrooted(current)) -+#endif -+ )) ++ if (inode && S_ISBLK(inode->i_mode) && ++ grsec_enable_chroot_caps && proc_is_chrooted(current) && ++ !capable(CAP_SYS_RAWIO)) + return 1; ++#endif + return 0; +} + @@ -10052,10 +10933,34 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke + return 1; +} + - static __inline__ char * ++static char * d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt, char *buf, int buflen) -@@ -101,10 +199,64 @@ d_real_path(const struct dentry *dentry, + { + char *res; +- struct dentry *our_dentry; +- struct vfsmount *our_mount; +- struct vfsmount *rootmnt; + struct dentry *root; ++ struct vfsmount *rootmnt; + +- our_dentry = (struct dentry *) dentry; +- our_mount = (struct vfsmount *) vfsmnt; +- ++ /* we can't use real_root, real_root_mnt, because they belong only to the RBAC system */ + read_lock(&child_reaper->fs->lock); +- rootmnt = mntget(child_reaper->fs->rootmnt); + root = dget(child_reaper->fs->root); ++ rootmnt = mntget(child_reaper->fs->rootmnt); + read_unlock(&child_reaper->fs->lock); + + spin_lock(&dcache_lock); +- res = __d_path(our_dentry, our_mount, root, rootmnt, buf, buflen); ++ res = __d_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, root, rootmnt, buf, buflen); + spin_unlock(&dcache_lock); + if (unlikely(IS_ERR(res))) + res = strcpy(buf, ""); +@@ -101,10 +198,60 @@ d_real_path(const struct dentry *dentry, return res; } @@ -10064,20 +10969,16 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke + char *buf, int buflen) +{ + char *res; -+ struct dentry *our_dentry; -+ struct vfsmount *our_mount; -+ struct vfsmount *rootmnt; + struct dentry *root; ++ struct vfsmount *rootmnt; + -+ our_dentry = (struct dentry *) dentry; -+ our_mount = (struct vfsmount *) vfsmnt; -+ ++ /* we can't use real_root, real_root_mnt, because they belong only to the RBAC system */ + read_lock(&child_reaper->fs->lock); -+ rootmnt = mntget(child_reaper->fs->rootmnt); + root = dget(child_reaper->fs->root); ++ rootmnt = mntget(child_reaper->fs->rootmnt); + read_unlock(&child_reaper->fs->lock); + -+ res = __d_path(our_dentry, our_mount, root, rootmnt, buf, buflen); ++ res = __d_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, root, rootmnt, buf, buflen); + if (unlikely(IS_ERR(res))) + res = strcpy(buf, ""); + dput(root); @@ -10121,7 +11022,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke PAGE_SIZE); } -@@ -119,29 +271,133 @@ to_gr_audit(const __u32 reqmode) +@@ -119,29 +266,146 @@ to_gr_audit(const __u32 reqmode) retmode |= (reqmode & GR_EXEC) ? GR_AUDIT_EXEC : 0; retmode |= (reqmode & GR_INHERIT) ? GR_AUDIT_INHERIT : 0; retmode |= (reqmode & GR_FIND) ? GR_AUDIT_FIND : 0; @@ -10156,8 +11057,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke + +static void +insert_subj_map_entry(struct subject_map *subjmap) - { -- unsigned long index = fhash(ino, dev, acl_subj_set.s_size); ++{ + unsigned long index = shash(subjmap->user, subj_map_set.s_size); + struct subject_map **curr; + __u8 i = 0; @@ -10182,30 +11082,43 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke + unsigned long index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size); + struct acl_role_label *match; + struct role_allowed_ip *ipp; ++ int x; + __u8 i = 0; + + match = acl_role_set.r_hash[index]; + -+ while (match -+ && (match->uidgid != uid || !(match->roletype & GR_ROLE_USER))) { ++ while (match) { ++ if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_USER)) == (GR_ROLE_DOMAIN | GR_ROLE_USER)) { ++ for (x = 0; x < match->domain_child_num; x++) { ++ if (match->domain_children[x] == uid) ++ goto found; ++ } ++ } else if (match->uidgid == uid && match->roletype & GR_ROLE_USER) ++ break; + index = (index + (1 << i)) % acl_role_set.r_size; + match = acl_role_set.r_hash[index]; + i = (i + 1) % 32; + } -+ ++found: + if (match == NULL) { + try_group: + index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size); + match = acl_role_set.r_hash[index]; + i = 0; + -+ while (match && (match->uidgid != gid -+ || !(match->roletype & GR_ROLE_GROUP))) { ++ while (match) { ++ if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) == (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) { ++ for (x = 0; x < match->domain_child_num; x++) { ++ if (match->domain_children[x] == gid) ++ goto found2; ++ } ++ } else if (match->uidgid == gid && match->roletype & GR_ROLE_GROUP) ++ break; + index = (index + (1 << i)) % acl_role_set.r_size; + match = acl_role_set.r_hash[index]; + i = (i + 1) % 32; + } -+ ++found2: + if (match == NULL) + match = default_role; + if (match->allowed_ips == NULL) @@ -10213,8 +11126,8 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke + else { + for (ipp = match->allowed_ips; ipp; ipp = ipp->next) { + if (likely -+ ((task->curr_ip & ipp->netmask) == -+ (ipp->addr & ipp->netmask))) ++ ((ntohl(task->curr_ip) & ipp->netmask) == ++ (ntohl(ipp->addr) & ipp->netmask))) + return match; + } + match = default_role; @@ -10224,8 +11137,8 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke + } else { + for (ipp = match->allowed_ips; ipp; ipp = ipp->next) { + if (likely -+ ((task->curr_ip & ipp->netmask) == -+ (ipp->addr & ipp->netmask))) ++ ((ntohl(task->curr_ip) & ipp->netmask) == ++ (ntohl(ipp->addr) & ipp->netmask))) + return match; + } + goto try_group; @@ -10237,7 +11150,8 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke +__inline__ struct acl_subject_label * +lookup_acl_subj_label(const ino_t ino, const kdev_t dev, + const struct acl_role_label *role) -+{ + { +- unsigned long index = fhash(ino, dev, acl_subj_set.s_size); + unsigned long subj_size = role->subj_hash_size; + struct acl_subject_label **s_hash = role->subj_hash; + unsigned long index = fhash(ino, dev, subj_size); @@ -10263,7 +11177,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke return match; else return NULL; -@@ -166,9 +422,7 @@ lookup_acl_obj_label(const ino_t ino, co +@@ -166,9 +430,7 @@ lookup_acl_obj_label(const ino_t ino, co i = (i + 1) % 32; } @@ -10274,7 +11188,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke return match; else return NULL; -@@ -193,13 +447,11 @@ lookup_acl_obj_label_create(const ino_t +@@ -193,13 +455,11 @@ lookup_acl_obj_label_create(const ino_t i = (i + 1) % 32; } @@ -10290,7 +11204,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke match = o_hash[index]; while (match && (match->inode != ino || match->device != dev || -@@ -209,9 +461,7 @@ lookup_acl_obj_label_create(const ino_t +@@ -209,9 +469,7 @@ lookup_acl_obj_label_create(const ino_t i = (i + 1) % 32; } @@ -10301,7 +11215,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke return match; else return NULL; -@@ -220,22 +470,20 @@ lookup_acl_obj_label_create(const ino_t +@@ -220,22 +478,20 @@ lookup_acl_obj_label_create(const ino_t static __inline__ struct name_entry * lookup_name_entry(const char *name) { @@ -10328,7 +11242,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke } static __inline__ struct name_entry * -@@ -253,16 +501,12 @@ lookup_inodev_entry(const ino_t ino, con +@@ -253,16 +509,12 @@ lookup_inodev_entry(const ino_t ino, con i = (i + 1) % 32; } @@ -10346,15 +11260,15 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke static void insert_inodev_entry(struct name_entry *nentry) { -@@ -284,16 +528,38 @@ insert_inodev_entry(struct name_entry *n +@@ -284,16 +536,50 @@ insert_inodev_entry(struct name_entry *n return; } +static void -+insert_acl_role_label(struct acl_role_label *role) ++__insert_acl_role_label(struct acl_role_label *role, uid_t uidgid) +{ + unsigned long index = -+ rhash(role->uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size); ++ rhash(uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size); + struct acl_role_label **curr; + __u8 i = 0; + @@ -10371,6 +11285,18 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke + return; +} + ++static void ++insert_acl_role_label(struct acl_role_label *role) ++{ ++ int i; ++ ++ if (role->roletype & GR_ROLE_DOMAIN) { ++ for (i = 0; i < role->domain_child_num; i++) ++ __insert_acl_role_label(role, role->domain_children[i]); ++ } else ++ __insert_acl_role_label(role, role->uidgid); ++} ++ static int insert_name_entry(char *name, const ino_t inode, const kdev_t device) { @@ -10387,7 +11313,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke index = (index + (1 << i)) % name_set.n_size; curr = &name_set.n_hash[index]; i = (i + 1) % 32; -@@ -307,6 +573,7 @@ insert_name_entry(char *name, const ino_ +@@ -307,6 +593,7 @@ insert_name_entry(char *name, const ino_ nentry->name = name; nentry->inode = inode; nentry->device = device; @@ -10395,7 +11321,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke *curr = nentry; /* insert us into the table searchable by inode/dev */ insert_inodev_entry(nentry); -@@ -338,18 +605,20 @@ insert_acl_obj_label(struct acl_object_l +@@ -338,18 +625,20 @@ insert_acl_obj_label(struct acl_object_l } static void @@ -10422,7 +11348,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke i = (i + 1) % 32; } -@@ -358,11 +627,6 @@ insert_acl_subj_label(struct acl_subject +@@ -358,11 +647,6 @@ insert_acl_subj_label(struct acl_subject return; } @@ -10434,40 +11360,46 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke static void ** create_table(__u32 * len) { -@@ -395,12 +659,18 @@ create_table(__u32 * len) +@@ -394,22 +678,21 @@ create_table(__u32 * len) + } static int - init_variables(const unsigned long acl_obj_size, -+ const unsigned long acl_glob_size, - const unsigned long acl_subj_size, +-init_variables(const unsigned long acl_obj_size, +- const unsigned long acl_subj_size, - const unsigned long acl_ip_size) -+ const unsigned long acl_ip_size, -+ const unsigned long acl_role_size, -+ const unsigned long allowed_ip_size, -+ const unsigned long acl_trans_size, -+ const __u16 num_sprole_pws) ++init_variables(const struct gr_arg *arg) { unsigned long stacksize; - acl_subj_set.s_size = acl_subj_size; -+ subj_map_set.s_size = acl_subj_size; -+ acl_role_set.r_size = acl_role_size; - name_set.n_size = (acl_obj_size + acl_subj_size); - inodev_set.n_size = (acl_obj_size + acl_subj_size); +- name_set.n_size = (acl_obj_size + acl_subj_size); +- inodev_set.n_size = (acl_obj_size + acl_subj_size); ++ subj_map_set.s_size = arg->role_db.num_subjects; ++ acl_role_set.r_size = arg->role_db.num_roles + arg->role_db.num_domain_children; ++ name_set.n_size = arg->role_db.num_objects; ++ inodev_set.n_size = arg->role_db.num_objects; -@@ -409,7 +679,9 @@ init_variables(const unsigned long acl_o + if (!gr_init_uidset()) + return 1; /* set up the stack that holds allocation info */ - stacksize = (3 * acl_obj_size) + (4 * acl_subj_size) + acl_ip_size + 3; -+ stacksize = (3 * acl_obj_size) + (3 * acl_role_size) + -+ (6 * acl_subj_size) + acl_ip_size + (2 * acl_trans_size) + -+ allowed_ip_size + (2 * num_sprole_pws) + (2 * acl_glob_size) + 5; ++ stacksize = arg->role_db.num_pointers + 5; if (!acl_alloc_stack_init(stacksize)) return 1; -@@ -433,16 +705,22 @@ init_variables(const unsigned long acl_o +@@ -431,18 +714,31 @@ init_variables(const unsigned long acl_o + memset(deleted_object, 0, sizeof (struct acl_object_label)); + memset(deleted_inodev, 0, sizeof (struct name_entry)); ++ /* grab reference for the real root dentry and vfsmount */ ++ read_lock(&child_reaper->fs->lock); ++ real_root_mnt = mntget(child_reaper->fs->rootmnt); ++ real_root = dget(child_reaper->fs->root); ++ read_unlock(&child_reaper->fs->lock); ++ ++ /* We only want 50% full tables for now */ - acl_subj_set.s_hash = @@ -10494,7 +11426,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke memset(name_set.n_hash, 0, sizeof (struct name_entry *) * name_set.n_size); memset(inodev_set.n_hash, 0, -@@ -451,42 +729,83 @@ init_variables(const unsigned long acl_o +@@ -451,42 +747,91 @@ init_variables(const unsigned long acl_o return 0; } @@ -10545,6 +11477,14 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke } read_unlock(&tasklist_lock); ++ /* release the reference to the real root dentry and vfsmount */ ++ if (real_root) ++ dput(real_root); ++ real_root = NULL; ++ if (real_root_mnt) ++ mntput(real_root_mnt); ++ real_root_mnt = NULL; ++ /* free all object hash tables */ - if (subj_list_head) { @@ -10592,7 +11532,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke } if (name_set.n_hash) { if ((name_set.n_size * sizeof (struct name_entry *)) <= -@@ -508,12 +827,11 @@ free_variables(void) +@@ -508,12 +853,11 @@ free_variables(void) memset(&name_set, 0, sizeof (struct name_db)); memset(&inodev_set, 0, sizeof (struct name_db)); @@ -10609,15 +11549,14 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke return; } -@@ -536,11 +854,61 @@ count_user_objs(struct acl_object_label +@@ -536,11 +880,61 @@ count_user_objs(struct acl_object_label return num; } +static struct acl_subject_label * +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role); + - static int --copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj) ++static int +copy_user_glob(struct acl_object_label *obj) +{ + struct acl_object_label *g_tmp, **guser, *glast = NULL; @@ -10662,7 +11601,8 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke + return 0; +} + -+static int + static int +-copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj) +copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj, + struct acl_role_label *role) { @@ -10672,7 +11612,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke char *tmp; while (userp) { -@@ -571,56 +939,443 @@ copy_user_objs(struct acl_object_label * +@@ -571,147 +965,524 @@ copy_user_objs(struct acl_object_label * if (!insert_name_entry(o_tmp->filename, o_tmp->inode, o_tmp->device)) return -ENOMEM; @@ -10693,17 +11633,46 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke return 0; } +-static int +-copy_user_acl(struct gr_arg *arg) +static __u32 +count_user_subjs(struct acl_subject_label *userp) -+{ + { +- struct acl_subject_label *s_tmp = NULL, **s_utmp, *s_utmp2, *s_last; +- struct acl_ip_label **i_tmp, *i_utmp2; +- unsigned long s_num, i_num; +- char *tmp; +- int err = 0; +- unsigned int len; +- __u32 num_objs; +- +- s_utmp = (struct acl_subject_label **) arg->subj_db.s_table; + struct acl_subject_label s_tmp; + __u32 num = 0; -+ + +- for (s_num = 0; s_num < arg->subj_db.s_entries; s_num++) { +- s_last = s_tmp; +- if ((s_tmp = +- acl_alloc(sizeof (struct acl_subject_label))) == NULL) { +- err = -ENOMEM; +- goto cleanup; +- } +- if (copy_from_user(&s_utmp2, s_utmp + s_num, +- sizeof (struct acl_subject_label *))) { +- err = -EFAULT; +- goto cleanup; +- } +- if (copy_from_user(s_tmp, s_utmp2, +- sizeof (struct acl_subject_label))) { +- err = -EFAULT; +- goto cleanup; +- } + while (userp) { + if (copy_from_user(&s_tmp, userp, + sizeof (struct acl_subject_label))) + break; -+ + +- /* set up subject pointers */ + userp = s_tmp.prev; + /* do not count nested subjects against this count, since + they are not included in the hash table, but are @@ -10714,46 +11683,80 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke + if (!(s_tmp.mode & GR_NESTED)) + num++; + } -+ + +- if (!s_last) { +- s_tmp->prev = NULL; +- subj_list_head = s_tmp; +- } else { +- s_last->next = s_tmp; +- s_tmp->prev = s_last; +- } + return num; +} -+ - static int --copy_user_acl(struct gr_arg *arg) + +- if (s_num == (arg->subj_db.s_entries - 1)) +- s_tmp->next = NULL; ++static int +copy_user_allowedips(struct acl_role_label *rolep) - { -- struct acl_subject_label *s_tmp = NULL, **s_utmp, *s_utmp2, *s_last; -- struct acl_ip_label **i_tmp, *i_utmp2; -- unsigned long s_num, i_num; ++{ + struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast; -+ + +- len = strnlen_user(s_tmp->filename, PATH_MAX); + ruserip = rolep->allowed_ips; -+ + +- if (!len || len >= PATH_MAX) { +- err = -EINVAL; +- goto cleanup; +- } + while (ruserip) { + rlast = rtmp; -+ + +- if ((tmp = (char *) acl_alloc(len)) == NULL) { +- err = -ENOMEM; +- goto cleanup; +- } +- if (copy_from_user(tmp, s_tmp->filename, len)) { +- err = -EFAULT; +- goto cleanup; +- } +- s_tmp->filename = tmp; + if ((rtmp = (struct role_allowed_ip *) + acl_alloc(sizeof (struct role_allowed_ip))) == NULL) + return -ENOMEM; -+ + +- /* set up object hash table */ +- num_objs = count_user_objs(s_tmp->proc_object); + if (copy_from_user(rtmp, ruserip, + sizeof (struct role_allowed_ip))) + return -EFAULT; -+ + +- s_tmp->obj_hash_size = num_objs; +- s_tmp->obj_hash = +- (struct acl_object_label **) +- create_table(&(s_tmp->obj_hash_size)); + ruserip = rtmp->prev; -+ + +- if (!s_tmp->obj_hash) { +- err = -ENOMEM; +- goto cleanup; + if (!rlast) { + rtmp->prev = NULL; + rolep->allowed_ips = rtmp; + } else { + rlast->next = rtmp; + rtmp->prev = rlast; -+ } -+ + } +- memset(s_tmp->obj_hash, 0, +- s_tmp->obj_hash_size * +- sizeof (struct acl_object_label *)); + +- /* add in objects */ +- err = copy_user_objs(s_tmp->proc_object, s_tmp); + if (!ruserip) + rtmp->next = NULL; + } -+ + +- if (err) + return 0; +} + @@ -10762,8 +11765,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke +{ + struct role_transition *rusertp, *rtmp = NULL, *rlast; + unsigned int len; - char *tmp; -- int err = 0; ++ char *tmp; + + rusertp = rolep->transitions; + @@ -10812,9 +11814,9 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role) +{ + struct acl_subject_label *s_tmp = NULL, *s_tmp2; - unsigned int len; ++ unsigned int len; + char *tmp; - __u32 num_objs; ++ __u32 num_objs; + struct acl_ip_label **i_tmp, *i_utmp2; + struct gr_hash_struct ghash; + struct subject_map *subjmap; @@ -10937,14 +11939,9 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke + + s_tmp->parent_subject = s_tmp2; + } - -- s_utmp = (struct acl_subject_label **) arg->subj_db.s_table; ++ + /* add in ip acls */ - -- for (s_num = 0; s_num < arg->subj_db.s_entries; s_num++) { -- s_last = s_tmp; -- if ((s_tmp = -- acl_alloc(sizeof (struct acl_subject_label))) == NULL) { ++ + if (!s_tmp->ip_num) { + s_tmp->ips = NULL; + goto insert; @@ -11029,6 +12026,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke + struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2, *r_last; + struct sprole_pw *sptmp; + struct gr_hash_struct *ghash; ++ uid_t *domainlist; + unsigned long r_num; + unsigned int len; + char *tmp; @@ -11037,7 +12035,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke + __u32 num_subjs; + + /* we need a default and kernel role */ -+ if (arg->role_db.r_entries < 2) ++ if (arg->role_db.num_roles < 2) + return -EINVAL; + + /* copy special role authentication info from userspace */ @@ -11053,18 +12051,14 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke + for (i = 0; i < num_sprole_pws; i++) { + sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw)); + if (!sptmp) { - err = -ENOMEM; - goto cleanup; - } -- if (copy_from_user(&s_utmp2, s_utmp + s_num, -- sizeof (struct acl_subject_label *))) { ++ err = -ENOMEM; ++ goto cleanup; ++ } + if (copy_from_user(sptmp, arg->sprole_pws + i, + sizeof (struct sprole_pw))) { - err = -EFAULT; - goto cleanup; - } -- if (copy_from_user(s_tmp, s_utmp2, -- sizeof (struct acl_subject_label))) { ++ err = -EFAULT; ++ goto cleanup; ++ } + + len = + strnlen_user(sptmp->rolename, GR_SPROLE_LEN); @@ -11093,7 +12087,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke + + r_utmp = (struct acl_role_label **) arg->role_db.r_table; + -+ for (r_num = 0; r_num < arg->role_db.r_entries; r_num++) { ++ for (r_num = 0; r_num < arg->role_db.num_roles; r_num++) { + r_last = r_tmp; + + r_tmp = acl_alloc(sizeof (struct acl_role_label)); @@ -11105,87 +12099,34 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke + + if (copy_from_user(&r_utmp2, r_utmp + r_num, + sizeof (struct acl_role_label *))) { - err = -EFAULT; - goto cleanup; - } - -- /* set up subject pointers */ ++ err = -EFAULT; ++ goto cleanup; ++ } ++ + if (copy_from_user(r_tmp, r_utmp2, + sizeof (struct acl_role_label))) { + err = -EFAULT; + goto cleanup; + } - -- if (!s_last) { -- s_tmp->prev = NULL; -- subj_list_head = s_tmp; ++ + if (!r_last) { + r_tmp->prev = NULL; + role_list_head = r_tmp; - } else { -- s_last->next = s_tmp; -- s_tmp->prev = s_last; ++ } else { + r_last->next = r_tmp; + r_tmp->prev = r_last; - } - -- if (s_num == (arg->subj_db.s_entries - 1)) -- s_tmp->next = NULL; -+ if (r_num == (arg->role_db.r_entries - 1)) -+ r_tmp->next = NULL; - -- len = strnlen_user(s_tmp->filename, PATH_MAX); -+ len = strnlen_user(r_tmp->rolename, PATH_MAX); - - if (!len || len >= PATH_MAX) { - err = -EINVAL; -@@ -631,87 +1386,62 @@ copy_user_acl(struct gr_arg *arg) - err = -ENOMEM; - goto cleanup; - } -- if (copy_from_user(tmp, s_tmp->filename, len)) { -+ if (copy_from_user(tmp, r_tmp->rolename, len)) { - err = -EFAULT; - goto cleanup; - } -- s_tmp->filename = tmp; -+ r_tmp->rolename = tmp; - -- /* set up object hash table */ -- num_objs = count_user_objs(s_tmp->proc_object); -- -- s_tmp->obj_hash_size = num_objs; -- s_tmp->obj_hash = -- (struct acl_object_label **) -- create_table(&(s_tmp->obj_hash_size)); -+ if (!strcmp(r_tmp->rolename, "default") -+ && (r_tmp->roletype & GR_ROLE_DEFAULT)) { -+ default_role = r_tmp; -+ } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) { -+ kernel_role = r_tmp; + } - -- if (!s_tmp->obj_hash) { -+ if ((ghash = (struct gr_hash_struct *) acl_alloc(sizeof(struct gr_hash_struct))) == NULL) { - err = -ENOMEM; ++ ++ if (r_num == (arg->role_db.num_roles - 1)) ++ r_tmp->next = NULL; ++ ++ len = strnlen_user(r_tmp->rolename, GR_SPROLE_LEN); ++ ++ if (!len || len >= PATH_MAX) { ++ err = -EINVAL; goto cleanup; - } -- memset(s_tmp->obj_hash, 0, -- s_tmp->obj_hash_size * -- sizeof (struct acl_object_label *)); -+ if (copy_from_user(ghash, r_tmp->hash, sizeof(struct gr_hash_struct))) { -+ err = -EFAULT; -+ goto cleanup; + } -- /* add in objects */ -- err = copy_user_objs(s_tmp->proc_object, s_tmp); -+ r_tmp->hash = ghash; - -- if (err) -- goto cleanup; -+ num_subjs = count_user_subjs(r_tmp->hash->first); - - if (!(strcmp(s_tmp->filename, "god"))) - god_label = s_tmp; - if (!(strcmp(s_tmp->filename, "kernel"))) @@ -11205,23 +12146,61 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke - sizeof (struct - acl_ip_label - *))) == NULL) { -+ r_tmp->subj_hash_size = num_subjs; -+ r_tmp->subj_hash = -+ (struct acl_subject_label **) -+ create_table(&(r_tmp->subj_hash_size)); -+ -+ if (!r_tmp->subj_hash) { ++ if ((tmp = (char *) acl_alloc(len)) == NULL) { err = -ENOMEM; goto cleanup; } ++ if (copy_from_user(tmp, r_tmp->rolename, len)) { ++ err = -EFAULT; ++ goto cleanup; ++ } ++ r_tmp->rolename = tmp; ++ ++ if (!strcmp(r_tmp->rolename, "default") ++ && (r_tmp->roletype & GR_ROLE_DEFAULT)) { ++ default_role = r_tmp; ++ } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) { ++ kernel_role = r_tmp; ++ } ++ ++ if ((ghash = (struct gr_hash_struct *) acl_alloc(sizeof(struct gr_hash_struct))) == NULL) { ++ err = -ENOMEM; ++ goto cleanup; ++ } ++ if (copy_from_user(ghash, r_tmp->hash, sizeof(struct gr_hash_struct))) { ++ err = -EFAULT; ++ goto cleanup; ++ } ++ ++ r_tmp->hash = ghash; ++ ++ num_subjs = count_user_subjs(r_tmp->hash->first); - for (i_num = 0; i_num < s_tmp->ip_num; i_num++) { - if ((*(i_tmp + i_num) = - (struct acl_ip_label *) - acl_alloc(sizeof (struct acl_ip_label))) == NULL) { -- err = -ENOMEM; -- goto cleanup; -- } ++ r_tmp->subj_hash_size = num_subjs; ++ r_tmp->subj_hash = ++ (struct acl_subject_label **) ++ create_table(&(r_tmp->subj_hash_size)); ++ ++ if (!r_tmp->subj_hash) { ++ err = -ENOMEM; ++ goto cleanup; ++ } ++ ++ err = copy_user_allowedips(r_tmp); ++ if (err) ++ goto cleanup; ++ ++ /* copy domain info */ ++ if (r_tmp->domain_children != NULL) { ++ domainlist = acl_alloc(r_tmp->domain_child_num * sizeof(uid_t)); ++ if (domainlist == NULL) { + err = -ENOMEM; + goto cleanup; + } - if (copy_from_user - (&i_utmp2, s_tmp->ips + i_num, - sizeof (struct acl_ip_label *))) { @@ -11231,13 +12210,12 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke - if (copy_from_user - (*(i_tmp + i_num), i_utmp2, - sizeof (struct acl_ip_label))) { -- err = -EFAULT; -- goto cleanup; -- } -- } -+ err = copy_user_allowedips(r_tmp); -+ if (err) -+ goto cleanup; ++ if (copy_from_user(domainlist, r_tmp->domain_children, r_tmp->domain_child_num * sizeof(uid_t))) { + err = -EFAULT; + goto cleanup; + } ++ r_tmp->domain_children = domainlist; + } - s_tmp->ips = i_tmp; + err = copy_user_transitions(r_tmp); @@ -11265,28 +12243,25 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke } cleanup: -@@ -724,14 +1454,13 @@ gracl_init(struct gr_arg *args) +@@ -724,14 +1495,10 @@ gracl_init(struct gr_arg *args) { int error = 0; - memcpy(gr_pwent->salt, args->salt, GR_SALT_LEN); - memcpy(gr_pwent->sum, args->sum, GR_SHA_LEN); -- -- if (args->subj_db.s_entries < 3) -- return -EINVAL; + memcpy(gr_system_salt, args->salt, GR_SALT_LEN); + memcpy(gr_system_sum, args->sum, GR_SHA_LEN); +- if (args->subj_db.s_entries < 3) +- return -EINVAL; +- - if (init_variables(args->subj_db.o_entries, args->subj_db.s_entries, - args->subj_db.i_entries)) { -+ if (init_variables(args->role_db.o_entries, args->role_db.g_entries, -+ args->role_db.s_entries, args->role_db.i_entries, -+ args->role_db.r_entries, args->role_db.a_entries, -+ args->role_db.t_entries, args->num_sprole_pws)) { ++ if (init_variables(args)) { security_alert_good(GR_INITF_ACL_MSG, GR_VERSION); error = -ENOMEM; free_variables(); -@@ -739,6 +1468,7 @@ gracl_init(struct gr_arg *args) +@@ -739,6 +1506,7 @@ gracl_init(struct gr_arg *args) } error = copy_user_acl(args); @@ -11294,7 +12269,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke if (error) { free_variables(); goto out; -@@ -750,24 +1480,105 @@ gracl_init(struct gr_arg *args) +@@ -750,44 +1518,210 @@ gracl_init(struct gr_arg *args) } gr_status |= GR_READY; @@ -11306,40 +12281,135 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke -/* * * * * * * * * * * * * * * * * * * * * * * - * Begin Misc Section - * * * * * * * * * * * * * * * * * * * * * * */ -+static int -+glob_match(char *pattern, char *string) -+{ -+ char *p1, *p2; ++/* derived from glibc fnmatch() 0: match, 1: no match*/ -static __u32 -+ p1 = pattern; -+ p2 = string; ++static int ++glob_match(const char *pattern, const char *string) ++{ ++ char *p = pattern, *n = string; ++ char c; + -+ while (*p1 != '\0' && *p2 != '\0' && *p1 != '*') { -+ if (*p1 == *p2 || *p1 == '?') { -+ p1++; -+ p2++; -+ } else ++ while ((c = *p++) != '\0') { ++ switch (c) { ++ case '?': ++ if (*n == '\0') ++ return 1; ++ else if (*n == '/') ++ return 1; ++ break; ++ case '\\': ++ if (*n != c) ++ return 1; ++ break; ++ case '*': ++ for (c = *p++; c == '?' || c == '*'; c = *p++) { ++ if (*n == '/') ++ return 1; ++ else if (c == '?') { ++ if (*n == '\0') ++ return 1; ++ else ++ ++n; ++ } ++ } ++ if (c == '\0') { ++ if (strchr(n, '/') != NULL) ++ return 1; ++ else ++ return 0; ++ } else { ++ const char *endp; ++ ++ if ((endp = strchr(n, '/')) == NULL) ++ endp = n + strlen(n); ++ ++ if (c == '[') { ++ for (--p; n < endp; ++n) ++ if (!glob_match(p, n)) ++ return 0; ++ } else if (c == '/') { ++ while (*n != '\0' && *n != '/') ++ ++n; ++ if (*n == '/' && !glob_match(p, n + 1)) ++ return 0; ++ } else { ++ for (--p; n < endp; ++n) ++ if (*n == c && !glob_match(p, n)) ++ return 0; ++ } ++ ++ return 1; ++ } ++ case '[': ++ { ++ int not; ++ char cold; ++ ++ if (*n == '\0' || *n == '/') ++ return 1; ++ ++ not = (*p == '!' || *p == '^'); ++ if (not) ++ ++p; ++ ++ c = *p++; ++ for (;;) { ++ unsigned char fn = (unsigned char)*n; ++ ++ if (c == '\0') ++ return 1; ++ else { ++ if (c == fn) ++ goto matched; ++ cold = c; ++ c = *p++; ++ ++ if (c == '-' && *p != ']') { ++ unsigned char cend = *p++; ++ ++ if (cend == '\0') ++ return 1; ++ ++ if (cold <= fn && fn <= cend) ++ goto matched; ++ ++ c = *p++; ++ } ++ } ++ ++ if (c == ']') ++ break; ++ } ++ if (!not) ++ return 1; + break; -+ } -+ if (*p1 == '*') { -+ p1++; -+ while (*p2 != '\0') { -+ if (!glob_match(p1, p2)) -+ return 0; -+ else -+ p2++; ++ matched: ++ while (c != ']') { ++ if (c == '\0') ++ return 1; ++ ++ c = *p++; ++ } ++ if (not) ++ return 1; + } ++ break; ++ default: ++ if (c != *n) ++ return 1; + } + -+ if (*p2 == '\0' && *p1 == '*') -+ while (*p1 == '*') -+ p1++; ++ ++n; ++ } ++ ++ if (*n == '\0') ++ return 0; + -+ if (*p1 == '\0' && *p2 == '\0') ++ if (*n == '/') + return 0; -+ else -+ return 1; ++ ++ return 1; +} + +static struct acl_object_label * @@ -11399,19 +12469,20 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke { struct dentry *dentry = (struct dentry *) l_dentry; struct vfsmount *mnt = (struct vfsmount *) l_mnt; - struct dentry *root; - struct vfsmount *rootmnt; +- struct dentry *root; +- struct vfsmount *rootmnt; struct acl_object_label *retval; + char *path = NULL; - read_lock(&child_reaper->fs->lock); - rootmnt = mntget(child_reaper->fs->rootmnt); -@@ -776,18 +1587,65 @@ chk_obj_label(const struct dentry *l_den +- read_lock(&child_reaper->fs->lock); +- rootmnt = mntget(child_reaper->fs->rootmnt); +- root = dget(child_reaper->fs->root); +- read_unlock(&child_reaper->fs->lock); spin_lock(&dcache_lock); for (;;) { - if (unlikely(dentry == root && mnt == rootmnt)) -+ if (dentry == root && mnt == rootmnt) ++ if (dentry == real_root && mnt == real_root_mnt) break; - if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) { + if (dentry == mnt->mnt_root || IS_ROOT(dentry)) { @@ -11426,61 +12497,10 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke - if (unlikely(retval != NULL)) + retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path); + if (retval != NULL) -+ goto out; -+ -+ dentry = mnt->mnt_mountpoint; -+ mnt = mnt->mnt_parent; -+ continue; -+ } -+ -+ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path); -+ if (retval != NULL) -+ goto out; -+ -+ dentry = dentry->d_parent; -+ } -+ -+ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path); -+ -+ if (retval == NULL) -+ retval = full_lookup(l_dentry, l_mnt, root, subj, &path); -+ out: -+ spin_unlock(&dcache_lock); -+ dput(root); -+ mntput(rootmnt); -+ -+ return retval; -+} -+ -+static struct acl_object_label * -+chk_obj_create_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt, -+ const struct acl_subject_label *subj, char *path) -+{ -+ struct dentry *dentry = (struct dentry *) l_dentry; -+ struct vfsmount *mnt = (struct vfsmount *) l_mnt; -+ struct dentry *root; -+ struct vfsmount *rootmnt; -+ struct acl_object_label *retval; -+ -+ read_lock(&child_reaper->fs->lock); -+ rootmnt = mntget(child_reaper->fs->rootmnt); -+ root = dget(child_reaper->fs->root); -+ read_unlock(&child_reaper->fs->lock); -+ spin_lock(&dcache_lock); -+ -+ for (;;) { -+ if (dentry == root && mnt == rootmnt) -+ break; -+ if (dentry == mnt->mnt_root || IS_ROOT(dentry)) { -+ if (mnt->mnt_parent == mnt) -+ break; -+ -+ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path); -+ if (retval != NULL) goto out; dentry = mnt->mnt_mountpoint; -@@ -795,40 +1653,28 @@ chk_obj_label(const struct dentry *l_den +@@ -795,55 +1729,78 @@ chk_obj_label(const struct dentry *l_den continue; } @@ -11510,13 +12530,55 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke - lookup_acl_obj_label(root->d_inode->i_ino, - root->d_inode->i_dev, subj); - read_unlock(&gr_inode_lock); -- } + if (retval == NULL) -+ retval = full_lookup(l_dentry, l_mnt, root, subj, &path); ++ retval = full_lookup(l_dentry, l_mnt, real_root, subj, &path); ++ out: ++ spin_unlock(&dcache_lock); ++ ++ return retval; ++} ++ ++static struct acl_object_label * ++chk_obj_create_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt, ++ const struct acl_subject_label *subj, char *path) ++{ ++ struct dentry *dentry = (struct dentry *) l_dentry; ++ struct vfsmount *mnt = (struct vfsmount *) l_mnt; ++ struct acl_object_label *retval; ++ ++ spin_lock(&dcache_lock); ++ ++ for (;;) { ++ if (dentry == real_root && mnt == real_root_mnt) ++ break; ++ if (dentry == mnt->mnt_root || IS_ROOT(dentry)) { ++ if (mnt->mnt_parent == mnt) ++ break; ++ ++ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path); ++ if (retval != NULL) ++ goto out; ++ ++ dentry = mnt->mnt_mountpoint; ++ mnt = mnt->mnt_parent; ++ continue; ++ } ++ ++ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path); ++ if (retval != NULL) ++ goto out; ++ ++ dentry = dentry->d_parent; + } ++ ++ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path); ++ ++ if (retval == NULL) ++ retval = full_lookup(l_dentry, l_mnt, real_root, subj, &path); out: spin_unlock(&dcache_lock); - dput(root); - mntput(rootmnt); +- dput(root); +- mntput(rootmnt); - return (retval->mode & reqmode); + return retval; @@ -11529,7 +12591,23 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke { struct dentry *dentry = (struct dentry *) l_dentry; struct vfsmount *mnt = (struct vfsmount *) l_mnt; -@@ -852,7 +1698,7 @@ chk_subj_label(const struct dentry *l_de +- struct dentry *root; +- struct vfsmount *rootmnt; + struct acl_subject_label *retval; + +- read_lock(&child_reaper->fs->lock); +- rootmnt = mntget(child_reaper->fs->rootmnt); +- root = dget(child_reaper->fs->root); +- read_unlock(&child_reaper->fs->lock); + spin_lock(&dcache_lock); + + for (;;) { +- if (unlikely(dentry == root && mnt == rootmnt)) ++ if (unlikely(dentry == real_root && mnt == real_root_mnt)) + break; + if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) { + if (mnt->mnt_parent == mnt) +@@ -852,7 +1809,7 @@ chk_subj_label(const struct dentry *l_de read_lock(&gr_inode_lock); retval = lookup_acl_subj_label(dentry->d_inode->i_ino, @@ -11538,7 +12616,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke read_unlock(&gr_inode_lock); if (unlikely(retval != NULL)) goto out; -@@ -865,7 +1711,7 @@ chk_subj_label(const struct dentry *l_de +@@ -865,7 +1822,7 @@ chk_subj_label(const struct dentry *l_de read_lock(&gr_inode_lock); retval = lookup_acl_subj_label(dentry->d_inode->i_ino, @@ -11547,7 +12625,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke read_unlock(&gr_inode_lock); if (unlikely(retval != NULL)) goto out; -@@ -876,14 +1722,14 @@ chk_subj_label(const struct dentry *l_de +@@ -876,35 +1833,31 @@ chk_subj_label(const struct dentry *l_de read_lock(&gr_inode_lock); retval = lookup_acl_subj_label(dentry->d_inode->i_ino, @@ -11558,13 +12636,18 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke if (unlikely(retval == NULL)) { read_lock(&gr_inode_lock); retval = - lookup_acl_subj_label(root->d_inode->i_ino, +- lookup_acl_subj_label(root->d_inode->i_ino, - root->d_inode->i_dev); -+ root->d_inode->i_dev, role); ++ lookup_acl_subj_label(real_root->d_inode->i_ino, ++ real_root->d_inode->i_dev, role); read_unlock(&gr_inode_lock); } out: -@@ -895,16 +1741,14 @@ chk_subj_label(const struct dentry *l_de + spin_unlock(&dcache_lock); +- dput(root); +- mntput(rootmnt); + + return retval; } static __inline__ void @@ -11589,7 +12672,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke return; } -@@ -915,26 +1759,28 @@ gr_check_link(const struct dentry * new_ +@@ -915,26 +1868,28 @@ gr_check_link(const struct dentry * new_ const struct vfsmount * parent_mnt, const struct dentry * old_dentry, const struct vfsmount * old_mnt) { @@ -11626,7 +12709,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke } else if (newmode & GR_SUPPRESS) return GR_SUPPRESS; else -@@ -947,25 +1793,28 @@ gr_search_file(const struct dentry * den +@@ -947,25 +1902,28 @@ gr_search_file(const struct dentry * den { __u32 retval = mode; struct acl_subject_label *curracl; @@ -11659,7 +12742,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke } return retval; -@@ -978,14 +1827,15 @@ gr_check_create(const struct dentry * ne +@@ -978,14 +1936,15 @@ gr_check_create(const struct dentry * ne struct name_entry *match; struct acl_object_label *matchpo; struct acl_subject_label *curracl; @@ -11677,7 +12760,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke if (!match) goto check_parent; -@@ -1004,8 +1854,8 @@ gr_check_create(const struct dentry * ne +@@ -1004,8 +1963,8 @@ gr_check_create(const struct dentry * ne new_mode &= ~(GR_AUDITS | GR_SUPPRESS); @@ -11688,7 +12771,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke preempt_enable(); return new_mode; -@@ -1014,10 +1864,11 @@ gr_check_create(const struct dentry * ne +@@ -1014,10 +1973,11 @@ gr_check_create(const struct dentry * ne return (matchpo->mode & mode); } @@ -11702,7 +12785,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))) && (curracl->mode & GR_LEARN)) { -@@ -1025,8 +1876,8 @@ gr_check_create(const struct dentry * ne +@@ -1025,8 +1985,8 @@ gr_check_create(const struct dentry * ne new_mode &= ~(GR_AUDITS | GR_SUPPRESS); @@ -11713,7 +12796,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke preempt_enable(); return new_mode; } -@@ -1062,19 +1913,16 @@ gr_check_protected_task(const struct tas +@@ -1062,19 +2022,16 @@ gr_check_protected_task(const struct tas __inline__ void gr_copy_label(struct task_struct *tsk) { @@ -11738,10 +12821,25 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke if (unlikely(current->used_accept)) current->curr_ip = 0; -@@ -1129,30 +1977,243 @@ gr_set_pax_flags(struct task_struct *tas +@@ -1103,9 +2060,11 @@ gr_set_proc_res(void) return; } ++#ifdef CONFIG_GRKERNSEC_PAX_HAVE_ACL_FLAGS + void +-gr_set_pax_flags(struct task_struct *task) ++pax_set_flags(struct linux_binprm *bprm) + { ++ struct task_struct *task = current; + struct acl_subject_label *proc; + + if (unlikely(!(gr_status & GR_READY))) +@@ -1128,31 +2087,245 @@ gr_set_pax_flags(struct task_struct *tas + + return; + } ++#endif ++ +static __inline__ void +do_set_role_label(struct task_struct *task, const uid_t uid, const gid_t gid) +{ @@ -11877,7 +12975,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke + return 1; + } +} -+ + void +gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid) +{ @@ -11931,10 +13029,10 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke if (unlikely(!(gr_status & GR_READY))) - return; + return 0; ++ ++ newacl = chk_subj_label(dentry, mnt, task->role); - newacl = chk_subj_label(dentry, mnt); -+ newacl = chk_subj_label(dentry, mnt, task->role); -+ + task_lock(task); + if (((task->ptrace & PT_PTRACED) && !(task->acl->mode & + GR_OVERRIDE) && (task->acl != newacl) && @@ -11993,7 +13091,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke } static __inline__ void -@@ -1161,14 +2222,22 @@ do_handle_delete(const ino_t ino, const +@@ -1161,14 +2334,22 @@ do_handle_delete(const ino_t ino, const struct acl_object_label *matchpo; struct acl_subject_label *matchps; struct acl_subject_label *i; @@ -12022,7 +13120,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke return; } -@@ -1180,7 +2249,7 @@ gr_handle_delete(const ino_t ino, const +@@ -1180,7 +2361,7 @@ gr_handle_delete(const ino_t ino, const return; write_lock(&gr_inode_lock); @@ -12031,7 +13129,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke do_handle_delete(ino, dev); write_unlock(&gr_inode_lock); -@@ -1226,24 +2295,27 @@ update_acl_obj_label(const ino_t oldinod +@@ -1226,24 +2407,27 @@ update_acl_obj_label(const ino_t oldinod static __inline__ void update_acl_subj_label(const ino_t oldinode, const kdev_t olddevice, @@ -12065,7 +13163,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke && ((*match)->inode == oldinode) && ((*match)->device == olddevice) && ((*match)->mode & GR_DELETED)) { -@@ -1255,7 +2327,7 @@ update_acl_subj_label(const ino_t oldino +@@ -1255,7 +2439,7 @@ update_acl_subj_label(const ino_t oldino *match = deleted_subject; @@ -12074,7 +13172,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke } return; -@@ -1301,14 +2373,24 @@ do_handle_create(const struct name_entry +@@ -1301,14 +2485,24 @@ do_handle_create(const struct name_entry const struct vfsmount *mnt) { struct acl_subject_label *i; @@ -12106,7 +13204,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke } update_inodev_entry(matchn->inode, matchn->device, -@@ -1329,7 +2411,7 @@ gr_handle_create(const struct dentry *de +@@ -1329,7 +2523,7 @@ gr_handle_create(const struct dentry *de matchn = lookup_name_entry(gr_to_filename(dentry, mnt)); preempt_enable(); @@ -12115,7 +13213,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke write_lock(&gr_inode_lock); do_handle_create(matchn, dentry, mnt); write_unlock(&gr_inode_lock); -@@ -1355,7 +2437,7 @@ gr_handle_rename(struct inode *old_dir, +@@ -1355,7 +2549,7 @@ gr_handle_rename(struct inode *old_dir, error = vfs_rename(old_dir, old_dentry, new_dir, new_dentry); unlock_kernel(); @@ -12124,7 +13222,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke return error; /* we wouldn't have to check d_inode if it weren't for -@@ -1364,9 +2446,9 @@ gr_handle_rename(struct inode *old_dir, +@@ -1364,9 +2558,9 @@ gr_handle_rename(struct inode *old_dir, write_lock(&gr_inode_lock); if (unlikely(replace && new_dentry->d_inode)) { @@ -12136,7 +13234,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke do_handle_delete(new_dentry->d_inode->i_ino, new_dentry->d_inode->i_dev); } -@@ -1377,77 +2459,190 @@ gr_handle_rename(struct inode *old_dir, +@@ -1377,77 +2571,211 @@ gr_handle_rename(struct inode *old_dir, do_handle_delete(old_dentry->d_inode->i_ino, old_dentry->d_inode->i_dev); @@ -12157,6 +13255,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke + unsigned char **sum) +{ + struct acl_role_label *r; ++ struct role_allowed_ip *ipp; + struct role_transition *trans; + __u16 i; + int found = 0; @@ -12173,14 +13272,29 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke + if (!found) + return 0; + -+ /* handle special roles that do not require authentication */ ++ /* handle special roles that do not require authentication ++ and check ip */ + + for (r = role_list_head; r; r = r->next) { -+ if (!strcmp(rolename, r->rolename) -+ && (r->roletype & GR_ROLE_NOPW)) { -+ *salt = NULL; -+ *sum = NULL; -+ return 1; ++ if (!strcmp(rolename, r->rolename) && ++ (r->roletype & GR_ROLE_SPECIAL)) { ++ found = 0; ++ if (r->allowed_ips != NULL) { ++ for (ipp = r->allowed_ips; ipp; ipp = ipp->next) { ++ if ((ntohl(current->curr_ip) & ipp->netmask) == ++ (ntohl(ipp->addr) & ipp->netmask)) ++ found = 1; ++ } ++ } else ++ found = 2; ++ if (!found) ++ return 0; ++ ++ if (r->roletype & GR_ROLE_NOPW) { ++ *salt = NULL; ++ *sum = NULL; ++ return 1; ++ } + } + } + @@ -12207,7 +13321,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke + struct acl_role_label *assigned = NULL; + struct task_struct *tsk; + struct file *filp; - ++ + for (r = role_list_head; r; r = r->next) + if (!strcmp(rolename, r->rolename) && + (r->roletype & GR_ROLE_SPECIAL)) @@ -12224,7 +13338,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke + read_unlock(&tasklist_lock); + return; + } -+ + + filp = tsk->exec_file; + if (filp == NULL) { + read_unlock(&grsec_exec_file_lock); @@ -12267,46 +13381,50 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke - struct gr_arg *arg; - struct gr_arg usermode; - int error = sizeof (struct gr_arg); -+ struct gr_arg *uarg; ++ struct gr_arg_wrapper uwrap; + unsigned char *sprole_salt; + unsigned char *sprole_sum; -+ int error = sizeof (struct gr_arg *); ++ int error = sizeof (struct gr_arg_wrapper); int error2 = 0; - if (!write) - return -EPERM; + down(&gr_dev_sem); - -- down(&gr_proc_sem); -+ if (count != sizeof (struct gr_arg *)) { -+ security_alert_good(GR_DEV_ACL_MSG, count, -+ (int) sizeof (struct gr_arg *)); ++ ++ if (count != sizeof (struct gr_arg_wrapper)) { ++ security_alert_good(GR_DEV_ACL_MSG, (int)count, ++ (int) sizeof (struct gr_arg_wrapper)); + error = -EINVAL; + goto out; + } -- arg = (struct gr_arg *) buffer; +- down(&gr_proc_sem); + if ((gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES) + && time_before_eq(gr_auth_expires, jiffies)) { + gr_auth_expires = 0; + gr_auth_attempts = 0; + } -- if (*lenp != sizeof (struct gr_arg)) { -- security_alert_good(GR_PROC_ACL_MSG, (int) *lenp, -- (int) sizeof (struct gr_arg)); -- error = -EINVAL; -+ if (copy_from_user(&uarg, buf, sizeof (struct gr_arg *))) { +- arg = (struct gr_arg *) buffer; ++ if (copy_from_user(&uwrap, buf, sizeof (struct gr_arg_wrapper))) { + error = -EFAULT; + goto out; + } -+ -+ if (copy_from_user(gr_usermode, uarg, sizeof (struct gr_arg))) { -+ error = -EFAULT; + +- if (*lenp != sizeof (struct gr_arg)) { +- security_alert_good(GR_PROC_ACL_MSG, (int) *lenp, +- (int) sizeof (struct gr_arg)); ++ if ((uwrap.version != GRSECURITY_VERSION) || (uwrap.size != sizeof(struct gr_arg))) { + error = -EINVAL; goto out; } - if (during_wait) { + ++ if (copy_from_user(gr_usermode, uwrap.arg, sizeof (struct gr_arg))) { ++ error = -EFAULT; ++ goto out; ++ } ++ + if (gr_usermode->mode != SPROLE && time_after(gr_auth_expires, jiffies)) { error = -EBUSY; goto out; @@ -12359,7 +13477,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke } else if (gr_status & GR_READY) { security_alert(GR_SHUTF_ACL_MSG, DEFAULTSECARGS); error = -EPERM; -@@ -1457,7 +2652,7 @@ gr_proc_handler(ctl_table * table, int w +@@ -1457,7 +2785,7 @@ gr_proc_handler(ctl_table * table, int w } break; case ENABLE: @@ -12368,7 +13486,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke security_alert_good(GR_ENABLE_ACL_MSG, GR_VERSION); else { if (gr_status & GR_READY) -@@ -1472,11 +2667,11 @@ gr_proc_handler(ctl_table * table, int w +@@ -1472,11 +2800,11 @@ gr_proc_handler(ctl_table * table, int w if (!(gr_status & GR_READY)) { security_alert_good(GR_RELOADI_ACL_MSG); error = -EAGAIN; @@ -12382,7 +13500,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke unlock_kernel(); security_alert_good(GR_RELOAD_ACL_MSG, GR_VERSION); -@@ -1500,53 +2695,93 @@ gr_proc_handler(ctl_table * table, int w +@@ -1500,53 +2828,93 @@ gr_proc_handler(ctl_table * table, int w break; } @@ -12498,7 +13616,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke DEFAULTSECARGS); error = -EINVAL; break; -@@ -1555,47 +2790,63 @@ gr_proc_handler(ctl_table * table, int w +@@ -1555,47 +2923,63 @@ gr_proc_handler(ctl_table * table, int w if (error != -EPERM) goto out; @@ -12574,7 +13692,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke if (!(curr->mode & GR_LEARN)) for (i = 0; i < RLIM_NLIMITS; i++) { if (!(curr->resmask & (1 << i))) -@@ -1607,6 +2858,7 @@ gr_set_acls(const int type) +@@ -1607,6 +2991,7 @@ gr_set_acls(const int type) curr->res[i].rlim_max; } } else { @@ -12582,7 +13700,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke read_unlock(&tasklist_lock); security_alert_good(GR_DEFACL_MSG, task->comm, task->pid); -@@ -1614,12 +2866,14 @@ gr_set_acls(const int type) +@@ -1614,12 +2999,14 @@ gr_set_acls(const int type) } } else { // it's a kernel process @@ -12599,18 +13717,18 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke read_unlock(&tasklist_lock); return 0; } -@@ -1693,8 +2947,8 @@ gr_learn_resource(const struct task_stru +@@ -1693,8 +3080,8 @@ gr_learn_resource(const struct task_stru if (wanted > acl->res[res].rlim_max) acl->res[res].rlim_max = res_add; - security_learn(GR_LEARN_AUDIT_MSG, acl->device, - (unsigned long) acl->inode, -+ security_learn(GR_LEARN_AUDIT_MSG, current->role->rolename, -+ current->role->roletype, acl->filename, ++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, ++ task->role->roletype, acl->filename, acl->res[res].rlim_cur, acl->res[res].rlim_max, "", (unsigned long) res); } -@@ -1712,7 +2966,8 @@ gr_handle_sysctl(const struct ctl_table +@@ -1712,7 +3099,8 @@ gr_handle_sysctl(const struct ctl_table struct proc_dir_entry *tmp; struct nameidata nd; const char *proc_sys = "/proc/sys"; @@ -12620,7 +13738,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke unsigned short len = 0, pos = 0, depth = 0, i; __u32 err = 0; __u32 mode = 0; -@@ -1762,9 +3017,8 @@ gr_handle_sysctl(const struct ctl_table +@@ -1762,9 +3150,8 @@ gr_handle_sysctl(const struct ctl_table if (err) goto out; @@ -12632,7 +13750,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke if (unlikely((current->acl->mode & GR_LEARN) && ((err & mode) != mode))) { __u32 new_mode = mode; -@@ -1772,7 +3026,8 @@ gr_handle_sysctl(const struct ctl_table +@@ -1772,7 +3159,8 @@ gr_handle_sysctl(const struct ctl_table new_mode &= ~(GR_AUDITS | GR_SUPPRESS); err = new_mode; @@ -12642,7 +13760,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke } else if ((err & mode) != mode && !(err & GR_SUPPRESS)) { security_alert(GR_SYSCTL_ACL_MSG, "denied", path, (mode & GR_READ) ? " reading" : "", -@@ -1796,21 +3051,96 @@ gr_handle_sysctl(const struct ctl_table +@@ -1796,21 +3184,88 @@ gr_handle_sysctl(const struct ctl_table #endif int @@ -12700,14 +13818,6 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke + if (unlikely(!(gr_status & GR_READY))) + return 0; + -+ if (task->acl->mode & GR_NOPTRACE) { -+ security_alert(GR_PTRACE_ACL_MSG, task->exec_file ? -+ gr_to_filename(task->exec_file->f_dentry, task->exec_file->f_vfsmnt) -+ : "(none)", task->comm, task->pid, -+ DEFAULTSECARGS); -+ return 1; -+ } -+ + read_lock(&tasklist_lock); + while (tmp->pid > 0) { + if (tmp == curtemp) @@ -12743,7 +13853,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke if (retmode & GR_PTRACERD) { switch (request) { case PTRACE_POKETEXT: -@@ -1831,12 +3161,12 @@ gr_handle_ptrace(struct task_struct *tas +@@ -1831,41 +3286,11 @@ gr_handle_ptrace(struct task_struct *tas return 0; } } else if (!(current->acl->mode & GR_OVERRIDE) && @@ -12751,20 +13861,18 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke - (current->acl != root_label - && current->pid != - task->pid))) { -+ !(current->role->roletype & GR_ROLE_GOD) -+ && (current->acl != task->acl -+ || (current->acl != current->role->root_label -+ && current->pid != task->pid))) { ++ !(current->role->roletype & GR_ROLE_GOD) && ++ (current->acl != task->acl)) { security_alert(GR_PTRACE_ACL_MSG, - gr_to_filename(filp->f_dentry, filp->f_vfsmnt), -+ gr_to_filename(task->exec_file->f_dentry, task->exec_file->f_vfsmnt), - task->comm, task->pid, DEFAULTSECARGS); - return 1; - } -@@ -1845,54 +3175,22 @@ gr_handle_ptrace(struct task_struct *tas - } - - int +- task->comm, task->pid, DEFAULTSECARGS); +- return 1; +- } +- +- return 0; +-} +- +-int -gr_handle_ptrace_exec(const struct dentry *dentry, const struct vfsmount *mnt) -{ - __u32 retmode; @@ -12786,13 +13894,13 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke - (current->acl != subj)) { - security_alert(GR_PTRACE_EXEC_ACL_MSG, - gr_to_filename(dentry, mnt), DEFAULTSECARGS); -- return 1; -- } -- -- return 0; --} -- --int ++ gr_to_filename(task->exec_file->f_dentry, task->exec_file->f_vfsmnt), ++ task->comm, task->pid, DEFAULTSECARGS); + return 1; + } + +@@ -1875,24 +3300,20 @@ gr_handle_ptrace_exec(const struct dentr + int gr_handle_mmap(const struct file *filp, const unsigned long prot) { - struct file *exec_file; @@ -12822,7 +13930,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke security_alert(GR_WRITLIB_ACL_MSG, gr_to_filename(filp->f_dentry, filp->f_vfsmnt), DEFAULTSECARGS); -@@ -1907,7 +3205,7 @@ gr_acl_handle_mmap(const struct file *fi +@@ -1907,7 +3328,7 @@ gr_acl_handle_mmap(const struct file *fi { __u32 mode; @@ -12831,7 +13939,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke return 1; mode = -@@ -1915,14 +3213,14 @@ gr_acl_handle_mmap(const struct file *fi +@@ -1915,14 +3336,14 @@ gr_acl_handle_mmap(const struct file *fi GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS, file->f_vfsmnt); @@ -12849,7 +13957,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke security_audit(GR_MMAP_ACL_MSG, "successful", gr_to_filename(file->f_dentry, file->f_vfsmnt), DEFAULTSECARGS); -@@ -1937,7 +3235,7 @@ gr_acl_handle_mprotect(const struct file +@@ -1937,7 +3358,7 @@ gr_acl_handle_mprotect(const struct file { __u32 mode; @@ -12858,7 +13966,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke return 1; mode = -@@ -1945,14 +3243,14 @@ gr_acl_handle_mprotect(const struct file +@@ -1945,14 +3366,14 @@ gr_acl_handle_mprotect(const struct file GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS, file->f_vfsmnt); @@ -12876,7 +13984,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke security_audit(GR_MPROTECT_ACL_MSG, "successful", gr_to_filename(file->f_dentry, file->f_vfsmnt), DEFAULTSECARGS); -@@ -1996,14 +3294,15 @@ gr_acl_handle_psacct(struct task_struct +@@ -1996,14 +3417,15 @@ gr_acl_handle_psacct(struct task_struct cputime -= cmin * 60; csec = cputime; @@ -12894,7 +14002,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke NIPQUAD(task->p_pptr->curr_ip), tty_name(task->p_pptr->tty, parent_tty), task->p_pptr->uid, task->p_pptr->euid, task->p_pptr->gid, -@@ -2014,8 +3313,9 @@ gr_acl_handle_psacct(struct task_struct +@@ -2014,8 +3436,9 @@ gr_acl_handle_psacct(struct task_struct void gr_set_kernel_label(struct task_struct *task) { @@ -12907,10 +14015,10 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke + } return; } -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/grsecurity/gracl_cap.c linux-2.4.20-wolk4.15-grsec2/grsecurity/gracl_cap.c ---- linux-2.4.20-wolk4.15-fullkernel/grsecurity/gracl_cap.c 2004-06-29 11:24:38.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/grsecurity/gracl_cap.c 2004-06-29 13:00:19.000000000 +0200 -@@ -40,28 +40,47 @@ static const char *captab_log[29] = { +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/grsecurity/gracl_cap.c linux-2.4.20-wolk4.16-grsec2/grsecurity/gracl_cap.c +--- linux-2.4.20-wolk4.16-fullkernel/grsecurity/gracl_cap.c 2004-09-05 15:48:18.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/grsecurity/gracl_cap.c 2004-09-05 17:07:52.000000000 +0200 +@@ -40,28 +40,48 @@ static const char *captab_log[29] = { }; int @@ -12931,7 +14039,8 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke + cap_mask = curracl->cap_mask; + + while ((curracl = curracl->parent_subject)) { -+ cap_drop |= curracl->cap_lower & (cap_mask & ~curracl->cap_mask); ++ if (!(cap_mask & (1 << cap)) && (curracl->cap_mask & (1 << cap))) ++ cap_drop |= curracl->cap_lower & (1 << cap); + cap_mask |= curracl->cap_mask; + } + @@ -12967,10 +14076,18 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke return 0; } -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/grsecurity/gracl_fs.c linux-2.4.20-wolk4.15-grsec2/grsecurity/gracl_fs.c ---- linux-2.4.20-wolk4.15-fullkernel/grsecurity/gracl_fs.c 2004-06-29 11:24:38.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/grsecurity/gracl_fs.c 2004-06-29 13:00:27.000000000 +0200 -@@ -25,7 +25,8 @@ gr_acl_handle_hidden_file(const struct d +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/grsecurity/gracl_fs.c linux-2.4.20-wolk4.16-grsec2/grsecurity/gracl_fs.c +--- linux-2.4.20-wolk4.16-fullkernel/grsecurity/gracl_fs.c 2004-09-05 15:48:18.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/grsecurity/gracl_fs.c 2004-09-05 17:07:52.000000000 +0200 +@@ -3,6 +3,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -25,7 +26,8 @@ gr_acl_handle_hidden_file(const struct d return mode; } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) { security_alert(GR_HIDDEN_ACL_MSG, "denied", @@ -12980,7 +14097,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke return 0; } else if (unlikely(!(mode & GR_FIND))) return 0; -@@ -43,11 +44,11 @@ gr_acl_handle_open(const struct dentry * +@@ -43,11 +45,11 @@ gr_acl_handle_open(const struct dentry * if (unlikely(!dentry->d_inode)) return reqmode; @@ -12995,7 +14112,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke reqmode |= GR_READ; mode = -@@ -80,22 +81,25 @@ gr_acl_handle_open(const struct dentry * +@@ -80,22 +82,25 @@ gr_acl_handle_open(const struct dentry * __u32 gr_acl_handle_creat(const struct dentry * dentry, const struct dentry * p_dentry, @@ -13026,7 +14143,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke gr_to_filename(dentry, p_mnt), reqmode & GR_READ ? " reading" : "", reqmode & GR_WRITE ? " writing" : -@@ -105,7 +109,7 @@ gr_acl_handle_creat(const struct dentry +@@ -105,7 +110,7 @@ gr_acl_handle_creat(const struct dentry } else if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS))) { @@ -13035,7 +14152,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke gr_to_filename(dentry, p_mnt), reqmode & GR_READ ? " reading" : "", reqmode & GR_WRITE ? " writing" : reqmode & -@@ -181,13 +185,13 @@ gr_acl_handle_access(const struct dentry +@@ -181,13 +186,13 @@ gr_acl_handle_access(const struct dentry __u32 gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt) { @@ -13051,7 +14168,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke } __u32 -@@ -203,15 +207,27 @@ gr_acl_handle_utime(const struct dentry +@@ -203,15 +208,30 @@ gr_acl_handle_utime(const struct dentry } __u32 @@ -13060,6 +14177,9 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke + mode_t mode) { - generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG); ++ if (unlikely(dentry->d_inode && S_ISSOCK(dentry->d_inode->i_mode))) ++ return 1; ++ + if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) { + generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID, + GR_FCHMOD_ACL_MSG); @@ -13083,7 +14203,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke } __u32 -@@ -237,14 +253,14 @@ __u32 +@@ -237,14 +257,14 @@ __u32 gr_acl_handle_filldir(const struct dentry *dentry, const struct vfsmount *mnt, const ino_t ino) { @@ -13100,7 +14220,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke return 0; } -@@ -258,26 +274,27 @@ gr_acl_handle_link(const struct dentry * +@@ -258,26 +278,27 @@ gr_acl_handle_link(const struct dentry * const struct dentry * old_dentry, const struct vfsmount * old_mnt, const char *to) { @@ -13132,7 +14252,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke } __u32 -@@ -285,26 +302,28 @@ gr_acl_handle_symlink(const struct dentr +@@ -285,26 +306,28 @@ gr_acl_handle_symlink(const struct dentr const struct dentry * parent_dentry, const struct vfsmount * parent_mnt, const char *from) { @@ -13165,7 +14285,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke } #define generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt, reqmode, fmt) \ -@@ -332,10 +351,15 @@ gr_acl_handle_symlink(const struct dentr +@@ -332,10 +355,15 @@ gr_acl_handle_symlink(const struct dentr __u32 gr_acl_handle_mknod(const struct dentry * new_dentry, const struct dentry * parent_dentry, @@ -13183,7 +14303,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke } __u32 -@@ -344,7 +368,7 @@ gr_acl_handle_mkdir(const struct dentry +@@ -344,7 +372,7 @@ gr_acl_handle_mkdir(const struct dentry const struct vfsmount *parent_mnt) { generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt, @@ -13192,7 +14312,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke } #define RENAME_CHECK_SUCCESS(old, new) \ -@@ -370,18 +394,22 @@ gr_acl_handle_rename(struct dentry *new_ +@@ -370,18 +398,22 @@ gr_acl_handle_rename(struct dentry *new_ gr_replace = 0; comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt, @@ -13217,7 +14337,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt); } -@@ -411,17 +439,23 @@ gr_acl_handle_rename(struct dentry *new_ +@@ -411,17 +443,25 @@ gr_acl_handle_rename(struct dentry *new_ void gr_acl_handle_exit(void) { @@ -13226,6 +14346,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke - id = current->acl_admin_id; + u16 id; + char *rolename; ++ struct file *exec_file; + + if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) { + id = current->acl_role_id; @@ -13236,18 +14357,23 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke + rolename, id, DEFAULTSECARGS); } -+ write_lock_irq(&grsec_exec_file_lock); - if (current->exec_file) { - fput(current->exec_file); - current->exec_file = NULL; - } -+ write_unlock_irq(&grsec_exec_file_lock); +- if (current->exec_file) { +- fput(current->exec_file); +- current->exec_file = NULL; +- } ++ write_lock(&grsec_exec_file_lock); ++ exec_file = current->exec_file; ++ current->exec_file = NULL; ++ write_unlock(&grsec_exec_file_lock); ++ ++ if (exec_file) ++ fput(exec_file); } int -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/grsecurity/gracl_ip.c linux-2.4.20-wolk4.15-grsec2/grsecurity/gracl_ip.c ---- linux-2.4.20-wolk4.15-fullkernel/grsecurity/gracl_ip.c 2004-06-29 11:30:54.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/grsecurity/gracl_ip.c 2004-06-29 13:00:19.000000000 +0200 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/grsecurity/gracl_ip.c linux-2.4.20-wolk4.16-grsec2/grsecurity/gracl_ip.c +--- linux-2.4.20-wolk4.16-fullkernel/grsecurity/gracl_ip.c 2004-09-05 16:05:21.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/grsecurity/gracl_ip.c 2004-09-05 17:07:52.000000000 +0200 @@ -25,6 +25,58 @@ #define GR_BIND 0x01 #define GR_CONNECT 0x02 @@ -13377,9 +14503,9 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke return 0; } -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/grsecurity/gracl_learn.c linux-2.4.20-wolk4.15-grsec2/grsecurity/gracl_learn.c ---- linux-2.4.20-wolk4.15-fullkernel/grsecurity/gracl_learn.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.20-wolk4.15-grsec2/grsecurity/gracl_learn.c 2004-06-29 13:00:19.000000000 +0200 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/grsecurity/gracl_learn.c linux-2.4.20-wolk4.16-grsec2/grsecurity/gracl_learn.c +--- linux-2.4.20-wolk4.16-fullkernel/grsecurity/gracl_learn.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.20-wolk4.16-grsec2/grsecurity/gracl_learn.c 2004-09-05 17:07:52.000000000 +0200 @@ -0,0 +1,170 @@ +#include +#include @@ -13551,9 +14677,9 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke + release: close_learn, + poll: poll_learn, +}; -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/grsecurity/gracl_res.c linux-2.4.20-wolk4.15-grsec2/grsecurity/gracl_res.c ---- linux-2.4.20-wolk4.15-fullkernel/grsecurity/gracl_res.c 2004-06-29 11:31:05.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/grsecurity/gracl_res.c 2004-06-29 13:00:43.000000000 +0200 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/grsecurity/gracl_res.c linux-2.4.20-wolk4.16-grsec2/grsecurity/gracl_res.c +--- linux-2.4.20-wolk4.16-fullkernel/grsecurity/gracl_res.c 2004-09-05 16:09:14.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/grsecurity/gracl_res.c 2004-09-05 17:07:53.000000000 +0200 @@ -40,10 +40,15 @@ gr_log_resource(const struct task_struct (!gt && wanted >= task->rlim[res].rlim_cur)) && task->rlim[res].rlim_cur != RLIM_INFINITY)) @@ -13573,9 +14699,9 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke preempt_enable_no_resched(); -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/grsecurity/gracl_segv.c linux-2.4.20-wolk4.15-grsec2/grsecurity/gracl_segv.c ---- linux-2.4.20-wolk4.15-fullkernel/grsecurity/gracl_segv.c 2004-06-29 11:24:38.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/grsecurity/gracl_segv.c 2004-06-29 13:00:19.000000000 +0200 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/grsecurity/gracl_segv.c linux-2.4.20-wolk4.16-grsec2/grsecurity/gracl_segv.c +--- linux-2.4.20-wolk4.16-fullkernel/grsecurity/gracl_segv.c 2004-09-05 15:48:18.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/grsecurity/gracl_segv.c 2004-09-05 17:07:52.000000000 +0200 @@ -27,8 +27,9 @@ static struct crash_uid *uid_set; static unsigned short uid_used; static rwlock_t gr_uid_lock = RW_LOCK_UNLOCKED; @@ -13633,9 +14759,9 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke read_unlock(&gr_inode_lock); if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) || -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/grsecurity/grsec_chroot.c linux-2.4.20-wolk4.15-grsec2/grsecurity/grsec_chroot.c ---- linux-2.4.20-wolk4.15-fullkernel/grsecurity/grsec_chroot.c 2004-06-29 11:31:06.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/grsecurity/grsec_chroot.c 2004-06-29 13:00:27.000000000 +0200 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/grsecurity/grsec_chroot.c linux-2.4.20-wolk4.16-grsec2/grsecurity/grsec_chroot.c +--- linux-2.4.20-wolk4.16-fullkernel/grsecurity/grsec_chroot.c 2004-09-05 16:05:38.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/grsecurity/grsec_chroot.c 2004-09-05 17:07:53.000000000 +0200 @@ -23,11 +23,17 @@ gr_handle_chroot_unix(const pid_t pid) for (p = *htable; p && p->pid != pid; p = p->pidhash_next) ; @@ -13927,10 +15053,10 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke return 0; } + -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/grsecurity/grsec_disabled.c linux-2.4.20-wolk4.15-grsec2/grsecurity/grsec_disabled.c ---- linux-2.4.20-wolk4.15-fullkernel/grsecurity/grsec_disabled.c 2004-06-29 11:31:05.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/grsecurity/grsec_disabled.c 2004-06-29 13:00:41.000000000 +0200 -@@ -10,13 +10,13 @@ +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/grsecurity/grsec_disabled.c linux-2.4.20-wolk4.16-grsec2/grsecurity/grsec_disabled.c +--- linux-2.4.20-wolk4.16-fullkernel/grsecurity/grsec_disabled.c 2004-09-05 16:05:37.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/grsecurity/grsec_disabled.c 2004-09-05 17:07:53.000000000 +0200 +@@ -10,68 +10,82 @@ #include #include #include @@ -13938,15 +15064,21 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke #include +#include #include - #include ++#ifdef CONFIG_GRKERNSEC_PAX_HAVE_ACL_FLAGS ++__inline__ void ++pax_set_flags(struct linux_binprm *bprm) ++{ ++ return; ++} ++#endif ++ #ifdef CONFIG_SYSCTL -__u32 +__inline__ __u32 gr_handle_sysctl(const struct ctl_table * table, const void *oldval, const void *newval) { - __u32 mode = 0; -@@ -29,56 +29,62 @@ gr_handle_sysctl(const struct ctl_table + return 1; } #endif @@ -14021,7 +15153,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke gr_check_protected_task(const struct task_struct *task) { return 0; -@@ -90,49 +96,49 @@ gr_copy_label(struct task_struct *tsk) +@@ -83,49 +97,49 @@ gr_copy_label(struct task_struct *tsk) return; } @@ -14080,7 +15212,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke gr_handle_rename(struct inode *old_dir, struct inode *new_dir, struct dentry *old_dentry, struct dentry *new_dentry, -@@ -141,123 +147,126 @@ gr_handle_rename(struct inode *old_dir, +@@ -134,123 +148,126 @@ gr_handle_rename(struct inode *old_dir, return 0; } @@ -14230,7 +15362,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke gr_acl_handle_mkdir(const struct dentry * new_dentry, const struct dentry * parent_dentry, const struct vfsmount * parent_mnt) -@@ -265,7 +274,7 @@ gr_acl_handle_mkdir(const struct dentry +@@ -258,7 +275,7 @@ gr_acl_handle_mkdir(const struct dentry return 1; } @@ -14239,7 +15371,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke gr_acl_handle_symlink(const struct dentry * new_dentry, const struct dentry * parent_dentry, const struct vfsmount * parent_mnt, const char *from) -@@ -273,7 +282,7 @@ gr_acl_handle_symlink(const struct dentr +@@ -266,7 +283,7 @@ gr_acl_handle_symlink(const struct dentr return 1; } @@ -14248,7 +15380,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke gr_acl_handle_link(const struct dentry * new_dentry, const struct dentry * parent_dentry, const struct vfsmount * parent_mnt, -@@ -283,7 +292,7 @@ gr_acl_handle_link(const struct dentry * +@@ -276,7 +293,7 @@ gr_acl_handle_link(const struct dentry * return 1; } @@ -14257,7 +15389,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke gr_acl_handle_rename(const struct dentry *new_dentry, const struct dentry *parent_dentry, const struct vfsmount *parent_mnt, -@@ -294,78 +303,98 @@ gr_acl_handle_rename(const struct dentry +@@ -287,78 +304,98 @@ gr_acl_handle_rename(const struct dentry return 1; } @@ -14369,9 +15501,9 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke + return 0; +} + -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/grsecurity/grsec_init.c linux-2.4.20-wolk4.15-grsec2/grsecurity/grsec_init.c ---- linux-2.4.20-wolk4.15-fullkernel/grsecurity/grsec_init.c 2004-06-29 11:31:06.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/grsecurity/grsec_init.c 2004-06-29 13:00:43.000000000 +0200 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/grsecurity/grsec_init.c linux-2.4.20-wolk4.16-grsec2/grsecurity/grsec_init.c +--- linux-2.4.20-wolk4.16-fullkernel/grsecurity/grsec_init.c 2004-09-05 16:05:39.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/grsecurity/grsec_init.c 2004-09-05 17:07:53.000000000 +0200 @@ -4,6 +4,7 @@ #include #include @@ -14380,7 +15512,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke int grsec_enable_link; int grsec_enable_dmesg; -@@ -57,40 +58,53 @@ spinlock_t grsec_alert_lock = SPIN_LOCK_ +@@ -57,40 +58,42 @@ spinlock_t grsec_alert_lock = SPIN_LOCK_ unsigned long grsec_alert_wtime = 0; unsigned long grsec_alert_fyet = 0; @@ -14399,8 +15531,6 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke +extern struct gr_arg *gr_usermode; +extern unsigned char *gr_system_salt; +extern unsigned char *gr_system_sum; -+extern struct task_struct **gr_conn_table; -+extern const unsigned int gr_conn_table_size; void grsecurity_init(void) @@ -14428,15 +15558,6 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke - preempt_enable(); -+ /* create hash tables for ip tagging */ -+ -+ gr_conn_table = (struct task_struct **) vmalloc(gr_conn_table_size * sizeof(struct task_struct *)); -+ if (gr_conn_table == NULL) { -+ panic("Unable to allocate grsecurity IP tagging table"); -+ return; -+ } -+ memset(gr_conn_table, 0, gr_conn_table_size * sizeof(struct task_struct *)); -+ /* allocate memory for authentication structure */ - gr_pwent = kmalloc(sizeof(struct admin_pw), GFP_KERNEL); - if (gr_pwent == NULL) { @@ -14452,9 +15573,9 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke #ifndef CONFIG_GRKERNSEC_SYSCTL grsec_lock = 1; -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/grsecurity/grsec_link.c linux-2.4.20-wolk4.15-grsec2/grsecurity/grsec_link.c ---- linux-2.4.20-wolk4.15-fullkernel/grsecurity/grsec_link.c 2004-06-29 11:24:38.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/grsecurity/grsec_link.c 2004-06-29 13:00:19.000000000 +0200 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/grsecurity/grsec_link.c linux-2.4.20-wolk4.16-grsec2/grsecurity/grsec_link.c +--- linux-2.4.20-wolk4.16-fullkernel/grsecurity/grsec_link.c 2004-09-05 15:48:18.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/grsecurity/grsec_link.c 2004-09-05 17:07:52.000000000 +0200 @@ -13,8 +13,7 @@ gr_handle_follow_link(const struct inode if (grsec_enable_link && S_ISLNK(inode->i_mode) && (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) && @@ -14465,22 +15586,34 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke inode->i_uid, inode->i_gid, DEFAULTSECARGS); return -EACCES; } -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/grsecurity/grsec_mem.c linux-2.4.20-wolk4.15-grsec2/grsecurity/grsec_mem.c ---- linux-2.4.20-wolk4.15-fullkernel/grsecurity/grsec_mem.c 2004-06-29 11:30:54.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/grsecurity/grsec_mem.c 2004-06-29 13:00:19.000000000 +0200 -@@ -41,8 +41,7 @@ gr_handle_open_port(void) +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/grsecurity/grsec_mem.c linux-2.4.20-wolk4.16-grsec2/grsecurity/grsec_mem.c +--- linux-2.4.20-wolk4.16-fullkernel/grsecurity/grsec_mem.c 2004-09-05 16:05:21.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/grsecurity/grsec_mem.c 2004-09-05 17:07:52.000000000 +0200 +@@ -41,10 +41,17 @@ gr_handle_open_port(void) int gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma) { - if (offset < __pa(high_memory) && - (pgprot_val(vma->vm_page_prot) & PROT_WRITE) && -+ if (offset < __pa(high_memory) && (vma->vm_flags & VM_WRITE) && - !(offset == 0xf0000 && ((vma->vm_end - vma->vm_start) <= 0x10000)) && - !(offset == 0xa0000 && ((vma->vm_end - vma->vm_start) <= 0x20000))) { +- !(offset == 0xf0000 && ((vma->vm_end - vma->vm_start) <= 0x10000)) && +- !(offset == 0xa0000 && ((vma->vm_end - vma->vm_start) <= 0x20000))) { ++ if (offset + vma->vm_end - vma->vm_start <= offset) { ++ security_alert(GR_MEM_MMAP_MSG, DEFAULTSECARGS); ++ return -EPERM; ++ } ++ ++ if (offset < __pa(high_memory) && (vma->vm_flags & VM_WRITE) ++#ifdef CONFIG_X86 ++ && !(offset == 0xf0000 && ((vma->vm_end - vma->vm_start) <= 0x10000)) ++ && !(offset == 0xa0000 && ((vma->vm_end - vma->vm_start) <= 0x20000)) ++#endif ++ ) { security_alert(GR_MEM_MMAP_MSG, DEFAULTSECARGS); -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/grsecurity/grsec_sig.c linux-2.4.20-wolk4.15-grsec2/grsecurity/grsec_sig.c ---- linux-2.4.20-wolk4.15-fullkernel/grsecurity/grsec_sig.c 2004-06-29 11:24:38.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/grsecurity/grsec_sig.c 2004-06-29 13:00:27.000000000 +0200 + return -EPERM; + } else if (offset < __pa(high_memory)) +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/grsecurity/grsec_sig.c linux-2.4.20-wolk4.16-grsec2/grsecurity/grsec_sig.c +--- linux-2.4.20-wolk4.16-fullkernel/grsecurity/grsec_sig.c 2004-09-05 15:48:18.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/grsecurity/grsec_sig.c 2004-09-05 17:07:52.000000000 +0200 @@ -12,11 +12,14 @@ gr_log_signal(const int sig, const struc security_alert_good(GR_UNISIGLOG_MSG, sig, DEFAULTSECARGS); @@ -14500,13 +15633,15 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke } } #endif -@@ -28,11 +31,15 @@ gr_handle_signal(const struct task_struc +@@ -27,14 +30,43 @@ int + gr_handle_signal(const struct task_struct *p, const int sig) { #ifdef CONFIG_GRKERNSEC - if (current->pid > 1 && gr_check_protected_task(p)) { +- if (current->pid > 1 && gr_check_protected_task(p)) { - security_alert(GR_SIG_ACL_MSG, sig, p->comm, p->pid, p->uid, - p->euid, p->p_pptr->comm, p->p_pptr->pid, - p->p_pptr->uid, p->p_pptr->euid, DEFAULTSECARGS); ++ if (current->pid > 1 && sig != SIGCHLD && gr_check_protected_task(p)) { + security_alert(GR_SIG_ACL_MSG, sig, gr_task_fullpath0(p), + p->comm, p->pid, p->uid, + p->euid, p->gid, p->egid, @@ -14520,16 +15655,43 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke return -EPERM; } #endif -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/grsecurity/grsec_sock.c linux-2.4.20-wolk4.15-grsec2/grsecurity/grsec_sock.c ---- linux-2.4.20-wolk4.15-fullkernel/grsecurity/grsec_sock.c 2004-06-29 11:30:54.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/grsecurity/grsec_sock.c 2004-06-29 13:00:19.000000000 +0200 + return 0; + } ++ ++void gr_handle_brute_attach(struct task_struct *p) ++{ ++#ifdef CONFIG_GRKERNSEC_BRUTE ++ read_lock(&tasklist_lock); ++ read_lock(&grsec_exec_file_lock); ++ if (p->p_pptr && p->p_pptr->exec_file == p->exec_file) ++ p->p_pptr->brute = 1; ++ read_unlock(&grsec_exec_file_lock); ++ read_unlock(&tasklist_lock); ++#endif ++ return; ++} ++ ++void gr_handle_brute_check(void) ++{ ++#ifdef CONFIG_GRKERNSEC_BRUTE ++ if (current->brute) { ++ set_current_state(TASK_UNINTERRUPTIBLE); ++ schedule_timeout(30 * HZ); ++ } ++#endif ++ return; ++} ++ +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/grsecurity/grsec_sock.c linux-2.4.20-wolk4.16-grsec2/grsecurity/grsec_sock.c +--- linux-2.4.20-wolk4.16-fullkernel/grsecurity/grsec_sock.c 2004-09-05 16:05:22.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/grsecurity/grsec_sock.c 2004-09-05 17:07:53.000000000 +0200 @@ -7,6 +7,114 @@ #include #include +#ifdef CONFIG_GRKERNSEC -+struct task_struct **gr_conn_table; -+const unsigned int gr_conn_table_size = 65521; ++#define gr_conn_table_size 65521 ++struct task_struct *gr_conn_table[gr_conn_table_size]; +struct task_struct *deleted_conn = (struct task_struct *)~0; +spinlock_t gr_conn_table_lock = SPIN_LOCK_UNLOCKED; + @@ -14690,9 +15852,22 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke return -EACCES; } #endif -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/grsecurity/grsec_sysctl.c linux-2.4.20-wolk4.15-grsec2/grsecurity/grsec_sysctl.c ---- linux-2.4.20-wolk4.15-fullkernel/grsecurity/grsec_sysctl.c 2004-06-29 11:24:38.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/grsecurity/grsec_sysctl.c 2004-06-29 13:00:19.000000000 +0200 +@@ -94,8 +191,11 @@ gr_cap_rtnetlink(void) + #ifdef CONFIG_GRKERNSEC + if (!gr_acl_is_enabled()) + return current->cap_effective; ++ else if (cap_raised(current->cap_effective, CAP_NET_ADMIN) && ++ gr_task_is_capable(current, CAP_NET_ADMIN)) ++ return current->cap_effective; + else +- return (current->cap_effective & ~(current->acl->cap_lower)); ++ return 0; + #else + return current->cap_effective; + #endif +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/grsecurity/grsec_sysctl.c linux-2.4.20-wolk4.16-grsec2/grsecurity/grsec_sysctl.c +--- linux-2.4.20-wolk4.16-fullkernel/grsecurity/grsec_sysctl.c 2004-09-05 15:48:18.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/grsecurity/grsec_sysctl.c 2004-09-05 17:07:52.000000000 +0200 @@ -6,9 +6,8 @@ int gr_handle_sysctl_mod(const char *dirname, const char *name, const int op) @@ -14705,9 +15880,9 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke security_alert(GR_SYSCTL_MSG, name, DEFAULTSECARGS); return -EACCES; } -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/grsecurity/grsec_tpe.c linux-2.4.20-wolk4.15-grsec2/grsecurity/grsec_tpe.c ---- linux-2.4.20-wolk4.15-fullkernel/grsecurity/grsec_tpe.c 2004-06-29 11:24:38.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/grsecurity/grsec_tpe.c 2004-06-29 13:00:19.000000000 +0200 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/grsecurity/grsec_tpe.c linux-2.4.20-wolk4.16-grsec2/grsecurity/grsec_tpe.c +--- linux-2.4.20-wolk4.16-fullkernel/grsecurity/grsec_tpe.c 2004-09-05 15:48:18.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/grsecurity/grsec_tpe.c 2004-09-05 17:07:52.000000000 +0200 @@ -4,13 +4,15 @@ #include #include @@ -14726,9 +15901,9 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))))) { security_alert(GR_EXEC_TPE_MSG, -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/grsecurity/grsum.c linux-2.4.20-wolk4.15-grsec2/grsecurity/grsum.c ---- linux-2.4.20-wolk4.15-fullkernel/grsecurity/grsum.c 2004-06-29 11:30:54.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/grsecurity/grsum.c 2004-06-29 13:00:19.000000000 +0200 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/grsecurity/grsum.c linux-2.4.20-wolk4.16-grsec2/grsecurity/grsum.c +--- linux-2.4.20-wolk4.16-fullkernel/grsecurity/grsum.c 2004-09-05 16:05:21.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/grsecurity/grsum.c 2004-09-05 17:07:52.000000000 +0200 @@ -5,12 +5,13 @@ #include #include @@ -14772,9 +15947,9 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke return retval; } - -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/include/asm-i386/pgtable.h linux-2.4.20-wolk4.15-grsec2/include/asm-i386/pgtable.h ---- linux-2.4.20-wolk4.15-fullkernel/include/asm-i386/pgtable.h 2004-06-29 11:31:02.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/include/asm-i386/pgtable.h 2004-06-29 13:00:30.000000000 +0200 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/include/asm-i386/pgtable.h linux-2.4.20-wolk4.16-grsec2/include/asm-i386/pgtable.h +--- linux-2.4.20-wolk4.16-fullkernel/include/asm-i386/pgtable.h 2004-09-05 16:05:34.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/include/asm-i386/pgtable.h 2004-09-05 17:07:52.000000000 +0200 @@ -21,12 +21,6 @@ #include #endif @@ -14819,10 +15994,10 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke #define __beep() asm("movb $0x3,%al; outb %al,$0x61") #define PMD_SIZE (1UL << PMD_SHIFT) -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/include/linux/gracl.h linux-2.4.20-wolk4.15-grsec2/include/linux/gracl.h ---- linux-2.4.20-wolk4.15-fullkernel/include/linux/gracl.h 2004-06-29 11:31:04.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/include/linux/gracl.h 2004-06-29 13:00:30.000000000 +0200 -@@ -1,28 +1,24 @@ +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/include/linux/gracl.h linux-2.4.20-wolk4.16-grsec2/include/linux/gracl.h +--- linux-2.4.20-wolk4.16-fullkernel/include/linux/gracl.h 2004-09-05 16:05:35.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/include/linux/gracl.h 2004-09-05 17:07:52.000000000 +0200 +@@ -1,28 +1,25 @@ #ifndef GR_ACL_H #define GR_ACL_H -#endif @@ -14842,6 +16017,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke -#define GR_VERSION "grsecurity 1.9.15" +#define GR_VERSION "grsecurity 2.0.1" ++#define GRSECURITY_VERSION 0x201 enum { @@ -14857,7 +16033,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke }; /* Password setup definitions -@@ -33,9 +29,14 @@ enum { +@@ -33,9 +30,14 @@ enum { GR_SHA_LEN = 32, }; @@ -14873,7 +16049,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke unsigned char salt[GR_SALT_LEN]; unsigned char sum[GR_SHA_LEN]; /* 256-bit SHA hash of the password */ }; -@@ -44,11 +45,12 @@ struct name_entry { +@@ -44,11 +46,12 @@ struct name_entry { ino_t inode; kdev_t device; char *name; @@ -14889,7 +16065,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke }; struct name_db { -@@ -61,18 +63,34 @@ struct crash_uid { +@@ -61,18 +64,34 @@ struct crash_uid { unsigned long expires; }; @@ -14925,23 +16101,26 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke __u32 ip_proto[8]; __u32 ip_type; struct acl_ip_label **ips; -@@ -81,7 +99,8 @@ struct acl_subject_label { +@@ -81,8 +100,8 @@ struct acl_subject_label { __u32 crashes; unsigned long expires; - struct acl_object_label *proc_object; +- struct acl_ip_label *ip_object; + struct acl_subject_label *parent_subject; + struct gr_hash_struct *hash; - struct acl_ip_label *ip_object; struct acl_subject_label *prev; struct acl_subject_label *next; -@@ -90,11 +109,50 @@ struct acl_subject_label { + +@@ -90,11 +109,51 @@ struct acl_subject_label { __u32 obj_hash_size; }; -struct user_acl_subject_db { - struct acl_subject_label **s_table; - __u32 s_entries; /* Number of entries in table */ +- __u32 i_entries; /* total number of ip acls */ +- __u32 o_entries; /* Total number of object acls */ +struct role_allowed_ip { + __u32 addr; + __u32 netmask; @@ -14973,23 +16152,24 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke + + struct role_transition *transitions; + struct role_allowed_ip *allowed_ips; ++ uid_t *domain_children; ++ __u16 domain_child_num; ++ + struct acl_subject_label **subj_hash; + __u32 subj_hash_size; +}; + +struct user_acl_role_db { + struct acl_role_label **r_table; -+ __u32 r_entries; /* number of entries in table */ -+ __u32 s_entries; /* total number of subject acls */ - __u32 i_entries; /* total number of ip acls */ - __u32 o_entries; /* Total number of object acls */ -+ __u32 g_entries; /* total number of globbed objects */ -+ __u32 a_entries; /* total number of allowed ips */ -+ __u32 t_entries; /* total number of transitions */ ++ __u32 num_pointers; /* Number of allocations to track */ ++ __u32 num_roles; /* Number of roles */ ++ __u32 num_domain_children; /* Number of domain children */ ++ __u32 num_subjects; /* Number of subjects */ ++ __u32 num_objects; /* Number of objects */ }; struct acl_object_label { -@@ -103,6 +161,9 @@ struct acl_object_label { +@@ -103,6 +162,9 @@ struct acl_object_label { kdev_t device; __u32 mode; @@ -14999,7 +16179,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke /* next two structures not used */ struct acl_object_label *prev; -@@ -124,15 +185,27 @@ struct acl_ip_label { +@@ -124,15 +186,33 @@ struct acl_ip_label { }; struct gr_arg { @@ -15017,6 +16197,12 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke __u16 mode; +}; ++struct gr_arg_wrapper { ++ struct gr_arg *arg; ++ __u32 version; ++ __u32 size; ++}; ++ +struct subject_map { + struct acl_subject_label *user; + struct acl_subject_label *kernel; @@ -15028,7 +16214,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke }; /* End Data Structures Section */ -@@ -143,13 +216,27 @@ struct gr_arg { +@@ -143,13 +223,27 @@ struct gr_arg { Shift/add algorithm with modulus of table size and an XOR*/ static __inline__ unsigned long @@ -15058,10 +16244,10 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke } + +#endif -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/include/linux/grdefs.h linux-2.4.20-wolk4.15-grsec2/include/linux/grdefs.h ---- linux-2.4.20-wolk4.15-fullkernel/include/linux/grdefs.h 2004-06-29 11:24:39.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/include/linux/grdefs.h 2004-06-29 13:00:19.000000000 +0200 -@@ -10,6 +10,20 @@ enum { +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/include/linux/grdefs.h linux-2.4.20-wolk4.16-grsec2/include/linux/grdefs.h +--- linux-2.4.20-wolk4.16-fullkernel/include/linux/grdefs.h 2004-09-05 15:48:20.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/include/linux/grdefs.h 2004-09-05 17:07:52.000000000 +0200 +@@ -10,6 +10,21 @@ enum { /* Begin ACL declarations */ @@ -15076,13 +16262,14 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke + GR_ROLE_NOPW = 0x0020, + GR_ROLE_GOD = 0x0040, + GR_ROLE_LEARN = 0x0080, -+ GR_ROLE_TPE = 0x0100 ++ GR_ROLE_TPE = 0x0100, ++ GR_ROLE_DOMAIN = 0x0200 +}; + /* ACL Subject and Object mode flags */ enum { GR_DELETED = 0x00000080 -@@ -17,49 +31,68 @@ enum { +@@ -17,49 +32,68 @@ enum { /* ACL Object-only mode flags */ enum { @@ -15186,9 +16373,9 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke }; #define GR_CRASH_RES 11 -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/include/linux/grinternal.h linux-2.4.20-wolk4.15-grsec2/include/linux/grinternal.h ---- linux-2.4.20-wolk4.15-fullkernel/include/linux/grinternal.h 2004-06-29 11:31:05.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/include/linux/grinternal.h 2004-06-29 13:00:43.000000000 +0200 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/include/linux/grinternal.h linux-2.4.20-wolk4.16-grsec2/include/linux/grinternal.h +--- linux-2.4.20-wolk4.16-fullkernel/include/linux/grinternal.h 2004-09-05 16:05:37.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/include/linux/grinternal.h 2004-09-05 17:07:53.000000000 +0200 @@ -4,24 +4,34 @@ #ifdef CONFIG_GRKERNSEC @@ -15379,9 +16566,9 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke }) #endif -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/include/linux/grmsg.h linux-2.4.20-wolk4.15-grsec2/include/linux/grmsg.h ---- linux-2.4.20-wolk4.15-fullkernel/include/linux/grmsg.h 2004-06-29 11:31:05.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/include/linux/grmsg.h 2004-06-29 13:00:19.000000000 +0200 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/include/linux/grmsg.h linux-2.4.20-wolk4.16-grsec2/include/linux/grmsg.h +--- linux-2.4.20-wolk4.16-fullkernel/include/linux/grmsg.h 2004-09-05 16:05:37.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/include/linux/grmsg.h 2004-09-05 17:07:53.000000000 +0200 @@ -1,5 +1,5 @@ -#define DEFAULTSECMSG "(%.16s:%d) UID(%d) EUID(%d), parent (%.16s:%d) UID(%d) EUID(%d)" -#define GR_ACL_PROCACCT_MSG "(%.16s:%d) IP:%u.%u.%u.%u TTY:%.64s UID(%d) EUID(%d) GID(%d) EGID(%d) run time:[%ud %uh %um %us] cpu time:[%ud %uh %um %us] %s with exit code %ld, parent (%.16s:%d) IP:%u.%u.%u.%u TTY:%.64s UID(%d) EUID(%d) GID(%d) EGID(%d)" @@ -15462,19 +16649,17 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke #define GR_REMOUNT_AUDIT_MSG "remount of %.30s by " DEFAULTSECMSG #define GR_UNMOUNT_AUDIT_MSG "unmount of %.30s by " DEFAULTSECMSG #define GR_MOUNT_AUDIT_MSG "mount %.30s to %.64s by " DEFAULTSECMSG -@@ -98,3 +106,4 @@ - #define GR_SHMR_AUDIT_MSG "shared memory of uid:%d euid:%d removed by " DEFAULTSECMSG - #define GR_RESOURCE_MSG "attempted resource overstep by requesting %lu for %.16s against limit %lu by " DEFAULTSECMSG - #define GR_TEXTREL_AUDIT_MSG "text relocation in %s, VMA:0x%08lx 0x%08lx by " DEFAULTSECMSG -+#define GR_TEXTREL_AUDIT_MSG "text relocation in %s, VMA:0x%08lx 0x%08lx by " DEFAULTSECMSG -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/include/linux/grsecurity.h linux-2.4.20-wolk4.15-grsec2/include/linux/grsecurity.h ---- linux-2.4.20-wolk4.15-fullkernel/include/linux/grsecurity.h 2004-06-29 11:31:06.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/include/linux/grsecurity.h 2004-06-29 13:00:30.000000000 +0200 -@@ -1,10 +1,16 @@ +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/include/linux/grsecurity.h linux-2.4.20-wolk4.16-grsec2/include/linux/grsecurity.h +--- linux-2.4.20-wolk4.16-fullkernel/include/linux/grsecurity.h 2004-09-05 16:05:39.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/include/linux/grsecurity.h 2004-09-05 17:07:53.000000000 +0200 +@@ -1,10 +1,19 @@ #ifndef GR_SECURITY_H #define GR_SECURITY_H -extern int gr_pid_is_chrooted(const struct task_struct *p); ++extern void gr_handle_brute_attach(struct task_struct *p); ++extern void gr_handle_brute_check(void); ++ +extern int gr_check_user_change(int real, int effective, int fs); +extern int gr_check_group_change(int real, int effective, int fs); + @@ -15489,7 +16674,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke extern int gr_handle_chroot_setpriority(const struct task_struct *p, const int niceval); extern int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt); -@@ -22,6 +28,7 @@ extern int gr_handle_chroot_mount(const +@@ -22,6 +31,7 @@ extern int gr_handle_chroot_mount(const extern int gr_handle_chroot_pivot(void); extern int gr_handle_chroot_unix(const pid_t pid); @@ -15497,7 +16682,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke extern int gr_handle_nproc(void); extern void gr_handle_ioperm(void); -@@ -63,7 +70,7 @@ extern int gr_handle_hardlink(const stru +@@ -63,7 +73,7 @@ extern int gr_handle_hardlink(const stru struct inode *inode, const int mode, const char *to); @@ -15506,7 +16691,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke extern void gr_learn_resource(const struct task_struct *task, const int limit, const unsigned long wanted, const int gt); extern void gr_copy_label(struct task_struct *tsk); -@@ -71,7 +78,6 @@ extern void gr_handle_crash(struct task_ +@@ -71,7 +81,6 @@ extern void gr_handle_crash(struct task_ extern int gr_handle_signal(const struct task_struct *p, const int sig); extern int gr_check_crash_uid(const uid_t uid); extern int gr_check_protected_task(const struct task_struct *task); @@ -15514,7 +16699,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke extern int gr_acl_handle_mmap(const struct file *file, const unsigned long prot); extern int gr_acl_handle_mprotect(const struct file *file, -@@ -84,20 +90,22 @@ extern __u32 gr_acl_handle_utime(const s +@@ -84,20 +93,22 @@ extern __u32 gr_acl_handle_utime(const s extern __u32 gr_acl_handle_access(const struct dentry *dentry, const struct vfsmount *mnt, const int fmode); extern __u32 gr_acl_handle_fchmod(const struct dentry *dentry, @@ -15542,7 +16727,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke const struct vfsmount *mnt); extern __u32 gr_acl_handle_hidden_file(const struct dentry *dentry, const struct vfsmount *mnt); -@@ -105,12 +113,14 @@ extern __u32 gr_acl_handle_open(const st +@@ -105,12 +116,14 @@ extern __u32 gr_acl_handle_open(const st const struct vfsmount *mnt, const int fmode); extern __u32 gr_acl_handle_creat(const struct dentry *dentry, const struct dentry *p_dentry, @@ -15559,7 +16744,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke extern __u32 gr_acl_handle_mkdir(const struct dentry *new_dentry, const struct dentry *parent_dentry, const struct vfsmount *parent_mnt); -@@ -128,17 +138,17 @@ extern __u32 gr_acl_handle_link(const st +@@ -128,22 +141,21 @@ extern __u32 gr_acl_handle_link(const st const struct vfsmount *parent_mnt, const struct dentry *old_dentry, const struct vfsmount *old_mnt, const char *to); @@ -15582,10 +16767,15 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke extern __u32 gr_acl_handle_filldir(const struct dentry *dentry, const struct vfsmount *mnt, const ino_t ino); extern __u32 gr_acl_handle_unix(const struct dentry *dentry, -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/include/linux/mm.h linux-2.4.20-wolk4.15-grsec2/include/linux/mm.h ---- linux-2.4.20-wolk4.15-fullkernel/include/linux/mm.h 2004-06-29 11:32:23.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/include/linux/mm.h 2004-06-29 13:00:30.000000000 +0200 -@@ -861,6 +861,11 @@ static inline int expand_stack(struct vm + const struct vfsmount *mnt); +-extern void gr_set_pax_flags(struct task_struct *task); + extern void gr_acl_handle_exit(void); + extern void gr_acl_handle_psacct(struct task_struct *task, const long code); + extern int gr_acl_handle_procpidmem(const struct task_struct *task); +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/include/linux/mm.h linux-2.4.20-wolk4.16-grsec2/include/linux/mm.h +--- linux-2.4.20-wolk4.16-fullkernel/include/linux/mm.h 2004-09-05 16:09:14.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/include/linux/mm.h 2004-09-05 17:07:52.000000000 +0200 +@@ -846,6 +846,11 @@ static inline int expand_stack(struct vm { unsigned long grow; @@ -15597,7 +16787,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke /* * vma->vm_start/vm_end cannot change under us because the caller is required * to hold the mmap_sem in write mode. We need to get the spinlock only -@@ -876,9 +881,6 @@ static inline int expand_stack(struct vm +@@ -861,9 +866,6 @@ static inline int expand_stack(struct vm #if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC) if (vma->vm_flags & VM_MIRROR) { @@ -15607,7 +16797,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke address_m = vma->vm_start + (unsigned long)vma->vm_private_data; vma_m = find_vma(vma->vm_mm, address_m); if (!vma_m || vma_m->vm_start != address_m || !(vma_m->vm_flags & VM_MIRROR) || -@@ -897,12 +899,6 @@ static inline int expand_stack(struct vm +@@ -882,12 +884,6 @@ static inline int expand_stack(struct vm spin_unlock(&vma->vm_mm->page_table_lock); return -ENOMEM; } @@ -15620,7 +16810,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke } else #endif -@@ -919,6 +915,17 @@ static inline int expand_stack(struct vm +@@ -904,6 +900,17 @@ static inline int expand_stack(struct vm vma->vm_mm->total_vm += grow; if (vma->vm_flags & VM_LOCKED) vma->vm_mm->locked_vm += grow; @@ -15638,9 +16828,9 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke spin_unlock(&vma->vm_mm->page_table_lock); return 0; } -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/include/linux/sched.h linux-2.4.20-wolk4.15-grsec2/include/linux/sched.h ---- linux-2.4.20-wolk4.15-fullkernel/include/linux/sched.h 2004-06-29 11:32:25.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/include/linux/sched.h 2004-06-29 13:00:27.000000000 +0200 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/include/linux/sched.h linux-2.4.20-wolk4.16-grsec2/include/linux/sched.h +--- linux-2.4.20-wolk4.16-fullkernel/include/linux/sched.h 2004-09-05 16:08:59.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/include/linux/sched.h 2004-09-05 17:07:52.000000000 +0200 @@ -29,8 +29,8 @@ extern unsigned long event; #include #include @@ -15652,7 +16842,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke struct exec_domain; -@@ -477,17 +477,18 @@ struct task_struct { +@@ -478,17 +478,19 @@ struct task_struct { /* added by grsecurity's ACL system */ #ifdef CONFIG_GRKERNSEC @@ -15673,10 +16863,11 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke u8 used_accept:1; - u8 used_connect:1; + u8 is_writable:1; ++ u8 brute:1; #endif /* TASK_UNMAPPED_BASE value */ -@@ -854,7 +855,7 @@ static inline int fsuser(void) +@@ -861,7 +863,7 @@ static inline int fsuser(void) static inline int capable(int cap) { #if 1 /* ok now */ @@ -15685,9 +16876,9 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke #else if (cap_is_fs_cap(cap) ? current->fsuid == 0 : current->euid == 0) #endif -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/init/main.c linux-2.4.20-wolk4.15-grsec2/init/main.c ---- linux-2.4.20-wolk4.15-fullkernel/init/main.c 2004-06-29 11:31:45.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/init/main.c 2004-06-29 13:00:34.000000000 +0200 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/init/main.c linux-2.4.20-wolk4.16-grsec2/init/main.c +--- linux-2.4.20-wolk4.16-fullkernel/init/main.c 2004-09-05 16:08:23.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/init/main.c 2004-09-05 17:07:53.000000000 +0200 @@ -612,7 +612,7 @@ asmlinkage void __init start_kernel(void * We want to tell the user if we are using grsecurity or not. */ @@ -15697,9 +16888,9 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke #endif -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/kernel/exit.c linux-2.4.20-wolk4.15-grsec2/kernel/exit.c ---- linux-2.4.20-wolk4.15-fullkernel/kernel/exit.c 2004-06-29 11:31:44.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/kernel/exit.c 2004-06-29 13:00:27.000000000 +0200 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/kernel/exit.c linux-2.4.20-wolk4.16-grsec2/kernel/exit.c +--- linux-2.4.20-wolk4.16-fullkernel/kernel/exit.c 2004-09-05 16:08:20.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/kernel/exit.c 2004-09-05 17:07:52.000000000 +0200 @@ -7,6 +7,7 @@ #include #include @@ -15754,10 +16945,22 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke #ifdef CONFIG_SYSTRACE systrace_exit(tsk); -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/kernel/ksyms.c linux-2.4.20-wolk4.15-grsec2/kernel/ksyms.c ---- linux-2.4.20-wolk4.15-fullkernel/kernel/ksyms.c 2004-06-29 11:32:00.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/kernel/ksyms.c 2004-06-29 13:00:19.000000000 +0200 -@@ -700,7 +700,7 @@ EXPORT_SYMBOL(kdb_usb_infos); +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/kernel/fork.c linux-2.4.20-wolk4.16-grsec2/kernel/fork.c +--- linux-2.4.20-wolk4.16-fullkernel/kernel/fork.c 2004-09-05 16:09:14.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/kernel/fork.c 2004-09-05 17:07:52.000000000 +0200 +@@ -799,6 +799,8 @@ int do_fork(unsigned long clone_flags, u + } + #endif + ++ gr_handle_brute_check(); ++ + retval = -ENOMEM; + p = alloc_task_struct(); + if (!p) +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/kernel/ksyms.c linux-2.4.20-wolk4.16-grsec2/kernel/ksyms.c +--- linux-2.4.20-wolk4.16-fullkernel/kernel/ksyms.c 2004-09-05 16:08:47.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/kernel/ksyms.c 2004-09-05 17:07:52.000000000 +0200 +@@ -701,7 +701,7 @@ EXPORT_SYMBOL(kdb_usb_infos); #endif /* grsecurity */ @@ -15766,9 +16969,78 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke EXPORT_SYMBOL(gr_pid_is_chrooted); EXPORT_SYMBOL(gr_learn_resource); EXPORT_SYMBOL(gr_set_kernel_label); -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/kernel/sys.c linux-2.4.20-wolk4.15-grsec2/kernel/sys.c ---- linux-2.4.20-wolk4.15-fullkernel/kernel/sys.c 2004-06-29 11:31:22.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/kernel/sys.c 2004-06-29 13:00:27.000000000 +0200 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/kernel/signal.c linux-2.4.20-wolk4.16-grsec2/kernel/signal.c +--- linux-2.4.20-wolk4.16-fullkernel/kernel/signal.c 2004-09-05 16:06:34.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/kernel/signal.c 2004-09-05 17:07:52.000000000 +0200 +@@ -369,7 +369,7 @@ int bad_signal(int sig, struct siginfo * + && ((sig != SIGCONT) || (current->session != t->session)) + && ( ( (current->euid ^ t->suid) && (current->euid ^ t->uid) + && (current->uid ^ t->suid) && (current->uid ^ t->uid) +- && !capable(CAP_KILL) ++ && !capable(CAP_KILL) && !gr_handle_signal(t, sig) + ) + /* RSBAC */ + #ifdef CONFIG_RSBAC +@@ -652,13 +652,9 @@ kill_pg_info(int sig, struct siginfo *in + read_lock(&tasklist_lock); + for_each_task(p) { + if (p->pgrp == pgrp && thread_group_leader(p)) { +- if (gr_handle_signal(p, sig)) +- retval = -EPERM; +- else { +- int err = send_sig_info(sig, info, p); +- if (retval) +- retval = err; +- } ++ int err = send_sig_info(sig, info, p); ++ if (retval) ++ retval = err; + } + } + read_unlock(&tasklist_lock); +@@ -709,10 +705,7 @@ kill_proc_info(int sig, struct siginfo * + if (tg) + p = tg; + } +- if (gr_handle_signal(p, sig)) +- error = -EPERM; +- else +- error = send_sig_info(sig, info, p); ++ error = send_sig_info(sig, info, p); + } + read_unlock(&tasklist_lock); + return error; +@@ -737,14 +730,10 @@ static int kill_something_info(int sig, + read_lock(&tasklist_lock); + for_each_task(p) { + if (p->pid > 1 && p != current && thread_group_leader(p)) { +- if (gr_handle_signal(p, sig)) +- retval = -EPERM; +- else { +- int err = send_sig_info(sig, info, p); +- ++count; +- if (err != -EPERM) +- retval = err; +- } ++ int err = send_sig_info(sig, info, p); ++ ++count; ++ if (err != -EPERM) ++ retval = err; + } + } + read_unlock(&tasklist_lock); +@@ -1092,7 +1081,7 @@ sys_tkill(int pid, int sig) + p = find_task_by_pid(pid); + error = -ESRCH; + if (p) { +- error = send_sig_info(sig, &info, p); ++ error = send_sig_info(sig, &info, p); + } + read_unlock(&tasklist_lock); + return error; +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/kernel/sys.c linux-2.4.20-wolk4.16-grsec2/kernel/sys.c +--- linux-2.4.20-wolk4.16-fullkernel/kernel/sys.c 2004-09-05 16:06:21.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/kernel/sys.c 2004-09-05 17:07:52.000000000 +0200 @@ -606,6 +606,10 @@ asmlinkage long sys_setregid(gid_t rgid, return -EPERM; } @@ -15905,9 +17177,9 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke if (!core_allow_setid && gid != old_fsgid) { current->mm->dumpable = 0; -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/kernel/sysctl.c linux-2.4.20-wolk4.15-grsec2/kernel/sysctl.c ---- linux-2.4.20-wolk4.15-fullkernel/kernel/sysctl.c 2004-06-29 11:31:55.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/kernel/sysctl.c 2004-06-29 13:00:43.000000000 +0200 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/kernel/sysctl.c linux-2.4.20-wolk4.16-grsec2/kernel/sysctl.c +--- linux-2.4.20-wolk4.16-fullkernel/kernel/sysctl.c 2004-09-05 16:09:03.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/kernel/sysctl.c 2004-09-05 17:07:53.000000000 +0200 @@ -52,8 +52,6 @@ #include #include @@ -15969,19 +17241,20 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke return -EACCES; if (gr_handle_chroot_sysctl(op)) return -EACCES; -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/mm/memory.c linux-2.4.20-wolk4.15-grsec2/mm/memory.c ---- linux-2.4.20-wolk4.15-fullkernel/mm/memory.c 2004-06-29 11:32:25.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/mm/memory.c 2004-06-29 13:00:30.000000000 +0200 -@@ -1122,17 +1122,21 @@ static void pax_mirror_fault(struct mm_s +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/mm/memory.c linux-2.4.20-wolk4.16-grsec2/mm/memory.c +--- linux-2.4.20-wolk4.16-fullkernel/mm/memory.c 2004-09-05 16:08:59.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/mm/memory.c 2004-09-05 17:07:53.000000000 +0200 +@@ -1129,17 +1129,22 @@ static void pax_mirror_fault(struct mm_s if (pte_none(entry_m)) { ++mm->rss; } else if (pte_present(entry_m)) { - page_remove_rmap(pte_page(entry_m), pte_m); - page_cache_release(pte_page(entry_m)); + page_m = pte_page(entry_m); -+ if (!PageReserved(page_m)) ++ if (!PageReserved(page_m)) { ++ page_remove_rmap(pte_page(entry_m), pte_m); + page_cache_release(page_m); -+ else ++ } else + ++mm->rss; } else { free_swap_and_cache(pte_to_swp_entry(entry_m)); @@ -15998,7 +17271,7 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke entry_m = pte_mkdirty(pte_mkwrite(entry_m)); establish_pte(vma_m, address_m, pte_m, entry_m); } -@@ -1719,12 +1723,9 @@ int handle_mm_fault(struct mm_struct *mm +@@ -1726,12 +1731,9 @@ int handle_mm_fault(struct mm_struct *mm address_m = address + (unsigned long)vma->vm_private_data; pgd_m = pgd_offset(mm, address_m); pmd_m = pmd_alloc(mm, pgd_m, address_m); @@ -16014,10 +17287,10 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke spin_unlock(&mm->page_table_lock); return -1; } -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/net/ipv4/tcp_ipv4.c linux-2.4.20-wolk4.15-grsec2/net/ipv4/tcp_ipv4.c ---- linux-2.4.20-wolk4.15-fullkernel/net/ipv4/tcp_ipv4.c 2004-06-29 11:30:54.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/net/ipv4/tcp_ipv4.c 2004-06-29 13:00:19.000000000 +0200 -@@ -783,11 +783,12 @@ static int tcp_v4_hash_connect(struct so +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/net/ipv4/tcp_ipv4.c linux-2.4.20-wolk4.16-grsec2/net/ipv4/tcp_ipv4.c +--- linux-2.4.20-wolk4.16-fullkernel/net/ipv4/tcp_ipv4.c 2004-09-05 16:09:36.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/net/ipv4/tcp_ipv4.c 2004-09-05 17:07:52.000000000 +0200 +@@ -780,11 +780,12 @@ static int tcp_v4_hash_connect(struct so spin_unlock(&head->lock); #ifdef CONFIG_GRKERNSEC @@ -16031,10 +17304,10 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke #endif if (tw) { -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/net/ipv4/udp.c linux-2.4.20-wolk4.15-grsec2/net/ipv4/udp.c ---- linux-2.4.20-wolk4.15-fullkernel/net/ipv4/udp.c 2004-06-29 11:30:54.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/net/ipv4/udp.c 2004-06-29 13:00:19.000000000 +0200 -@@ -487,6 +487,7 @@ int udp_sendmsg(struct sock *sk, struct +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/net/ipv4/udp.c linux-2.4.20-wolk4.16-grsec2/net/ipv4/udp.c +--- linux-2.4.20-wolk4.16-fullkernel/net/ipv4/udp.c 2004-09-05 16:09:36.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/net/ipv4/udp.c 2004-09-05 17:07:52.000000000 +0200 +@@ -490,6 +490,7 @@ int udp_sendmsg(struct sock *sk, struct ufh.uh.dest = usin->sin_port; if (ufh.uh.dest == 0) return -EINVAL; @@ -16042,9 +17315,9 @@ diff -Naurp linux-2.4.20-wolk4.15-fullke if (!gr_search_udp_sendmsg(sk, usin)) return -EPERM; } else { -diff -Naurp linux-2.4.20-wolk4.15-fullkernel/net/unix/af_unix.c linux-2.4.20-wolk4.15-grsec2/net/unix/af_unix.c ---- linux-2.4.20-wolk4.15-fullkernel/net/unix/af_unix.c 2004-06-29 11:25:23.000000000 +0200 -+++ linux-2.4.20-wolk4.15-grsec2/net/unix/af_unix.c 2004-06-29 13:00:19.000000000 +0200 +diff -Naurp linux-2.4.20-wolk4.16-fullkernel/net/unix/af_unix.c linux-2.4.20-wolk4.16-grsec2/net/unix/af_unix.c +--- linux-2.4.20-wolk4.16-fullkernel/net/unix/af_unix.c 2004-09-05 15:55:19.000000000 +0200 ++++ linux-2.4.20-wolk4.16-grsec2/net/unix/af_unix.c 2004-09-05 17:07:52.000000000 +0200 @@ -736,7 +736,7 @@ static int unix_bind(struct socket *sock */ mode = S_IFSOCK | (sock->inode->i_mode & ~current->fs->umask); diff -Naurp linux-2.4.20-wolk4.15-fullkernel/CREDITS linux-2.4.20-wolk4.16-fullkernel/CREDITS --- linux-2.4.20-wolk4.15-fullkernel/CREDITS 2004-06-29 11:31:21.000000000 +0200 +++ linux-2.4.20-wolk4.16-fullkernel/CREDITS 2004-09-05 16:06:18.000000000 +0200 @@ -1337,8 +1337,10 @@ S: USA N: Marcel Holtmann E: marcel@holtmann.org W: http://www.holtmann.org +D: Maintainer of the Linux Bluetooth Subsystem D: Author and maintainer of the various Bluetooth HCI drivers D: Author and maintainer of the CAPI message transport protocol driver +D: Author and maintainer of the Bluetooth HID protocol driver D: Various other Bluetooth related patches, cleanups and fixes S: Germany @@ -2596,6 +2598,7 @@ S: Australia N: Aristeu Sergio Rozanski Filho E: aris@conectiva.com.br D: Support for EtherExpress 10 ISA (i82595) in eepro driver +D: User level driver support for input S: Conectiva S.A. S: R. Tocantins, 89 - Cristo Rei S: 80050-430 - Curitiba - Paraná diff -Naurp linux-2.4.20-wolk4.15-fullkernel/Changelog.rmap linux-2.4.20-wolk4.16-fullkernel/Changelog.rmap --- linux-2.4.20-wolk4.15-fullkernel/Changelog.rmap 2004-06-29 11:24:33.000000000 +0200 +++ linux-2.4.20-wolk4.16-fullkernel/Changelog.rmap 1970-01-01 01:00:00.000000000 +0100 @@ -1,279 +0,0 @@ -The eleventh maintenance release of the 15th version of the reverse -mapping based VM is now available. -This is an attempt at making a more robust and flexible VM -subsystem, while cleaning up a lot of code at the same time. -The patch is available from: - - http://surriel.com/patches/2.4/2.4.22-rmap15l -and http://linuxvm.bkbits.net/ - - -My big TODO items for a next release are: - - 2.4-rmap is now in maintenance mode, let me know when something - needs fixing - -rmap 15l: - - merge hfsplus with rmap (Rene Herman) - - fix inode code ordering bug (Harald Hoyer) - - clean a tunable percentage of the inactive pages (Larry Woodman) - - fix double-decrement inactive_clean_pages on SMP race (Martin Wilck) - - also clean pages on free shortage (me) -rmap 15k: - - fix various SMP races (Larry Woodman, - Stephen Tweedie, - me) - - make the per-cpu free lists work better (me) - - make the OOM killer a bit less agressive (me) - - fix page->flags corruption problem (Matt Domsch, - | should go upstream Robert Hentosh) - - treat shared memory segment as anon for swapping (me) - - backport various 2.6 optimisations and fixes (me) - - a "can't happen" situation does happen, deal with it (Stephen Tweedie, - Larry Woodman) - - shrink kiobuf slab when reclaiming buffer heads (Arjan van de Ven) - - deal with a non-zero highmem zone that's all IO space (Larry Woodman) - - only reclaim buffer heads / mapped inodes when lots (me) - - make O(1) page launder work as advertised (me) - - fix potential loop in inode pruning (Ernie Petrides) -rmap 15j: - - agressive inode reclaim on highmem boxes (me) - - OOM killer tweaks, hopefully better now (me) - - better higher-order page allocations (me) - - small updates and tweaks -rmap 15i: - - drop behind only drops really new pages (Arjan van de Ven) - - lots of VM tuning left and right (Arjan, Ingo, me) -rmap 15h: - - fix obscure SMP race (Ben LaHaise, me) - - fix smp races with bufferhead reclaim (Andrew Morton, me) - - architecture updates (various) - - add barrier to page_unlock_rmap (Pete Zaitcev) -rmap 15g: - - more ppc64 pte-highmem stuff (Julie DeWandel) - - hammer pte-highmem stuff (Jim Paradis) - - reclaim buffer heads under memory pressure (me) -rmap 15f: - - remove pte-highmem compat define from ieee1394 (Marc-C. Petersen) - - clean up scan_active_list after suggestion from hch (me) - - lock ordering fix (me) - - add barrier() to page_chain_lock() (Pete Zaitcev) - - fix pte-highmem defines for ppc64 (Julie DeWandel) - - add pte-highmem defines for s390 & s390x (Pete Zaitcev) -rmap 15e: - - make reclaiming unused inodes more efficient (Arjan van de Ven) - | push to Marcelo and Andrew once it's well tested ! - - fix DRM memory leak (Arjan van de Ven) - - fix potential infinite loop in kswapd (me) - - clean up elevator.h (no IO scheduler in -rmap...) (me) - - page aging interval tuned on a per zone basis, better - wakeup mechanism for sudden memory pressure (Arjan, me) -rmap 15d: - - compatability with PREEMPT patch (me) - | fairly ugly, but should work - - bugfix for the pte_chain allocation code (Arjan van de Ven) -rmap 15c: - - backport and audit akpm's reliable pte_chain alloc - code from 2.5 (me) - - reintroduce cache size tuning knobs in /proc (me) - | on very, very popular request -rmap 15b: - - adjust anon/cache work table (me) - - make active_age_bias a per-active list thing (me) - - don't wake up kswapd early from mark_page_accessed (me) - - make sure pte-chains are cacheline aligned with PAE (me, Andrew Morton) - - change some O(1) VM thresholds (me) - - fix pte-highmem backport (me) - - 2.5 backport: pte-highmem (Ben LaHaise) - - 2.5 backport: large cacheline aligned pte-chains (Ben LaHaise) - - 2.5 backport: direct pte pointers (Ben LaHaise) - - undo __find_pagecache_page braindamage (Christoph Hellwig) -rmap 15a: - - more agressive freeing for higher order allocations (me) - - export __find_pagecache_page, find_get_page define (me, Christoph, Arjan) - - make memory statistics SMP safe again (me) - - make page aging slow down again when needed (Andrew Morton) - - first stab at fine-tuning arjan's O(1) VM (me) - - split active list in cache / working set (me) - - fix SMP locking in arjan's O(1) VM (me) -rmap 15: - - small code cleanups and spelling fixes for O(1) VM (me) - - O(1) page launder, O(1) page aging (Arjan van de Ven) - - resync code with -ac (12 small patches) (me) -rmap 14c: - - fold page_over_rsslimit() into page_referenced() (me) - - 2.5 backport: get pte_chains from the slab cache (William Lee Irwin) - - remove dead code from page_launder_zone() (me) - - make OOM detection a bit more agressive (me) -rmap 14b: - - don't unmap pages not in pagecache (ext3 & reiser) (Andrew Morton, me) - - clean up mark_page_accessed a bit (me) - - Alpha NUMA fix for Ingo's per-cpu pages (Flávio Leitner, me) - - remove explicit low latency schedule zap_page_range (Robert Love) - - fix OOM stuff for good, hopefully (me) -rmap 14a: - - Ingo Molnar's per-cpu pages (SMP speedup) (Christoph Hellwig) - - fix SMP bug in page_launder_zone (rmap14 only) (Arjan van de Ven) - - semicolon day, fix typo in rmap.c w/ DEBUG_RMAP (Craig Kulesa) - - remove unneeded pte_chain_unlock/lock pair vmscan.c (Craig Kulesa) - - low latency zap_page_range also without preempt (Arjan van de Ven) - - do some throughput tuning for kswapd/page_launder (me) - - don't allocate swap space for pages we're not writing (me) -rmap 14: - - get rid of stalls during swapping, hopefully (me) - - low latency zap_page_range (Robert Love) -rmap 13c: - - add wmb() to wakeup_memwaiters (Arjan van de Ven) - - remap_pmd_range now calls pte_alloc with full address (Paul Mackerras) - - #ifdef out pte_chain_lock/unlock on UP machines (Andrew Morton) - - un-BUG() truncate_complete_page, the race is expected (Andrew Morton, me) - - remove NUMA changes from rmap13a (Christoph Hellwig) -rmap 13b: - - prevent PF_MEMALLOC recursion for higher order allocs (Arjan van de Ven, me) - - fix small SMP race, PG_lru (Hugh Dickins) -rmap 13a: - - NUMA changes for page_address (Samuel Ortiz) - - replace vm.freepages with simpler kswapd_minfree (Christoph Hellwig) -rmap 13: - - rename touch_page to mark_page_accessed and uninline (Christoph Hellwig) - - NUMA bugfix for __alloc_pages (William Irwin) - - kill __find_page (Christoph Hellwig) - - make pte_chain_freelist per zone (William Irwin) - - protect pte_chains by per-page lock bit (William Irwin) - - minor code cleanups (me) -rmap 12i: - - slab cleanup (Christoph Hellwig) - - remove references to compiler.h from mm/* (me) - - move rmap to marcelo's bk tree (me) - - minor cleanups (me) -rmap 12h: - - hopefully fix OOM detection algorithm (me) - - drop pte quicklist in anticipation of pte-highmem (me) - - replace andrea's highmem emulation by ingo's one (me) - - improve rss limit checking (Nick Piggin) -rmap 12g: - - port to armv architecture (David Woodhouse) - - NUMA fix to zone_table initialisation (Samuel Ortiz) - - remove init_page_count (David Miller) -rmap 12f: - - for_each_pgdat macro (William Lee Irwin) - - put back EXPORT(__find_get_page) for modular rd (me) - - make bdflush and kswapd actually start queued disk IO (me) -rmap 12e - - RSS limit fix, the limit can be 0 for some reason (me) - - clean up for_each_zone define to not need pgdata_t (William Lee Irwin) - - fix i810_dma bug introduced with page->wait removal (William Lee Irwin) -rmap 12d: - - fix compiler warning in rmap.c (Roger Larsson) - - read latency improvement (read-latency2) (Andrew Morton) -rmap 12c: - - fix small balancing bug in page_launder_zone (Nick Piggin) - - wakeup_kswapd / wakeup_memwaiters code fix (Arjan van de Ven) - - improve RSS limit enforcement (me) -rmap 12b: - - highmem emulation (for debugging purposes) (Andrea Arcangeli) - - ulimit RSS enforcement when memory gets tight (me) - - sparc64 page->virtual quickfix (Greg Procunier) -rmap 12a: - - fix the compile warning in buffer.c (me) - - fix divide-by-zero on highmem initialisation DOH! (me) - - remove the pgd quicklist (suspicious ...) (DaveM, me) -rmap 12: - - keep some extra free memory on large machines (Arjan van de Ven, me) - - higher-order allocation bugfix (Adrian Drzewiecki) - - nr_free_buffer_pages() returns inactive + free mem (me) - - pages from unused objects directly to inactive_clean (me) - - use fast pte quicklists on non-pae machines (Andrea Arcangeli) - - remove sleep_on from wakeup_kswapd (Arjan van de Ven) - - page waitqueue cleanup (Christoph Hellwig) -rmap 11c: - - oom_kill race locking fix (Andres Salomon) - - elevator improvement (Andrew Morton) - - dirty buffer writeout speedup (hopefully ;)) (me) - - small documentation updates (me) - - page_launder() never does synchronous IO, kswapd - and the processes calling it sleep on higher level (me) - - deadlock fix in touch_page() (me) -rmap 11b: - - added low latency reschedule points in vmscan.c (me) - - make i810_dma.c include mm_inline.h too (William Lee Irwin) - - wake up kswapd sleeper tasks on OOM kill so the - killed task can continue on its way out (me) - - tune page allocation sleep point a little (me) -rmap 11a: - - don't let refill_inactive() progress count for OOM (me) - - after an OOM kill, wait 5 seconds for the next kill (me) - - agpgart_be fix for hashed waitqueues (William Lee Irwin) -rmap 11: - - fix stupid logic inversion bug in wakeup_kswapd() (Andrew Morton) - - fix it again in the morning (me) - - add #ifdef BROKEN_PPC_PTE_ALLOC_ONE to rmap.h, it - seems PPC calls pte_alloc() before mem_map[] init (me) - - disable the debugging code in rmap.c ... the code - is working and people are running benchmarks (me) - - let the slab cache shrink functions return a value - to help prevent early OOM killing (Ed Tomlinson) - - also, don't call the OOM code if we have enough - free pages (me) - - move the call to lru_cache_del into __free_pages_ok (Ben LaHaise) - - replace the per-page waitqueue with a hashed - waitqueue, reduces size of struct page from 64 - bytes to 52 bytes (48 bytes on non-highmem machines) (William Lee Irwin) -rmap 10: - - fix the livelock for real (yeah right), turned out - to be a stupid bug in page_launder_zone() (me) - - to make sure the VM subsystem doesn't monopolise - the CPU, let kswapd and some apps sleep a bit under - heavy stress situations (me) - - let __GFP_HIGH allocations dig a little bit deeper - into the free page pool, the SCSI layer seems fragile (me) -rmap 9: - - improve comments all over the place (Michael Cohen) - - don't panic if page_remove_rmap() cannot find the - rmap in question, it's possible that the memory was - PG_reserved and belonging to a driver, but the driver - exited and cleared the PG_reserved bit (me) - - fix the VM livelock by replacing > by >= in a few - critical places in the pageout code (me) - - treat the reclaiming of an inactive_clean page like - allocating a new page, calling try_to_free_pages() - and/or fixup_freespace() if required (me) - - when low on memory, don't make things worse by - doing swapin_readahead (me) -rmap 8: - - add ANY_ZONE to the balancing functions to improve - kswapd's balancing a bit (me) - - regularize some of the maximum loop bounds in - vmscan.c for cosmetic purposes (William Lee Irwin) - - move page_address() to architecture-independent - code, now the removal of page->virtual is portable (William Lee Irwin) - - speed up free_area_init_core() by doing a single - pass over the pages and not using atomic ops (William Lee Irwin) - - documented the buddy allocator in page_alloc.c (William Lee Irwin) -rmap 7: - - clean up and document vmscan.c (me) - - reduce size of page struct, part one (William Lee Irwin) - - add rmap.h for other archs (untested, not for ARM) (me) -rmap 6: - - make the active and inactive_dirty list per zone, - this is finally possible because we can free pages - based on their physical address (William Lee Irwin) - - cleaned up William's code a bit (me) - - turn some defines into inlines and move those to - mm_inline.h (the includes are a mess ...) (me) - - improve the VM balancing a bit (me) - - add back inactive_target to /proc/meminfo (me) -rmap 5: - - fixed recursive buglet, introduced by directly - editing the patch for making rmap 4 ;))) (me) -rmap 4: - - look at the referenced bits in page tables (me) -rmap 3: - - forgot one FASTCALL definition (me) -rmap 2: - - teach try_to_unmap_one() about mremap() (me) - - don't assign swap space to pages with buffers (me) - - make the rmap.c functions FASTCALL / inline (me) -rmap 1: - - fix the swap leak in rmap 0 (Dave McCracken) -rmap 0: - - port of reverse mapping VM to 2.4.16 (me) diff -Naurp linux-2.4.20-wolk4.15-fullkernel/Documentation/Configure.help linux-2.4.20-wolk4.16-fullkernel/Documentation/Configure.help --- linux-2.4.20-wolk4.15-fullkernel/Documentation/Configure.help 2004-06-29 13:29:05.000000000 +0200 +++ linux-2.4.20-wolk4.16-fullkernel/Documentation/Configure.help 2004-09-09 13:21:58.000000000 +0200 @@ -1601,7 +1601,7 @@ CONFIG_X86_UP_APIC here: the local APIC will be used automatically. Do not report APIC errors on CPU(s) -CONFIG_X86_UP_APIC_ERRORS +CONFIG_X86_FUCK_DIFFERENT_NAMINGS_BC_XCONFIG_IS_FUCKED_ERRORS If you see annoying messages in your dmesg|syslog like: kernel: APIC error on CPU0: 08(00) @@ -1913,6 +1913,10 @@ CONFIG_05GB Select "1GB" otherwise Win4Lin and valgrind won't work! + Select "1GB.REAL" to allocate even the last 128MB of RAM which + are normally mapped as high, but with this option mapped as low + without the need for enabling high memory support. + You can't select anything but 1GB here if you said Y to Segmentation based non-executable pages (CONFIG_GRKERNSEC_PAX_SEGMEXEC) @@ -2200,6 +2204,16 @@ CONFIG_BLK_DEV_LOOP_AES If you want to use AES encryption algorithm to encrypt loop devices, say Y here. If you don't know what to do here, say N. +loop encryption key scrubbing support +CONFIG_BLK_DEV_LOOP_KEYSCRUB + Loop encryption key scrubbing moves and inverts key bits in + kernel RAM so that the thin oxide which forms the storage + capacitor dielectric of DRAM cells is not permitted to develop + detectable property. For more info, see Peter Gutmann's paper: + http://www.cs.auckland.ac.nz/~pgut001/pubs/secure_del.html + + Paranoid tinfoil hat crowd say Y here, everyone else say N. + ATA/IDE/MFM/RLL support CONFIG_IDE If you say Y here, your kernel will be able to manage low cost mass @@ -2983,7 +2997,7 @@ CONFIG_PIIX_TUNING If unsure, say N. -PROMISE PDC20246/PDC20262/PDC20265/PDC20267 support +Promise PDC202{46|62|65|67} support CONFIG_BLK_DEV_PDC202XX_OLD Promise Ultra 33 [PDC20246] Promise Ultra 66 [PDC20262] @@ -2992,14 +3006,13 @@ CONFIG_BLK_DEV_PDC202XX_OLD Promise Ultra 100 [PDC20267] This driver adds up to 4 more EIDE devices sharing a single - interrupt. This device is a bootable PCI UDMA controller. Since + interrupt. This add-on card is a bootable PCI UDMA controller. Since multiple cards can be installed and there are BIOS ROM problems that - happen if the BIOS revisions of all installed cards (max of three) do + happen if the BIOS revisions of all installed cards (three-max) do not match, the driver attempts to do dynamic tuning of the chipset - at boot-time for max speed. Ultra33 BIOS 1.25 or newer is required + at boot-time for max-speed. Ultra33 BIOS 1.25 or newer is required for more than one card. This card may require that you say Y to - "Special UDMA Feature" to force UDMA mode for connected UDMA capable - disk drives. + "Force (U)DMA burst transfers" (old name: "Special UDMA Feature"). If you say Y here, you need to say Y to "Use DMA by default when available" as well. @@ -3009,7 +3022,7 @@ CONFIG_BLK_DEV_PDC202XX_OLD If unsure, say N. -PROMISE PDC202{68|69|70|71|75|76|77} support +Promise PDC202{68|69|70|71|75|76|77} support CONFIG_BLK_DEV_PDC202XX_NEW Promise Ultra 100 TX2 [PDC20268] Promise Ultra 133 PTX2 [PDC20269] @@ -3024,42 +3037,39 @@ CONFIG_BLK_DEV_PDC202XX_NEW multiple cards can be installed and there are BIOS ROM problems that happen if the BIOS revisions of all installed cards (max of five) do not match, the driver attempts to do dynamic tuning of the chipset - at boot-time for max speed. Ultra33 BIOS 1.25 or newer is required - for more than one card. + at boot-time for max speed. If you say Y here, you need to say Y to "Use DMA by default when available" as well. - + If unsure, say N. - -Override-Enable UDMA for Promise Controllers + +Force (U)DMA burst transfers CONFIG_PDC202XX_BURST - This option causes the pdc202xx driver to enable UDMA modes on the + This option causes the pdc202xx_old driver to enable UDMA modes on the PDC202xx even when the PDC202xx BIOS has not done so. - + It was originally designed for the PDC20246/Ultra33, whose BIOS will only setup UDMA on the first two PDC20246 cards. It has also been used successfully on a PDC20265/Ultra100, allowing use of UDMA modes when the PDC20265 BIOS has been disabled (for faster boot up). + Please read the comments at the top of + . + If unsure, say N. -Use FastTrak RAID capable device as plain IDE controller +Ignore BIOS port disabled setting on FastTrak CONFIG_PDC202XX_FORCE - Setting this option causes the kernel to use your Promise IDE disk - controller as an ordinary IDE controller, rather than as a FastTrak - RAID controller. RAID is a system for using multiple physical disks - as one virtual disk. - - You need to say Y here if you have a PDC20276 IDE interface but either - you do not have a RAID disk array, or you wish to use the Linux - internal RAID software (/dev/mdX). - - You need to say N here if you wish to use your Promise controller to - control a FastTrak RAID disk array, and you you must also say Y to - CONFIG_BLK_DEV_ATARAID_PDC. + Chipsets affected: + + PDC202{46|62|63|65|67} + (pdc202xx_old driver) - If unsure, say Y. + PDC202{70|76} + (pdc202xx_new driver) + + Say Y unless you want to use Promise proprietary driver. CONFIG_SCSI_PTI_ST This driver supports the Promise SX6000 hardware ATA-RAID controller. @@ -6604,12 +6614,6 @@ CONFIG_BINFMT_ELF ld.so (check the file for location and latest version). - If you want to compile this as a module ( = code which can be - inserted in and removed from the running kernel whenever you want), - say M here and read . The module - will be called binfmt_elf.o. Saying M or N here is dangerous because - some crucial programs on your system might be in ELF format. - ELF binaries with a.out format interpreters or a.out libraries CONFIG_BINFMT_ELF_AOUT The kernel may support ELF executables which use an a.out format @@ -8016,32 +8020,6 @@ CONFIG_KMOD replacement for kerneld.) Say Y here and read about configuring it in . -Kernel .config file saved in kernel image -CONFIG_IKCONFIG - This option enables the complete Linux kernel ".config" file - contents, information on compiler used to build the kernel, - kernel running when this kernel was built and kernel version - from Makefile to be saved in kernel. It provides documentation - of which kernel options are used in a running kernel or in an - on-disk kernel. This information can be extracted from the kernel - image file with the script scripts/extract-ikconfig and used as - input to rebuild the current kernel or to build another kernel. - It can also be extracted from a running kernel by reading - /proc/ikconfig/config and /proc/ikconfig/built_with, if enabled. - /proc/ikconfig/config will list the configuration that was used - to build the kernel and /proc/ikconfig/built_with will list - information on the compiler and host machine that was used to - build the kernel. Since the kernel image is zipped, using this - option adds approximately 8 KB to a kernel image file. - This option is not available as a module. If you want a separate - file to save the kernel's .config contents, use 'installkernel' or 'cp' - or a similar tool, or just save it in '/lib/modules/'. - -Enable access to .config through /proc/ikconfig -CONFIG_IKCONFIG_PROC - This option enables access to kernel configuration file and build - information through /proc/ikconfig. - ARP daemon support CONFIG_ARPD Normally, the kernel maintains an internal cache which maps IP @@ -8318,6 +8296,21 @@ CONFIG_NET_IPGRE . The module will be called ip_gre.o +IP: WCCP tunnels over IP +CONFIG_NET_IPWCCP + Tunneling means encapsulating data of one protocol type within + another protocol and sending it over a channel that understands the + encapsulating protocol. This particular tunneling driver implements + WCCP (Web Cache Coordination Protocol) GRE. This driver is useful + if you have a WCCP-enabled router, and would like to use WCCP to + redirect packets to a web cache. + + This driver is also available as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + If you want to compile it as a module, say M here and read + . The module will be called + ip_wccp.o + Broadcast GRE over IP CONFIG_NET_IPGRE_BROADCAST One application of GRE/IP is to construct a broadcast WAN (Wide Area @@ -10121,6 +10114,15 @@ CONFIG_CHR_DEV_SG . The module will be called sg.o. If unsure, say N. +SCSI generic support Use Direct I/O +CONFIG_CHR_DEV_SG_DIO + Per default Direct I/O for SCSI generic support is off. Enabling this + will increae performance. This is the same as doing: + + echo 1 >/proc/scsi/sg/allow_dio + + If unsure, say Y. + SCSI media changer support CONFIG_CHR_DEV_SCH This is a driver for SCSI media changers. Most common devices are @@ -10524,7 +10526,7 @@ CONFIG_SCSI_IPS_OLD inserted in and removed from the running kernel whenever you want), but only a single instance may be loaded. If you want to compile it as a module, say M here and read . - The module will be called ips.o. + The module will be called ips_old.o. NOTE: This driver is known to deadlock under heavy load. You should use the new driver 7.x instead. @@ -11495,6 +11497,17 @@ CONFIG_SCSI_MEGARAID2 say M here and read . The module will be called megaraid2.o. +Collect statistics to report in /proc +CONFIG_SCSI_MEGARAID2_PROC_STATS + Set this if you are interested in statics about number of I/O completed + on each logical drive and how many interrupts generated. If enabled, + this information is available through /proc/megaraid and through the + private ioctl. + + Setting this has a performance penalty. + + If unsure, say N. + CONFIG_SCSI_SATA This driver family supports Serial ATA host controllers and devices. @@ -12868,6 +12881,21 @@ CONFIG_AIRO_CS say M here and read . The module will be called airo_cs.o. +NDIS driver wrapper support +CONFIG_NDISWRAPPER + Some wireless LAN vendors refuse to release hardware specifications or + drivers for their products for operating systems other than Microsoft + Windows. The ndiswrapper project makes it possible to use such + hardware with Linux by means of a loadable kernel module that "wraps + around" NDIS (Windows network driver API) drivers. + + For more informations please visit + + If you want to compile the driver as a module ( = code which can be + inserted in and removed from the running kernel whenever you want), + say M here and read . The module + will be called ndiswrapper.o. + Aviator/Raytheon 2.4MHz wireless support CONFIG_PCMCIA_RAYCS Say Y here if you intend to attach an Aviator/Raytheon PCMCIA @@ -13429,6 +13457,16 @@ CONFIG_NET_SCH_TBF whenever you want). If you want to compile it as a module, say M here and read . +CONFIG_NET_SCH_NETEM + Say Y if you want to emulate network delay, loss, and packet + re-ordering. This is often useful to simulate networks when + testing applications or protocols. + + To compile this driver as a module, choose M here: the module + will be called sch_netem. + + If unsure, say N. + If unsure, say N. Ingress Qdisc @@ -14488,6 +14526,8 @@ CONFIG_SK98LIN by this driver: - 3Com 3C940 Gigabit LOM Ethernet Adapter - 3Com 3C941 Gigabit LOM Ethernet Adapter + - Abocom EFE3K - 10/100 Ethernet Expresscard + - Abocom EGE5K - Giga Ethernet Expresscard - Allied Telesyn AT-2970LX Gigabit Ethernet Adapter - Allied Telesyn AT-2970LX/2SC Gigabit Ethernet Adapter - Allied Telesyn AT-2970SX Gigabit Ethernet Adapter @@ -14500,29 +14540,68 @@ CONFIG_SK98LIN - DGE-530T Gigabit Ethernet Adapter - EG1032 v2 Instant Gigabit Network Adapter - EG1064 v2 Instant Gigabit Network Adapter - - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Abit) - - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Albatron) - - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Asus) - - Marvell 88E8001 Gigabit LOM Ethernet Adapter (ECS) - - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Epox) - - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Foxconn) - - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Gigabyte) - - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Iwill) - - Marvell 88E8050 Gigabit LOM Ethernet Adapter (Intel) + - Marvell 88E8001 Gigabit Ethernet Controller (Abit) + - Marvell 88E8001 Gigabit Ethernet Controller (Albatron) + - Marvell 88E8001 Gigabit Ethernet Controller (Asus) + - Marvell 88E8001 Gigabit Ethernet Controller (Chaintech) + - Marvell 88E8001 Gigabit Ethernet Controller (ECS) + - Marvell 88E8001 Gigabit Ethernet Controller (Epox) + - Marvell 88E8001 Gigabit Ethernet Controller (Foxconn) + - Marvell 88E8001 Gigabit Ethernet Controller (Gigabyte) + - Marvell 88E8001 Gigabit Ethernet Controller (Iwill) + - Marvell 88E8035 Fast Ethernet Controller (LGE) + - Marvell 88E8035 Fast Ethernet Controller (Toshiba) + - Marvell 88E8036 Fast Ethernet Controller (Arima) + - Marvell 88E8036 Fast Ethernet Controller (Compal) + - Marvell 88E8036 Fast Ethernet Controller (Inventec) + - Marvell 88E8036 Fast Ethernet Controller (LGE) + - Marvell 88E8036 Fast Ethernet Controller (Toshiba) + - Marvell 88E8036 Fast Ethernet Controller (Wistron) + - Marvell 88E8050 Gigabit Ethernet Controller (Intel) + - Marvell 88E8052 Gigabit Ethernet Controller (ASRock) + - Marvell 88E8052 Gigabit Ethernet Controller (Aopen) + - Marvell 88E8052 Gigabit Ethernet Controller (Asus) + - Marvell 88E8052 Gigabit Ethernet Controller (Gigabyte) + - Marvell 88E8052 Gigabit Ethernet Controller (MSI) + - Marvell 88E8052 Gigabit Ethernet Controller (Wistron) + - Marvell 88E8053 Gigabit Ethernet Controller (ASRock) + - Marvell 88E8053 Gigabit Ethernet Controller (Albatron) + - Marvell 88E8053 Gigabit Ethernet Controller (Aopen) + - Marvell 88E8053 Gigabit Ethernet Controller (Arima) + - Marvell 88E8053 Gigabit Ethernet Controller (Asus) + - Marvell 88E8053 Gigabit Ethernet Controller (Chaintech) + - Marvell 88E8053 Gigabit Ethernet Controller (Clevo) + - Marvell 88E8053 Gigabit Ethernet Controller (Compal) + - Marvell 88E8053 Gigabit Ethernet Controller (DFI) + - Marvell 88E8053 Gigabit Ethernet Controller (Epox) + - Marvell 88E8053 Gigabit Ethernet Controller (Gigabyte) + - Marvell 88E8053 Gigabit Ethernet Controller (Inventec) + - Marvell 88E8053 Gigabit Ethernet Controller (LGE) + - Marvell 88E8053 Gigabit Ethernet Controller (MSI) + - Marvell 88E8053 Gigabit Ethernet Controller (Quanta) + - Marvell 88E8053 Gigabit Ethernet Controller (SOYO) + - Marvell 88E8053 Gigabit Ethernet Controller (Shuttle) + - Marvell 88E8053 Gigabit Ethernet Controller (Toshiba) + - Marvell 88E8053 Gigabit Ethernet Controller (Trigem) + - Marvell RDK-8001 - Marvell RDK-8001 Adapter - Marvell RDK-8002 Adapter + - Marvell RDK-8003 - Marvell RDK-8003 Adapter - Marvell RDK-8004 Adapter - Marvell RDK-8006 Adapter - Marvell RDK-8007 Adapter - Marvell RDK-8008 Adapter - Marvell RDK-8009 Adapter - - Marvell RDK-8010 Adapter + - Marvell RDK-8010 - Marvell RDK-8011 Adapter - Marvell RDK-8012 Adapter - - Marvell RDK-8052 Adapter - - Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (32 bit) - - Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (64 bit) + - Marvell RDK-8035 + - Marvell RDK-8036 + - Marvell RDK-8052 + - Marvell RDK-8053 + - Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Controller (32 bit) + - Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Controller (64 bit) - N-Way PCI-Bus Giga-Card 1000/100/10Mbps(L) - SK-9521 10/100/1000Base-T Adapter - SK-9521 V2.0 10/100/1000Base-T Adapter @@ -14558,6 +14637,32 @@ CONFIG_SK98LIN say M here and read Documentation/modules.txt. This is recommended. The module will be called sk98lin.o. +SysKonnect SK-98xx Use DualNET +CONFIG_SK98LIN_DUAL + If you have a Dual NIC from SysKonnect, and want to make use of both + channels, i.e. for LACP, say Y here. + + If you said M to the option above, you can change this via a module + parameter. Please refer to + + If unsure, say N. + +SysKonnect SK-98xx Autonegotiation +CONFIG_SK98LIN_AUTONEG_SENSE + If you want to use LACP with an Enterasys Switch, in most cases it'll + only work if you set autonegotiation off. + + SysKonnects default is On, WOLKs default is Sense. + + Select On to use autonegotiation, select Off to disable autonegotiation + or select Sense to automatically detect whether the link partner supports + autonegotiation or not. + + If you said M to the option above, you can change this via a module + parameter. Please refer to + + If unsure, select Sense. + SysKonnect SK-9Dxx support CONFIG_SK9DLIN Say Y here if you have a SysKonnect SK-9Dxx Gigabit Ethernet Adapter. @@ -14593,8 +14698,8 @@ CONFIG_SUNGEM will be called sungem.o. Broadcom NetXtreme BCM5700 Gigabit Ethernet support -CONFIG_NET_BROADCOM - Say Y here if you have a Broadcom BCM570x, or 3Com +CONFIG_NET_BCM5700 + Say Y here if you have a Broadcom BCM57xx, or 3Com 3C996/3C997/3C1000/3C940 PCI/PCIX Gigabit Ethernet adapter. If you want to compile this driver as a module ( = code which can be @@ -14606,6 +14711,9 @@ Broadcom Tigon3 support CONFIG_TIGON3 This driver supports Broadcom Tigon3 based gigabit Ethernet cards. + Say Y here if you have a Broadcom BCM57xx, or 3Com + 3C996/3C997/3C1000/3C940 PCI/PCIX Gigabit Ethernet adapter. + If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . This is @@ -14683,6 +14791,9 @@ CONFIG_E100 A22220-xxx, A23796-xxx +CONFIG_SK98LIN_NAPI + NAPI is a new driver API designed to reduce CPU and interrupt load + when the driver is receiving lots of packets from the card. To verify that your adapter is supported, find the board ID number on the adapter. Look for a label that has a barcode and a number @@ -14763,6 +14874,32 @@ CONFIG_E1000_NAPI If in doubt, say N. +Intel(R) PRO/10GbE support +CONFIG_IXGB + This driver supports Intel(R) PRO/10GbE family of + adapters, which includes: + + Controller Adapter Name Board IDs + ---------- ------------ --------- + 82597EX Intel(R) PRO/10GbE LR Server Adapter A82505-xxx + + For more information on how to identify your adapter, go to the + Adapter & Driver ID Guide at: + + + + For general information and support, go to the Intel support + website at: + + + + More specific information on configuring the driver is in + . + + To compile this driver as a module, choose M here and read + . The module + will be called ixgb.o. + AMD LANCE and PCnet (AT1500 and NE2100) support CONFIG_LANCE If you have a network (Ethernet) card of this type, say Y and read @@ -15122,6 +15259,40 @@ CONFIG_E2100 module, say M here and read as well as . +Broadcom BCM4400 support (b44, alternate driver) +CONFIG_NET_B44 + If you have a network (Ethernet) controller of this type, say Y and + read the Ethernet-HOWTO, available from + . + + If you want to compile this as a module ( = code which can be + inserted in and removed from the running kernel whenever you want), + say M here and read as well as + . The module will be + called b44. + +Broadcom BCM4400 support (bcm4440, original Broadcom driver) +CONFIG_NET_BCM4400 + If you have a network (Ethernet) controller of this type, say Y and + read the Ethernet-HOWTO, available from + . + + If you want to compile this as a module ( = code which can be + inserted in and removed from the running kernel whenever you want), + say M here and read as well as + . The module will be + called bcm4400. + +nForce Ethernet support (EXPERIMENTAL) +CONFIG_NET_FORCEDETH + If you have a network (Ethernet) controller of this type, say Y and + read the Ethernet-HOWTO, available from + . + + To compile this driver as a module, choose M here and read + . + The module will be called forcedeth.o. + CS89x0 support (Daynaport CS and LC cards) CONFIG_CS89x0 Support for CS89x0 chipset based Ethernet cards. If you have a @@ -17699,6 +17870,15 @@ CONFIG_INPUT_EVDEV accessible under char device 13:64+ - /dev/input/eventX in a generic way. This is the future ... +CONFIG_INPUT_UINPUT + Say Y here if you want to support user level drivers for input + subsystem accessible under char device 10:223 - /dev/input/uinput. + + This driver is also available as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module will be called uinput.o. If you want to compile it as a + module, say M here and read . + USB Scanner support CONFIG_USB_SCANNER Say Y here if you want to connect a USB scanner to your computer's @@ -19811,6 +19991,36 @@ CONFIG_PROC_FS_ENHANCED_MEMINFO If unsure, say Y. It's usefull :) +Provide kernel config via /proc +CONFIG_PROC_CONFIG + If you enable this, you can read the configuration of the running + kernel from /proc/config. This is very convenient if you are managing + a large number of machines. + + The kernel enlargement depends on your kernel configuration and the + compression method chosen (see next option). An average configuration + with gzip compression should be around 5-7 KB. + + This code is also available as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module will be called kconfig.o. If you want to compile it as a + module, say M here and read Documentation/modules.txt. + + Note that if you compile this as a module, there is always the + possibility of an outdated module floating around, so you probably + don't want to compile this as a module. + +Compression algorithm for /proc/config.* +CONFIG_PROC_CONFIG_GZ + The compression method used for /proc/config. This reduces the size + of the configuration data noticeably. An appropriate extension is + added to /proc/config, depending on the compression method (e.g. + /proc/config.gz for gzip compression). + + Note that the proc file provides the compressed data, so you have + to use the appropriate userspace utility to decompress them (e.g. + zcat). + Support for PReP Residual Data CONFIG_PREP_RESIDUAL Some PReP systems have residual data passed to the kernel by the @@ -19862,16 +20072,6 @@ CONFIG_DEVFS_DEBUG If unsure, say N. -/proc/config.gz support -CONFIG_PROC_CONFIG - Say Y here if you want a copy of your current kernel configuration - saved in the kernel that you build. This is extremely useful if you - ever build more than one kernel. The cost is around 1K-4K of running - memory. Only say no if you really can't spare this. You can sneeze - and lose more on memory than this. - - If unsure, say Y. - NFS file system support CONFIG_NFS_FS If you are connected to some other (usually local) Unix computer @@ -20072,13 +20272,29 @@ CONFIG_NTFS_DEBUG debugging messages while the misbehaviour was occurring. CONFIG_NTFS_RW - This enables the experimental write support in the NTFS driver. + This enables the partial, but safe, write support in the NTFS driver. - WARNING: Do not use this option unless you are actively developing - NTFS as it is currently guaranteed to be broken and you - may lose all your data! + The only supported operation is overwriting existing files, without + changing the file length. No file or directory creation, deletion or + renaming is possible. Note only non-resident files can be written to + so you may find that some very small files (<500 bytes or so) cannot + be written to. + + While we cannot guarantee that it will not damage any data, we have + so far not received a single report where the driver would have + damaged someones data so we assume it is perfectly safe to use. + + Note: While write support is safe in this version (a rewrite from + scratch of the NTFS support), it should be noted that the old NTFS + write support, is not safe. + + This is currently useful with TopologiLinux. TopologiLinux is run + on top of any DOS/Microsoft Windows system without partitioning your + hard disk. Unlike other Linux distributions TopologiLinux does not + need its own partition. For more information see + - It is strongly recommended and perfectly safe to say N here. + It is perfectly safe to say N here. NetWare 3/4/5 file system support (NWFS) CONFIG_NWFS_FS @@ -20512,7 +20728,7 @@ CONFIG_LUFS_FS the lufsd daemon and file system modules available from http://lufs.sourceforge.net. - Say Y here if you want to get access to a bunch of usefull file systems + Say Y here if you want to get access to a bunch of useful file systems (sshfs, ftpfs, gnutellafs, gvfs, cardfs, cefs, etc). Advanced partition selection @@ -22567,14 +22783,6 @@ CONFIG_ATIXL_BUSMOUSE If you are unsure, say N and read the HOWTO nevertheless: it will tell you what you have. -QIC-02 tape support -CONFIG_QIC02_TAPE - If you have a non-SCSI tape drive like that, say Y. Or, if you want - to compile this driver as a module ( = code which can be inserted in - and removed from the running kernel whenever you want), say M here - and read . The module will be called - tpqic02.o. - iSeries Virtual Tape Support CONFIG_VIOTAPE If you are running Linux on an iSeries system and you want Linux @@ -26435,22 +26643,21 @@ CONFIG_BLUEZ Linux Bluetooth subsystem consist of several layers: BlueZ Core (HCI device and connection manager, scheduler) - HCI Device drivers (interface to the hardware) - L2CAP Module (L2CAP protocol) - SCO Module (SCO links) - RFCOMM Module (RFCOMM protocol) - BNEP Module (BNEP protocol) - CMTP Module (CMTP protocol) + HCI Device drivers (Interface to the hardware) + SCO Module (SCO audio links) + L2CAP Module (Logical Link Control and Adaptation Protocol) + RFCOMM Module (RFCOMM Protocol) + BNEP Module (Bluetooth Network Encapsulation Protocol) + CMTP Module (CAPI Message Transport Protocol) + HIDP Module (Human Interface Device Protocol) - Say Y here to enable Linux Bluetooth support and to build BlueZ Core - layer. + Say Y here to compile Bluetooth support into the kernel or say M to + compile it as module (bluez.o). To use Linux Bluetooth subsystem, you will need several user-space utilities like hciconfig and hcid. These utilities and updates to Bluetooth kernel modules are provided in the BlueZ package. - For more information, see . - - If you want to compile BlueZ Core as module (bluez.o) say M here. + For more information, see . L2CAP protocol support CONFIG_BLUEZ_L2CAP @@ -26463,7 +26670,7 @@ CONFIG_BLUEZ_L2CAP SCO links support CONFIG_BLUEZ_SCO - SCO link provides voice transport over Bluetooth. SCO support is + SCO link provides voice transport over Bluetooth. SCO support is required for voice applications like Headset and Audio. Say Y here to compile SCO support into the kernel or say M to @@ -26471,7 +26678,7 @@ CONFIG_BLUEZ_SCO RFCOMM protocol support CONFIG_BLUEZ_RFCOMM - RFCOMM provides connection oriented stream transport. RFCOMM + RFCOMM provides connection oriented stream transport. RFCOMM support is required for Dialup Networking, OBEX and other Bluetooth applications. @@ -26485,32 +26692,37 @@ CONFIG_BLUEZ_RFCOMM_TTY BNEP protocol support CONFIG_BLUEZ_BNEP BNEP (Bluetooth Network Encapsulation Protocol) is Ethernet - emulation layer on top of Bluetooth. BNEP is required for Bluetooth - PAN (Personal Area Network). - - To use BNEP, you will need user-space utilities provided in the - BlueZ-PAN package. - For more information, see . + emulation layer on top of Bluetooth. BNEP is required for + Bluetooth PAN (Personal Area Network). Say Y here to compile BNEP support into the kernel or say M to compile it as module (bnep.o). +BNEP multicast filter support +CONFIG_BLUEZ_BNEP_MC_FILTER + This option enables the multicast filter support for BNEP. + +BNEP protocol filter support +CONFIG_BLUEZ_BNEP_PROTO_FILTER + This option enables the protocol filter support for BNEP. + CMTP protocol support CONFIG_BLUEZ_CMTP CMTP (CAPI Message Transport Protocol) is a transport layer - for CAPI messages. CMTP is required for the Bluetooth Common + for CAPI messages. CMTP is required for the Bluetooth Common ISDN Access Profile. Say Y here to compile CMTP support into the kernel or say M to compile it as module (cmtp.o). -BNEP multicast filter support -CONFIG_BLUEZ_BNEP_MC_FILTER - This option enables the multicast filter support for BNEP. +HIDP protocol support +CONFIG_BLUEZ_HIDP + HIDP (Human Interface Device Protocol) is a transport layer + for HID reports. HIDP is required for the Bluetooth Human + Interface Device Profile. -BNEP protocol filter support -CONFIG_BLUEZ_BNEP_PROTO_FILTER - This option enables the protocol filter support for BNEP. + Say Y here to compile HIDP support into the kernel or say M to + compile it as module (hidp.o). HCI UART driver CONFIG_BLUEZ_HCIUART @@ -26556,7 +26768,7 @@ CONFIG_BLUEZ_HCIUSB kernel or say M to compile it as module (hci_usb.o). HCI USB SCO (voice) support -CONFIG_BLUEZ_USB_SCO +CONFIG_BLUEZ_HCIUSB_SCO This option enables the SCO support in the HCI USB driver. You need this to transmit voice data with your Bluetooth USB device. And your device must also support sending SCO data over the HCI layer, because some of @@ -26564,14 +26776,6 @@ CONFIG_BLUEZ_USB_SCO Say Y here to compile support for HCI SCO data. -HCI USB zero packet support -CONFIG_BLUEZ_USB_ZERO_PACKET - This option is provided only as a work around for buggy Bluetooth USB - devices. Do NOT enable it unless you know for sure that your device - requires zero packets. - - Most people should say N here. - HCI VHCI Virtual HCI device driver CONFIG_BLUEZ_HCIVHCI Bluetooth Virtual HCI device driver. @@ -26609,9 +26813,6 @@ CONFIG_BLUEZ_HCIBT3C 3Com Bluetooth Card (3CRWB6096) HP Bluetooth Card - The HCI BT3C driver uses external firmware loader program provided in - the BlueFW package. For more information, see . - Say Y here to compile support for HCI BT3C devices into the kernel or say M to compile it as module (bt3c_cs.o). @@ -27144,6 +27345,17 @@ CONFIG_GRKERNSEC_HIDESYM useful protection against local and remote kernel exploitation of overflows and arbitrary read/write vulnerabilities. +Deter exploit bruteforcing +CONFIG_GRKERNSEC_BRUTE + If you say Y here, attempts to bruteforce exploits against forking + daemons such as apache or sshd will be deterred. When a child of a + forking daemon is killed by PaX or crashes due to an illegal + instruction, the parent process will be delayed 30 seconds upon every + subsequent fork until the administrator is able to assess the + situation and restart the daemon. It is recommended that you also + enable signal logging in the auditing section so that logs are + generated when a process performs an illegal instruction. + /proc//ipaddr support CONFIG_GRKERNSEC_PROC_IPADDR If you say Y here, a new entry will be added to each /proc/ @@ -27371,9 +27583,9 @@ CONFIG_GRKERNSEC_CHROOT_PIVOT Deny double-chroots CONFIG_GRKERNSEC_CHROOT_DOUBLE If you say Y here, processes inside a chroot will not be able to chroot - again. This is a widely used method of breaking out of a chroot jail - and should not be allowed. If the sysctl option is enabled, a sysctl - option with name "chroot_deny_chroot" is created. + again outside of the chroot. This is a widely used method of breaking + out of a chroot jail and should not be allowed. If the sysctl option + is enabled, a sysctl option with name "chroot_deny_chroot" is created. Deny fchdir outside of chroot CONFIG_GRKERNSEC_CHROOT_FCHDIR @@ -32947,6 +33159,18 @@ CONFIG_CRYPTO_SHA512 This code also includes SHA-384, a 384 bit hash with 192 bits of security against collision attacks. +CONFIG_CRYPTO_WHIRLPOOL + Whirlpool hash algorithm. + + Whirlpool is part of the NESSIE cryptographic primtives. + Whirlpool works on messages shorter than 2^256 bits and + produces a 512 bit hash. + + Whirlpool will be part of the ISO/IEC 10118-3:2003(E) standard + + See also: + http://planeta.terra.com.br/informatica/paulobarreto/WhirlpoolPage.html + CONFIG_CRYPTO_DES DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3). @@ -33008,6 +33232,17 @@ CONFIG_CRYPTO_CAST6 The CAST6 encryption algorithm (synonymous with CAST-256) is described in RFC2612. +CONFIG_CRYPTO_TEA + TEA cipher algorithm. + + Tiny Encryption Algorithm is a simple cipher that uses + many rounds for security. It is very fast and uses + little memory. + + Xtendend Tiny Encryption Algorithm is a modification to + the TEA algorithm to address a potential key weakness + in the TEA algorithm. + CONFIG_CRYPTO_ARC4 ARC4 cipher algorithm. @@ -33016,6 +33251,16 @@ CONFIG_CRYPTO_ARC4 WEP, but it should not be for other purposes because of the weakness of the algorithm. +CONFIG_CRYPTO_KHAZAD + Khazad cipher algorithm. + + Khazad was a finalist in the initial NESSIE competition. It is + an algorithm optimized for 64-bit processors with good performance + on 32-bit processors. Khazad uses an 128 bit key size. + + See also: + http://planeta.terra.com.br/informatica/paulobarreto/KhazadPage.html + CONFIG_CRYPTO_DEFLATE This is the Deflate algorithm (RFC1951), specified for use in IPSec with the IPCOMP protocol (RFC3173, RFC2394). diff -Naurp linux-2.4.20-wolk4.15-fullkernel/Documentation/crypto/api-intro.txt linux-2.4.20-wolk4.16-fullkernel/Documentation/crypto/api-intro.txt --- linux-2.4.20-wolk4.15-fullkernel/Documentation/crypto/api-intro.txt 2004-06-29 11:24:05.000000000 +0200 +++ linux-2.4.20-wolk4.16-fullkernel/Documentation/crypto/api-intro.txt 2004-09-05 15:47:28.000000000 +0200 @@ -219,6 +219,15 @@ AES algorithm contributors: CAST5/CAST6 algorithm contributors: Kartikey Mahendra Bhatt (original developers unknown, FSF copyright). +TEA/XTEA algorithm contributors: + Aaron Grothe + +Khazad algorithm contributors: + Aaron Grothe + +Whirlpool algorithm contributors: + Aaron Grothe + Generic scatterwalk code by Adam J. Richter Please send any credits updates or corrections to: diff -Naurp linux-2.4.20-wolk4.15-fullkernel/Documentation/devices.txt linux-2.4.20-wolk4.16-fullkernel/Documentation/devices.txt --- linux-2.4.20-wolk4.15-fullkernel/Documentation/devices.txt 2004-06-29 11:31:45.000000000 +0200 +++ linux-2.4.20-wolk4.16-fullkernel/Documentation/devices.txt 2004-09-05 16:08:22.000000000 +0200 @@ -426,6 +426,7 @@ Your cooperation is appreciated. 220 = /dev/mptctl Message passing technology (MPT) control 221 = /dev/mvista/hssdsi Montavista PICMG hot swap system driver 222 = /dev/mvista/hasi Montavista PICMG high availability + 223 = /dev/input/uinput User level driver support for input 223 = /dev/systrace Systrace device 224 = /dev/tpm TCPA TPM driver 225 = /dev/pps Pulse Per Second driver diff -Naurp linux-2.4.20-wolk4.15-fullkernel/Documentation/filesystems/ntfs.txt linux-2.4.20-wolk4.16-fullkernel/Documentation/filesystems/ntfs.txt --- linux-2.4.20-wolk4.15-fullkernel/Documentation/filesystems/ntfs.txt 2004-06-29 11:24:11.000000000 +0200 +++ linux-2.4.20-wolk4.16-fullkernel/Documentation/filesystems/ntfs.txt 2004-09-05 15:47:37.000000000 +0200 @@ -247,6 +247,19 @@ ChangeLog Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog. +2.1.6b: + - Update kernel help documentation on NTFS write support. + +2.1.6a: + - Fix minor bug in handling of compressed directories that fixes the + erroneous "du" and "stat" output people reported. +2.1.5a: + - Minor bug fix in attribute list attribute handling that fixes the + I/O errors on "ls" of certain fragmented files found by at least two + people running Windows XP. +2.1.4a: + - Minor update allowing compilation with all gcc versions (well, the + ones the kernel can be compiled with anyway). 2.1.3a: - Major bug fixes for reading files and volumes in corner cases which were being hit by Windows 2k/XP users. diff -Naurp linux-2.4.20-wolk4.15-fullkernel/Documentation/mkdev_dyn.cciss linux-2.4.20-wolk4.16-fullkernel/Documentation/mkdev_dyn.cciss --- linux-2.4.20-wolk4.15-fullkernel/Documentation/mkdev_dyn.cciss 2004-06-29 11:24:47.000000000 +0200 +++ linux-2.4.20-wolk4.16-fullkernel/Documentation/mkdev_dyn.cciss 1970-01-01 01:00:00.000000000 +0100 @@ -1,171 +0,0 @@ -#!/bin/sh -# -# Author: Francis Wiran -# -# Script to create device nodes for SMART Array controllers, idea from -# mkdev.cciss found in Documentation. The argument syntax is different, -# hence, the name change. -# -# Usage: -# mkdev_dyn.cciss [ctlr num] [major num] [num log vol] [num partitions] -# -# With no arguments, the script will check to see if there are any cciss -# nodes already created in the /dev directory. If so, then it will assume -# that the nodes for the first 8 controllers are already created by -# /etc/makedev.d, which is likely. If not, then the script will create -# them, using the major numbers reserved for cciss controllers (104 thru 111). -# -# After that, it will start creating nodes for the controllers which major -# numbers are dynamically allocated by the kernel. It will check -# /proc/devices for any cciss controllers with major numbers other than -# 104 thru 111 and creates the nodes. -# -# Note that it is a good idea to run rmdev_dyn.cciss script if you remove -# those controllers (the ones which major numbers were dynamically allocated) -# This will unclutter /dev, as well as preventing possible problems due to -# referenced devices and major numbers no longer available or taken by -# other non-cciss drivers. -# -# With no arguments, the script assumes 16 logical volumes per controller -# and 16 partitions per volume; -# -# Passing arguments: -# If you know that one of your controllers, say cciss8, has been dynamically -# assigned major number 254, and were planning on no more than 2 logical -# volumes, using a maximum of 4 partitions per volume, you could do: -# -# mkdev_dyn.cciss 8 254 2 4 -# -# Of course, this has no real benefit over "mkdev_dyn.cciss 8 254" except -# that it doesn't create as many device nodes in /dev/cciss. -# - -# Inputs -NR_CTLR=${1-8} -NR_MAJOR=${2-254} -NR_VOL=${3-16} -NR_PART=${4-16} - -echo_usage() -{ - echo "Usage: mkdev_dyn.cciss [ctlr num] [maj] [volumes] [partitions]" - echo "The script assumes that ctlr 0 thru 7 is statically created" - echo "Therefore, if you want to pass arguments make sure that" - echo "ctlr num is equal or greater than 8, and the major number" - echo "is not one that's statically assigned for cciss controller." - echo "Check the correct major number in /proc/devices" - - # Hmm... we don't support volumes and partitions greater than 16 - # either. -} - -echo_create() -{ - echo "created /dev/cciss/c${1}* nodes using major number ${2}" -} - - -# Function: do_mknod() -# Creates devices nodes under /dev/cciss -# Inputs: $1 - ctlr number -# $2 - major number -# $3 - number of devices on controller -# $4 - number of partitions per device -do_mknod() -{ - D=0; - while [ $D -lt $3 ]; do - P=0; - while [ $P -lt $4 ]; do - MIN=`expr $D \* 16 + $P`; - if [ $P -eq 0 ]; then - mknod /dev/cciss/c${1}d${D} b $2 $MIN - else - mknod /dev/cciss/c${1}d${D}p${P} b $2 $MIN - fi - P=`expr $P + 1`; - done - D=`expr $D + 1`; - done -} - -# Function: do_dyn -# Search and create cciss nodes for the controllers which -# major numbers are allocated dynamically by the kernel -# instead of using kernel.org 's value of 104 to 111. -# -# Input: $1 - ctlr num - will create nodes /dev/cciss/c${1} -# $2 - major num - the major number to assign to the nodes -# $3 - volumes - max number of volumes per controller -# $4 - partitions - max number of partitions per volume -# -# Note: Without input, this function will start creating nodes -# for controller c8 and above, making assumption that -# c0 thru c7 are already made, and the name c8 and above -# are not already taken. -do_dyn() -{ - if [ $# -eq 0 ]; then - C=0; - for MAJ in `cat /proc/devices |\ - grep cciss |\ - awk '/cciss[0-9]$/ { sub("cciss", "cciss0") }; {print}' |\ - sort -k 2,2 |\ - awk '{print $1-i}'`; - do - if [ `ls -l /dev/cciss/c* |\ - awk '{print $5-i}' |\ - uniq |\ - grep $MAJ |\ - wc -l` -gt 0 ]; then - : - else - do_mknod $C $MAJ $NR_VOL $NR_PART; - echo_create $C $MAJ; - fi - C=`expr $C + 1`; - done - else - do_mknod $1 $2 $3 $4; - echo_create $1 $2; - fi - - exit -} - -# Start here - -# Check the input values -if [ $NR_CTLR -lt 8 ]; then - echo_usage; - exit -fi - -if [ $NR_CTLR -ge 8 ]; then - if [ \( $NR_MAJOR -ge 104 \) -a \( $NR_MAJOR -le 111 \) ]; then - echo_usage; - exit - fi -fi - -if [ ! -d /dev/cciss ]; then - mkdir -p /dev/cciss -fi - -# Assume that if c0d0p1 node already exist, then all nodes from c0d0p1 -# to c7d15p15 have been created for us. -if [ ! -b /dev/cciss/c0d0p1 ]; then - C=0; - while [ $C -lt 8 ]; do - MAJ=`expr $C + 104`; - do_mknod $C $MAJ $NR_VOL $NR_PART; - echo_create $C $MAJ; - C=`expr $C + 1`; - done -fi - -if [ $# -gt 0 ]; then - do_dyn $NR_CTLR $NR_MAJOR $NR_VOL $NR_PART; -else - do_dyn; -fi diff -Naurp linux-2.4.20-wolk4.15-fullkernel/Documentation/networking/bonding.txt linux-2.4.20-wolk4.16-fullkernel/Documentation/networking/bonding.txt --- linux-2.4.20-wolk4.15-fullkernel/Documentation/networking/bonding.txt 2004-06-29 11:25:07.000000000 +0200 +++ linux-2.4.20-wolk4.16-fullkernel/Documentation/networking/bonding.txt 2004-09-05 15:54:58.000000000 +0200 @@ -31,6 +31,7 @@ Verifying Bond Configuration Frequently Asked Questions High Availability Promiscuous Sniffing notes +8021q VLAN support Limitations Resources and Links @@ -140,10 +141,6 @@ probeall bond0 eth0 eth1 bonding Be careful not to reference bond0 itself at the end of the line, or modprobe will die in an endless recursive loop. -To have device characteristics (such as MTU size) propagate to slave devices, -set the bond characteristics before enslaving the device. The characteristics -are propagated during the enslave process. - If running SNMP agents, the bonding driver should be loaded before any network drivers participating in a bond. This requirement is due to the the interface index (ipAdEntIfIndex) being associated to the first interface found with a @@ -612,7 +609,7 @@ Frequently Asked Questions For ethernet cards not supporting MII status, the arp_interval and arp_ip_target parameters must be specified for bonding to work correctly. If packets have not been sent or received during the - specified arp_interval durration, an ARP request is sent to the + specified arp_interval duration, an ARP request is sent to the targets to generate send and receive traffic. If after this interval, either the successful send and/or receive count has not incremented, the next slave in the sequence will become the active @@ -680,16 +677,8 @@ Frequently Asked Questions that will be added. To restore your slaves' MAC addresses, you need to detach them - from the bond (`ifenslave -d bond0 eth0'), set them down - (`ifconfig eth0 down'), unload the drivers (`rmmod 3c59x', for - example) and reload them to get the MAC addresses from their - eeproms. If the driver is shared by several devices, you need - to turn them all down. Another solution is to look for the MAC - address at boot time (dmesg or tail /var/log/messages) and to - reset it by hand with ifconfig : - - # ifconfig eth0 down - # ifconfig eth0 hw ether 00:20:40:60:80:A0 + from the bond (`ifenslave -d bond0 eth0'). The bonding driver will then + restore the MAC addresses that the slaves had before they were enslaved. 9. Which transmit polices can be used? @@ -854,7 +843,7 @@ point of failure" solution. In this configuration, there is an ISL - Inter Switch Link (could be a trunk), several servers (host1, host2 ...) attached to both switches each, and one or -more ports to the outside world (port3...). One an only one slave on each host +more ports to the outside world (port3...). One and only one slave on each host is active at a time, while all links are still monitored (the system can detect a failure of active and backup links). @@ -944,6 +933,41 @@ capacity aggregating; but it works fine just ignore all the warnings it emits. +8021q VLAN support +================== + +It is possible to configure VLAN devices over a bond interface using the 8021q +driver. However, only packets coming from the 8021q driver and passing through +bonding will be tagged by default. Self generated packets, like bonding's +learning packets or ARP packets generated by either ALB mode or the ARP +monitor mechanism, are tagged internally by bonding itself. As a result, +bonding has to "learn" what VLAN IDs are configured on top of it, and it uses +those IDs to tag self generated packets. + +For simplicity reasons, and to support the use of adapters that can do VLAN +hardware acceleration offloding, the bonding interface declares itself as +fully hardware offloaing capable, it gets the add_vid/kill_vid notifications +to gather the necessary information, and it propagates those actions to the +slaves. +In case of mixed adapter types, hardware accelerated tagged packets that should +go through an adapter that is not offloading capable are "un-accelerated" by the +bonding driver so the VLAN tag sits in the regular location. + +VLAN interfaces *must* be added on top of a bonding interface only after +enslaving at least one slave. This is because until the first slave is added the +bonding interface has a HW address of 00:00:00:00:00:00, which will be copied by +the VLAN interface when it is created. + +Notice that a problem would occur if all slaves are released from a bond that +still has VLAN interfaces on top of it. When later coming to add new slaves, the +bonding interface would get a HW address from the first slave, which might not +match that of the VLAN interfaces. It is recommended that either all VLANs are +removed and then re-added, or to manually set the bonding interface's HW +address so it matches the VLAN's. (Note: changing a VLAN interface's HW address +would set the underlying device -- i.e. the bonding interface -- to promiscouos +mode, which might not be what you want). + + Limitations =========== The main limitations are : diff -Naurp linux-2.4.20-wolk4.15-fullkernel/Documentation/networking/ifenslave.c linux-2.4.20-wolk4.16-fullkernel/Documentation/networking/ifenslave.c --- linux-2.4.20-wolk4.15-fullkernel/Documentation/networking/ifenslave.c 2004-06-29 11:25:05.000000000 +0200 +++ linux-2.4.20-wolk4.16-fullkernel/Documentation/networking/ifenslave.c 2004-09-05 15:54:58.000000000 +0200 @@ -89,21 +89,17 @@ * while it is running. It was already set during enslave. To * simplify things, it is now handeled separately. * - * - 2003/09/24 - Shmulik Hen + * - 2003/12/01 - Shmulik Hen * - Code cleanup and style changes * set version to 1.1.0 */ #define APP_VERSION "1.1.0" -#define APP_RELDATE "Septemer 24, 2003" +#define APP_RELDATE "December 1, 2003" #define APP_NAME "ifenslave" static char *version = -APP_NAME ".c:v" APP_VERSION " (" APP_RELDATE ")\n" -"o Donald Becker (becker@cesdis.gsfc.nasa.gov).\n" -"o Detach support added on 2000/10/02 by Willy Tarreau (willy at meta-x.org).\n" -"o 2.4 kernel support added on 2001/02/16 by Chad N. Tindel\n" -" (ctindel at ieee dot org).\n"; +APP_NAME ".c:v" APP_VERSION " (" APP_RELDATE ")\n"; static const char *usage_msg = "Usage: ifenslave [-f] [...]\n" @@ -159,7 +155,7 @@ static const char *help_msg = #include #include #include -#include +#include #include #include #include diff -Naurp linux-2.4.20-wolk4.15-fullkernel/Documentation/networking/ixgb.txt linux-2.4.20-wolk4.16-fullkernel/Documentation/networking/ixgb.txt --- linux-2.4.20-wolk4.15-fullkernel/Documentation/networking/ixgb.txt 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.20-wolk4.16-fullkernel/Documentation/networking/ixgb.txt 2004-09-09 13:21:58.000000000 +0200 @@ -0,0 +1,431 @@ +Linux* Base Driver for the Intel(R) PRO/10GbE Family of Adapters +================================================================ + +March 05, 2004 + + +Contents +======== + +- In This Release +- Supported Adapters +- Building and Installation +- Command Line Parameters +- Improving Performance +- Additional Configurations +- Known Issues +- Support + + +In This Release +=============== + +This file describes the Linux* Base Driver for the Intel(R) PRO/10GbE Family +of Adapters, version 1.0.x. This driver is intended for 2.4.x kernels; it is +known to build properly on 2.4.x kernels through 2.4.20. Intel focused +testing on Intel architectures running the 2.4.20 kernel. This driver +includes support for Itanium(R)-based systems. + +This driver is only supported as a loadable module at this time. Intel is not +supplying patches against the kernel source to allow for static linking of +the driver. For questions related to hardware requirements, refer to the +documentation supplied with your Intel PRO/10GbE adapter. All hardware +requirements listed apply to use with Linux. + +Native VLANs are now available with supported kernels. + +The driver information previously displayed in the /proc filesystem is not +supported in this release. Alternatively, you can use ethtool (version 1.6 +or later), lspci, and ifconfig to obtain the same information. Instructions +on updating ethtool can be found in the section "Additional Configurations" +later in this document. + + +Supported Adapters +================== + +The following Intel network adapters are compatible with the drivers in this +release: + + Controller Adapter Name Physical Layer + ---------- ------------ -------------- + + 82597EX Intel(R) PRO/10GbE LR/SR 10G Base -LR and -SR + Server Adapters (850 and 1310 nm optical fiber) + +For more information on how to identify your adapter, go to the Adapter & +Driver ID Guide at: + + http://support.intel.com/support/network/adapter/pro100/21397.htm + +For the latest Intel network drivers for Linux, refer to the following +website. In the search field, enter your adapter name or type, or use the +networking link on the left to search for your adapter: + + http://downloadfinder.intel.com/scripts-df/support_intel.asp + + +Building and Installation +========================= + +To build a binary RPM* package of this driver, run 'rpmbuild -tb +'. Replace with the specific filename of +the driver. + +NOTE: For the build to work properly, the currently running kernel MUST match + the version and configuration of the installed kernel sources. If you + have just recompiled the kernel reboot the system now. + + RPM functionality has only been tested in Red Hat distributions. + +To manually build this driver: + +1. Move the base driver tar file to the directory of your choice. For example, + use /home/username/ixgb or /usr/local/src/ixgb. + +2. Untar/unzip archive: + + tar zxf ixgb-x.x.x.tar.gz + +3. Change to the driver src directory: + + cd ixgb-x.x.x/src/ + +4. Compile the driver module: + + make install + + The binary will be installed as: + + /lib/modules/[KERNEL_VERSION]/kernel/drivers/net/ixgb.o + + The install locations listed above are the default locations. They might + not be correct for certain Linux distributions. For more information, + see the ldistrib.txt file included in the driver tar. + +5. Install the module: + + insmod ixgb = + +6. Assign an IP address to the interface by entering the following, where + x is the interface number: + + ifconfig ethx + +7. Verify that the interface works. Enter the following, where + is the IP address for another machine on the same subnet as the interface + that is being tested: + + ping + + +Command Line Parameters +======================= + +If the driver is built as a module, the following optional parameters are +used by entering them on the command line with the modprobe or insmod command +using this syntax: + + modprobe ixgb [