# This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2005/02/01 13:57:41-05:00 katzj@xxxxxxxxxx # Hook up netfront devices to x bus. # # linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c # 2005/02/01 13:57:39-05:00 katzj@xxxxxxxxxx +41 -27 # Register netfront device with virtual bus. Hook everything up so that # network devices show up under /sys/bus/x/devices with driver links, etc # # ChangeSet # 2005/02/01 13:56:13-05:00 katzj@xxxxxxxxxx # Register block frontend with xbus # # linux-2.6.10-xen-sparse/drivers/xen/blkfront/blkfront.c # 2005/02/01 13:56:12-05:00 katzj@xxxxxxxxxx +10 -1 # Basic registration with xbus # # ChangeSet # 2005/02/01 13:53:31-05:00 katzj@xxxxxxxxxx # First pass at creating xbus virtual bus for Xen devices to sit # on. Heavily inspired by the vio code for ppc64. # # Lets devices appear under /sys/bus/x # # linux-2.6.10-xen-sparse/include/asm-xen/xbus.h # 2005/02/01 13:53:22-05:00 katzj@xxxxxxxxxx +45 -0 # # linux-2.6.10-xen-sparse/arch/xen/kernel/xbus.c # 2005/02/01 13:53:22-05:00 katzj@xxxxxxxxxx +201 -0 # # linux-2.6.10-xen-sparse/include/asm-xen/xbus.h # 2005/02/01 13:53:22-05:00 katzj@xxxxxxxxxx +0 -0 # BitKeeper file /home/katzj/cvs/xen/xen-katzj/linux-2.6.10-xen-sparse/include/asm-xen/xbus.h # # linux-2.6.10-xen-sparse/arch/xen/kernel/xbus.c # 2005/02/01 13:53:22-05:00 katzj@xxxxxxxxxx +0 -0 # BitKeeper file /home/katzj/cvs/xen/xen-katzj/linux-2.6.10-xen-sparse/arch/xen/kernel/xbus.c # # linux-2.6.10-xen-sparse/arch/xen/kernel/Makefile # 2005/02/01 13:53:22-05:00 katzj@xxxxxxxxxx +1 -1 # Add build of xbus # diff -Nru a/linux-2.6.10-xen-sparse/arch/xen/kernel/Makefile b/linux-2.6.10-xen-sparse/arch/xen/kernel/Makefile --- a/linux-2.6.10-xen-sparse/arch/xen/kernel/Makefile 2005-02-01 14:50:53 -05:00 +++ b/linux-2.6.10-xen-sparse/arch/xen/kernel/Makefile 2005-02-01 14:50:53 -05:00 @@ -12,4 +12,4 @@ extra-y += vmlinux.lds obj-y := ctrl_if.o evtchn.o fixup.o reboot.o xen_proc.o \ - gnttab.o skbuff.o devmem.o smp.o + gnttab.o skbuff.o devmem.o smp.o xbus.o diff -Nru a/linux-2.6.10-xen-sparse/arch/xen/kernel/xbus.c b/linux-2.6.10-xen-sparse/arch/xen/kernel/xbus.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/linux-2.6.10-xen-sparse/arch/xen/kernel/xbus.c 2005-02-01 14:50:53 -05:00 @@ -0,0 +1,201 @@ +/* + * X IO Bus for Xen + * + * Heavily based on arch/ppc64/kernel/vio.c + * + * Copyright (c) 2005 Red Hat, Inc. + * Jeremy Katz + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static struct xdev *xbus_dev; + +static int xbus_probe(struct device *dev) +{ + struct xdev *xdev = to_xdev(dev); + struct xdriver *xdrv = to_xdriver(dev->driver); + + if (!xdrv->probe) + return -ENODEV; + + /* match the device */ + return xdrv->probe(xdev, xdev->type); +} + +static int xbus_match(struct device *dev, struct device_driver *drv) +{ + const struct xdev *xdev = to_xdev(dev); + struct xdriver *xdrv = to_xdriver(drv); + + return !strcmp(xdrv->type, xdev->type); +} + +/** + * x_register_driver: - Register a new driver + * @drv: The xdriver structure to be registered. + */ +int x_register_driver(struct xdriver *xdrv) +{ + printk(KERN_DEBUG "%s: driver %s registering\n", __FUNCTION__, + xdrv->name); + + /* fill in 'struct driver' fields */ + xdrv->driver.name = xdrv->name; + xdrv->driver.bus = &xbus_type; + xdrv->driver.probe = &xbus_probe; + xdrv->driver.remove = NULL; + + return driver_register(&xdrv->driver); +} +EXPORT_SYMBOL(x_register_driver); + +static void __devinit xdev_release(struct device *dev) +{ + kfree(to_xdev(dev)); +} + +void __devinit x_unregister_device(struct xdev *dev) +{ + device_unregister(&dev->dev); +} +EXPORT_SYMBOL(x_unregister_device); + +static struct xdev *__init x_register_device (char *type, unsigned int handle) { + struct xdev *dev; + int err; + + dev = kmalloc(sizeof(struct xdev), GFP_KERNEL); + if (!dev) + return NULL; + memset(dev, 0, sizeof(struct xdev)); + + snprintf(dev->dev.bus_id, BUS_ID_SIZE, "%s%d", type, handle); + dev->name = dev->dev.bus_id; + dev->type = type; + dev->handle = handle; + + /* init generic struct fields */ + dev->dev.parent = &xbus_dev->dev; + dev->dev.bus = &xbus_type; + dev->dev.release = xdev_release; + + /* register with device framework */ + if ((err = device_register(&dev->dev))) { + printk(KERN_ERR "%s: failed to register device %s: %d\n", + __FUNCTION__, dev->dev.bus_id, err); + return NULL; + } + + return dev; +} + +static int num_intfs = 0; + +static void count_netif_rxmsg_handler(ctrl_msg_t *msg, unsigned long id) +{ + if (msg->subtype == CMSG_NETIF_FE_INTERFACE_STATUS) { + netif_fe_interface_status_t *n; + + n = (netif_fe_interface_status_t *) &msg->msg[0]; + x_register_device("net", n->handle); + num_intfs++; + } + msg->length = 0; + ctrl_if_send_response(msg); +} + +/** + * xunregister_driver - Remove registration of driver. + * @driver: The xdriver struct to be removed form registration + */ +void x_unregister_driver(struct xdriver *xdrv) +{ + driver_unregister(&xdrv->driver); +} +EXPORT_SYMBOL(x_unregister_driver); + +/* FIXME: this is ugly in that we have to do the netif specific bits + * in what should be generic code. + */ +static void register_net_devs(void) +{ + int err; + ctrl_msg_t cmsg = { + .type = CMSG_NETIF_FE, + .subtype = CMSG_NETIF_FE_DRIVER_STATUS, + .length = sizeof(netif_fe_driver_status_t) + }; + int i; + netif_fe_driver_status_t *msg = (void*)cmsg.msg; + msg->status = (NETIF_DRIVER_STATUS_UP); + + (void)ctrl_if_register_receiver(CMSG_NETIF_FE, count_netif_rxmsg_handler, + CALLBACK_IN_BLOCKING_CONTEXT); + + + err = ctrl_if_send_message_block(&cmsg, NULL, 0, + TASK_UNINTERRUPTIBLE); + if (!err) { + for (i=0; i < 5; i++) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(10); + } + } + + ctrl_if_unregister_receiver(CMSG_NETIF_FE, count_netif_rxmsg_handler); + msg->status = (NETIF_DRIVER_STATUS_DOWN); + err = ctrl_if_send_message_block(&cmsg, NULL, 0, + TASK_UNINTERRUPTIBLE); + +} + +static int __init xbus_init(void) +{ + int err = 0; + + err = bus_register(&xbus_type); + if (err) { + printk(KERN_ERR "failed to register x bus\n"); + return err; + } + + xbus_dev = kmalloc(sizeof(struct xdev), GFP_KERNEL); + if (!xbus_dev) + return 1; + memset(xbus_dev, 0, sizeof(struct xdev)); + strcpy(xbus_dev->dev.bus_id, "x"); + + err = device_register(&xbus_dev->dev); + if (err) { + printk(KERN_WARNING "%s: device_register returned %i\n", + __FUNCTION__, err); + kfree(xbus_dev); + return err; + } + + register_net_devs(); + + return 0; +} + +__initcall(xbus_init); + +struct bus_type xbus_type = { + .name = "x", + .match = &xbus_match, +}; + +EXPORT_SYMBOL(xbus_type); diff -Nru a/linux-2.6.10-xen-sparse/drivers/xen/blkfront/blkfront.c b/linux-2.6.10-xen-sparse/drivers/xen/blkfront/blkfront.c --- a/linux-2.6.10-xen-sparse/drivers/xen/blkfront/blkfront.c 2005-02-01 14:50:53 -05:00 +++ b/linux-2.6.10-xen-sparse/drivers/xen/blkfront/blkfront.c 2005-02-01 14:50:53 -05:00 @@ -46,6 +46,7 @@ #include #include #include +#include typedef unsigned char byte; /* from linux/ide.h */ @@ -1350,6 +1351,14 @@ return err; } +static char blkfront_driver_name[] = "xen_blk"; +static char blkfront_driver_type[] = "blk"; + +static struct xdriver xen_blkfront_driver = { + .name = (char *)blkfront_driver_name, + .type = blkfront_driver_type, +}; + int __init xlblk_init(void) { int i; @@ -1370,7 +1379,7 @@ wait_for_blkif(); - return 0; + return x_register_driver(&xen_blkfront_driver); } void blkdev_suspend(void) diff -Nru a/linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c b/linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c --- a/linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c 2005-02-01 14:50:53 -05:00 +++ b/linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c 2005-02-01 14:50:53 -05:00 @@ -46,6 +46,7 @@ #include #include #include +#include #include #include @@ -93,7 +94,8 @@ struct net_private { struct list_head list; - struct net_device *dev; + struct net_device *netdev; + struct device *dev; struct net_device_stats stats; NETIF_RING_IDX rx_resp_cons, tx_resp_cons; @@ -175,7 +177,7 @@ { np = list_entry(ent, struct net_private, list); if ( np->handle == handle ) - return np->dev; + return np->netdev; } return NULL; } @@ -710,7 +712,7 @@ { struct net_private *np = netdev_priv(dev); np->user_state = UST_CLOSED; - netif_stop_queue(np->dev); + netif_stop_queue(dev); return 0; } @@ -856,14 +858,14 @@ /* Stop old i/f to prevent errors whilst we rebuild the state. */ spin_lock_irq(&np->tx_lock); spin_lock(&np->rx_lock); - netif_stop_queue(np->dev); + netif_stop_queue(np->netdev); /* np->backend_state = BEST_DISCONNECTED; */ spin_unlock(&np->rx_lock); spin_unlock_irq(&np->tx_lock); /* Free resources. */ if(np->tx != NULL){ - free_irq(np->irq, np->dev); + free_irq(np->irq, np->netdev); unbind_evtchn_from_irq(np->evtchn); free_page((unsigned long)np->tx); free_page((unsigned long)np->rx); @@ -936,7 +938,7 @@ vif_connect( struct net_private *np, netif_fe_interface_status_t *status) { - struct net_device *dev = np->dev; + struct net_device *dev = np->netdev; memcpy(dev->dev_addr, status->mac, ETH_ALEN); network_connect(dev, status); np->evtchn = status->evtchn; @@ -953,7 +955,7 @@ * @param val return parameter for created device * @return 0 on success, error code otherwise */ -static int create_netdev(int handle, struct net_device **val) +static struct net_device * __init create_netdev(int handle, struct device *xdev) { int i, err = 0; struct net_device *dev = NULL; @@ -995,15 +997,16 @@ printk(KERN_WARNING "%s> register_netdev err=%d\n", __FUNCTION__, err); goto exit; } - np->dev = dev; + np->dev = xdev; + np->netdev = dev; + SET_MODULE_OWNER(dev); + SET_NETDEV_DEV(dev, xdev); list_add(&np->list, &dev_list); exit: if ( (err != 0) && (dev != NULL ) ) kfree(dev); - else if ( val != NULL ) - *val = dev; - return err; + return dev; } /* Get the target interface for a status message. @@ -1036,13 +1039,6 @@ if ( status->status == NETIF_INTERFACE_STATUS_CHANGED ) goto exit; - /* It's a new interface in a good state - create it. */ - DPRINTK("> create device...\n"); - if ( (err = create_netdev(status->handle, &dev)) != 0 ) - goto exit; - - netctrl.interface_n++; - exit: if ( np != NULL ) *np = ((dev && !err) ? netdev_priv(dev) : NULL); @@ -1056,8 +1052,8 @@ int err = 0; struct net_private *np = NULL; - DPRINTK("> status=%s handle=%d\n", - status_name[status->status], status->handle); + DPRINTK("> status=%s handle=%d evtchn=%d\n", + status_name[status->status], status->handle, status->evtchn); if ( (err = target_vif(status, &np)) != 0 ) { @@ -1277,7 +1273,7 @@ list_for_each ( ent, &dev_list ) { np = list_entry(ent, struct net_private, list); - if ( np->dev == dev ) + if ( np->netdev == dev ) (void)send_fake_arp(dev); } @@ -1291,6 +1287,28 @@ .priority = 0 }; +static int xen_net_probe(struct xdev *xdev, const char * id) { + struct net_device *dev; + dev = create_netdev(xdev->handle, &xdev->dev); + if (dev == NULL) { + /* should remove the device here */ + return 1; + } + + netctrl.interface_n++; + return 0; +} + +static char netfront_driver_name[] = "xen_net"; +static char netfront_driver_type[] = "net"; + +static struct xdriver xen_netfront_driver = { + .name = (char *)netfront_driver_name, + .type = netfront_driver_type, + .probe = xen_net_probe, +}; + + static int __init netif_init(void) { int err = 0; @@ -1306,18 +1324,14 @@ (void)ctrl_if_register_receiver(CMSG_NETIF_FE, netif_ctrlif_rx, CALLBACK_IN_BLOCKING_CONTEXT); send_driver_status(1); - err = probe_interfaces(); - if ( err ) - ctrl_if_unregister_receiver(CMSG_NETIF_FE, netif_ctrlif_rx); - DPRINTK("< err=%d\n", err); - return err; + return x_register_driver(&xen_netfront_driver); } static void vif_suspend(struct net_private *np) { /* Avoid having tx/rx stuff happen until we're ready. */ - free_irq(np->irq, np->dev); + free_irq(np->irq, np->netdev); unbind_evtchn_from_irq(np->evtchn); } diff -Nru a/linux-2.6.10-xen-sparse/include/asm-xen/xbus.h b/linux-2.6.10-xen-sparse/include/asm-xen/xbus.h --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/linux-2.6.10-xen-sparse/include/asm-xen/xbus.h 2005-02-01 14:50:53 -05:00 @@ -0,0 +1,45 @@ +#ifndef _ASM_XBUS_H +#define _ASM_XBUS_H + +#include +#include + +struct xdev { + char * name; + char * type; + + unsigned int irq; + unsigned int evtchn; + unsigned int handle; + + struct device dev; +}; + +struct xdriver { + char * name; + char * type; + int (*probe) (struct xdev *dev, const char * id); + int (*remove) (struct xdev *dev); + unsigned long driver_data; + + struct device_driver driver; +}; + + +extern struct bus_type xbus_type; + +int xregister_driver(struct xdriver *xdrv); + +static inline struct xdev *to_xdev(struct device *dev) +{ + return container_of(dev, struct xdev, dev); +} + +static inline struct xdriver *to_xdriver(struct device_driver *drv) +{ + return container_of(drv, struct xdriver, driver); +} + + + +#endif