Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /* Copyright (c) 2012 Coraid, Inc.  See COPYING for GPL terms. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * aoechr.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * AoE character device driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/hdreg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/blkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/completion.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include "aoe.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 	//MINOR_STAT = 1, (moved to sysfs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 	MINOR_ERR = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 	MINOR_DISCOVER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 	MINOR_INTERFACES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 	MINOR_REVALIDATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 	MINOR_FLUSH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 	MSGSZ = 2048,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 	NMSG = 100,		/* message backlog to retain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) struct aoe_chardev {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	ulong minor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	char name[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) enum { EMFL_VALID = 1 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) struct ErrMsg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	short flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	short len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	char *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) static DEFINE_MUTEX(aoechr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) /* A ring buffer of error messages, to be read through
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44)  * "/dev/etherd/err".  When no messages are present,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45)  * readers will block waiting for messages to appear.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) static struct ErrMsg emsgs[NMSG];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) static int emsgs_head_idx, emsgs_tail_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) static struct completion emsgs_comp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) static spinlock_t emsgs_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) static int nblocked_emsgs_readers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) static struct class *aoe_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) static struct aoe_chardev chardevs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	{ MINOR_ERR, "err" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	{ MINOR_DISCOVER, "discover" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	{ MINOR_INTERFACES, "interfaces" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	{ MINOR_REVALIDATE, "revalidate" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	{ MINOR_FLUSH, "flush" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) discover(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	aoecmd_cfg(0xffff, 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) interfaces(const char __user *str, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	if (set_aoe_iflist(str, size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		printk(KERN_ERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 			"aoe: could not set interface list: too many interfaces\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) revalidate(const char __user *str, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	int major, minor, n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	ulong flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	struct aoedev *d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	char buf[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	if (size >= sizeof buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	buf[sizeof buf - 1] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	if (copy_from_user(buf, str, size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	n = sscanf(buf, "e%d.%d", &major, &minor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	if (n != 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		pr_err("aoe: invalid device specification %s\n", buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	d = aoedev_by_aoeaddr(major, minor, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	if (!d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	spin_lock_irqsave(&d->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	aoecmd_cleanslate(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	aoecmd_cfg(major, minor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) loop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	skb = aoecmd_ata_id(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	spin_unlock_irqrestore(&d->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	/* try again if we are able to sleep a bit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	 * otherwise give up this revalidation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	if (!skb && !msleep_interruptible(250)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		spin_lock_irqsave(&d->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		goto loop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	aoedev_put(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	if (skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		struct sk_buff_head queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 		__skb_queue_head_init(&queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		__skb_queue_tail(&queue, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		aoenet_xmit(&queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) aoechr_error(char *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	struct ErrMsg *em;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	char *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	ulong flags, n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	n = strlen(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	spin_lock_irqsave(&emsgs_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	em = emsgs + emsgs_tail_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	if ((em->flags & EMFL_VALID)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) bail:		spin_unlock_irqrestore(&emsgs_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	mp = kmemdup(msg, n, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	if (mp == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 		printk(KERN_ERR "aoe: allocation failure, len=%ld\n", n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 		goto bail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	em->msg = mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	em->flags |= EMFL_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	em->len = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	emsgs_tail_idx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	emsgs_tail_idx %= ARRAY_SIZE(emsgs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	spin_unlock_irqrestore(&emsgs_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	if (nblocked_emsgs_readers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		complete(&emsgs_comp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) aoechr_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	int ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	switch ((unsigned long) filp->private_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 		printk(KERN_INFO "aoe: can't write to that file.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	case MINOR_DISCOVER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 		ret = discover();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	case MINOR_INTERFACES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 		ret = interfaces(buf, cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	case MINOR_REVALIDATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 		ret = revalidate(buf, cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	case MINOR_FLUSH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 		ret = aoedev_flush(buf, cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		ret = cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) aoechr_open(struct inode *inode, struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	int n, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	mutex_lock(&aoechr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	n = iminor(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	filp->private_data = (void *) (unsigned long) n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	for (i = 0; i < ARRAY_SIZE(chardevs); ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 		if (chardevs[i].minor == n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 			mutex_unlock(&aoechr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	mutex_unlock(&aoechr_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) aoechr_rel(struct inode *inode, struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) aoechr_read(struct file *filp, char __user *buf, size_t cnt, loff_t *off)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	unsigned long n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	char *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	struct ErrMsg *em;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	ssize_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	ulong flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	n = (unsigned long) filp->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	if (n != MINOR_ERR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	spin_lock_irqsave(&emsgs_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		em = emsgs + emsgs_head_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		if ((em->flags & EMFL_VALID) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 		if (filp->f_flags & O_NDELAY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 			spin_unlock_irqrestore(&emsgs_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 			return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		nblocked_emsgs_readers++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		spin_unlock_irqrestore(&emsgs_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 		n = wait_for_completion_interruptible(&emsgs_comp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 		spin_lock_irqsave(&emsgs_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		nblocked_emsgs_readers--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		if (n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 			spin_unlock_irqrestore(&emsgs_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 			return -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	if (em->len > cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 		spin_unlock_irqrestore(&emsgs_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 		return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	mp = em->msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	len = em->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	em->msg = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	em->flags &= ~EMFL_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	emsgs_head_idx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	emsgs_head_idx %= ARRAY_SIZE(emsgs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	spin_unlock_irqrestore(&emsgs_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	n = copy_to_user(buf, mp, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	kfree(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	return n == 0 ? len : -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) static const struct file_operations aoe_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	.write = aoechr_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	.read = aoechr_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	.open = aoechr_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	.release = aoechr_rel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	.owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	.llseek = noop_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) static char *aoe_devnode(struct device *dev, umode_t *mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	return kasprintf(GFP_KERNEL, "etherd/%s", dev_name(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) int __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) aoechr_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	int n, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	n = register_chrdev(AOE_MAJOR, "aoechr", &aoe_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	if (n < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 		printk(KERN_ERR "aoe: can't register char device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 		return n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	init_completion(&emsgs_comp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	spin_lock_init(&emsgs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	aoe_class = class_create(THIS_MODULE, "aoe");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	if (IS_ERR(aoe_class)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 		unregister_chrdev(AOE_MAJOR, "aoechr");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 		return PTR_ERR(aoe_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	aoe_class->devnode = aoe_devnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	for (i = 0; i < ARRAY_SIZE(chardevs); ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 		device_create(aoe_class, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 			      MKDEV(AOE_MAJOR, chardevs[i].minor), NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 			      chardevs[i].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) aoechr_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	for (i = 0; i < ARRAY_SIZE(chardevs); ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 		device_destroy(aoe_class, MKDEV(AOE_MAJOR, chardevs[i].minor));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	class_destroy(aoe_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	unregister_chrdev(AOE_MAJOR, "aoechr");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)