aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/tg3.c32
-rw-r--r--include/linux/net.h6
-rw-r--r--include/linux/x25.h26
-rw-r--r--include/net/compat.h4
-rw-r--r--include/net/x25.h21
-rw-r--r--net/bluetooth/bnep/core.c4
-rw-r--r--net/compat.c19
-rw-r--r--net/socket.c21
-rw-r--r--net/x25/af_x25.c173
-rw-r--r--net/x25/x25_facilities.c82
-rw-r--r--net/x25/x25_in.c3
-rw-r--r--net/x25/x25_subr.c6
12 files changed, 366 insertions, 31 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index e03d1ae50c3e..88829eb9568e 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -69,8 +69,8 @@
69 69
70#define DRV_MODULE_NAME "tg3" 70#define DRV_MODULE_NAME "tg3"
71#define PFX DRV_MODULE_NAME ": " 71#define PFX DRV_MODULE_NAME ": "
72#define DRV_MODULE_VERSION "3.52" 72#define DRV_MODULE_VERSION "3.53"
73#define DRV_MODULE_RELDATE "Mar 06, 2006" 73#define DRV_MODULE_RELDATE "Mar 22, 2006"
74 74
75#define TG3_DEF_MAC_MODE 0 75#define TG3_DEF_MAC_MODE 0
76#define TG3_DEF_RX_MODE 0 76#define TG3_DEF_RX_MODE 0
@@ -1148,6 +1148,19 @@ static int tg3_halt_cpu(struct tg3 *, u32);
1148static int tg3_nvram_lock(struct tg3 *); 1148static int tg3_nvram_lock(struct tg3 *);
1149static void tg3_nvram_unlock(struct tg3 *); 1149static void tg3_nvram_unlock(struct tg3 *);
1150 1150
1151static void tg3_power_down_phy(struct tg3 *tp)
1152{
1153 /* The PHY should not be powered down on some chips because
1154 * of bugs.
1155 */
1156 if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
1157 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 ||
1158 (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780 &&
1159 (tp->tg3_flags2 & TG3_FLG2_MII_SERDES)))
1160 return;
1161 tg3_writephy(tp, MII_BMCR, BMCR_PDOWN);
1162}
1163
1151static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) 1164static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
1152{ 1165{
1153 u32 misc_host_ctrl; 1166 u32 misc_host_ctrl;
@@ -1327,8 +1340,7 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
1327 tg3_writephy(tp, MII_TG3_EXT_CTRL, 1340 tg3_writephy(tp, MII_TG3_EXT_CTRL,
1328 MII_TG3_EXT_CTRL_FORCE_LED_OFF); 1341 MII_TG3_EXT_CTRL_FORCE_LED_OFF);
1329 tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x01b2); 1342 tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x01b2);
1330 if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700) 1343 tg3_power_down_phy(tp);
1331 tg3_writephy(tp, MII_BMCR, BMCR_PDOWN);
1332 } 1344 }
1333 } 1345 }
1334 1346
@@ -9436,12 +9448,18 @@ static inline struct subsys_tbl_ent *lookup_by_subsys(struct tg3 *tp)
9436 return NULL; 9448 return NULL;
9437} 9449}
9438 9450
9439/* Since this function may be called in D3-hot power state during
9440 * tg3_init_one(), only config cycles are allowed.
9441 */
9442static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) 9451static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp)
9443{ 9452{
9444 u32 val; 9453 u32 val;
9454 u16 pmcsr;
9455
9456 /* On some early chips the SRAM cannot be accessed in D3hot state,
9457 * so need make sure we're in D0.
9458 */
9459 pci_read_config_word(tp->pdev, tp->pm_cap + PCI_PM_CTRL, &pmcsr);
9460 pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
9461 pci_write_config_word(tp->pdev, tp->pm_cap + PCI_PM_CTRL, pmcsr);
9462 msleep(1);
9445 9463
9446 /* Make sure register accesses (indirect or otherwise) 9464 /* Make sure register accesses (indirect or otherwise)
9447 * will function correctly. 9465 * will function correctly.
diff --git a/include/linux/net.h b/include/linux/net.h
index 152fa6551fd8..84a490e5f0a1 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -143,6 +143,8 @@ struct proto_ops {
143 struct poll_table_struct *wait); 143 struct poll_table_struct *wait);
144 int (*ioctl) (struct socket *sock, unsigned int cmd, 144 int (*ioctl) (struct socket *sock, unsigned int cmd,
145 unsigned long arg); 145 unsigned long arg);
146 int (*compat_ioctl) (struct socket *sock, unsigned int cmd,
147 unsigned long arg);
146 int (*listen) (struct socket *sock, int len); 148 int (*listen) (struct socket *sock, int len);
147 int (*shutdown) (struct socket *sock, int flags); 149 int (*shutdown) (struct socket *sock, int flags);
148 int (*setsockopt)(struct socket *sock, int level, 150 int (*setsockopt)(struct socket *sock, int level,
@@ -251,6 +253,8 @@ SOCKCALL_UWRAP(name, poll, (struct file *file, struct socket *sock, struct poll_
251 (file, sock, wait)) \ 253 (file, sock, wait)) \
252SOCKCALL_WRAP(name, ioctl, (struct socket *sock, unsigned int cmd, \ 254SOCKCALL_WRAP(name, ioctl, (struct socket *sock, unsigned int cmd, \
253 unsigned long arg), (sock, cmd, arg)) \ 255 unsigned long arg), (sock, cmd, arg)) \
256SOCKCALL_WRAP(name, compat_ioctl, (struct socket *sock, unsigned int cmd, \
257 unsigned long arg), (sock, cmd, arg)) \
254SOCKCALL_WRAP(name, listen, (struct socket *sock, int len), (sock, len)) \ 258SOCKCALL_WRAP(name, listen, (struct socket *sock, int len), (sock, len)) \
255SOCKCALL_WRAP(name, shutdown, (struct socket *sock, int flags), (sock, flags)) \ 259SOCKCALL_WRAP(name, shutdown, (struct socket *sock, int flags), (sock, flags)) \
256SOCKCALL_WRAP(name, setsockopt, (struct socket *sock, int level, int optname, \ 260SOCKCALL_WRAP(name, setsockopt, (struct socket *sock, int level, int optname, \
@@ -275,6 +279,7 @@ static const struct proto_ops name##_ops = { \
275 .getname = __lock_##name##_getname, \ 279 .getname = __lock_##name##_getname, \
276 .poll = __lock_##name##_poll, \ 280 .poll = __lock_##name##_poll, \
277 .ioctl = __lock_##name##_ioctl, \ 281 .ioctl = __lock_##name##_ioctl, \
282 .compat_ioctl = __lock_##name##_compat_ioctl, \
278 .listen = __lock_##name##_listen, \ 283 .listen = __lock_##name##_listen, \
279 .shutdown = __lock_##name##_shutdown, \ 284 .shutdown = __lock_##name##_shutdown, \
280 .setsockopt = __lock_##name##_setsockopt, \ 285 .setsockopt = __lock_##name##_setsockopt, \
@@ -283,6 +288,7 @@ static const struct proto_ops name##_ops = { \
283 .recvmsg = __lock_##name##_recvmsg, \ 288 .recvmsg = __lock_##name##_recvmsg, \
284 .mmap = __lock_##name##_mmap, \ 289 .mmap = __lock_##name##_mmap, \
285}; 290};
291
286#endif 292#endif
287 293
288#define MODULE_ALIAS_NETPROTO(proto) \ 294#define MODULE_ALIAS_NETPROTO(proto) \
diff --git a/include/linux/x25.h b/include/linux/x25.h
index 16d44931afa0..d035e4e87d07 100644
--- a/include/linux/x25.h
+++ b/include/linux/x25.h
@@ -11,6 +11,8 @@
11#ifndef X25_KERNEL_H 11#ifndef X25_KERNEL_H
12#define X25_KERNEL_H 12#define X25_KERNEL_H
13 13
14#include <linux/types.h>
15
14#define SIOCX25GSUBSCRIP (SIOCPROTOPRIVATE + 0) 16#define SIOCX25GSUBSCRIP (SIOCPROTOPRIVATE + 0)
15#define SIOCX25SSUBSCRIP (SIOCPROTOPRIVATE + 1) 17#define SIOCX25SSUBSCRIP (SIOCPROTOPRIVATE + 1)
16#define SIOCX25GFACILITIES (SIOCPROTOPRIVATE + 2) 18#define SIOCX25GFACILITIES (SIOCPROTOPRIVATE + 2)
@@ -21,6 +23,8 @@
21#define SIOCX25SCUDMATCHLEN (SIOCPROTOPRIVATE + 7) 23#define SIOCX25SCUDMATCHLEN (SIOCPROTOPRIVATE + 7)
22#define SIOCX25CALLACCPTAPPRV (SIOCPROTOPRIVATE + 8) 24#define SIOCX25CALLACCPTAPPRV (SIOCPROTOPRIVATE + 8)
23#define SIOCX25SENDCALLACCPT (SIOCPROTOPRIVATE + 9) 25#define SIOCX25SENDCALLACCPT (SIOCPROTOPRIVATE + 9)
26#define SIOCX25GDTEFACILITIES (SIOCPROTOPRIVATE + 10)
27#define SIOCX25SDTEFACILITIES (SIOCPROTOPRIVATE + 11)
24 28
25/* 29/*
26 * Values for {get,set}sockopt. 30 * Values for {get,set}sockopt.
@@ -77,6 +81,8 @@ struct x25_subscrip_struct {
77#define X25_MASK_PACKET_SIZE 0x04 81#define X25_MASK_PACKET_SIZE 0x04
78#define X25_MASK_WINDOW_SIZE 0x08 82#define X25_MASK_WINDOW_SIZE 0x08
79 83
84#define X25_MASK_CALLING_AE 0x10
85#define X25_MASK_CALLED_AE 0x20
80 86
81 87
82/* 88/*
@@ -99,6 +105,26 @@ struct x25_facilities {
99}; 105};
100 106
101/* 107/*
108* ITU DTE facilities
109* Only the called and calling address
110* extension are currently implemented.
111* The rest are in place to avoid the struct
112* changing size if someone needs them later
113*/
114
115struct x25_dte_facilities {
116 __u16 delay_cumul;
117 __u16 delay_target;
118 __u16 delay_max;
119 __u8 min_throughput;
120 __u8 expedited;
121 __u8 calling_len;
122 __u8 called_len;
123 __u8 calling_ae[20];
124 __u8 called_ae[20];
125};
126
127/*
102 * Call User Data structure. 128 * Call User Data structure.
103 */ 129 */
104struct x25_calluserdata { 130struct x25_calluserdata {
diff --git a/include/net/compat.h b/include/net/compat.h
index 290bab46d457..8662b8f43df5 100644
--- a/include/net/compat.h
+++ b/include/net/compat.h
@@ -23,6 +23,9 @@ struct compat_cmsghdr {
23 compat_int_t cmsg_type; 23 compat_int_t cmsg_type;
24}; 24};
25 25
26struct sock;
27extern int compat_sock_get_timestamp(struct sock *, struct timeval __user *);
28
26#else /* defined(CONFIG_COMPAT) */ 29#else /* defined(CONFIG_COMPAT) */
27#define compat_msghdr msghdr /* to avoid compiler warnings */ 30#define compat_msghdr msghdr /* to avoid compiler warnings */
28#endif /* defined(CONFIG_COMPAT) */ 31#endif /* defined(CONFIG_COMPAT) */
@@ -34,7 +37,6 @@ extern asmlinkage long compat_sys_recvmsg(int,struct compat_msghdr __user *,unsi
34extern asmlinkage long compat_sys_getsockopt(int, int, int, char __user *, int __user *); 37extern asmlinkage long compat_sys_getsockopt(int, int, int, char __user *, int __user *);
35extern int put_cmsg_compat(struct msghdr*, int, int, int, void *); 38extern int put_cmsg_compat(struct msghdr*, int, int, int, void *);
36 39
37struct sock;
38extern int cmsghdr_from_user_compat_to_kern(struct msghdr *, struct sock *, unsigned char *, int); 40extern int cmsghdr_from_user_compat_to_kern(struct msghdr *, struct sock *, unsigned char *, int);
39 41
40#endif /* NET_COMPAT_H */ 42#endif /* NET_COMPAT_H */
diff --git a/include/net/x25.h b/include/net/x25.h
index fee62ff8c194..0ad90ebcf86e 100644
--- a/include/net/x25.h
+++ b/include/net/x25.h
@@ -101,9 +101,17 @@ enum {
101#define X25_FAC_PACKET_SIZE 0x42 101#define X25_FAC_PACKET_SIZE 0x42
102#define X25_FAC_WINDOW_SIZE 0x43 102#define X25_FAC_WINDOW_SIZE 0x43
103 103
104#define X25_MAX_FAC_LEN 20 /* Plenty to spare */ 104#define X25_MAX_FAC_LEN 60
105#define X25_MAX_CUD_LEN 128 105#define X25_MAX_CUD_LEN 128
106 106
107#define X25_FAC_CALLING_AE 0xCB
108#define X25_FAC_CALLED_AE 0xC9
109
110#define X25_MARKER 0x00
111#define X25_DTE_SERVICES 0x0F
112#define X25_MAX_AE_LEN 40 /* Max num of semi-octets in AE - OSI Nw */
113#define X25_MAX_DTE_FACIL_LEN 21 /* Max length of DTE facility params */
114
107/** 115/**
108 * struct x25_route - x25 routing entry 116 * struct x25_route - x25 routing entry
109 * @node - entry in x25_list_lock 117 * @node - entry in x25_list_lock
@@ -148,6 +156,7 @@ struct x25_sock {
148 struct timer_list timer; 156 struct timer_list timer;
149 struct x25_causediag causediag; 157 struct x25_causediag causediag;
150 struct x25_facilities facilities; 158 struct x25_facilities facilities;
159 struct x25_dte_facilities dte_facilities;
151 struct x25_calluserdata calluserdata; 160 struct x25_calluserdata calluserdata;
152 unsigned long vc_facil_mask; /* inc_call facilities mask */ 161 unsigned long vc_facil_mask; /* inc_call facilities mask */
153}; 162};
@@ -180,9 +189,13 @@ extern void x25_establish_link(struct x25_neigh *);
180extern void x25_terminate_link(struct x25_neigh *); 189extern void x25_terminate_link(struct x25_neigh *);
181 190
182/* x25_facilities.c */ 191/* x25_facilities.c */
183extern int x25_parse_facilities(struct sk_buff *, struct x25_facilities *, unsigned long *); 192extern int x25_parse_facilities(struct sk_buff *, struct x25_facilities *,
184extern int x25_create_facilities(unsigned char *, struct x25_facilities *, unsigned long); 193 struct x25_dte_facilities *, unsigned long *);
185extern int x25_negotiate_facilities(struct sk_buff *, struct sock *, struct x25_facilities *); 194extern int x25_create_facilities(unsigned char *, struct x25_facilities *,
195 struct x25_dte_facilities *, unsigned long);
196extern int x25_negotiate_facilities(struct sk_buff *, struct sock *,
197 struct x25_facilities *,
198 struct x25_dte_facilities *);
186extern void x25_limit_facilities(struct x25_facilities *, struct x25_neigh *); 199extern void x25_limit_facilities(struct x25_facilities *, struct x25_neigh *);
187 200
188/* x25_in.c */ 201/* x25_in.c */
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c
index cbb20c32a6c8..d908d49dc9f8 100644
--- a/net/bluetooth/bnep/core.c
+++ b/net/bluetooth/bnep/core.c
@@ -532,8 +532,8 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
532 dev = alloc_netdev(sizeof(struct bnep_session), 532 dev = alloc_netdev(sizeof(struct bnep_session),
533 (*req->device) ? req->device : "bnep%d", 533 (*req->device) ? req->device : "bnep%d",
534 bnep_net_setup); 534 bnep_net_setup);
535 if (!dev) 535 if (!dev)
536 return ENOMEM; 536 return -ENOMEM;
537 537
538 538
539 down_write(&bnep_session_sem); 539 down_write(&bnep_session_sem);
diff --git a/net/compat.c b/net/compat.c
index 13177a1a4b39..8fd37cd7b501 100644
--- a/net/compat.c
+++ b/net/compat.c
@@ -543,6 +543,25 @@ static int compat_sock_getsockopt(struct socket *sock, int level, int optname,
543 return sock_getsockopt(sock, level, optname, optval, optlen); 543 return sock_getsockopt(sock, level, optname, optval, optlen);
544} 544}
545 545
546int compat_sock_get_timestamp(struct sock *sk, struct timeval __user *userstamp)
547{
548 struct compat_timeval __user *ctv =
549 (struct compat_timeval __user*) userstamp;
550 int err = -ENOENT;
551
552 if (!sock_flag(sk, SOCK_TIMESTAMP))
553 sock_enable_timestamp(sk);
554 if (sk->sk_stamp.tv_sec == -1)
555 return err;
556 if (sk->sk_stamp.tv_sec == 0)
557 do_gettimeofday(&sk->sk_stamp);
558 if (put_user(sk->sk_stamp.tv_sec, &ctv->tv_sec) ||
559 put_user(sk->sk_stamp.tv_usec, &ctv->tv_usec))
560 err = -EFAULT;
561 return err;
562}
563EXPORT_SYMBOL(compat_sock_get_timestamp);
564
546asmlinkage long compat_sys_getsockopt(int fd, int level, int optname, 565asmlinkage long compat_sys_getsockopt(int fd, int level, int optname,
547 char __user *optval, int __user *optlen) 566 char __user *optval, int __user *optlen)
548{ 567{
diff --git a/net/socket.c b/net/socket.c
index e3c21d5ec288..e2d5bae994de 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -107,6 +107,10 @@ static unsigned int sock_poll(struct file *file,
107 struct poll_table_struct *wait); 107 struct poll_table_struct *wait);
108static long sock_ioctl(struct file *file, 108static long sock_ioctl(struct file *file,
109 unsigned int cmd, unsigned long arg); 109 unsigned int cmd, unsigned long arg);
110#ifdef CONFIG_COMPAT
111static long compat_sock_ioctl(struct file *file,
112 unsigned int cmd, unsigned long arg);
113#endif
110static int sock_fasync(int fd, struct file *filp, int on); 114static int sock_fasync(int fd, struct file *filp, int on);
111static ssize_t sock_readv(struct file *file, const struct iovec *vector, 115static ssize_t sock_readv(struct file *file, const struct iovec *vector,
112 unsigned long count, loff_t *ppos); 116 unsigned long count, loff_t *ppos);
@@ -128,6 +132,9 @@ static struct file_operations socket_file_ops = {
128 .aio_write = sock_aio_write, 132 .aio_write = sock_aio_write,
129 .poll = sock_poll, 133 .poll = sock_poll,
130 .unlocked_ioctl = sock_ioctl, 134 .unlocked_ioctl = sock_ioctl,
135#ifdef CONFIG_COMPAT
136 .compat_ioctl = compat_sock_ioctl,
137#endif
131 .mmap = sock_mmap, 138 .mmap = sock_mmap,
132 .open = sock_no_open, /* special open code to disallow open via /proc */ 139 .open = sock_no_open, /* special open code to disallow open via /proc */
133 .release = sock_close, 140 .release = sock_close,
@@ -2136,6 +2143,20 @@ void socket_seq_show(struct seq_file *seq)
2136} 2143}
2137#endif /* CONFIG_PROC_FS */ 2144#endif /* CONFIG_PROC_FS */
2138 2145
2146#ifdef CONFIG_COMPAT
2147static long compat_sock_ioctl(struct file *file, unsigned cmd,
2148 unsigned long arg)
2149{
2150 struct socket *sock = file->private_data;
2151 int ret = -ENOIOCTLCMD;
2152
2153 if (sock->ops->compat_ioctl)
2154 ret = sock->ops->compat_ioctl(sock, cmd, arg);
2155
2156 return ret;
2157}
2158#endif
2159
2139/* ABI emulation layers need these two */ 2160/* ABI emulation layers need these two */
2140EXPORT_SYMBOL(move_addr_to_kernel); 2161EXPORT_SYMBOL(move_addr_to_kernel);
2141EXPORT_SYMBOL(move_addr_to_user); 2162EXPORT_SYMBOL(move_addr_to_user);
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index 72b6ff3299ba..282ce4e40d7b 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -54,7 +54,10 @@
54#include <linux/termios.h> /* For TIOCINQ/OUTQ */ 54#include <linux/termios.h> /* For TIOCINQ/OUTQ */
55#include <linux/notifier.h> 55#include <linux/notifier.h>
56#include <linux/init.h> 56#include <linux/init.h>
57#include <linux/compat.h>
58
57#include <net/x25.h> 59#include <net/x25.h>
60#include <net/compat.h>
58 61
59int sysctl_x25_restart_request_timeout = X25_DEFAULT_T20; 62int sysctl_x25_restart_request_timeout = X25_DEFAULT_T20;
60int sysctl_x25_call_request_timeout = X25_DEFAULT_T21; 63int sysctl_x25_call_request_timeout = X25_DEFAULT_T21;
@@ -69,6 +72,14 @@ static const struct proto_ops x25_proto_ops;
69 72
70static struct x25_address null_x25_address = {" "}; 73static struct x25_address null_x25_address = {" "};
71 74
75#ifdef CONFIG_COMPAT
76struct compat_x25_subscrip_struct {
77 char device[200-sizeof(compat_ulong_t)];
78 compat_ulong_t global_facil_mask;
79 compat_uint_t extended;
80};
81#endif
82
72int x25_addr_ntoa(unsigned char *p, struct x25_address *called_addr, 83int x25_addr_ntoa(unsigned char *p, struct x25_address *called_addr,
73 struct x25_address *calling_addr) 84 struct x25_address *calling_addr)
74{ 85{
@@ -514,6 +525,13 @@ static int x25_create(struct socket *sock, int protocol)
514 x25->facilities.pacsize_out = X25_DEFAULT_PACKET_SIZE; 525 x25->facilities.pacsize_out = X25_DEFAULT_PACKET_SIZE;
515 x25->facilities.throughput = X25_DEFAULT_THROUGHPUT; 526 x25->facilities.throughput = X25_DEFAULT_THROUGHPUT;
516 x25->facilities.reverse = X25_DEFAULT_REVERSE; 527 x25->facilities.reverse = X25_DEFAULT_REVERSE;
528 x25->dte_facilities.calling_len = 0;
529 x25->dte_facilities.called_len = 0;
530 memset(x25->dte_facilities.called_ae, '\0',
531 sizeof(x25->dte_facilities.called_ae));
532 memset(x25->dte_facilities.calling_ae, '\0',
533 sizeof(x25->dte_facilities.calling_ae));
534
517 rc = 0; 535 rc = 0;
518out: 536out:
519 return rc; 537 return rc;
@@ -550,6 +568,7 @@ static struct sock *x25_make_new(struct sock *osk)
550 x25->t2 = ox25->t2; 568 x25->t2 = ox25->t2;
551 x25->facilities = ox25->facilities; 569 x25->facilities = ox25->facilities;
552 x25->qbitincl = ox25->qbitincl; 570 x25->qbitincl = ox25->qbitincl;
571 x25->dte_facilities = ox25->dte_facilities;
553 x25->cudmatchlength = ox25->cudmatchlength; 572 x25->cudmatchlength = ox25->cudmatchlength;
554 x25->accptapprv = ox25->accptapprv; 573 x25->accptapprv = ox25->accptapprv;
555 574
@@ -733,7 +752,7 @@ out:
733 return rc; 752 return rc;
734} 753}
735 754
736static int x25_wait_for_data(struct sock *sk, int timeout) 755static int x25_wait_for_data(struct sock *sk, long timeout)
737{ 756{
738 DECLARE_WAITQUEUE(wait, current); 757 DECLARE_WAITQUEUE(wait, current);
739 int rc = 0; 758 int rc = 0;
@@ -829,6 +848,7 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb,
829 struct x25_sock *makex25; 848 struct x25_sock *makex25;
830 struct x25_address source_addr, dest_addr; 849 struct x25_address source_addr, dest_addr;
831 struct x25_facilities facilities; 850 struct x25_facilities facilities;
851 struct x25_dte_facilities dte_facilities;
832 int len, rc; 852 int len, rc;
833 853
834 /* 854 /*
@@ -865,7 +885,8 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb,
865 /* 885 /*
866 * Try to reach a compromise on the requested facilities. 886 * Try to reach a compromise on the requested facilities.
867 */ 887 */
868 if ((len = x25_negotiate_facilities(skb, sk, &facilities)) == -1) 888 len = x25_negotiate_facilities(skb, sk, &facilities, &dte_facilities);
889 if (len == -1)
869 goto out_sock_put; 890 goto out_sock_put;
870 891
871 /* 892 /*
@@ -896,9 +917,12 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb,
896 makex25->source_addr = source_addr; 917 makex25->source_addr = source_addr;
897 makex25->neighbour = nb; 918 makex25->neighbour = nb;
898 makex25->facilities = facilities; 919 makex25->facilities = facilities;
920 makex25->dte_facilities= dte_facilities;
899 makex25->vc_facil_mask = x25_sk(sk)->vc_facil_mask; 921 makex25->vc_facil_mask = x25_sk(sk)->vc_facil_mask;
900 /* ensure no reverse facil on accept */ 922 /* ensure no reverse facil on accept */
901 makex25->vc_facil_mask &= ~X25_MASK_REVERSE; 923 makex25->vc_facil_mask &= ~X25_MASK_REVERSE;
924 /* ensure no calling address extension on accept */
925 makex25->vc_facil_mask &= ~X25_MASK_CALLING_AE;
902 makex25->cudmatchlength = x25_sk(sk)->cudmatchlength; 926 makex25->cudmatchlength = x25_sk(sk)->cudmatchlength;
903 927
904 /* Normally all calls are accepted immediatly */ 928 /* Normally all calls are accepted immediatly */
@@ -1305,6 +1329,36 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
1305 break; 1329 break;
1306 } 1330 }
1307 1331
1332 case SIOCX25GDTEFACILITIES: {
1333 rc = copy_to_user(argp, &x25->dte_facilities,
1334 sizeof(x25->dte_facilities));
1335 if (rc)
1336 rc = -EFAULT;
1337 break;
1338 }
1339
1340 case SIOCX25SDTEFACILITIES: {
1341 struct x25_dte_facilities dtefacs;
1342 rc = -EFAULT;
1343 if (copy_from_user(&dtefacs, argp, sizeof(dtefacs)))
1344 break;
1345 rc = -EINVAL;
1346 if (sk->sk_state != TCP_LISTEN &&
1347 sk->sk_state != TCP_CLOSE)
1348 break;
1349 if (dtefacs.calling_len > X25_MAX_AE_LEN)
1350 break;
1351 if (dtefacs.calling_ae == NULL)
1352 break;
1353 if (dtefacs.called_len > X25_MAX_AE_LEN)
1354 break;
1355 if (dtefacs.called_ae == NULL)
1356 break;
1357 x25->dte_facilities = dtefacs;
1358 rc = 0;
1359 break;
1360 }
1361
1308 case SIOCX25GCALLUSERDATA: { 1362 case SIOCX25GCALLUSERDATA: {
1309 struct x25_calluserdata cud = x25->calluserdata; 1363 struct x25_calluserdata cud = x25->calluserdata;
1310 rc = copy_to_user(argp, &cud, 1364 rc = copy_to_user(argp, &cud,
@@ -1387,6 +1441,118 @@ static struct net_proto_family x25_family_ops = {
1387 .owner = THIS_MODULE, 1441 .owner = THIS_MODULE,
1388}; 1442};
1389 1443
1444#ifdef CONFIG_COMPAT
1445static int compat_x25_subscr_ioctl(unsigned int cmd,
1446 struct compat_x25_subscrip_struct __user *x25_subscr32)
1447{
1448 struct compat_x25_subscrip_struct x25_subscr;
1449 struct x25_neigh *nb;
1450 struct net_device *dev;
1451 int rc = -EINVAL;
1452
1453 rc = -EFAULT;
1454 if (copy_from_user(&x25_subscr, x25_subscr32, sizeof(*x25_subscr32)))
1455 goto out;
1456
1457 rc = -EINVAL;
1458 dev = x25_dev_get(x25_subscr.device);
1459 if (dev == NULL)
1460 goto out;
1461
1462 nb = x25_get_neigh(dev);
1463 if (nb == NULL)
1464 goto out_dev_put;
1465
1466 dev_put(dev);
1467
1468 if (cmd == SIOCX25GSUBSCRIP) {
1469 x25_subscr.extended = nb->extended;
1470 x25_subscr.global_facil_mask = nb->global_facil_mask;
1471 rc = copy_to_user(x25_subscr32, &x25_subscr,
1472 sizeof(*x25_subscr32)) ? -EFAULT : 0;
1473 } else {
1474 rc = -EINVAL;
1475 if (x25_subscr.extended == 0 || x25_subscr.extended == 1) {
1476 rc = 0;
1477 nb->extended = x25_subscr.extended;
1478 nb->global_facil_mask = x25_subscr.global_facil_mask;
1479 }
1480 }
1481 x25_neigh_put(nb);
1482out:
1483 return rc;
1484out_dev_put:
1485 dev_put(dev);
1486 goto out;
1487}
1488
1489static int compat_x25_ioctl(struct socket *sock, unsigned int cmd,
1490 unsigned long arg)
1491{
1492 void __user *argp = compat_ptr(arg);
1493 struct sock *sk = sock->sk;
1494
1495 int rc = -ENOIOCTLCMD;
1496
1497 switch(cmd) {
1498 case TIOCOUTQ:
1499 case TIOCINQ:
1500 rc = x25_ioctl(sock, cmd, (unsigned long)argp);
1501 break;
1502 case SIOCGSTAMP:
1503 rc = -EINVAL;
1504 if (sk)
1505 rc = compat_sock_get_timestamp(sk,
1506 (struct timeval __user*)argp);
1507 break;
1508 case SIOCGIFADDR:
1509 case SIOCSIFADDR:
1510 case SIOCGIFDSTADDR:
1511 case SIOCSIFDSTADDR:
1512 case SIOCGIFBRDADDR:
1513 case SIOCSIFBRDADDR:
1514 case SIOCGIFNETMASK:
1515 case SIOCSIFNETMASK:
1516 case SIOCGIFMETRIC:
1517 case SIOCSIFMETRIC:
1518 rc = -EINVAL;
1519 break;
1520 case SIOCADDRT:
1521 case SIOCDELRT:
1522 rc = -EPERM;
1523 if (!capable(CAP_NET_ADMIN))
1524 break;
1525 rc = x25_route_ioctl(cmd, argp);
1526 break;
1527 case SIOCX25GSUBSCRIP:
1528 rc = compat_x25_subscr_ioctl(cmd, argp);
1529 break;
1530 case SIOCX25SSUBSCRIP:
1531 rc = -EPERM;
1532 if (!capable(CAP_NET_ADMIN))
1533 break;
1534 rc = compat_x25_subscr_ioctl(cmd, argp);
1535 break;
1536 case SIOCX25GFACILITIES:
1537 case SIOCX25SFACILITIES:
1538 case SIOCX25GDTEFACILITIES:
1539 case SIOCX25SDTEFACILITIES:
1540 case SIOCX25GCALLUSERDATA:
1541 case SIOCX25SCALLUSERDATA:
1542 case SIOCX25GCAUSEDIAG:
1543 case SIOCX25SCUDMATCHLEN:
1544 case SIOCX25CALLACCPTAPPRV:
1545 case SIOCX25SENDCALLACCPT:
1546 rc = x25_ioctl(sock, cmd, (unsigned long)argp);
1547 break;
1548 default:
1549 rc = -ENOIOCTLCMD;
1550 break;
1551 }
1552 return rc;
1553}
1554#endif
1555
1390static const struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = { 1556static const struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = {
1391 .family = AF_X25, 1557 .family = AF_X25,
1392 .owner = THIS_MODULE, 1558 .owner = THIS_MODULE,
@@ -1398,6 +1564,9 @@ static const struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = {
1398 .getname = x25_getname, 1564 .getname = x25_getname,
1399 .poll = datagram_poll, 1565 .poll = datagram_poll,
1400 .ioctl = x25_ioctl, 1566 .ioctl = x25_ioctl,
1567#ifdef CONFIG_COMPAT
1568 .compat_ioctl = compat_x25_ioctl,
1569#endif
1401 .listen = x25_listen, 1570 .listen = x25_listen,
1402 .shutdown = sock_no_shutdown, 1571 .shutdown = sock_no_shutdown,
1403 .setsockopt = x25_setsockopt, 1572 .setsockopt = x25_setsockopt,
diff --git a/net/x25/x25_facilities.c b/net/x25/x25_facilities.c
index 54278b962f4c..9f42b9c9de37 100644
--- a/net/x25/x25_facilities.c
+++ b/net/x25/x25_facilities.c
@@ -28,18 +28,28 @@
28#include <net/x25.h> 28#include <net/x25.h>
29 29
30/* 30/*
31 * Parse a set of facilities into the facilities structure. Unrecognised 31 * Parse a set of facilities into the facilities structures. Unrecognised
32 * facilities are written to the debug log file. 32 * facilities are written to the debug log file.
33 */ 33 */
34int x25_parse_facilities(struct sk_buff *skb, 34int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities,
35 struct x25_facilities *facilities, 35 struct x25_dte_facilities *dte_facs, unsigned long *vc_fac_mask)
36 unsigned long *vc_fac_mask)
37{ 36{
38 unsigned char *p = skb->data; 37 unsigned char *p = skb->data;
39 unsigned int len = *p++; 38 unsigned int len = *p++;
40 39
41 *vc_fac_mask = 0; 40 *vc_fac_mask = 0;
42 41
42 /*
43 * The kernel knows which facilities were set on an incoming call but
44 * currently this information is not available to userspace. Here we
45 * give userspace who read incoming call facilities 0 length to indicate
46 * it wasn't set.
47 */
48 dte_facs->calling_len = 0;
49 dte_facs->called_len = 0;
50 memset(dte_facs->called_ae, '\0', sizeof(dte_facs->called_ae));
51 memset(dte_facs->calling_ae, '\0', sizeof(dte_facs->calling_ae));
52
43 while (len > 0) { 53 while (len > 0) {
44 switch (*p & X25_FAC_CLASS_MASK) { 54 switch (*p & X25_FAC_CLASS_MASK) {
45 case X25_FAC_CLASS_A: 55 case X25_FAC_CLASS_A:
@@ -74,6 +84,8 @@ int x25_parse_facilities(struct sk_buff *skb,
74 facilities->throughput = p[1]; 84 facilities->throughput = p[1];
75 *vc_fac_mask |= X25_MASK_THROUGHPUT; 85 *vc_fac_mask |= X25_MASK_THROUGHPUT;
76 break; 86 break;
87 case X25_MARKER:
88 break;
77 default: 89 default:
78 printk(KERN_DEBUG "X.25: unknown facility " 90 printk(KERN_DEBUG "X.25: unknown facility "
79 "%02X, value %02X\n", 91 "%02X, value %02X\n",
@@ -112,11 +124,30 @@ int x25_parse_facilities(struct sk_buff *skb,
112 len -= 4; 124 len -= 4;
113 break; 125 break;
114 case X25_FAC_CLASS_D: 126 case X25_FAC_CLASS_D:
115 printk(KERN_DEBUG "X.25: unknown facility %02X, " 127 switch (*p) {
116 "length %d, values %02X, %02X, %02X, %02X\n", 128 case X25_FAC_CALLING_AE:
117 p[0], p[1], p[2], p[3], p[4], p[5]); 129 if (p[1] > X25_MAX_DTE_FACIL_LEN)
130 break;
131 dte_facs->calling_len = p[2];
132 memcpy(dte_facs->calling_ae, &p[3], p[1] - 1);
133 *vc_fac_mask |= X25_MASK_CALLING_AE;
134 break;
135 case X25_FAC_CALLED_AE:
136 if (p[1] > X25_MAX_DTE_FACIL_LEN)
137 break;
138 dte_facs->called_len = p[2];
139 memcpy(dte_facs->called_ae, &p[3], p[1] - 1);
140 *vc_fac_mask |= X25_MASK_CALLED_AE;
141 break;
142 default:
143 printk(KERN_DEBUG "X.25: unknown facility %02X,"
144 "length %d, values %02X, %02X, "
145 "%02X, %02X\n",
146 p[0], p[1], p[2], p[3], p[4], p[5]);
147 break;
148 }
118 len -= p[1] + 2; 149 len -= p[1] + 2;
119 p += p[1] + 2; 150 p += p[1] + 2;
120 break; 151 break;
121 } 152 }
122 } 153 }
@@ -128,8 +159,8 @@ int x25_parse_facilities(struct sk_buff *skb,
128 * Create a set of facilities. 159 * Create a set of facilities.
129 */ 160 */
130int x25_create_facilities(unsigned char *buffer, 161int x25_create_facilities(unsigned char *buffer,
131 struct x25_facilities *facilities, 162 struct x25_facilities *facilities,
132 unsigned long facil_mask) 163 struct x25_dte_facilities *dte_facs, unsigned long facil_mask)
133{ 164{
134 unsigned char *p = buffer + 1; 165 unsigned char *p = buffer + 1;
135 int len; 166 int len;
@@ -168,6 +199,33 @@ int x25_create_facilities(unsigned char *buffer,
168 *p++ = facilities->winsize_out ? : facilities->winsize_in; 199 *p++ = facilities->winsize_out ? : facilities->winsize_in;
169 } 200 }
170 201
202 if (facil_mask & (X25_MASK_CALLING_AE|X25_MASK_CALLED_AE)) {
203 *p++ = X25_MARKER;
204 *p++ = X25_DTE_SERVICES;
205 }
206
207 if (dte_facs->calling_len && (facil_mask & X25_MASK_CALLING_AE)) {
208 unsigned bytecount = (dte_facs->calling_len % 2) ?
209 dte_facs->calling_len / 2 + 1 :
210 dte_facs->calling_len / 2;
211 *p++ = X25_FAC_CALLING_AE;
212 *p++ = 1 + bytecount;
213 *p++ = dte_facs->calling_len;
214 memcpy(p, dte_facs->calling_ae, bytecount);
215 p += bytecount;
216 }
217
218 if (dte_facs->called_len && (facil_mask & X25_MASK_CALLED_AE)) {
219 unsigned bytecount = (dte_facs->called_len % 2) ?
220 dte_facs->called_len / 2 + 1 :
221 dte_facs->called_len / 2;
222 *p++ = X25_FAC_CALLED_AE;
223 *p++ = 1 + bytecount;
224 *p++ = dte_facs->called_len;
225 memcpy(p, dte_facs->called_ae, bytecount);
226 p+=bytecount;
227 }
228
171 len = p - buffer; 229 len = p - buffer;
172 buffer[0] = len - 1; 230 buffer[0] = len - 1;
173 231
@@ -180,7 +238,7 @@ int x25_create_facilities(unsigned char *buffer,
180 * The only real problem is with reverse charging. 238 * The only real problem is with reverse charging.
181 */ 239 */
182int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk, 240int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk,
183 struct x25_facilities *new) 241 struct x25_facilities *new, struct x25_dte_facilities *dte)
184{ 242{
185 struct x25_sock *x25 = x25_sk(sk); 243 struct x25_sock *x25 = x25_sk(sk);
186 struct x25_facilities *ours = &x25->facilities; 244 struct x25_facilities *ours = &x25->facilities;
@@ -190,7 +248,7 @@ int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk,
190 memset(&theirs, 0, sizeof(theirs)); 248 memset(&theirs, 0, sizeof(theirs));
191 memcpy(new, ours, sizeof(*new)); 249 memcpy(new, ours, sizeof(*new));
192 250
193 len = x25_parse_facilities(skb, &theirs, &x25->vc_facil_mask); 251 len = x25_parse_facilities(skb, &theirs, dte, &x25->vc_facil_mask);
194 252
195 /* 253 /*
196 * They want reverse charging, we won't accept it. 254 * They want reverse charging, we won't accept it.
diff --git a/net/x25/x25_in.c b/net/x25/x25_in.c
index 26146874b839..eed50e10f09b 100644
--- a/net/x25/x25_in.c
+++ b/net/x25/x25_in.c
@@ -106,7 +106,8 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametyp
106 skb_pull(skb, x25_addr_ntoa(skb->data, &source_addr, &dest_addr)); 106 skb_pull(skb, x25_addr_ntoa(skb->data, &source_addr, &dest_addr));
107 skb_pull(skb, 107 skb_pull(skb,
108 x25_parse_facilities(skb, &x25->facilities, 108 x25_parse_facilities(skb, &x25->facilities,
109 &x25->vc_facil_mask)); 109 &x25->dte_facilities,
110 &x25->vc_facil_mask));
110 /* 111 /*
111 * Copy any Call User Data. 112 * Copy any Call User Data.
112 */ 113 */
diff --git a/net/x25/x25_subr.c b/net/x25/x25_subr.c
index 8be9b8fbc24d..8d6220aa5d0f 100644
--- a/net/x25/x25_subr.c
+++ b/net/x25/x25_subr.c
@@ -190,8 +190,9 @@ void x25_write_internal(struct sock *sk, int frametype)
190 dptr = skb_put(skb, len); 190 dptr = skb_put(skb, len);
191 memcpy(dptr, addresses, len); 191 memcpy(dptr, addresses, len);
192 len = x25_create_facilities(facilities, 192 len = x25_create_facilities(facilities,
193 &x25->facilities, 193 &x25->facilities,
194 x25->neighbour->global_facil_mask); 194 &x25->dte_facilities,
195 x25->neighbour->global_facil_mask);
195 dptr = skb_put(skb, len); 196 dptr = skb_put(skb, len);
196 memcpy(dptr, facilities, len); 197 memcpy(dptr, facilities, len);
197 dptr = skb_put(skb, x25->calluserdata.cudlength); 198 dptr = skb_put(skb, x25->calluserdata.cudlength);
@@ -206,6 +207,7 @@ void x25_write_internal(struct sock *sk, int frametype)
206 *dptr++ = 0x00; /* Address lengths */ 207 *dptr++ = 0x00; /* Address lengths */
207 len = x25_create_facilities(facilities, 208 len = x25_create_facilities(facilities,
208 &x25->facilities, 209 &x25->facilities,
210 &x25->dte_facilities,
209 x25->vc_facil_mask); 211 x25->vc_facil_mask);
210 dptr = skb_put(skb, len); 212 dptr = skb_put(skb, len);
211 memcpy(dptr, facilities, len); 213 memcpy(dptr, facilities, len);