Jump stacks before unlocking semaphores
[akaros.git] / kern / drivers / dev / ether.c
index b45ee98..4f8e7b7 100644 (file)
@@ -1,4 +1,31 @@
-// INFERNO
+/* Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
+ * Portions Copyright © 1997-1999 Vita Nuova Limited
+ * Portions Copyright © 2000-2007 Vita Nuova Holdings Limited
+ *                                (www.vitanuova.com)
+ * Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
+ *
+ * Modified for the Akaros operating system:
+ * Copyright (c) 2013-2014 The Regents of the University of California
+ * Copyright (c) 2013-2015 Google Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE. */
+
 #include <vfs.h>
 #include <kfs.h>
 #include <slab.h>
@@ -44,15 +71,15 @@ struct chan *etherattach(char *spec)
                /* somebody interpret this for me. */
                if (((ctlrno == 0) && (p == spec)) ||
                        (ctlrno >= MaxEther) || ((*p) && (*p != '.')))
-                       error(EINVAL, NULL);
+                       error(EINVAL, ERROR_FIXME);
                if (*p == '.') {        /* vlan */
                        vlanid = strtoul(p + 1, &p, 0);
                        if (vlanid <= 0 || vlanid > 0xFFF || *p)
-                               error(EINVAL, NULL);
+                               error(EINVAL, ERROR_FIXME);
                }
        }
        if ((ether = etherxx[ctlrno]) == 0)
-               error(ENODEV, NULL);
+               error(ENODEV, ERROR_FIXME);
        rlock(&ether->rwlock);
        if (waserror()) {
                runlock(&ether->rwlock);
@@ -243,7 +270,7 @@ static void etherrtrace(struct netfile *f, struct etherpkt *pkt, int len)
                n = 58;
        else
                n = len;
-       bp = iallocb(68);
+       bp = block_alloc(68, MEM_ATOMIC);
        if (bp == NULL)
                return;
        memmove(bp->wp, pkt->d, n);
@@ -344,7 +371,7 @@ struct block *etheriq(struct ether *ether, struct block *bp, int fromwire)
                                        fx = f;
                                        continue;
                                }
-                               xbp = iallocb(len);
+                               xbp = block_alloc(len, MEM_ATOMIC);
                                if (xbp == 0) {
                                        ether->soverflows++;
                                        continue;
@@ -460,12 +487,12 @@ static long etherwrite(struct chan *chan, void *buf, long n, int64_t unused)
                        l = ether->ctl(ether, buf, n);
                        goto out;
                }
-               error(EINVAL, NULL);
+               error(EINVAL, ERROR_FIXME);
        }
 
        if (n > ether->maxmtu + ETHERHDRSIZE)
-               error(E2BIG, NULL);
-       bp = allocb(n);
+               error(E2BIG, ERROR_FIXME);
+       bp = block_alloc(n, MEM_WAIT);
        if (waserror()) {
                freeb(bp);
                nexterror();
@@ -507,7 +534,7 @@ static long etherbwrite(struct chan *chan, struct block *bp, uint32_t unused)
        }
        if (n > ether->maxmtu + ETHERHDRSIZE && (bp->flag & Btso) == 0) {
                freeb(bp);
-               error(E2BIG, NULL);
+               error(E2BIG, ERROR_FIXME);
        }
        n = etheroq(ether, bp);
        poperror();
@@ -548,7 +575,7 @@ static long vlanctl(struct ether *ether, void *buf, long n)
                return 0;
        }
        kfree(cb);
-       error(EINVAL, NULL);
+       error(EINVAL, ERROR_FIXME);
        return -1;      /* not reached */
 }
 
@@ -576,13 +603,13 @@ static struct ether *vlanalloc(struct ether *ether, int id)
                        fid = i;
        }
        if (fid < 0)
-               error(ENOENT, NULL);
+               error(ENOENT, ERROR_FIXME);
        snprintf(name, sizeof(name), "ether%d.%d", ether->ctlrno, id);
        vlan = ether->vlans[fid];
        if (vlan == NULL) {
                vlan = kzmalloc(sizeof(struct ether), 1);
                if (vlan == NULL)
-                       error(ENOMEM, NULL);
+                       error(ENOMEM, ERROR_FIXME);
                rwinit(&vlan->rwlock);
                qlock_init(&vlan->vlq);
                netifinit(vlan, name, Ntypes, ether->limit);
@@ -810,23 +837,23 @@ uint32_t ethercrc(uint8_t * p, int len)
 }
 
 struct dev etherdevtab __devtab = {
-       "ether",
-
-       etherreset,
-       devinit,
-       ethershutdown,
-       etherattach,
-       etherwalk,
-       etherstat,
-       etheropen,
-       devcreate,
-       etherclose,
-       etherread,
-       etherbread,
-       etherwrite,
-       etherbwrite,
-       devremove,
-       etherwstat,
-       etherpower,
-       devchaninfo,
+       .name = "ether",
+
+       .reset = etherreset,
+       .init = devinit,
+       .shutdown = ethershutdown,
+       .attach = etherattach,
+       .walk = etherwalk,
+       .stat = etherstat,
+       .open = etheropen,
+       .create = devcreate,
+       .close = etherclose,
+       .read = etherread,
+       .bread = etherbread,
+       .write = etherwrite,
+       .bwrite = etherbwrite,
+       .remove = devremove,
+       .wstat = etherwstat,
+       .power = etherpower,
+       .chaninfo = devchaninfo,
 };