~ubuntu-branches/ubuntu/trusty/linux-armadaxp/trusty

« back to all changes in this revision

Viewing changes to net/econet/af_econet.c

  • Committer: Package Import Robot
  • Author(s): Michael Casadevall, Bryan Wu, Dann Frazier, Michael Casadeall
  • Date: 2012-03-10 15:00:54 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20120310150054-flugb39zon8vvgwe
Tags: 3.2.0-1600.1
[ Bryan Wu ]
* UBUNTU: import debian/debian.env and debian.armadaxp

[ Dann Frazier ]
* ARM: Armada XP: remove trailing '/' in dirnames in mvRules.mk

[ Michael Casadeall ]
* tools: add some tools for Marvell Armada XP processor
* kernel: timer tick hacking from Marvell
* kernel: Sheeva Errata: add delay on Sheeva when powering down
* net: add Marvell NFP netfilter
* net: socket and skb modifications made by Marvell
* miscdevice: add minor IDs for some Marvell Armada drivers
* fs: introduce memory pool for splice()
* video: EDID detection updates from Marvell Armada XP patchset
* video: backlight: add Marvell Dove LCD backlight driver
* video: display: add THS8200 display driver
* video: framebuffer: add Marvell Dove and Armada XP processor onchip LCD controller driver
* usbtest: add Interrupt transfer testing by Marvell Armada XP code
* usb: ehci: add support for Marvell EHCI controler
* tty/serial: 8250: add support for Marvell Armada XP processor and DeviceTree work
* rtc: add support for Marvell Armada XP onchip RTC controller
* net: pppoe: add Marvell ethernet NFP hook in PPPoE networking driver
* mtd: nand: add support for Marvell Armada XP Nand Flash Controller
* mtd: maps: add Marvell Armada XP specific map driver
* mmc: add support for Marvell Armada XP MMC/SD host controller
* i2c: add support for Marvell Armada XP onchip i2c bus controller
* hwmon: add Kconfig option for Armada XP onchip thermal sensor driver
* dmaengine: add Net DMA support for splice and update Marvell XOR DMA engine driver
* ata: add support for Marvell Armada XP SATA controller and update some quirks
* ARM: add Marvell Armada XP machine to mach-types
* ARM: oprofile: add support for Marvell PJ4B core
* ARM: mm: more ARMv6 switches for Marvell Armada XP
* ARM: remove static declaration to allow compilation
* ARM: alignment access fault trick
* ARM: mm: skip some fault fixing when run on NONE SMP ARMv6 mode during early abort event
* ARM: mm: add Marvell Sheeva CPU Architecture for PJ4B
* ARM: introduce optimized copy operation for Marvell Armada XP
* ARM: SAUCE: hardware breakpoint trick for Marvell Armada XP
* ARM: big endian and little endian tricks for Marvell Armada XP
* ARM: SAUCE: Add Marvell Armada XP build rules to arch/arm/kernel/Makefile
* ARM: vfp: add special handling for Marvell Armada XP
* ARM: add support for Marvell U-Boot
* ARM: add mv_controller_num for ARM PCI drivers
* ARM: add support for local PMUs, general SMP tweaks and cache flushing
* ARM: add Marvell device identifies in glue-proc.h
* ARM: add IPC driver support for Marvell platforms
* ARM: add DMA mapping for Marvell platforms
* ARM: add Sheeva errata and PJ4B code for booting
* ARM: update Kconfig and Makefile to include Marvell Armada XP platforms
* ARM: Armada XP: import LSP from Marvell for Armada XP 3.2 kernel enablement

Show diffs side-by-side

added added

removed removed

Lines of Context:
9
9
 *
10
10
 */
11
11
 
 
12
#define pr_fmt(fmt) fmt
 
13
 
12
14
#include <linux/module.h>
13
15
 
14
16
#include <linux/types.h>
44
46
#include <linux/bitops.h>
45
47
#include <linux/mutex.h>
46
48
 
47
 
#include <asm/uaccess.h>
 
49
#include <linux/uaccess.h>
48
50
#include <asm/system.h>
49
51
 
50
52
static const struct proto_ops econet_ops;
63
65
static struct socket *udpsock;
64
66
#define AUN_PORT        0x8000
65
67
 
66
 
 
67
 
struct aunhdr
68
 
