Annotation of OSKit-Mach/oskit/ds_net.c, revision 1.1

1.1     ! root        1: #include "ds_oskit.h"
        !             2: 
        !             3: #include <device/net_io.h>
        !             4: #include <device/if_ether.h>
        !             5: 
        !             6: #include <stddef.h>
        !             7: #include <string.h>
        !             8: #include <oskit/dev/net.h>
        !             9: #include <oskit/dev/ethernet.h>
        !            10: 
        !            11: 
        !            12: io_return_t
        !            13: ds_net_get_status (device_t dev, dev_flavor_t flavor, dev_status_t status,
        !            14:                   mach_msg_type_number_t *status_count)
        !            15: {
        !            16:   oskit_error_t rc;
        !            17:   oskit_etherdev_t *eth;
        !            18: 
        !            19:   rc = oskit_device_query (dev->com_device, &oskit_etherdev_iid,
        !            20:                           (void **) &eth);
        !            21:   if (OSKIT_FAILED (rc))
        !            22:     return D_INVALID_OPERATION;        /* XXX we only support ethernet devices */
        !            23: 
        !            24:   switch (flavor)
        !            25:     {
        !            26:     case NET_ADDRESS:
        !            27:       {
        !            28: #define WORDS ((OSKIT_ETHERDEV_ADDR_SIZE + sizeof (int) - 1) / sizeof (int))
        !            29: 
        !            30:        if (*status_count < WORDS)
        !            31:          {
        !            32:            oskit_etherdev_release (eth);
        !            33:            return D_INVALID_OPERATION;
        !            34:          }
        !            35:        *status_count = WORDS;
        !            36: 
        !            37:        bzero (status, OSKIT_ETHERDEV_ADDR_SIZE);
        !            38:        oskit_etherdev_getaddr (eth, (void *) status);
        !            39:        oskit_etherdev_release (eth);
        !            40: 
        !            41:        status[0] = ntohl (status[0]);
        !            42:        status[1] = ntohl (status[1]);
        !            43: 
        !            44:        return D_SUCCESS;
        !            45:       }
        !            46: 
        !            47:     case NET_STATUS:
        !            48:       {
        !            49:        struct net_status *ns = (void *) status;
        !            50: 
        !            51:        oskit_etherdev_release (eth);
        !            52: 
        !            53:        if (*status_count < NET_STATUS_COUNT)
        !            54:          return D_INVALID_OPERATION;
        !            55:        *status_count = NET_STATUS_COUNT;
        !            56: 
        !            57:        ns->header_format = HDR_ETHERNET;
        !            58:        ns->min_packet_size = ns->header_size = sizeof (struct ether_header);
        !            59:        ns->max_packet_size = sizeof (struct ether_header) + ETHERMTU;
        !            60:        ns->address_size = OSKIT_ETHERDEV_ADDR_SIZE;
        !            61:        ns->flags = IFF_UP|IFF_RUNNING|IFF_BROADCAST;
        !            62:        ns->mapped_size = 0;
        !            63: 
        !            64:        return D_SUCCESS;
        !            65:       }
        !            66:     }
        !            67: 
        !            68:   oskit_etherdev_release (eth);
        !            69:   return D_INVALID_OPERATION;
        !            70: }
        !            71: 
        !            72: io_return_t
        !            73: ds_net_set_filter (device_t dev, ipc_port_t port, int priority,
        !            74:                   filter_t *filter, unsigned filter_count)
        !            75: {
        !            76:   return net_set_filter (&dev->com.net.ifnet,
        !            77:                         port, priority, filter, filter_count);
        !            78: }
        !            79: 
        !            80: 
        !            81: #if 0
        !            82: io_return_t
        !            83: ds_net_write (device_t dev, ipc_port_t reply_port,
        !            84:              mach_msg_type_name_t reply_port_type, dev_mode_t mode,
        !            85:              recnum_t recnum, io_buf_ptr_t data, unsigned int count,
        !            86:              int *bytes_written)
        !            87: {
        !            88:   oskit_error_t rc;
        !            89:   io_return_t err;
        !            90:   oskit_u32_t wrote;
        !            91:   vm_offset_t addr;
        !            92:   oskit_bufio_t *bio;
        !            93: 
        !            94:   if (count < sizeof (struct ether_header) ||
        !            95:       count > sizeof (struct ether_header) + ETHERMTU)
        !            96:     return D_INVALID_SIZE;
        !            97: 
        !            98:   err = vm_map_copyout (device_io_map, &addr, (vm_map_copy_t) data);
        !            99:   if (err != KERN_SUCCESS)
        !           100:     return err;
        !           101: 
        !           102: 
        !           103: }
        !           104: #endif
        !           105: 
        !           106: /* XXX
        !           107:    The oskit network drivers want to call our bufio object from interrupt
        !           108:    handlers.  This makes it impractical for us to do anything fancy in
        !           109:    there, like map the VM on demand--we can't do that from interrupt level!
        !           110:    So we rely on the outbound netio_push to see bufio_map fail and copy out
        !           111:    the data without attempting to save a reference to the bufio COM object.  */
        !           112: 
        !           113: struct bufio_impl
        !           114: {
        !           115:   oskit_bufio_t ioi;
        !           116:   char *buf;
        !           117:   oskit_size_t size;
        !           118: };
        !           119: 
        !           120: static OSKIT_COMDECL
        !           121: bufio_query(oskit_bufio_t *io, const oskit_iid_t *iid, void **out_ihandle)
        !           122: { panic(__FUNCTION__); }
        !           123: 
        !           124: static OSKIT_COMDECL_U
        !           125: bufio_addref(oskit_bufio_t *io)
        !           126: { panic(__FUNCTION__); }
        !           127: 
        !           128: static OSKIT_COMDECL_U
        !           129: bufio_release(oskit_bufio_t *io)
        !           130: { panic(__FUNCTION__); }
        !           131: 
        !           132: static OSKIT_COMDECL_U
        !           133: bufio_getblocksize(oskit_bufio_t *io)
        !           134: {
        !           135:   return 1;
        !           136: }
        !           137: 
        !           138: static OSKIT_COMDECL
        !           139: bufio_read(oskit_bufio_t *io, void *dest, oskit_off_t offset,
        !           140:           oskit_size_t count, oskit_size_t *out_actual)
        !           141: {
        !           142:   struct bufio_impl *b = (struct bufio_impl *) io;
        !           143: 
        !           144:   if (offset >= b->size)
        !           145:     return OSKIT_EINVAL;
        !           146:   if (offset + count > b->size)
        !           147:     count = b->size - offset;
        !           148: 
        !           149:   memcpy (dest, b->buf + offset, count);
        !           150:   *out_actual = count;
        !           151:   return 0;
        !           152: }
        !           153: 
        !           154: static OSKIT_COMDECL
        !           155: bufio_write(oskit_bufio_t *io, const void *src, oskit_off_t offset,
        !           156:            oskit_size_t count, oskit_size_t *out_actual)
        !           157: { panic(__FUNCTION__); }
        !           158: 
        !           159: static OSKIT_COMDECL
        !           160: bufio_getsize(oskit_bufio_t *io, oskit_off_t *out_size)
        !           161: {
        !           162:   struct bufio_impl *b = (struct bufio_impl *) io;
        !           163: 
        !           164:   *out_size = b->size;
        !           165:   return 0;
        !           166: }
        !           167: 
        !           168: static OSKIT_COMDECL
        !           169: bufio_setsize(oskit_bufio_t *io, oskit_off_t size)
        !           170: { return OSKIT_E_NOTIMPL; }
        !           171: 
        !           172: 
        !           173: static OSKIT_COMDECL
        !           174: bufio_map(oskit_bufio_t *io, void **out_addr,
        !           175:          oskit_off_t offset, oskit_size_t count)
        !           176: { return OSKIT_E_NOTIMPL; }
        !           177: 
        !           178: static OSKIT_COMDECL
        !           179: bufio_unmap(oskit_bufio_t *io, void *addr, oskit_off_t offset, oskit_size_t count)
        !           180: { return OSKIT_E_NOTIMPL; }
        !           181: 
        !           182: static OSKIT_COMDECL
        !           183: bufio_wire(oskit_bufio_t *io, oskit_addr_t *out_physaddr,
        !           184:           oskit_off_t offset, oskit_size_t count)
        !           185: {
        !           186:        return OSKIT_E_NOTIMPL;
        !           187: }
        !           188: 
        !           189: static OSKIT_COMDECL
        !           190: bufio_unwire(oskit_bufio_t *io, oskit_addr_t phys_addr,
        !           191:             oskit_off_t offset, oskit_size_t count)
        !           192: {
        !           193:        return OSKIT_E_NOTIMPL;
        !           194: }
        !           195: 
        !           196: static OSKIT_COMDECL
        !           197: bufio_copy(oskit_bufio_t *io, oskit_off_t offset, oskit_size_t count,
        !           198:           oskit_bufio_t **out_io)
        !           199: {
        !           200:        return OSKIT_E_NOTIMPL;
        !           201: }
        !           202: 
        !           203: 
        !           204: static struct oskit_bufio_ops bio_ops = {
        !           205:        bufio_query, bufio_addref, bufio_release,
        !           206:        bufio_getblocksize,
        !           207:        bufio_read, bufio_write,
        !           208:        bufio_getsize, bufio_setsize,
        !           209:        bufio_map, bufio_unmap,
        !           210:        bufio_wire, bufio_unwire,
        !           211:        bufio_copy
        !           212: };
        !           213: 
        !           214: 
        !           215: io_return_t
        !           216: ds_net_write_inband (device_t dev, ipc_port_t reply_port,
        !           217:                     mach_msg_type_name_t reply_port_type, dev_mode_t mode,
        !           218:                     recnum_t recnum, io_buf_ptr_t data, unsigned int count,
        !           219:                     int *bytes_written)
        !           220: {
        !           221:   oskit_error_t rc;
        !           222:   struct bufio_impl bio = { { &bio_ops }, data, count };
        !           223: 
        !           224:   if (count < sizeof (struct ether_header) ||
        !           225:       count > sizeof (struct ether_header) + ETHERMTU)
        !           226:     return D_INVALID_SIZE;
        !           227: 
        !           228:   rc = oskit_netio_push (dev->com.net.sendi, &bio.ioi, count);
        !           229:   *bytes_written = count;
        !           230: 
        !           231:   return oskit_to_mach_error (rc);
        !           232: }
        !           233: 
        !           234: 
        !           235: const struct device_ops net_device_ops =
        !           236: {
        !           237:   write_inband: ds_net_write_inband,
        !           238:   set_filter: ds_net_set_filter,
        !           239:   get_status: ds_net_get_status,
        !           240: };
        !           241: 
        !           242: 
        !           243: static device_t
        !           244: recv_netio_device (oskit_netio_t *recvi)
        !           245: {
        !           246:   return (device_t) ((char *) recvi - offsetof (struct device, com.net.recvi));
        !           247: }
        !           248: 
        !           249: static OSKIT_COMDECL
        !           250: net_query(oskit_netio_t *io, const oskit_iid_t *iid, void **out_ihandle)
        !           251: {
        !           252:   device_t dev = recv_netio_device (io);
        !           253: 
        !           254:   if (memcmp(iid, &oskit_iunknown_iid, sizeof(*iid)) == 0 ||
        !           255:       memcmp(iid, &oskit_netio_iid, sizeof(*iid)) == 0) {
        !           256:     *out_ihandle = &dev->com.net.recvi;
        !           257:     device_reference (dev);
        !           258:     return 0;
        !           259:   }
        !           260: 
        !           261:   *out_ihandle = 0;
        !           262:   return OSKIT_E_NOINTERFACE;
        !           263: }
        !           264: 
        !           265: static OSKIT_COMDECL_U
        !           266: net_addref(oskit_netio_t *io)
        !           267: {
        !           268:   device_t dev = recv_netio_device (io);
        !           269:   device_reference (dev);
        !           270:   return dev->ref_count;
        !           271: }
        !           272: 
        !           273: static OSKIT_COMDECL_U
        !           274: net_release(oskit_netio_t *io)
        !           275: {
        !           276:   device_t dev = recv_netio_device (io);
        !           277:   oskit_u32_t n = dev->ref_count - 1;
        !           278:   device_deallocate (dev);
        !           279:   return n;
        !           280: }
        !           281: 
        !           282: static OSKIT_COMDECL
        !           283: net_push(oskit_netio_t *ioi, oskit_bufio_t *b, oskit_size_t pkt_size)
        !           284: {
        !           285:   device_t dev = recv_netio_device (ioi);
        !           286:   ipc_kmsg_t kmsg;
        !           287:   struct ether_header *eh;
        !           288:   struct packet_header *ph;
        !           289:   oskit_error_t rc;
        !           290:   oskit_size_t n;
        !           291: 
        !           292:   /* Allocate a kernel message buffer.  */
        !           293:   kmsg = net_kmsg_get ();
        !           294:   if (!kmsg)
        !           295:     /* No buffer, drop packet.  */
        !           296:     return 0;
        !           297: 
        !           298:   /* Copy packet into message buffer.  */
        !           299:   eh = (struct ether_header *) (net_kmsg (kmsg)->header);
        !           300:   ph = (struct packet_header *) (net_kmsg (kmsg)->packet);
        !           301: 
        !           302:   rc = oskit_bufio_read (b, eh, 0, sizeof (struct ether_header), &n);
        !           303:   if (rc || n != sizeof (struct ether_header))
        !           304:     panic("oskit_bufio_read: %x\n", rc);
        !           305:   rc = oskit_bufio_read (b, ph + 1, sizeof (struct ether_header),
        !           306:                         pkt_size - sizeof (struct ether_header), &n);
        !           307:   if (rc || n != pkt_size - sizeof (struct ether_header))
        !           308:     panic("oskit_bufio_read: %x\n", rc);
        !           309: 
        !           310:   ph->type = eh->ether_type;
        !           311:   ph->length = (sizeof (struct packet_header)
        !           312:                + pkt_size - sizeof (struct ether_header));
        !           313: 
        !           314:   /* Pass packet up to the microkernel.  */
        !           315:   net_packet (&dev->com.net.ifnet, kmsg, ph->length, ethernet_priority (kmsg));
        !           316: 
        !           317:   return 0;
        !           318: }
        !           319: 
        !           320: static struct oskit_netio_ops recv_netio_ops =
        !           321: { net_query, net_addref, net_release, net_push };
        !           322: 
        !           323: 
        !           324: oskit_error_t
        !           325: ds_netdev_open (device_t dev, oskit_netdev_t *netdev)
        !           326: {
        !           327:   oskit_error_t rc;
        !           328:   struct ifnet *const ifp = &dev->com.net.ifnet;
        !           329: 
        !           330:   if_init_queues (ifp);
        !           331: 
        !           332:   dev->com.net.recvi.ops = &recv_netio_ops;
        !           333: 
        !           334:   rc = oskit_netdev_open (netdev, 0, &dev->com.net.recvi, &dev->com.net.sendi);
        !           335: 
        !           336:   return rc;
        !           337: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.