#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/ioctls.h>
+#include <asm/page.h>
+#include <asm/io.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/poll.h>
{
struct tpacket_stats stats;
#ifdef CONFIG_PACKET_MMAP
- unsigned long *pg_vec;
+ char * *pg_vec;
unsigned int head;
unsigned int frames_per_block;
unsigned int frame_size;
#ifdef CONFIG_PACKET_MMAP
-static inline unsigned long packet_lookup_frame(struct packet_opt *po, unsigned int position)
+static inline char *packet_lookup_frame(struct packet_opt *po, unsigned int position)
{
unsigned int pg_vec_pos, frame_offset;
- unsigned long frame;
+ char *frame;
pg_vec_pos = position / po->frames_per_block;
frame_offset = position % po->frames_per_block;
- frame = (unsigned long) (po->pg_vec[pg_vec_pos] + (frame_offset * po->frame_size));
+ frame = po->pg_vec[pg_vec_pos] + (frame_offset * po->frame_size);
return frame;
}
static int packet_release(struct socket *sock)
{
struct sock *sk = sock->sk;
- struct packet_opt *po = pkt_sk(sk);
+ struct packet_opt *po;
if (!sk)
return 0;
+ po = pkt_sk(sk);
+
write_lock_bh(&packet_sklist_lock);
sk_del_node_init(sk);
write_unlock_bh(&packet_sklist_lock);
int copied, err;
err = -EINVAL;
- if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC))
+ if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC|MSG_CMSG_COMPAT))
goto out;
#if 0
#endif
static int
-packet_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
+packet_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen)
{
struct sock *sk = sock->sk;
int ret;
}
int packet_getsockopt(struct socket *sock, int level, int optname,
- char *optval, int *optlen)
+ char __user *optval, int __user *optlen)
{
int len;
struct sock *sk = sock->sk;
case SIOCOUTQ:
{
int amount = atomic_read(&sk->sk_wmem_alloc);
- return put_user(amount, (int *)arg);
+ return put_user(amount, (int __user *)arg);
}
case SIOCINQ:
{
if (skb)
amount = skb->len;
spin_unlock_bh(&sk->sk_receive_queue.lock);
- return put_user(amount, (int *)arg);
+ return put_user(amount, (int __user *)arg);
}
case SIOCGSTAMP:
- return sock_get_timestamp(sk, (struct timeval *)arg);
+ return sock_get_timestamp(sk, (struct timeval __user *)arg);
#ifdef CONFIG_INET
case SIOCADDRT:
#endif
default:
- return dev_ioctl(cmd, (void *)arg);
+ return dev_ioctl(cmd, (void __user *)arg);
}
return 0;
}
.close =packet_mm_close,
};
-static void free_pg_vec(unsigned long *pg_vec, unsigned order, unsigned len)
+static inline struct page *pg_vec_endpage(char *one_pg_vec, unsigned int order)
+{
+ return virt_to_page(one_pg_vec + (PAGE_SIZE << order) - 1);
+}
+
+static void free_pg_vec(char **pg_vec, unsigned order, unsigned len)
{
int i;
if (pg_vec[i]) {
struct page *page, *pend;
- pend = virt_to_page(pg_vec[i] + (PAGE_SIZE << order) - 1);
+ pend = pg_vec_endpage(pg_vec[i], order);
for (page = virt_to_page(pg_vec[i]); page <= pend; page++)
ClearPageReserved(page);
- free_pages(pg_vec[i], order);
+ free_pages((unsigned long)pg_vec[i], order);
}
}
kfree(pg_vec);
static int packet_set_ring(struct sock *sk, struct tpacket_req *req, int closing)
{
- unsigned long *pg_vec = NULL;
+ char **pg_vec = NULL;
struct packet_opt *po = pkt_sk(sk);
int was_running, num, order = 0;
int err = 0;
err = -ENOMEM;
- pg_vec = kmalloc(req->tp_block_nr*sizeof(unsigned long*), GFP_KERNEL);
+ pg_vec = kmalloc(req->tp_block_nr*sizeof(char *), GFP_KERNEL);
if (pg_vec == NULL)
goto out;
- memset(pg_vec, 0, req->tp_block_nr*sizeof(unsigned long*));
+ memset(pg_vec, 0, req->tp_block_nr*sizeof(char **));
for (i=0; i<req->tp_block_nr; i++) {
struct page *page, *pend;
- pg_vec[i] = __get_free_pages(GFP_KERNEL, order);
+ pg_vec[i] = (char *)__get_free_pages(GFP_KERNEL, order);
if (!pg_vec[i])
goto out_free_pgvec;
- pend = virt_to_page(pg_vec[i] + (PAGE_SIZE << order) - 1);
+ pend = pg_vec_endpage(pg_vec[i], order);
for (page = virt_to_page(pg_vec[i]); page <= pend; page++)
SetPageReserved(page);
}
l = 0;
for (i=0; i<req->tp_block_nr; i++) {
- unsigned long ptr = pg_vec[i];
+ char *ptr = pg_vec[i];
struct tpacket_hdr *header;
int k;