{
 
68
struct aunhdr {
69
69
        unsigned char code;             /* AUN magic protocol byte */
70
70
        unsigned char port;
71
71
        unsigned char cb;
82
82
#endif          /* CONFIG_ECONET_AUNUDP */
83
83
 
84
84
/* Per-packet information */
85
 
struct ec_cb
86
 
{
 
85
struct ec_cb {
87
86
        struct sockaddr_ec sec;
88
87
        unsigned long cookie;           /* Supplied by user. */
89
88
#ifdef CONFIG_ECONET_AUNUDP
137
136
         *      but then it will block.
138
137
         */
139
138
 
140
 
        skb=skb_recv_datagram(sk,flags,flags&MSG_DONTWAIT,&err);
 
139
        skb = skb_recv_datagram(sk, flags, flags & MSG_DONTWAIT, &err);
141
140
 
142
141
        /*
143
142
         *      An error occurred so return it. Because skb_recv_datagram()
145
144
         *      retries.
146
145
         */
147
146
 
148
 
        if(skb==NULL)
 
147
        if (skb == NULL)
149
148
                goto out;
150
149
 
151
150
        /*
154
153
         */
155
154
 
156
155
        copied = skb->len;
157
 
        if (copied > len)
158
 
        {
159
 
                copied=len;
160
 
                msg->msg_flags|=MSG_TRUNC;
 
156
        if (copied > len) {
 
157
                copied = len;
 
158
                msg->msg_flags |= MSG_TRUNC;
161
159
        }
162
160
 
163
161
        /* We can't use skb_copy_datagram here */
186
184
 *      Bind an Econet socket.
187
185
 */
188
186
 
189
 
static int econet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
 
187
static int econet_bind(struct socket *sock, struct sockaddr *uaddr,
 
188
                       int addr_len)
190
189
{
191
190
        struct sockaddr_ec *sec = (struct sockaddr_ec *)uaddr;
192
191
        struct sock *sk;
226
225
        struct ec_cb *eb;
227
226
        struct sockaddr_ec *sec;
228
227
 
229
 
        if (skb == NULL)
230
 
        {
231
 
                printk(KERN_DEBUG "ec: memory squeeze, transmit result dropped.\n");
 
228
        if (skb == NULL) {
 
229
                pr_debug("econet: memory squeeze, transmit result dropped\n");
232
230
                return;
233
231
        }
234
232
 
265
263
static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
266
264
                          struct msghdr *msg, size_t len)
267
265
{
268
 
        struct sockaddr_ec *saddr=(struct sockaddr_ec *)msg->msg_name;
 
266
        struct sockaddr_ec *saddr = (struct sockaddr_ec *)msg->msg_name;
269
267
        struct net_device *dev;
270
268
        struct ec_addr addr;
271
269
        int err;
298
296
 
299
297
        mutex_lock(&econet_mutex);
300
298
 
301
 
        if (saddr == NULL || msg->msg_namelen < sizeof(struct sockaddr_ec)) {
302
 
                mutex_unlock(&econet_mutex);
303
 
                return -EINVAL;
304
 
        }
305
 
        addr.station = saddr->addr.station;
306
 
        addr.net = saddr->addr.net;
307
 
        port = saddr->port;
308
 
        cb = saddr->cb;
 
299
        if (saddr == NULL || msg->msg_namelen < sizeof(struct sockaddr_ec)) {
 
300
                mutex_unlock(&econet_mutex);
 
301
                return -EINVAL;
 
302
        }
 
303
        addr.station = saddr->addr.station;
 
304
        addr.net = saddr->addr.net;
 
305
        port = saddr->port;
 
306
        cb = saddr->cb;
309
307
 
310
308
        /* Look for a device with the right network number. */
311
309
        dev = net2dev_map[addr.net];
333
331
 
334
332
                dev_hold(dev);
335
333
 
336
 
                skb = sock_alloc_send_skb(sk, len+LL_ALLOCATED_SPACE(dev),
 
334
                skb = sock_alloc_send_skb(sk, len + LL_ALLOCATED_SPACE(dev),
337
335
                                          msg->msg_flags & MSG_DONTWAIT, &err);
338
 
                if (skb==NULL)
 
336
                if (skb == NULL)
339
337
                        goto out_unlock;
340
338
 
341
339
                skb_reserve(skb, LL_RESERVED_SPACE(dev));
355
353
                        struct ec_framehdr *fh;
356
354
                        /* Poke in our control byte and
357
355
                           port number.  Hack, hack.  */
358
 
                        fh = (struct ec_framehdr *)(skb->data);
 
356
                        fh = (struct ec_framehdr *)skb->data;
359
357
                        fh->cb = cb;
360
358
                        fh->port = port;
361
359
                        if (sock->type != SOCK_DGRAM) {
365
363
                }
366
364
 
367
365
                /* Copy the data. Returns -EFAULT on error */
368
 
                err = memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len);
 
366
                err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len);
369
367
                skb->protocol = proto;
370
368
                skb->dev = dev;
371
369
                skb->priority = sk->sk_priority;
385
383
                mutex_unlock(&econet_mutex);
386
384
                return len;
387
385
 
388
 
        out_free:
 
386
out_free:
389
387
                kfree_skb(skb);
390
 
        out_unlock:
 
388
out_unlock:
391
389
                if (dev)
392
390
                        dev_put(dev);
393
391
#else
458
456
                goto error_free_buf;
459
457
 
460
458
        /* Get a skbuff (no data, just holds our cb information) */
461
 
        if ((skb = sock_alloc_send_skb(sk, 0,
462
 
                                       msg->msg_flags & MSG_DONTWAIT,
463
 
                                       &err)) == NULL)
 
459
        skb = sock_alloc_send_skb(sk, 0, msg->msg_flags & MSG_DONTWAIT, &err);
 
460
        if (skb == NULL)
464
461
                goto error_free_buf;
465
462
 
466
463
        eb = (struct ec_cb *)&skb->cb;
467
464
 
468
465
        eb->cookie = saddr->cookie;
469
 
        eb->timeout = (5*HZ);
 
466
        eb->timeout = 5 * HZ;
470
467
        eb->start = jiffies;
471
468
        ah.handle = aun_seq;
472
469
        eb->seq = (aun_seq++);
480
477
        udpmsg.msg_iovlen = 2;
481
478
        udpmsg.msg_control = NULL;
482
479
        udpmsg.msg_controllen = 0;
483
 
        udpmsg.msg_flags=0;
 
480
        udpmsg.msg_flags = 0;
484
481
 
485
 
        oldfs = get_fs(); set_fs(KERNEL_DS);    /* More privs :-) */
 
482
        oldfs = get_fs();
 
483
        set_fs(KERNEL_DS);              /* More privs :-) */
486
484
        err = sock_sendmsg(udpsock, &udpmsg, size);
487
485
        set_fs(oldfs);
488
486
 
530
528
 
531
529
static void econet_destroy_timer(unsigned long data)
532
530
{
533
 
        struct sock *sk=(struct sock *)data;
 
531
        struct sock *sk = (struct sock *)data;
534
532
 
535
533
        if (!sk_has_allocations(sk)) {
536
534
                sk_free(sk);
539
537
 
540
538
        sk->sk_timer.expires = jiffies + 10 * HZ;
541
539
        add_timer(&sk->sk_timer);
542
 
        printk(KERN_DEBUG "econet socket destroy delayed\n");
 
540
        pr_debug("econet: socket destroy delayed\n");
543
541
}
544
542
 
545
543
/*
651
649
        if (copy_from_user(&ifr, arg, sizeof(struct ifreq)))
652
650
                return -EFAULT;
653
651
 
654
 
        if ((dev = dev_get_by_name(&init_net, ifr.ifr_name)) == NULL)
 
652
        dev = dev_get_by_name(&init_net, ifr.ifr_name);
 
653
        if (dev == NULL)
655
654
                return -ENODEV;
656
655
 
657
656
        sec = (struct sockaddr_ec *)&ifr.ifr_addr;
715
714
 *      Handle generic ioctls
716
715
 */
717
716
 
718
 
static int econet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 
717
static int econet_ioctl(struct socket *sock, unsigned int cmd,
 
718
                        unsigned long arg)
719
719
{
720
720
        struct sock *sk = sock->sk;
721
721
        void __user *argp = (void __user *)arg;
722
722
 
723
 
        switch(cmd) {
724
 
                case SIOCGSTAMP:
725
 
                        return sock_get_timestamp(sk, argp);
726
 
 
727
 
                case SIOCGSTAMPNS:
728
 
                        return sock_get_timestampns(sk, argp);
729
 
 
730
 
                case SIOCSIFADDR:
731
 
                case SIOCGIFADDR:
732
 
                        return ec_dev_ioctl(sock, cmd, argp);
733
 
                        break;
734
 
 
735
 
                default:
736
 
                        return -ENOIOCTLCMD;
 
723
        switch (cmd) {
 
724
        case SIOCGSTAMP:
 
725
                return sock_get_timestamp(sk, argp);
 
726
 
 
727
        case SIOCGSTAMPNS:
 
728
                return sock_get_timestampns(sk, argp);
 
729
 
 
730
        case SIOCSIFADDR:
 
731
        case SIOCGIFADDR:
 
732
                return ec_dev_ioctl(sock, cmd, argp);
 
733
 
737
734
        }
738
 
        /*NOTREACHED*/
739
 
        return 0;
 
735
 
 
736
        return -ENOIOCTLCMD;
740
737
}
741
738
 
742
739
static const struct net_proto_family econet_family_ops = {
836
833
        udpmsg.msg_namelen = sizeof(sin);
837
834
        udpmsg.msg_control = NULL;
838
835
        udpmsg.msg_controllen = 0;
839
 
        udpmsg.msg_flags=0;
 
836
        udpmsg.msg_flags = 0;
840
837
 
841
838
        kernel_sendmsg(udpsock, &udpmsg, &iov, 1, sizeof(ah));
842
839
}
859
856
        if (dst)
860
857
                edev = dst->dev->ec_ptr;
861
858
 
862
 
        if (! edev)
 
859
        if (!edev)
863
860
                goto bad;
864
861
 
865
 
        if ((sk = ec_listening_socket(ah->port, stn, edev->net)) == NULL)
 
862
        sk = ec_listening_socket(ah->port, stn, edev->net);
 
863
        if (sk == NULL)
866
864
                goto bad;               /* Nobody wants it */
867
865
 
868
866
        newskb = alloc_skb((len - sizeof(struct aunhdr) + 15) & ~15,
869
867
                           GFP_ATOMIC);
870
 
        if (newskb == NULL)
871
 
        {
872
 
                printk(KERN_DEBUG "AUN: memory squeeze, dropping packet.\n");
 
868
        if (newskb == NULL) {
 
869
                pr_debug("AUN: memory squeeze, dropping packet\n");
873
870
                /* Send nack and hope sender tries again */
874
871
                goto bad;
875
872
        }
876
873
 
877
 
        memcpy(skb_put(newskb, len - sizeof(struct aunhdr)), (void *)(ah+1),
 
874
        memcpy(skb_put(newskb, len - sizeof(struct aunhdr)), (void *)(ah + 1),
878
875
               len - sizeof(struct aunhdr));
879
876
 
880
 
        if (ec_queue_packet(sk, newskb, stn, edev->net, ah->cb, ah->port))
881
 
        {
 
877
        if (ec_queue_packet(sk, newskb, stn, edev->net, ah->cb, ah->port)) {
882
878
                /* Socket is bankrupt. */
883
879
                kfree_skb(newskb);
884
880
                goto bad;
914
910
                        goto foundit;
915
911
        }
916
912
        spin_unlock_irqrestore(&aun_queue_lock, flags);
917
 
        printk(KERN_DEBUG "AUN: unknown sequence %ld\n", seq);
 
913
        pr_debug("AUN: unknown sequence %ld\n", seq);
918
914
        return;
919
915
 
920
916
foundit:
939
935
 
940
936
        while ((skb = skb_recv_datagram(sk, 0, 1, &err)) == NULL) {
941
937
                if (err == -EAGAIN) {
942
 
                        printk(KERN_ERR "AUN: no data available?!");
 
938
                        pr_err("AUN: no data available?!\n");
943
939
                        return;
944
940
                }
945
 
                printk(KERN_DEBUG "AUN: recvfrom() error %d\n", -err);
 
941
                pr_debug("AUN: recvfrom() error %d\n", -err);
946
942
        }
947
943
 
948
944
        data = skb_transport_header(skb) + sizeof(struct udphdr);
949
945
        ah = (struct aunhdr *)data;
950
946
        len = skb->len - sizeof(struct udphdr);
951
947
 
952
 
        switch (ah->code)
953
 
        {
 
948
        switch (ah->code) {
954
949
        case 2:
955
950
                aun_incoming(skb, ah, len);
956
951
                break;
961
956
                aun_tx_ack(ah->handle, ECTYPE_TRANSMIT_NOT_LISTENING);
962
957
                break;
963
958
        default:
964
 
                printk(KERN_DEBUG "unknown AUN packet (type %d)\n", data[0]);
 
959
                pr_debug("AUN: unknown packet type: %d\n", data[0]);
965
960
        }
966
961
 
967
962
        skb_free_datagram(sk, skb);
991
986
        }
992
987
        spin_unlock_irqrestore(&aun_queue_lock, flags);
993
988
 
994
 
        mod_timer(&ab_cleanup_timer, jiffies + (HZ*2));
 
989
        mod_timer(&ab_cleanup_timer, jiffies + (HZ * 2));
995
990
}
996
991
 
997
992
static int __init aun_udp_initialise(void)
1001
996
 
1002
997
        skb_queue_head_init(&aun_queue);
1003
998
        setup_timer(&ab_cleanup_timer, ab_cleanup, 0);
1004
 
        ab_cleanup_timer.expires = jiffies + (HZ*2);
 
999
        ab_cleanup_timer.expires = jiffies + (HZ * 2);
1005
1000
        add_timer(&ab_cleanup_timer);
1006
1001
 
1007
1002
        memset(&sin, 0, sizeof(sin));
1009
1004
 
1010
1005
        /* We can count ourselves lucky Acorn machines are too dim to
1011
1006
           speak IPv6. :-) */
1012
 
        if ((error = sock_create_kern(PF_INET, SOCK_DGRAM, 0, &udpsock)) < 0)
1013
 
        {
1014
 
                printk("AUN: socket error %d\n", -error);
 
1007
        error = sock_create_kern(PF_INET, SOCK_DGRAM, 0, &udpsock);
 
1008
        if (error < 0) {
 
1009
                pr_err("AUN: socket error %d\n", -error);
1015
1010
                return error;
1016
1011
        }
1017
1012
 
1020
1015
                                                    from interrupts */
1021
1016
 
1022
1017
        error = udpsock->ops->bind(udpsock, (struct sockaddr *)&sin,
1023
 
                                sizeof(sin));
1024
 
        if (error < 0)
1025
 
        {
1026
 
                printk("AUN: bind error %d\n", -error);
 
1018
                                   sizeof(sin));
 
1019
        if (error < 0) {
 
1020
                pr_err("AUN: bind error %d\n", -error);
1027
1021
                goto release;
1028
1022
        }
1029
1023
 
1044
1038
 *      Receive an Econet frame from a device.
1045
1039
 */
1046
1040
 
1047
 
static int econet_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
 
1041
static int econet_rcv(struct sk_buff *skb, struct net_device *dev,
 
1042
                      struct packet_type *pt, struct net_device *orig_dev)
1048
1043
{
1049
1044
        struct ec_framehdr *hdr;
1050
1045
        struct sock *sk = NULL;
1059
1054
        if (!edev)
1060
1055
                goto drop;
1061
1056
 
1062
 
        if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
 
1057
        skb = skb_share_check(skb, GFP_ATOMIC);
 
1058
        if (skb == NULL)
1063
1059
                return NET_RX_DROP;
1064
1060
 
1065
1061
        if (!pskb_may_pull(skb, sizeof(struct ec_framehdr)))
1066
1062
                goto drop;
1067
1063
 
1068
 
        hdr = (struct ec_framehdr *) skb->data;
 
1064
        hdr = (struct ec_framehdr *)skb->data;
1069
1065
 
1070
1066
        /* First check for encapsulated IP */
1071
1067
        if (hdr->port == EC_PORT_IP) {
1093
1089
}
1094
1090
 
1095
1091
static struct packet_type econet_packet_type __read_mostly = {
1096
 
        .type =         cpu_to_be16(ETH_P_ECONET),
1097
 
        .func =         econet_rcv,
 
1092
        .type = cpu_to_be16(ETH_P_ECONET),
 
1093
        .func = econet_rcv,
1098
1094
};
1099
1095
 
1100
1096
static void econet_hw_initialise(void)
1104
1100
 
1105
1101
#endif
1106
1102
 
1107
 
static int econet_notifier(struct notifier_block *this, unsigned long msg, void *data)
 
1103
static int econet_notifier(struct notifier_block *this, unsigned long msg,
 
1104
                           void *data)
1108
1105
{
1109
 
        struct net_device *dev = (struct net_device *)data;
 
1106
        struct net_device *dev = data;
1110
1107
        struct ec_device *edev;
1111
1108
 
1112
1109
        if (!net_eq(dev_net(dev), &init_net))
1116
1113
        case NETDEV_UNREGISTER:
1117
1114
                /* A device has gone down - kill any data we hold for it. */
1118
1115
                edev = dev->ec_ptr;
1119
 
                if (edev)
1120
 
                {
 
1116
                if (edev) {
1121
1117
                        if (net2dev_map[0] == dev)
1122
1118
                                net2dev_map[0] = NULL;
1123
1119
                        net2dev_map[edev->net] = NULL;
1131
1127
}
1132
1128
 
1133
1129
static struct notifier_block econet_netdev_notifier = {
1134
 
        .notifier_call =econet_notifier,
 
1130
        .notifier_call = econet_notifier,
1135
1131
};
1136
1132
 
1137
1133
static void __exit econet_proto_exit(void)