network devices to other guests via a high-performance shared-memory
interface.
-config XEN_NETDEV_TX_SHIFT
- int "Maximum simultaneous transmit requests (as a power of 2)"
- depends on XEN_NETDEV_BACKEND
- range 5 16
- default 8
- help
- The maximum number transmits the driver can hold pending, expressed
- as the exponent of a power of 2.
-
config XEN_NETDEV_PIPELINED_TRANSMITTER
bool "Pipelined transmitter (DANGEROUS)"
depends on XEN_NETDEV_BACKEND
/* VM /proc information for memory */
extern unsigned long totalram_pages;
-#ifndef MODULE
+#if !defined(MODULE) && defined(CONFIG_HIGHMEM)
extern unsigned long totalhigh_pages;
#define inc_totalhigh_pages() (totalhigh_pages++)
#define dec_totalhigh_pages() (totalhigh_pages--)
static LIST_HEAD(ballooned_pages);
/* Main work function, always executed in process context. */
-static void balloon_process(void *unused);
-static DECLARE_WORK(balloon_worker, balloon_process, NULL);
+static void balloon_process(struct work_struct *unused);
+static DECLARE_WORK(balloon_worker, balloon_process);
static struct timer_list balloon_timer;
/* When ballooning out (allocating memory to return to Xen) we don't really
* by the balloon lock), or with changes to the Xen hard limit, but we will
* recover from these in time.
*/
-static void balloon_process(void *unused)
+static void balloon_process(struct work_struct *unused)
{
int need_sleep = 0;
long credit;
goto out;
}
-void free_empty_pages_and_pagevec(struct page **pagevec, int nr_pages)
+static void _free_empty_pages_and_pagevec(struct page **pagevec, int nr_pages, int free_vec)
{
unsigned long flags;
int i;
}
balloon_unlock(flags);
- kfree(pagevec);
+ if (free_vec)
+ kfree(pagevec);
+ else
+ totalram_pages = bs.current_pages -= nr_pages;
schedule_work(&balloon_worker);
}
+void free_empty_pages_and_pagevec(struct page **pagevec, int nr_pages)
+{
+ _free_empty_pages_and_pagevec(pagevec, nr_pages, 1);
+}
+
+void free_empty_pages(struct page **pagevec, int nr_pages)
+{
+ _free_empty_pages_and_pagevec(pagevec, nr_pages, 0);
+}
+
void balloon_release_driver_page(struct page *page)
{
unsigned long flags;
#define BALLOON_SHOW(name, format, args...) \
static ssize_t show_##name(struct sys_device *dev, \
+ struct sysdev_attribute *attr, \
char *buf) \
{ \
return sprintf(buf, format, ##args); \
(bs.hard_limit!=~0UL) ? PAGES2KB(bs.hard_limit) : 0);
BALLOON_SHOW(driver_kb, "%lu\n", PAGES2KB(bs.driver_pages));
-static ssize_t show_target_kb(struct sys_device *dev, char *buf)
+static ssize_t show_target_kb(struct sys_device *dev,
+ struct sysdev_attribute *attr, char *buf)
{
return sprintf(buf, "%lu\n", PAGES2KB(bs.target_pages));
}
static ssize_t store_target_kb(struct sys_device *dev,
- const char *buf,
- size_t count)
+ struct sysdev_attribute *attr,
+ const char *buf, size_t count)
{
char memstring[64], *endchar;
unsigned long long target_bytes;
};
static struct sysdev_class balloon_sysdev_class = {
- set_kset_name(BALLOON_CLASS_NAME),
+ .name = BALLOON_CLASS_NAME,
};
static struct sys_device balloon_sysdev;
#include <linux/spinlock.h>
#include <linux/kthread.h>
+#include <linux/freezer.h>
#include <linux/list.h>
#include <linux/delay.h>
#include <xen/balloon.h>
static void plug_queue(blkif_t *blkif, struct block_device *bdev)
{
- request_queue_t *q = bdev_get_queue(bdev);
+ struct request_queue *q = bdev_get_queue(bdev);
if (q == blkif->plug)
return;
}
}
-static int end_block_io_op(struct bio *bio, unsigned int done, int error)
+static void end_block_io_op(struct bio *bio, int error)
{
- if (bio->bi_size != 0)
- return 1;
__end_block_io_op(bio->bi_private, error);
bio_put(bio);
- return error;
}
wake_up(&blkif->wq);
}
-irqreturn_t blkif_be_int(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t blkif_be_int(int irq, void *dev_id)
{
blkif_notify_work(dev_id);
return IRQ_HANDLED;
wait_queue_head_t wq;
struct task_struct *xenblkd;
unsigned int waiting_reqs;
- request_queue_t *plug;
+ struct request_queue *plug;
/* statistics */
unsigned long st_print;
void blkif_xenbus_init(void);
-irqreturn_t blkif_be_int(int irq, void *dev_id, struct pt_regs *regs);
+irqreturn_t blkif_be_int(int irq, void *dev_id);
int blkif_schedule(void *arg);
int blkback_barrier(struct xenbus_transaction xbt,
#include <xen/evtchn.h>
#include <linux/kthread.h>
-static kmem_cache_t *blkif_cachep;
+static struct kmem_cache *blkif_cachep;
blkif_t *blkif_alloc(domid_t domid)
{
void __init blkif_interface_init(void)
{
blkif_cachep = kmem_cache_create("blkif_cache", sizeof(blkif_t),
- 0, 0, NULL, NULL);
+ 0, 0, NULL);
}
static struct xenbus_driver blkback = {
.name = "vbd",
- .owner = THIS_MODULE,
.ids = blkback_ids,
.probe = blkback_probe,
.remove = blkback_remove,
static void kick_pending_request_queues(struct blkfront_info *);
-static irqreturn_t blkif_int(int irq, void *dev_id, struct pt_regs *ptregs);
-static void blkif_restart_queue(void *arg);
+static irqreturn_t blkif_int(int irq, void *dev_id);
+static void blkif_restart_queue(struct work_struct *arg);
static void blkif_recover(struct blkfront_info *);
static void blkif_completion(struct blk_shadow *);
static void blkif_free(struct blkfront_info *, int);
info->xbdev = dev;
info->vdevice = vdevice;
info->connected = BLKIF_STATE_DISCONNECTED;
- INIT_WORK(&info->work, blkif_restart_queue, (void *)info);
+ INIT_WORK(&info->work, blkif_restart_queue);
for (i = 0; i < BLK_RING_SIZE; i++)
info->shadow[i].req.id = i+1;
info->ring_ref = err;
err = bind_listening_port_to_irqhandler(
- dev->otherend_id, blkif_int, SA_SAMPLE_RANDOM, "blkif", info);
+ dev->otherend_id, blkif_int, IRQF_SAMPLE_RANDOM, "blkif", info);
if (err <= 0) {
xenbus_dev_fatal(dev, err,
"bind_listening_port_to_irqhandler");
}
}
-static void blkif_restart_queue(void *arg)
+static void blkif_restart_queue(struct work_struct *arg)
{
- struct blkfront_info *info = (struct blkfront_info *)arg;
+ struct blkfront_info *info = container_of(arg, struct blkfront_info, work);
spin_lock_irq(&blkif_io_lock);
if (info->connected == BLKIF_STATE_CONNECTED)
kick_pending_request_queues(info);
struct blkfront_info *info = req->rq_disk->private_data;
unsigned long buffer_mfn;
blkif_request_t *ring_req;
- struct bio *bio;
struct bio_vec *bvec;
- int idx;
+ struct req_iterator iter;
unsigned long id;
unsigned int fsect, lsect;
int ref;
ring_req->operation = BLKIF_OP_WRITE_BARRIER;
ring_req->nr_segments = 0;
- rq_for_each_bio (bio, req) {
- bio_for_each_segment (bvec, bio, idx) {
+ rq_for_each_segment(bvec, req, iter) {
BUG_ON(ring_req->nr_segments
== BLKIF_MAX_SEGMENTS_PER_REQUEST);
buffer_mfn = page_to_phys(bvec->bv_page) >> PAGE_SHIFT;
.last_sect = lsect };
ring_req->nr_segments++;
- }
}
info->ring.req_prod_pvt++;
* do_blkif_request
* read a block; request is in a request queue
*/
-void do_blkif_request(request_queue_t *rq)
+void do_blkif_request(struct request_queue *rq)
{
struct blkfront_info *info = NULL;
struct request *req;
}
-static irqreturn_t blkif_int(int irq, void *dev_id, struct pt_regs *ptregs)
+static irqreturn_t blkif_int(int irq, void *dev_id)
{
struct request *req;
blkif_response_t *bret;
RING_IDX i, rp;
unsigned long flags;
struct blkfront_info *info = (struct blkfront_info *)dev_id;
- int uptodate;
spin_lock_irqsave(&blkif_io_lock, flags);
ADD_ID_TO_FREELIST(info, id);
- uptodate = (bret->status == BLKIF_RSP_OKAY);
+ ret = bret->status == BLKIF_RSP_OKAY ? 0 : -EIO;
switch (bret->operation) {
case BLKIF_OP_WRITE_BARRIER:
if (unlikely(bret->status == BLKIF_RSP_EOPNOTSUPP)) {
printk("blkfront: %s: write barrier op failed\n",
info->gd->disk_name);
- uptodate = -EOPNOTSUPP;
+ ret = -EOPNOTSUPP;
info->feature_barrier = 0;
xlvbd_barrier(info);
}
DPRINTK("Bad return from blkdev data "
"request: %x\n", bret->status);
- ret = end_that_request_first(req, uptodate,
- req->hard_nr_sectors);
+ ret = __blk_end_request(req, ret, blk_rq_bytes(req));
BUG_ON(ret);
- end_that_request_last(req, uptodate);
break;
default:
BUG();
static struct xenbus_driver blkfront = {
.name = "vbd",
- .owner = THIS_MODULE,
.ids = blkfront_ids,
.probe = blkfront_probe,
.remove = blkfront_remove,
blkif_front_ring_t ring;
unsigned int irq;
struct xlbd_major_info *mi;
- request_queue_t *rq;
+ struct request_queue *rq;
struct work_struct work;
struct gnttab_free_callback callback;
struct blk_shadow shadow[BLK_RING_SIZE];
extern int blkif_getgeo(struct block_device *, struct hd_geometry *);
extern int blkif_check(dev_t dev);
extern int blkif_revalidate(dev_t dev);
-extern void do_blkif_request (request_queue_t *rq);
+extern void do_blkif_request (struct request_queue *rq);
/* Virtual block-device subsystem. */
/* Note that xlvbd_add doesn't call add_disk for you: you're expected
static int
xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size)
{
- request_queue_t *rq;
+ struct request_queue *rq;
rq = blk_init_queue(do_blkif_request, &blkif_io_lock);
if (rq == NULL)
#include <linux/spinlock.h>
#include <linux/kthread.h>
+#include <linux/freezer.h>
#include <linux/list.h>
#include <asm/hypervisor.h>
#include "common.h"
#include <linux/gfp.h>
#include <linux/poll.h>
#include <linux/delay.h>
+#include <linux/nsproxy.h>
#include <asm/tlbflush.h>
#define MAX_TAP_DEV 256 /*the maximum number of tapdisk ring devices */
unsigned long mode; /*current switching mode */
int minor; /*Minor number for tapdisk device */
pid_t pid; /*tapdisk process id */
+ struct pid_namespace *pid_ns; /*... and its corresponding namespace */
enum { RUNNING, CLEANSHUTDOWN } status; /*Detect a clean userspace
shutdown */
unsigned long *idx_map; /*Record the user ring id to kern
* BLKTAP VM OPS
*/
-static struct page *blktap_nopage(struct vm_area_struct *vma,
- unsigned long address,
- int *type)
+static int blktap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
/*
* if the page has not been mapped in by the driver then return
- * NOPAGE_SIGBUS to the domain.
+ * VM_FAULT_SIGBUS to the domain.
*/
- return NOPAGE_SIGBUS;
+ return VM_FAULT_SIGBUS;
}
static pte_t blktap_clear_pte(struct vm_area_struct *vma,
}
struct vm_operations_struct blktap_vm_ops = {
- nopage: blktap_nopage,
+ fault: blktap_fault,
zap_pte: blktap_clear_pte,
};
tapfds[minor] = info;
if ((class = get_xen_class()) != NULL)
- class_device_create(class, NULL,
- MKDEV(blktap_major, minor), NULL,
- "blktap%d", minor);
+ device_create(class, NULL, MKDEV(blktap_major, minor),
+ NULL, "blktap%d", minor);
}
out:
return;
if (info->pid > 0) {
- ptask = find_task_by_pid(info->pid);
+ ptask = find_task_by_pid_ns(info->pid, info->pid_ns);
if (ptask)
info->status = CLEANSHUTDOWN;
}
{
if (info) {
info->pid = (pid_t)arg;
- DPRINTK("blktap: pid received %d\n",
- info->pid);
+ info->pid_ns = current->nsproxy->pid_ns;
+ DPRINTK("blktap: pid received %p:%d\n",
+ info->pid_ns, info->pid);
}
return 0;
}
wake_up(&blkif->wq);
}
-irqreturn_t tap_blkif_be_int(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t tap_blkif_be_int(int irq, void *dev_id)
{
blkif_notify_work(dev_id);
return IRQ_HANDLED;
* We only create the device when a request of a new device is
* made.
*/
- class_device_create(class, NULL,
- MKDEV(blktap_major, 0), NULL,
- "blktap0");
+ device_create(class, NULL, MKDEV(blktap_major, 0), NULL,
+ "blktap0");
} else {
/* this is bad, but not fatal */
WPRINTK("blktap: sysfs xen_class not created\n");
wait_queue_head_t wq;
struct task_struct *xenblkd;
unsigned int waiting_reqs;
- request_queue_t *plug;
+ struct request_queue *plug;
/* statistics */
unsigned long st_print;
void tap_blkif_xenbus_init(void);
-irqreturn_t tap_blkif_be_int(int irq, void *dev_id, struct pt_regs *regs);
+irqreturn_t tap_blkif_be_int(int irq, void *dev_id);
int tap_blkif_schedule(void *arg);
int dom_to_devid(domid_t domid, int xenbus_id, blkif_t *blkif);
#include "common.h"
#include <xen/evtchn.h>
-static kmem_cache_t *blkif_cachep;
+static struct kmem_cache *blkif_cachep;
blkif_t *tap_alloc_blkif(domid_t domid)
{
void __init tap_blkif_interface_init(void)
{
blkif_cachep = kmem_cache_create("blktapif_cache", sizeof(blkif_t),
- 0, 0, NULL, NULL);
+ 0, 0, NULL);
}
static struct xenbus_driver blktap = {
.name = "tap",
- .owner = THIS_MODULE,
.ids = blktap_ids,
.probe = blktap_probe,
.remove = blktap_remove,
#define XEN_HVC_MAJOR 229
#define XEN_HVC_MINOR 0
+void xencons_early_setup(void)
+{
+ extern int console_use_vt;
+
+ if (is_initial_xendomain()) {
+ xc_mode = XC_SERIAL;
+ } else {
+ xc_mode = XC_TTY;
+ console_use_vt = 0;
+ }
+}
+
static int __init xencons_setup(char *str)
{
char *q;
if (IS_ERR(eth_name)) {
/* Probably means not present */
- DPRINTK("%s: no match due to xenbus_read accel error %d\n",
+ DPRINTK("%s: no match due to xenbus_read accel error %ld\n",
__FUNCTION__, PTR_ERR(eth_name));
return 0;
} else {
int netif_be_start_xmit(struct sk_buff *skb, struct net_device *dev);
struct net_device_stats *netif_be_get_stats(struct net_device *dev);
-irqreturn_t netif_be_int(int irq, void *dev_id, struct pt_regs *regs);
+irqreturn_t netif_be_int(int irq, void *dev_id);
static inline int netbk_can_queue(struct net_device *dev)
{
struct ethtool_drvinfo *info)
{
strcpy(info->driver, "netbk");
- strcpy(info->bus_info, dev->class_dev.dev->bus_id);
+ strcpy(info->bus_info, dev->dev.parent->bus_id);
}
static const struct netif_stat {
#include <net/dst.h>
#include <net/xfrm.h> /* secpath_reset() */
#include <asm/hypervisor.h> /* is_initial_xendomain() */
+#include <../net/core/kmap_skb.h> /* k{,un}map_skb_frag() */
static int nloopbacks = -1;
module_param(nloopbacks, int, 0);
np->stats.rx_bytes += skb->len;
np->stats.rx_packets++;
- if (skb->ip_summed == CHECKSUM_HW) {
+ if (skb->ip_summed == CHECKSUM_PARTIAL) {
/* Defer checksum calculation. */
skb->proto_csum_blank = 1;
/* Must be a local packet: assert its integrity. */
char dev_name[IFNAMSIZ];
sprintf(dev_name, "vif0.%d", i);
- dev1 = dev_get_by_name(dev_name);
+ dev1 = dev_get_by_name(&init_net, dev_name);
sprintf(dev_name, "veth%d", i);
- dev2 = dev_get_by_name(dev_name);
+ dev2 = dev_get_by_name(&init_net, dev_name);
if (dev1 && dev2) {
unregister_netdev(dev2);
unregister_netdev(dev1);
goto err;
skb_reserve(nskb, 16 + NET_IP_ALIGN);
- headlen = nskb->end - nskb->data;
+ headlen = skb_end_pointer(nskb) - nskb->data;
if (headlen > skb_headlen(skb))
headlen = skb_headlen(skb);
ret = skb_copy_bits(skb, 0, __skb_put(nskb, headlen), headlen);
len -= copy;
}
+#ifdef NET_SKBUFF_DATA_USES_OFFSET
+ offset = 0;
+#else
offset = nskb->data - skb->data;
+#endif
- nskb->h.raw = skb->h.raw + offset;
- nskb->nh.raw = skb->nh.raw + offset;
- nskb->mac.raw = skb->mac.raw + offset;
+ nskb->transport_header = skb->transport_header + offset;
+ nskb->network_header = skb->network_header + offset;
+ nskb->mac_header = skb->mac_header + offset;
return nskb;
id = meta[npo.meta_cons].id;
flags = nr_frags ? NETRXF_more_data : 0;
- if (skb->ip_summed == CHECKSUM_HW) /* local packet? */
+ if (skb->ip_summed == CHECKSUM_PARTIAL) /* local packet? */
flags |= NETRXF_csum_blank | NETRXF_data_validated;
else if (skb->proto_data_valid) /* remote but checksummed? */
flags |= NETRXF_data_validated;
netif_idx_release(idx);
}
-irqreturn_t netif_be_int(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t netif_be_int(int irq, void *dev_id)
{
netif_t *netif = dev_id;
* and vif variables to the environment, for the benefit of the vif-* hotplug
* scripts.
*/
-static int netback_uevent(struct xenbus_device *xdev, char **envp,
- int num_envp, char *buffer, int buffer_size)
+static int netback_uevent(struct xenbus_device *xdev, struct kobj_uevent_env *env)
{
struct backend_info *be = xdev->dev.driver_data;
netif_t *netif = be->netif;
- int i = 0, length = 0;
char *val;
DPRINTK("netback_uevent");
return err;
}
else {
- add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
- &length, "script=%s", val);
+ add_uevent_var(env, "script=%s", val);
kfree(val);
}
- add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
- "vif=%s", netif->dev->name);
-
- envp[i] = NULL;
+ add_uevent_var(env, "vif=%s", netif->dev->name);
return 0;
}
static struct xenbus_driver netback = {
.name = "vif",
- .owner = THIS_MODULE,
.ids = netback_ids,
.probe = netback_probe,
.remove = netback_remove,
* IN THE SOFTWARE.
*/
+#include <linux/version.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/list.h>
DPRINTK("%p\n",vif_state);
/* Make sure there are no data path operations going on */
- netif_poll_disable(vif_state->np->netdev);
+ napi_disable(&vif_state->np->napi);
netif_tx_lock_bh(vif_state->np->netdev);
vif_state->hooks = vif_state->np->accelerator->hooks;
netif_tx_unlock_bh(vif_state->np->netdev);
- netif_poll_enable(vif_state->np->netdev);
+ napi_enable(&vif_state->np->napi);
}
struct netfront_accel_vif_state *vif_state)
{
/* Make sure there are no data path operations going on */
- netif_poll_disable(vif_state->np->netdev);
+ napi_disable(&vif_state->np->napi);
netif_tx_lock_bh(vif_state->np->netdev);
/*
vif_state->hooks = NULL;
netif_tx_unlock_bh(vif_state->np->netdev);
- netif_poll_enable(vif_state->np->netdev);
+ napi_enable(&vif_state->np->napi);
}
{
return skb_is_gso(skb) &&
(!skb_gso_ok(skb, dev->features) ||
- unlikely(skb->ip_summed != CHECKSUM_HW));
+ unlikely(skb->ip_summed != CHECKSUM_PARTIAL));
}
#else
#define HAVE_GSO 0
static void network_alloc_rx_buffers(struct net_device *);
static void send_fake_arp(struct net_device *);
-static irqreturn_t netif_int(int irq, void *dev_id, struct pt_regs *ptregs);
+static irqreturn_t netif_int(int irq, void *dev_id);
#ifdef CONFIG_SYSFS
static int xennet_sysfs_addif(struct net_device *netdev);
memcpy(netdev->dev_addr, info->mac, ETH_ALEN);
err = bind_listening_port_to_irqhandler(
- dev->otherend_id, netif_int, SA_SAMPLE_RANDOM, netdev->name,
+ dev->otherend_id, netif_int, IRQF_SAMPLE_RANDOM, netdev->name,
netdev);
if (err < 0)
goto fail;
struct netfront_info *np = netdev_priv(dev);
memset(&np->stats, 0, sizeof(np->stats));
+ napi_enable(&np->napi);
spin_lock_bh(&np->rx_lock);
if (netfront_carrier_ok(np)) {
if (RING_HAS_UNCONSUMED_RESPONSES(&np->rx)){
netfront_accelerator_call_stop_napi_irq(np, dev);
- netif_rx_schedule(dev);
+ netif_rx_schedule(dev, &np->napi);
}
}
spin_unlock_bh(&np->rx_lock);
- network_maybe_wake_tx(dev);
+ netif_start_queue(dev);
return 0;
}
netfront_accelerator_call_stop_napi_irq(np, dev);
- netif_rx_schedule(dev);
+ netif_rx_schedule(dev, &np->napi);
}
static void network_alloc_rx_buffers(struct net_device *dev)
tx->flags = 0;
extra = NULL;
- if (skb->ip_summed == CHECKSUM_HW) /* local packet? */
+ if (skb->ip_summed == CHECKSUM_PARTIAL) /* local packet? */
tx->flags |= NETTXF_csum_blank | NETTXF_data_validated;
#ifdef CONFIG_XEN
if (skb->proto_data_valid) /* remote but checksummed? */
return 0;
}
-static irqreturn_t netif_int(int irq, void *dev_id, struct pt_regs *ptregs)
+static irqreturn_t netif_int(int irq, void *dev_id)
{
struct net_device *dev = dev_id;
struct netfront_info *np = netdev_priv(dev);
if (RING_HAS_UNCONSUMED_RESPONSES(&np->rx)) {
netfront_accelerator_call_stop_napi_irq(np, dev);
- netif_rx_schedule(dev);
+ netif_rx_schedule(dev, &np->napi);
dev->last_rx = jiffies;
}
}
#endif
}
-static int netif_poll(struct net_device *dev, int *pbudget)
+static int netif_poll(struct napi_struct *napi, int budget)
{
- struct netfront_info *np = netdev_priv(dev);
+ struct netfront_info *np = container_of(napi, struct netfront_info, napi);
+ struct net_device *dev = np->netdev;
struct sk_buff *skb;
struct netfront_rx_info rinfo;
struct netif_rx_response *rx = &rinfo.rx;
struct netif_extra_info *extras = rinfo.extras;
RING_IDX i, rp;
struct multicall_entry *mcl;
- int work_done, budget, more_to_do = 1, accel_more_to_do = 1;
+ int work_done, more_to_do = 1, accel_more_to_do = 1;
struct sk_buff_head rxq;
struct sk_buff_head errq;
struct sk_buff_head tmpq;
skb_queue_head_init(&errq);
skb_queue_head_init(&tmpq);
- if ((budget = *pbudget) > dev->quota)
- budget = dev->quota;
rp = np->rx.sring->rsp_prod;
rmb(); /* Ensure we see queued responses up to 'rp'. */
}
}
- while ((skb = __skb_dequeue(&errq)))
- kfree_skb(skb);
+ __skb_queue_purge(&errq);
while ((skb = __skb_dequeue(&rxq)) != NULL) {
struct page *page = NETFRONT_SKB_CB(skb)->page;
accel_more_to_do = 0;
}
- *pbudget -= work_done;
- dev->quota -= work_done;
-
if (work_done < budget) {
local_irq_save(flags);
}
if (!more_to_do && !accel_more_to_do)
- __netif_rx_complete(dev);
+ __netif_rx_complete(dev, napi);
local_irq_restore(flags);
}
{
struct netfront_info *np = netdev_priv(dev);
netif_stop_queue(np->netdev);
+ napi_disable(&np->napi);
return 0;
}
};
#ifdef CONFIG_SYSFS
-static ssize_t show_rxbuf_min(struct class_device *cd, char *buf)
+static ssize_t show_rxbuf_min(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
- struct net_device *netdev = container_of(cd, struct net_device,
- class_dev);
- struct netfront_info *info = netdev_priv(netdev);
+ struct netfront_info *info = netdev_priv(to_net_dev(dev));
return sprintf(buf, "%u\n", info->rx_min_target);
}
-static ssize_t store_rxbuf_min(struct class_device *cd,
+static ssize_t store_rxbuf_min(struct device *dev,
+ struct device_attribute *attr,
const char *buf, size_t len)
{
- struct net_device *netdev = container_of(cd, struct net_device,
- class_dev);
+ struct net_device *netdev = to_net_dev(dev);
struct netfront_info *np = netdev_priv(netdev);
char *endp;
unsigned long target;
return len;
}
-static ssize_t show_rxbuf_max(struct class_device *cd, char *buf)
+static ssize_t show_rxbuf_max(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
- struct net_device *netdev = container_of(cd, struct net_device,
- class_dev);
- struct netfront_info *info = netdev_priv(netdev);
+ struct netfront_info *info = netdev_priv(to_net_dev(dev));
return sprintf(buf, "%u\n", info->rx_max_target);
}
-static ssize_t store_rxbuf_max(struct class_device *cd,
+static ssize_t store_rxbuf_max(struct device *dev,
+ struct device_attribute *attr,
const char *buf, size_t len)
{
- struct net_device *netdev = container_of(cd, struct net_device,
- class_dev);
+ struct net_device *netdev = to_net_dev(dev);
struct netfront_info *np = netdev_priv(netdev);
char *endp;
unsigned long target;
return len;
}
-static ssize_t show_rxbuf_cur(struct class_device *cd, char *buf)
+static ssize_t show_rxbuf_cur(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
- struct net_device *netdev = container_of(cd, struct net_device,
- class_dev);
- struct netfront_info *info = netdev_priv(netdev);
+ struct netfront_info *info = netdev_priv(to_net_dev(dev));
return sprintf(buf, "%u\n", info->rx_target);
}
-static const struct class_device_attribute xennet_attrs[] = {
+static struct device_attribute xennet_attrs[] = {
__ATTR(rxbuf_min, S_IRUGO|S_IWUSR, show_rxbuf_min, store_rxbuf_min),
__ATTR(rxbuf_max, S_IRUGO|S_IWUSR, show_rxbuf_max, store_rxbuf_max),
__ATTR(rxbuf_cur, S_IRUGO, show_rxbuf_cur, NULL),
int error = 0;
for (i = 0; i < ARRAY_SIZE(xennet_attrs); i++) {
- error = class_device_create_file(&netdev->class_dev,
- &xennet_attrs[i]);
+ error = device_create_file(&netdev->dev,
+ &xennet_attrs[i]);
if (error)
goto fail;
}
fail:
while (--i >= 0)
- class_device_remove_file(&netdev->class_dev,
- &xennet_attrs[i]);
+ device_remove_file(&netdev->dev, &xennet_attrs[i]);
return error;
}
{
int i;
- for (i = 0; i < ARRAY_SIZE(xennet_attrs); i++) {
- class_device_remove_file(&netdev->class_dev,
- &xennet_attrs[i]);
- }
+ for (i = 0; i < ARRAY_SIZE(xennet_attrs); i++)
+ device_remove_file(&netdev->dev, &xennet_attrs[i]);
}
#endif /* CONFIG_SYSFS */
netdev->hard_start_xmit = network_start_xmit;
netdev->stop = network_close;
netdev->get_stats = network_get_stats;
- netdev->poll = netif_poll;
+ netif_napi_add(netdev, &np->napi, netif_poll, 64);
netdev->set_multicast_list = network_set_multicast_list;
netdev->uninit = netif_uninit;
netdev->set_mac_address = xennet_set_mac_address;
netdev->change_mtu = xennet_change_mtu;
- netdev->weight = 64;
netdev->features = NETIF_F_IP_CSUM;
SET_ETHTOOL_OPS(netdev, &network_ethtool_ops);
- SET_MODULE_OWNER(netdev);
SET_NETDEV_DEV(netdev, &dev->dev);
np->netdev = netdev;
static struct xenbus_driver netfront_driver = {
.name = "vif",
- .owner = THIS_MODULE,
.ids = netfront_ids,
.probe = netfront_probe,
.remove = __devexit_p(netfront_remove),
spinlock_t tx_lock;
spinlock_t rx_lock;
+ struct napi_struct napi;
+
unsigned int irq;
unsigned int copying_receiver;
unsigned int carrier;
{
int err;
- if (!dev->is_enabled && is_enable_cmd(value)) {
+ if (!atomic_read(&dev->enable_cnt) && is_enable_cmd(value)) {
if (unlikely(verbose_request))
printk(KERN_DEBUG "pciback: %s: enable\n",
pci_name(dev));
err = pci_enable_device(dev);
if (err)
return err;
- } else if (dev->is_enabled && !is_enable_cmd(value)) {
+ } else if (atomic_read(&dev->enable_cnt) && !is_enable_cmd(value)) {
if (unlikely(verbose_request))
printk(KERN_DEBUG "pciback: %s: disable\n",
pci_name(dev));
void pciback_release_devices(struct pciback_device *pdev);
/* Handles events from front-end */
-irqreturn_t pciback_handle_event(int irq, void *dev_id, struct pt_regs *regs);
-void pciback_do_op(void *data);
+irqreturn_t pciback_handle_event(int irq, void *dev_id);
+void pciback_do_op(struct work_struct *work);
int pciback_xenbus_register(void);
void pciback_xenbus_unregister(void);
pci_write_config_word(dev, PCI_COMMAND, 0);
- dev->is_enabled = 0;
+ atomic_set(&dev->enable_cnt, 0);
dev->is_busmaster = 0;
} else {
pci_read_config_word(dev, PCI_COMMAND, &cmd);
* context because some of the pci_* functions can sleep (mostly due to ACPI
* use of semaphores). This function is intended to be called from a work
* queue in process context taking a struct pciback_device as a parameter */
-void pciback_do_op(void *data)
+void pciback_do_op(struct work_struct *work)
{
- struct pciback_device *pdev = data;
+ struct pciback_device *pdev = container_of(work, struct pciback_device, op_work);
struct pci_dev *dev;
struct xen_pci_op *op = &pdev->sh_info->op;
test_and_schedule_op(pdev);
}
-irqreturn_t pciback_handle_event(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t pciback_handle_event(int irq, void *dev_id)
{
struct pciback_device *pdev = dev_id;
pdev->evtchn_irq = INVALID_EVTCHN_IRQ;
pdev->be_watching = 0;
- INIT_WORK(&pdev->op_work, pciback_do_op, pdev);
+ INIT_WORK(&pdev->op_work, pciback_do_op);
if (pciback_init_devices(pdev)) {
kfree(pdev);
/* If the driver domain started an op, make sure we complete it or
* delete it before releasing the shared memory */
- cancel_delayed_work(&pdev->op_work);
flush_scheduled_work();
if (pdev->sh_info != NULL) {
err = bind_interdomain_evtchn_to_irqhandler(
pdev->xdev->otherend_id, remote_evtchn, pciback_handle_event,
- SA_SAMPLE_RANDOM, "pciback", pdev);
+ IRQF_SAMPLE_RANDOM, "pciback", pdev);
if (err < 0) {
xenbus_dev_fatal(pdev->xdev, err,
"Error binding event channel to IRQ");
static struct xenbus_driver xenbus_pciback_driver = {
.name = "pciback",
- .owner = THIS_MODULE,
.ids = xenpci_ids,
.probe = pciback_xenbus_probe,
.remove = pciback_xenbus_remove,
* Authors: Jimi Xenidis <jimix@watson.ibm.com>
*/
-#include <linux/config.h>
#include <linux/compat.h>
#include <linux/ioctl.h>
#include <linux/syscalls.h>
}
#ifndef HAVE_ARCH_PRIVCMD_MMAP
-static struct page *privcmd_nopage(struct vm_area_struct *vma,
- unsigned long address,
- int *type)
+static int privcmd_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
- return NOPAGE_SIGBUS;
+ return VM_FAULT_SIGBUS;
}
static struct vm_operations_struct privcmd_vm_ops = {
- .nopage = privcmd_nopage
+ .fault = privcmd_fault
};
static int privcmd_mmap(struct file * file, struct vm_area_struct * vma)
return -ENOSYS;
/* DONTCOPY is essential for Xen as copy_page_range is broken. */
- vma->vm_flags |= VM_RESERVED | VM_IO | VM_DONTCOPY;
+ vma->vm_flags |= VM_RESERVED | VM_IO | VM_PFNMAP | VM_DONTCOPY;
vma->vm_ops = &privcmd_vm_ops;
vma->vm_private_data = NULL;
#ifndef NETBACK_ACCEL_H
#define NETBACK_ACCEL_H
+#include <linux/version.h>
#include <linux/slab.h>
#include <linux/ip.h>
#include <linux/tcp.h>
unsigned long flags;
cuckoo_hash_mac_key key = cuckoo_mac_to_key(mac);
struct port_fwd *fwd_set = (struct port_fwd *)fwd_priv;
+ DECLARE_MAC_BUF(buf);
BUG_ON(fwd_priv == NULL);
- DPRINTK("Adding mac " MAC_FMT "\n", MAC_ARG(mac));
+ DPRINTK("Adding mac %s\n", print_mac(buf, mac));
spin_lock_irqsave(&fwd_set->fwd_lock, flags);
if (cuckoo_hash_lookup(&fwd_set->fwd_hash_table,
(cuckoo_hash_key *)(&key), &rc) != 0) {
spin_unlock_irqrestore(&fwd_set->fwd_lock, flags);
- EPRINTK("MAC address " MAC_FMT " already accelerated.\n",
- MAC_ARG(mac));
+ EPRINTK("MAC address %s already accelerated.\n",
+ print_mac(buf, mac));
return -EEXIST;
}
unsigned long flags;
cuckoo_hash_mac_key key = cuckoo_mac_to_key(mac);
struct port_fwd *fwd_set = (struct port_fwd *)fwd_priv;
+ DECLARE_MAC_BUF(buf);
- DPRINTK("Removing mac " MAC_FMT "\n", MAC_ARG(mac));
+ DPRINTK("Removing mac %s\n", print_mac(buf, mac));
BUG_ON(fwd_priv == NULL);
static inline int packet_is_arp_reply(struct sk_buff *skb)
{
return skb->protocol == ntohs(ETH_P_ARP)
- && skb->nh.arph->ar_op == ntohs(ARPOP_REPLY);
+ && arp_hdr(skb)->ar_op == ntohs(ARPOP_REPLY);
}
BUG_ON(fwd_priv == NULL);
- if (is_broadcast_ether_addr(skb->mac.raw) && packet_is_arp_reply(skb)) {
+ if (is_broadcast_ether_addr(skb_mac_header(skb))
+ && packet_is_arp_reply(skb)) {
+ DECLARE_MAC_BUF(buf);
+
/*
* update our fast path forwarding to reflect this
* gratuitous ARP
*/
- mac = skb->mac.raw+ETH_ALEN;
+ mac = skb_mac_header(skb)+ETH_ALEN;
- DPRINTK("%s: found gratuitous ARP for " MAC_FMT "\n",
- __FUNCTION__, MAC_ARG(mac));
+ DPRINTK("%s: found gratuitous ARP for %s\n",
+ __FUNCTION__, print_mac(buf, mac));
spin_lock_irqsave(&fwd_set->fwd_lock, flags);
/*
BUG_ON(port == NULL);
NETBACK_ACCEL_STATS_OP(global_stats.dl_tx_packets++);
- if (skb->mac.raw != NULL)
+ if (skb_mac_header_was_set(skb))
netback_accel_tx_packet(skb, port->fwd_priv);
else {
DPRINTK("Ignoring packet with missing mac address\n");
int i;
for (i = 0; i < EFHW_MAX_NR_DEVS; i++) {
- struct efhw_nic *nic = efrm_nic_table.nic[i];
+ struct efhw_nic *nic = efrm_nic_tablep->nic[i];
/*
* It's possible for the nic structure to have not
/* Demultiplex a message IRQ from the frontend driver. */
-static irqreturn_t msgirq_from_frontend(int irq, void *context,
- struct pt_regs *unused)
+static irqreturn_t msgirq_from_frontend(int irq, void *context)
{
struct xenbus_device *dev = context;
struct netback_accel *bend = NETBACK_ACCEL_FROM_XENBUS_DEVICE(dev);
* functionally, but we need it to pass to the bind function, and may
* get called spuriously
*/
-static irqreturn_t netirq_from_frontend(int irq, void *context,
- struct pt_regs *unused)
+static irqreturn_t netirq_from_frontend(int irq, void *context)
{
VPRINTK("netirq %d from device %s\n", irq,
((struct xenbus_device *)context)->nodename);
};
/* Resource driver structures used by other drivers as well */
-extern struct efrm_nic_table efrm_nic_table;
+extern struct efrm_nic_table *efrm_nic_tablep;
static inline void efrm_nic_table_hold(void)
{
- atomic_inc(&efrm_nic_table.ref_count);
+ atomic_inc(&efrm_nic_tablep->ref_count);
}
static inline void efrm_nic_table_rele(void)
{
- atomic_dec(&efrm_nic_table.ref_count);
+ atomic_dec(&efrm_nic_tablep->ref_count);
}
static inline int efrm_nic_table_held(void)
{
- return (atomic_read(&efrm_nic_table.ref_count) != 0);
+ return (atomic_read(&efrm_nic_tablep->ref_count) != 0);
}
/* Run code block _x multiple times with variable nic set to each
for ((_nic_i) = (efrm_nic_table_hold(), 0); \
(_nic_i) < EFHW_MAX_NR_DEVS || (efrm_nic_table_rele(), 0); \
(_nic_i)++) \
- if (((_nic) = efrm_nic_table.nic[_nic_i]))
+ if (((_nic) = efrm_nic_tablep->nic[_nic_i]))
#define EFRM_FOR_EACH_NIC_IN_SET(_set, _i, _nic) \
for ((_i) = (efrm_nic_table_hold(), 0); \
(_i) < EFHW_MAX_NR_DEVS || (efrm_nic_table_rele(), 0); \
++(_i)) \
- if (((_nic) = efrm_nic_table.nic[_i]) && \
+ if (((_nic) = efrm_nic_tablep->nic[_i]) && \
efrm_nic_set_read((_set), (_i)))
#endif /* __CI_EFRM_NIC_TABLE_H__ */
#include <xen/evtchn.h>
#include <linux/kernel.h>
+#include <linux/version.h>
#include <linux/list.h>
enum netfront_accel_post_status {
u32 ip, u16 port, u8 protocol);
/* Process an IRQ received from back end driver */
-irqreturn_t netfront_accel_msg_channel_irq_from_bend(int irq, void *context,
- struct pt_regs *unused);
-irqreturn_t netfront_accel_net_channel_irq_from_bend(int irq, void *context,
- struct pt_regs *unused);
+irqreturn_t netfront_accel_msg_channel_irq_from_bend(int irq, void *context);
+irqreturn_t netfront_accel_net_channel_irq_from_bend(int irq, void *context);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
extern void netfront_accel_msg_from_bend(struct work_struct *context);
/* Prime our interrupt */
spin_lock_irqsave(&vnic->irq_enabled_lock, flags);
if (!netfront_accel_vi_enable_interrupts(vnic)) {
+ struct netfront_info *np = netdev_priv(vnic->net_dev);
+
/* Cripes, that was quick, better pass it up */
netfront_accel_disable_net_interrupts(vnic);
vnic->irq_enabled = 0;
NETFRONT_ACCEL_STATS_OP(vnic->stats.poll_schedule_count++);
- netif_rx_schedule(vnic->net_dev);
+ netif_rx_schedule(vnic->net_dev, &np->napi);
} else {
/*
* Nothing yet, make sure we get interrupts through
static void vnic_start_fastpath(netfront_accel_vnic *vnic)
{
struct net_device *net_dev = vnic->net_dev;
+ struct netfront_info *np = netdev_priv(net_dev);
unsigned long flags;
DPRINTK("%s\n", __FUNCTION__);
vnic->tx_enabled = 1;
spin_unlock_irqrestore(&vnic->tx_lock, flags);
- netif_poll_disable(net_dev);
+ napi_disable(&np->napi);
vnic->poll_enabled = 1;
- netif_poll_enable(net_dev);
+ napi_enable(&np->napi);
vnic_start_interrupts(vnic);
}
spin_unlock_irqrestore(&vnic->tx_lock, flags1);
/* Must prevent polls and hold lock to modify poll_enabled */
- netif_poll_disable(net_dev);
+ napi_disable(&np->napi);
spin_lock_irqsave(&vnic->irq_enabled_lock, flags1);
vnic->poll_enabled = 0;
spin_unlock_irqrestore(&vnic->irq_enabled_lock, flags1);
- netif_poll_enable(net_dev);
+ napi_enable(&np->napi);
}
cuckoo_hash_mac_key key;
if (msg->u.localmac.flags & NET_ACCEL_MSG_ADD) {
- DPRINTK("MAC has moved, could be local: " MAC_FMT "\n",
- MAC_ARG(msg->u.localmac.mac));
+ DECLARE_MAC_BUF(buf);
+
+ DPRINTK("MAC has moved, could be local: %s\n",
+ print_mac(buf, msg->u.localmac.mac));
key = cuckoo_mac_to_key(msg->u.localmac.mac);
spin_lock_irqsave(&vnic->table_lock, flags);
/* Try to remove it, not a big deal if not there */
}
-irqreturn_t netfront_accel_msg_channel_irq_from_bend(int irq, void *context,
- struct pt_regs *unused)
+irqreturn_t netfront_accel_msg_channel_irq_from_bend(int irq, void *context)
{
netfront_accel_vnic *vnic = (netfront_accel_vnic *)context;
VPRINTK("irq %d from device %s\n", irq, vnic->dev->nodename);
}
/* Process an interrupt received from the NIC via backend */
-irqreturn_t netfront_accel_net_channel_irq_from_bend(int irq, void *context,
- struct pt_regs *unused)
+irqreturn_t netfront_accel_net_channel_irq_from_bend(int irq, void *context)
{
netfront_accel_vnic *vnic = (netfront_accel_vnic *)context;
struct net_device *net_dev = vnic->net_dev;
spin_lock_irqsave(&vnic->irq_enabled_lock, flags);
if (vnic->irq_enabled) {
+ struct netfront_info *np = netdev_priv(net_dev);
+
netfront_accel_disable_net_interrupts(vnic);
vnic->irq_enabled = 0;
spin_unlock_irqrestore(&vnic->irq_enabled_lock, flags);
vnic->stats.event_count_since_irq;
vnic->stats.event_count_since_irq = 0;
#endif
- netif_rx_schedule(net_dev);
+ netif_rx_schedule(net_dev, &np->napi);
}
else {
spin_unlock_irqrestore(&vnic->irq_enabled_lock, flags);
#include "accel_tso.h"
-#define PTR_DIFF(p1, p2) ((u8*)(p1) - (u8*)(p2))
-#define ETH_HDR_LEN(skb) ((skb)->nh.raw - (skb)->data)
-#define SKB_TCP_OFF(skb) PTR_DIFF ((skb)->h.th, (skb)->data)
-#define SKB_IP_OFF(skb) PTR_DIFF ((skb)->nh.iph, (skb)->data)
+#define ETH_HDR_LEN(skb) skb_network_offset(skb)
+#define SKB_TCP_OFF(skb) skb_transport_offset(skb)
+#define SKB_IP_OFF(skb) skb_network_offset(skb)
/*
* Set a maximum number of buffers in each output packet to make life
static inline void tso_check_safe(struct sk_buff *skb) {
EPRINTK_ON(skb->protocol != htons (ETH_P_IP));
EPRINTK_ON(((struct ethhdr*) skb->data)->h_proto != htons (ETH_P_IP));
- EPRINTK_ON(skb->nh.iph->protocol != IPPROTO_TCP);
- EPRINTK_ON((SKB_TCP_OFF(skb)
- + (skb->h.th->doff << 2u)) > skb_headlen(skb));
+ EPRINTK_ON(ip_hdr(skb)->protocol != IPPROTO_TCP);
+ EPRINTK_ON((SKB_TCP_OFF(skb) + tcp_hdrlen(skb)) > skb_headlen(skb));
}
* All ethernet/IP/TCP headers combined size is TCP header size
* plus offset of TCP header relative to start of packet.
*/
- st->p.header_length = (skb->h.th->doff << 2u) + SKB_TCP_OFF(skb);
+ st->p.header_length = tcp_hdrlen(skb) + SKB_TCP_OFF(skb);
st->p.full_packet_size = (st->p.header_length
+ skb_shinfo(skb)->gso_size);
st->p.gso_size = skb_shinfo(skb)->gso_size;
- st->p.ip_id = htons(skb->nh.iph->id);
- st->seqnum = ntohl(skb->h.th->seq);
+ st->p.ip_id = htons(ip_hdr(skb)->id);
+ st->seqnum = ntohl(tcp_hdr(skb)->seq);
- EPRINTK_ON(skb->h.th->urg);
- EPRINTK_ON(skb->h.th->syn);
- EPRINTK_ON(skb->h.th->rst);
+ EPRINTK_ON(tcp_hdr(skb)->urg);
+ EPRINTK_ON(tcp_hdr(skb)->syn);
+ EPRINTK_ON(tcp_hdr(skb)->rst);
st->remaining_len = skb->len - st->p.header_length;
/* This packet will be the last in the TSO burst. */
ip_length = (st->p.header_length - ETH_HDR_LEN(skb)
+ st->remaining_len);
- tsoh_th->fin = skb->h.th->fin;
- tsoh_th->psh = skb->h.th->psh;
+ tsoh_th->fin = tcp_hdr(skb)->fin;
+ tsoh_th->psh = tcp_hdr(skb)->psh;
}
tsoh_iph->tot_len = htons(ip_length);
tso_check_safe(skb);
- if (skb->ip_summed != CHECKSUM_HW)
+ if (skb->ip_summed != CHECKSUM_PARTIAL)
EPRINTK("Trying to TSO send a packet without HW checksum\n");
tso_start(&state, skb);
frag_i = -1;
- if (skb->ip_summed == CHECKSUM_HW) {
+ if (skb->ip_summed == CHECKSUM_PARTIAL) {
/* Set to zero to encourage falcon to work it out for us */
- *(u16*)(skb->h.raw + skb->csum) = 0;
+ *(u16*)(skb->head + skb->csum_start + skb->csum_offset) = 0;
}
if (multi_post_start_new_buffer(vnic, &state)) {
kva = buf->pkt_kva;
- if (skb->ip_summed == CHECKSUM_HW) {
+ if (skb->ip_summed == CHECKSUM_PARTIAL) {
/* Set to zero to encourage falcon to work it out for us */
- *(u16*)(skb->h.raw + skb->csum) = 0;
+ *(u16*)(skb->head + skb->csum_start + skb->csum_offset) = 0;
}
NETFRONT_ACCEL_PKTBUFF_FOR_EACH_FRAGMENT
(skb, idx, frag_data, frag_len, {
(cuckoo_hash_key *)(&key), &value);
if (!try_fastpath) {
- VPRINTK("try fast path false for mac: " MAC_FMT "\n",
- MAC_ARG(skb->data));
+ DECLARE_MAC_BUF(buf);
+
+ VPRINTK("try fast path false for mac: %s\n",
+ print_mac(buf, skb->data));
return NETFRONT_ACCEL_STATUS_CANT;
}
if (compare_ether_addr(skb->data, vnic->mac)) {
struct iphdr *ip = (struct iphdr *)(skb->data + ETH_HLEN);
u16 port;
+ DECLARE_MAC_BUF(buf);
- DPRINTK("%s: saw wrong MAC address " MAC_FMT "\n",
- __FUNCTION__, MAC_ARG(skb->data));
+ DPRINTK("%s: saw wrong MAC address %s\n",
+ __FUNCTION__, print_mac(buf, skb->data));
if (ip->protocol == IPPROTO_TCP) {
struct tcphdr *tcp = (struct tcphdr *)
/* Create xenbus msg event channel */
err = bind_listening_port_to_irqhandler
(dev->otherend_id, netfront_accel_msg_channel_irq_from_bend,
- SA_SAMPLE_RANDOM, "vnicctrl", vnic);
+ IRQF_SAMPLE_RANDOM, "vnicctrl", vnic);
if (err < 0) {
EPRINTK("Couldn't bind msg event channel\n");
goto fail_msg_irq;
/* Create xenbus net event channel */
err = bind_listening_port_to_irqhandler
(dev->otherend_id, netfront_accel_net_channel_irq_from_bend,
- SA_SAMPLE_RANDOM, "vnicfront", vnic);
+ IRQF_SAMPLE_RANDOM, "vnicfront", vnic);
if (err < 0) {
EPRINTK("Couldn't bind net event channel\n");
goto fail_net_irq;
DPRINTK("%s at %s:%d\n", #exp, __FILE__, __LINE__); \
} while(0)
-#define MAC_FMT "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x"
-#define MAC_ARG(_mac) (_mac)[0], (_mac)[1], (_mac)[2], (_mac)[3], (_mac)[4], (_mac)[5]
-
#include <xen/xenbus.h>
/*! Map a set of pages from another domain
static int xenbus_irq;
-extern void xenbus_probe(void *);
+extern void xenbus_probe(struct work_struct *);
extern int xenstored_ready;
-static DECLARE_WORK(probe_work, xenbus_probe, NULL);
+static DECLARE_WORK(probe_work, xenbus_probe);
static DECLARE_WAIT_QUEUE_HEAD(xb_waitq);
-static irqreturn_t wake_waiting(int irq, void *unused, struct pt_regs *regs)
+static irqreturn_t wake_waiting(int irq, void *unused)
{
if (unlikely(xenstored_ready == 0)) {
xenstored_ready = 1;
__FUNCTION__, __LINE__, ##args)
#include <linux/kernel.h>
+#include <linux/version.h>
#include <linux/err.h>
#include <linux/string.h>
#include <linux/ctype.h>
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-static int xenbus_uevent_frontend(struct device *dev, char **envp,
- int num_envp, char *buffer, int buffer_size)
+static int xenbus_uevent_frontend(struct device *dev, struct kobj_uevent_env *env)
{
struct xenbus_device *xdev;
- int length = 0, i = 0;
if (dev == NULL)
return -ENODEV;
return -ENODEV;
/* stuff we want to pass to /sbin/hotplug */
- add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
- "XENBUS_TYPE=%s", xdev->devicetype);
- add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
- "XENBUS_PATH=%s", xdev->nodename);
- add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
- "MODALIAS=xen:%s", xdev->devicetype);
+ add_uevent_var(env, "XENBUS_TYPE=%s", xdev->devicetype);
+ add_uevent_var(env, "XENBUS_PATH=%s", xdev->nodename);
+ add_uevent_var(env, "MODALIAS=xen:%s", xdev->devicetype);
return 0;
}
}
int xenbus_register_driver_common(struct xenbus_driver *drv,
- struct xen_bus_type *bus)
+ struct xen_bus_type *bus,
+ struct module *owner,
+ const char *mod_name)
{
int ret;
drv->driver.name = drv->name;
drv->driver.bus = &bus->bus;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
- drv->driver.owner = drv->owner;
+ drv->driver.owner = owner;
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
+ drv->driver.mod_name = mod_name;
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)
drv->driver.probe = xenbus_dev_probe;
return ret;
}
-int xenbus_register_frontend(struct xenbus_driver *drv)
+int __xenbus_register_frontend(struct xenbus_driver *drv,
+ struct module *owner, const char *mod_name)
{
int ret;
drv->read_otherend_details = read_backend_details;
- ret = xenbus_register_driver_common(drv, &xenbus_frontend);
+ ret = xenbus_register_driver_common(drv, &xenbus_frontend, owner, mod_name);
if (ret)
return ret;
return 0;
}
-EXPORT_SYMBOL_GPL(xenbus_register_frontend);
+EXPORT_SYMBOL_GPL(__xenbus_register_frontend);
void xenbus_unregister_driver(struct xenbus_driver *drv)
{
extern int xenbus_dev_probe(struct device *_dev);
extern int xenbus_dev_remove(struct device *_dev);
extern int xenbus_register_driver_common(struct xenbus_driver *drv,
- struct xen_bus_type *bus);
+ struct xen_bus_type *bus,
+ struct module *owner,
+ const char *mod_name);
extern int xenbus_probe_node(struct xen_bus_type *bus,
const char *type,
const char *nodename);
#include <xen/platform-compat.h>
#endif
-static int xenbus_uevent_backend(struct device *dev, char **envp,
- int num_envp, char *buffer, int buffer_size);
+static int xenbus_uevent_backend(struct device *dev, struct kobj_uevent_env *env);
static int xenbus_probe_backend(const char *type, const char *domid);
extern int read_otherend_details(struct xenbus_device *xendev,
},
};
-static int xenbus_uevent_backend(struct device *dev, char **envp,
- int num_envp, char *buffer, int buffer_size)
+static int xenbus_uevent_backend(struct device *dev, struct kobj_uevent_env *env)
{
struct xenbus_device *xdev;
struct xenbus_driver *drv;
- int i = 0;
- int length = 0;
DPRINTK("");
return -ENODEV;
/* stuff we want to pass to /sbin/hotplug */
- add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
- "XENBUS_TYPE=%s", xdev->devicetype);
+ add_uevent_var(env, "XENBUS_TYPE=%s", xdev->devicetype);
- add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
- "XENBUS_PATH=%s", xdev->nodename);
+ add_uevent_var(env, "XENBUS_PATH=%s", xdev->nodename);
- add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
- "XENBUS_BASE_PATH=%s", xenbus_backend.root);
-
- /* terminate, set to next free slot, shrink available space */
- envp[i] = NULL;
- envp = &envp[i];
- num_envp -= i;
- buffer = &buffer[length];
- buffer_size -= length;
+ add_uevent_var(env, "XENBUS_BASE_PATH=%s", xenbus_backend.root);
if (dev->driver) {
drv = to_xenbus_driver(dev->driver);
if (drv && drv->uevent)
- return drv->uevent(xdev, envp, num_envp, buffer,
- buffer_size);
+ return drv->uevent(xdev, env);
}
return 0;
}
-int xenbus_register_backend(struct xenbus_driver *drv)
+int __xenbus_register_backend(struct xenbus_driver *drv,
+ struct module *owner, const char *mod_name)
{
drv->read_otherend_details = read_frontend_details;
- return xenbus_register_driver_common(drv, &xenbus_backend);
+ return xenbus_register_driver_common(drv, &xenbus_backend,
+ owner, mod_name);
}
-EXPORT_SYMBOL_GPL(xenbus_register_backend);
+EXPORT_SYMBOL_GPL(__xenbus_register_backend);
/* backend/<typename>/<frontend-uuid>/<name> */
static int xenbus_probe_backend_unit(const char *dir,