diff options
Diffstat (limited to 'drivers/staging/batman-adv/device.c')
-rw-r--r-- | drivers/staging/batman-adv/device.c | 53 |
1 files changed, 31 insertions, 22 deletions
diff --git a/drivers/staging/batman-adv/device.c b/drivers/staging/batman-adv/device.c index 1e7d1f88674..e7f44215b5f 100644 --- a/drivers/staging/batman-adv/device.c +++ b/drivers/staging/batman-adv/device.c @@ -19,14 +19,13 @@ * */ +#include <linux/device.h> #include "main.h" #include "device.h" -#include "log.h" #include "send.h" #include "types.h" #include "hash.h" - -#include "compat.h" +#include "hard-interface.h" static struct class *batman_class; @@ -60,7 +59,7 @@ int bat_device_setup(void) /* register our device - kernel assigns a free major number */ tmp_major = register_chrdev(0, DRIVER_DEVICE, &fops); if (tmp_major < 0) { - debug_log(LOG_TYPE_WARN, "Registering the character device failed with %d\n", + printk(KERN_ERR "batman-adv:Registering the character device failed with %d\n", tmp_major); return 0; } @@ -68,7 +67,7 @@ int bat_device_setup(void) batman_class = class_create(THIS_MODULE, "batman-adv"); if (IS_ERR(batman_class)) { - debug_log(LOG_TYPE_WARN, "Could not register class 'batman-adv' \n"); + printk(KERN_ERR "batman-adv:Could not register class 'batman-adv' \n"); return 0; } @@ -111,7 +110,7 @@ int bat_device_open(struct inode *inode, struct file *file) } if (device_client_hash[i] != device_client) { - debug_log(LOG_TYPE_WARN, "Error - can't add another packet client: maximum number of clients reached \n"); + printk(KERN_ERR "batman-adv:Error - can't add another packet client: maximum number of clients reached \n"); kfree(device_client); return -EXFULL; } @@ -119,7 +118,7 @@ int bat_device_open(struct inode *inode, struct file *file) INIT_LIST_HEAD(&device_client->queue_list); device_client->queue_len = 0; device_client->index = i; - device_client->lock = __SPIN_LOCK_UNLOCKED(device_client->lock); + spin_lock_init(&device_client->lock); init_waitqueue_head(&device_client->queue_wait); file->private_data = device_client; @@ -134,8 +133,9 @@ int bat_device_release(struct inode *inode, struct file *file) (struct device_client *)file->private_data; struct device_packet *device_packet; struct list_head *list_pos, *list_pos_tmp; + unsigned long flags; - spin_lock(&device_client->lock); + spin_lock_irqsave(&device_client->lock, flags); /* for all packets in the queue ... */ list_for_each_safe(list_pos, list_pos_tmp, &device_client->queue_list) { @@ -147,7 +147,7 @@ int bat_device_release(struct inode *inode, struct file *file) } device_client_hash[device_client->index] = NULL; - spin_unlock(&device_client->lock); + spin_unlock_irqrestore(&device_client->lock, flags); kfree(device_client); dec_module_count(); @@ -162,6 +162,7 @@ ssize_t bat_device_read(struct file *file, char __user *buf, size_t count, (struct device_client *)file->private_data; struct device_packet *device_packet; int error; + unsigned long flags; if ((file->f_flags & O_NONBLOCK) && (device_client->queue_len == 0)) return -EAGAIN; @@ -178,14 +179,14 @@ ssize_t bat_device_read(struct file *file, char __user *buf, size_t count, if (error) return error; - spin_lock(&device_client->lock); + spin_lock_irqsave(&device_client->lock, flags); device_packet = list_first_entry(&device_client->queue_list, struct device_packet, list); list_del(&device_packet->list); device_client->queue_len--; - spin_unlock(&device_client->lock); + spin_unlock_irqrestore(&device_client->lock, flags); error = __copy_to_user(buf, &device_packet->icmp_packet, sizeof(struct icmp_packet)); @@ -206,9 +207,11 @@ ssize_t bat_device_write(struct file *file, const char __user *buff, struct icmp_packet icmp_packet; struct orig_node *orig_node; struct batman_if *batman_if; + uint8_t dstaddr[ETH_ALEN]; + unsigned long flags; if (len < sizeof(struct icmp_packet)) { - debug_log(LOG_TYPE_NOTICE, "Error - can't send packet from char device: invalid packet size\n"); + bat_dbg(DBG_BATMAN, "batman-adv:Error - can't send packet from char device: invalid packet size\n"); return -EINVAL; } @@ -219,12 +222,12 @@ ssize_t bat_device_write(struct file *file, const char __user *buff, return -EFAULT; if (icmp_packet.packet_type != BAT_ICMP) { - debug_log(LOG_TYPE_NOTICE, "Error - can't send packet from char device: got bogus packet type (expected: BAT_ICMP)\n"); + bat_dbg(DBG_BATMAN, "batman-adv:Error - can't send packet from char device: got bogus packet type (expected: BAT_ICMP)\n"); return -EINVAL; } if (icmp_packet.msg_type != ECHO_REQUEST) { - debug_log(LOG_TYPE_NOTICE, "Error - can't send packet from char device: got bogus message type (expected: ECHO_REQUEST)\n"); + bat_dbg(DBG_BATMAN, "batman-adv:Error - can't send packet from char device: got bogus message type (expected: ECHO_REQUEST)\n"); return -EINVAL; } @@ -240,7 +243,7 @@ ssize_t bat_device_write(struct file *file, const char __user *buff, if (atomic_read(&module_state) != MODULE_ACTIVE) goto dst_unreach; - spin_lock(&orig_hash_lock); + spin_lock_irqsave(&orig_hash_lock, flags); orig_node = ((struct orig_node *)hash_find(orig_hash, icmp_packet.dst)); if (!orig_node) @@ -250,9 +253,15 @@ ssize_t bat_device_write(struct file *file, const char __user *buff, goto unlock; batman_if = orig_node->batman_if; + memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); + + spin_unlock_irqrestore(&orig_hash_lock, flags); if (!batman_if) - goto unlock; + goto dst_unreach; + + if (batman_if->if_active != IF_ACTIVE) + goto dst_unreach; memcpy(icmp_packet.orig, batman_if->net_dev->dev_addr, @@ -260,13 +269,12 @@ ssize_t bat_device_write(struct file *file, const char __user *buff, send_raw_packet((unsigned char *)&icmp_packet, sizeof(struct icmp_packet), - batman_if, orig_node->router->addr); + batman_if, dstaddr); - spin_unlock(&orig_hash_lock); goto out; unlock: - spin_unlock(&orig_hash_lock); + spin_unlock_irqrestore(&orig_hash_lock, flags); dst_unreach: icmp_packet.msg_type = DESTINATION_UNREACHABLE; bat_device_add_packet(device_client, &icmp_packet); @@ -291,6 +299,7 @@ void bat_device_add_packet(struct device_client *device_client, struct icmp_packet *icmp_packet) { struct device_packet *device_packet; + unsigned long flags; device_packet = kmalloc(sizeof(struct device_packet), GFP_KERNEL); @@ -301,12 +310,12 @@ void bat_device_add_packet(struct device_client *device_client, memcpy(&device_packet->icmp_packet, icmp_packet, sizeof(struct icmp_packet)); - spin_lock(&device_client->lock); + spin_lock_irqsave(&device_client->lock, flags); /* while waiting for the lock the device_client could have been * deleted */ if (!device_client_hash[icmp_packet->uid]) { - spin_unlock(&device_client->lock); + spin_unlock_irqrestore(&device_client->lock, flags); kfree(device_packet); return; } @@ -323,7 +332,7 @@ void bat_device_add_packet(struct device_client *device_client, device_client->queue_len--; } - spin_unlock(&device_client->lock); + spin_unlock_irqrestore(&device_client->lock, flags); wake_up(&device_client->queue_wait); } |