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