[PATCH] aoe [2/8]: support dynamic resizing of AoE devices
[safe/jmp/linux-2.6] / drivers / block / aoe / aoecmd.c
1 /* Copyright (c) 2004 Coraid, Inc.  See COPYING for GPL terms. */
2 /*
3  * aoecmd.c
4  * Filesystem request handling methods
5  */
6
7 #include <linux/hdreg.h>
8 #include <linux/blkdev.h>
9 #include <linux/skbuff.h>
10 #include <linux/netdevice.h>
11 #include <linux/genhd.h>
12 #include <asm/unaligned.h>
13 #include "aoe.h"
14
15 #define TIMERTICK (HZ / 10)
16 #define MINTIMER (2 * TIMERTICK)
17 #define MAXTIMER (HZ << 1)
18 #define MAXWAIT (60 * 3)        /* After MAXWAIT seconds, give up and fail dev */
19
20 static struct sk_buff *
21 new_skb(struct net_device *if_dev, ulong len)
22 {
23         struct sk_buff *skb;
24
25         skb = alloc_skb(len, GFP_ATOMIC);
26         if (skb) {
27                 skb->nh.raw = skb->mac.raw = skb->data;
28                 skb->dev = if_dev;
29                 skb->protocol = __constant_htons(ETH_P_AOE);
30                 skb->priority = 0;
31                 skb_put(skb, len);
32                 memset(skb->head, 0, len);
33                 skb->next = skb->prev = NULL;
34
35                 /* tell the network layer not to perform IP checksums
36                  * or to get the NIC to do it
37                  */
38                 skb->ip_summed = CHECKSUM_NONE;
39         }
40         return skb;
41 }
42
43 static struct sk_buff *
44 skb_prepare(struct aoedev *d, struct frame *f)
45 {
46         struct sk_buff *skb;
47         char *p;
48
49         skb = new_skb(d->ifp, f->ndata + f->writedatalen);
50         if (!skb) {
51                 printk(KERN_INFO "aoe: skb_prepare: failure to allocate skb\n");
52                 return NULL;
53         }
54
55         p = skb->mac.raw;
56         memcpy(p, f->data, f->ndata);
57
58         if (f->writedatalen) {
59                 p += sizeof(struct aoe_hdr) + sizeof(struct aoe_atahdr);
60                 memcpy(p, f->bufaddr, f->writedatalen);
61         }
62
63         return skb;
64 }
65
66 static struct frame *
67 getframe(struct aoedev *d, int tag)
68 {
69         struct frame *f, *e;
70
71         f = d->frames;
72         e = f + d->nframes;
73         for (; f<e; f++)
74                 if (f->tag == tag)
75                         return f;
76         return NULL;
77 }
78
79 /*
80  * Leave the top bit clear so we have tagspace for userland.
81  * The bottom 16 bits are the xmit tick for rexmit/rttavg processing.
82  * This driver reserves tag -1 to mean "unused frame."
83  */
84 static int
85 newtag(struct aoedev *d)
86 {
87         register ulong n;
88
89         n = jiffies & 0xffff;
90         return n |= (++d->lasttag & 0x7fff) << 16;
91 }
92
93 static int
94 aoehdr_atainit(struct aoedev *d, struct aoe_hdr *h)
95 {
96         u32 host_tag = newtag(d);
97
98         memcpy(h->src, d->ifp->dev_addr, sizeof h->src);
99         memcpy(h->dst, d->addr, sizeof h->dst);
100         h->type = __constant_cpu_to_be16(ETH_P_AOE);
101         h->verfl = AOE_HVER;
102         h->major = cpu_to_be16(d->aoemajor);
103         h->minor = d->aoeminor;
104         h->cmd = AOECMD_ATA;
105         h->tag = cpu_to_be32(host_tag);
106
107         return host_tag;
108 }
109
110 static void
111 aoecmd_ata_rw(struct aoedev *d, struct frame *f)
112 {
113         struct aoe_hdr *h;
114         struct aoe_atahdr *ah;
115         struct buf *buf;
116         struct sk_buff *skb;
117         ulong bcnt;
118         register sector_t sector;
119         char writebit, extbit;
120
121         writebit = 0x10;
122         extbit = 0x4;
123
124         buf = d->inprocess;
125
126         sector = buf->sector;
127         bcnt = buf->bv_resid;
128         if (bcnt > MAXATADATA)
129                 bcnt = MAXATADATA;
130
131         /* initialize the headers & frame */
132         h = (struct aoe_hdr *) f->data;
133         ah = (struct aoe_atahdr *) (h+1);
134         f->ndata = sizeof *h + sizeof *ah;
135         memset(h, 0, f->ndata);
136         f->tag = aoehdr_atainit(d, h);
137         f->waited = 0;
138         f->buf = buf;
139         f->bufaddr = buf->bufaddr;
140
141         /* set up ata header */
142         ah->scnt = bcnt >> 9;
143         ah->lba0 = sector;
144         ah->lba1 = sector >>= 8;
145         ah->lba2 = sector >>= 8;
146         ah->lba3 = sector >>= 8;
147         if (d->flags & DEVFL_EXT) {
148                 ah->aflags |= AOEAFL_EXT;
149                 ah->lba4 = sector >>= 8;
150                 ah->lba5 = sector >>= 8;
151         } else {
152                 extbit = 0;
153                 ah->lba3 &= 0x0f;
154                 ah->lba3 |= 0xe0;       /* LBA bit + obsolete 0xa0 */
155         }
156
157         if (bio_data_dir(buf->bio) == WRITE) {
158                 ah->aflags |= AOEAFL_WRITE;
159                 f->writedatalen = bcnt;
160         } else {
161                 writebit = 0;
162                 f->writedatalen = 0;
163         }
164
165         ah->cmdstat = WIN_READ | writebit | extbit;
166
167         /* mark all tracking fields and load out */
168         buf->nframesout += 1;
169         buf->bufaddr += bcnt;
170         buf->bv_resid -= bcnt;
171 /* printk(KERN_INFO "aoe: bv_resid=%ld\n", buf->bv_resid); */
172         buf->resid -= bcnt;
173         buf->sector += bcnt >> 9;
174         if (buf->resid == 0) {
175                 d->inprocess = NULL;
176         } else if (buf->bv_resid == 0) {
177                 buf->bv++;
178                 buf->bv_resid = buf->bv->bv_len;
179                 buf->bufaddr = page_address(buf->bv->bv_page) + buf->bv->bv_offset;
180         }
181
182         skb = skb_prepare(d, f);
183         if (skb) {
184                 skb->next = NULL;
185                 if (d->sendq_hd)
186                         d->sendq_tl->next = skb;
187                 else
188                         d->sendq_hd = skb;
189                 d->sendq_tl = skb;
190         }
191 }
192
193 /* some callers cannot sleep, and they can call this function,
194  * transmitting the packets later, when interrupts are on
195  */
196 static struct sk_buff *
197 aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail)
198 {
199         struct aoe_hdr *h;
200         struct aoe_cfghdr *ch;
201         struct sk_buff *skb, *sl, *sl_tail;
202         struct net_device *ifp;
203
204         sl = sl_tail = NULL;
205
206         read_lock(&dev_base_lock);
207         for (ifp = dev_base; ifp; dev_put(ifp), ifp = ifp->next) {
208                 dev_hold(ifp);
209                 if (!is_aoe_netif(ifp))
210                         continue;
211
212                 skb = new_skb(ifp, sizeof *h + sizeof *ch);
213                 if (skb == NULL) {
214                         printk(KERN_INFO "aoe: aoecmd_cfg: skb alloc failure\n");
215                         continue;
216                 }
217                 if (sl_tail == NULL)
218                         sl_tail = skb;
219                 h = (struct aoe_hdr *) skb->mac.raw;
220                 memset(h, 0, sizeof *h + sizeof *ch);
221
222                 memset(h->dst, 0xff, sizeof h->dst);
223                 memcpy(h->src, ifp->dev_addr, sizeof h->src);
224                 h->type = __constant_cpu_to_be16(ETH_P_AOE);
225                 h->verfl = AOE_HVER;
226                 h->major = cpu_to_be16(aoemajor);
227                 h->minor = aoeminor;
228                 h->cmd = AOECMD_CFG;
229
230                 skb->next = sl;
231                 sl = skb;
232         }
233         read_unlock(&dev_base_lock);
234
235         if (tail != NULL)
236                 *tail = sl_tail;
237         return sl;
238 }
239
240 /* enters with d->lock held */
241 void
242 aoecmd_work(struct aoedev *d)
243 {
244         struct frame *f;
245         struct buf *buf;
246
247         if (d->flags & DEVFL_PAUSE) {
248                 if (!aoedev_isbusy(d))
249                         d->sendq_hd = aoecmd_cfg_pkts(d->aoemajor,
250                                                 d->aoeminor, &d->sendq_tl);
251                 return;
252         }
253
254 loop:
255         f = getframe(d, FREETAG);
256         if (f == NULL)
257                 return;
258         if (d->inprocess == NULL) {
259                 if (list_empty(&d->bufq))
260                         return;
261                 buf = container_of(d->bufq.next, struct buf, bufs);
262                 list_del(d->bufq.next);
263 /*printk(KERN_INFO "aoecmd_work: bi_size=%ld\n", buf->bio->bi_size); */
264                 d->inprocess = buf;
265         }
266         aoecmd_ata_rw(d, f);
267         goto loop;
268 }
269
270 static void
271 rexmit(struct aoedev *d, struct frame *f)
272 {
273         struct sk_buff *skb;
274         struct aoe_hdr *h;
275         char buf[128];
276         u32 n;
277
278         n = newtag(d);
279
280         snprintf(buf, sizeof buf,
281                 "%15s e%ld.%ld oldtag=%08x@%08lx newtag=%08x\n",
282                 "retransmit",
283                 d->aoemajor, d->aoeminor, f->tag, jiffies, n);
284         aoechr_error(buf);
285
286         h = (struct aoe_hdr *) f->data;
287         f->tag = n;
288         h->tag = cpu_to_be32(n);
289
290         skb = skb_prepare(d, f);
291         if (skb) {
292                 skb->next = NULL;
293                 if (d->sendq_hd)
294                         d->sendq_tl->next = skb;
295                 else
296                         d->sendq_hd = skb;
297                 d->sendq_tl = skb;
298         }
299 }
300
301 static int
302 tsince(int tag)
303 {
304         int n;
305
306         n = jiffies & 0xffff;
307         n -= tag & 0xffff;
308         if (n < 0)
309                 n += 1<<16;
310         return n;
311 }
312
313 static void
314 rexmit_timer(ulong vp)
315 {
316         struct aoedev *d;
317         struct frame *f, *e;
318         struct sk_buff *sl;
319         register long timeout;
320         ulong flags, n;
321
322         d = (struct aoedev *) vp;
323         sl = NULL;
324
325         /* timeout is always ~150% of the moving average */
326         timeout = d->rttavg;
327         timeout += timeout >> 1;
328
329         spin_lock_irqsave(&d->lock, flags);
330
331         if (d->flags & DEVFL_TKILL) {
332 tdie:           spin_unlock_irqrestore(&d->lock, flags);
333                 return;
334         }
335         f = d->frames;
336         e = f + d->nframes;
337         for (; f<e; f++) {
338                 if (f->tag != FREETAG && tsince(f->tag) >= timeout) {
339                         n = f->waited += timeout;
340                         n /= HZ;
341                         if (n > MAXWAIT) { /* waited too long.  device failure. */
342                                 aoedev_downdev(d);
343                                 goto tdie;
344                         }
345                         rexmit(d, f);
346                 }
347         }
348
349         sl = d->sendq_hd;
350         d->sendq_hd = d->sendq_tl = NULL;
351         if (sl) {
352                 n = d->rttavg <<= 1;
353                 if (n > MAXTIMER)
354                         d->rttavg = MAXTIMER;
355         }
356
357         d->timer.expires = jiffies + TIMERTICK;
358         add_timer(&d->timer);
359
360         spin_unlock_irqrestore(&d->lock, flags);
361
362         aoenet_xmit(sl);
363 }
364
365 /* this function performs work that has been deferred until sleeping is OK
366  */
367 void
368 aoecmd_sleepwork(void *vp)
369 {
370         struct aoedev *d = (struct aoedev *) vp;
371
372         if (d->flags & DEVFL_GDALLOC)
373                 aoeblk_gdalloc(d);
374
375         if (d->flags & DEVFL_NEWSIZE) {
376                 struct block_device *bd;
377                 unsigned long flags;
378                 u64 ssize;
379
380                 ssize = d->gd->capacity;
381                 bd = bdget_disk(d->gd, 0);
382
383                 if (bd) {
384                         mutex_lock(&bd->bd_inode->i_mutex);
385                         i_size_write(bd->bd_inode, (loff_t)ssize<<9);
386                         mutex_unlock(&bd->bd_inode->i_mutex);
387                         bdput(bd);
388                 }
389                 spin_lock_irqsave(&d->lock, flags);
390                 d->flags |= DEVFL_UP;
391                 d->flags &= ~DEVFL_NEWSIZE;
392                 spin_unlock_irqrestore(&d->lock, flags);
393         }
394 }
395
396 static void
397 ataid_complete(struct aoedev *d, unsigned char *id)
398 {
399         u64 ssize;
400         u16 n;
401
402         /* word 83: command set supported */
403         n = le16_to_cpu(get_unaligned((__le16 *) &id[83<<1]));
404
405         /* word 86: command set/feature enabled */
406         n |= le16_to_cpu(get_unaligned((__le16 *) &id[86<<1]));
407
408         if (n & (1<<10)) {      /* bit 10: LBA 48 */
409                 d->flags |= DEVFL_EXT;
410
411                 /* word 100: number lba48 sectors */
412                 ssize = le64_to_cpu(get_unaligned((__le64 *) &id[100<<1]));
413
414                 /* set as in ide-disk.c:init_idedisk_capacity */
415                 d->geo.cylinders = ssize;
416                 d->geo.cylinders /= (255 * 63);
417                 d->geo.heads = 255;
418                 d->geo.sectors = 63;
419         } else {
420                 d->flags &= ~DEVFL_EXT;
421
422                 /* number lba28 sectors */
423                 ssize = le32_to_cpu(get_unaligned((__le32 *) &id[60<<1]));
424
425                 /* NOTE: obsolete in ATA 6 */
426                 d->geo.cylinders = le16_to_cpu(get_unaligned((__le16 *) &id[54<<1]));
427                 d->geo.heads = le16_to_cpu(get_unaligned((__le16 *) &id[55<<1]));
428                 d->geo.sectors = le16_to_cpu(get_unaligned((__le16 *) &id[56<<1]));
429         }
430
431         if (d->ssize != ssize)
432                 printk(KERN_INFO "aoe: %012llx e%lu.%lu v%04x has %llu "
433                         "sectors\n", (unsigned long long)mac_addr(d->addr),
434                         d->aoemajor, d->aoeminor,
435                         d->fw_ver, (long long)ssize);
436         d->ssize = ssize;
437         d->geo.start = 0;
438         if (d->gd != NULL) {
439                 d->gd->capacity = ssize;
440                 d->flags |= DEVFL_NEWSIZE;
441         } else {
442                 if (d->flags & DEVFL_GDALLOC) {
443                         printk(KERN_INFO "aoe: %s: %s e%lu.%lu, %s\n",
444                                __FUNCTION__,
445                                "can't schedule work for",
446                                d->aoemajor, d->aoeminor,
447                                "it's already on! (This really shouldn't happen).\n");
448                         return;
449                 }
450                 d->flags |= DEVFL_GDALLOC;
451         }
452         schedule_work(&d->work);
453 }
454
455 static void
456 calc_rttavg(struct aoedev *d, int rtt)
457 {
458         register long n;
459
460         n = rtt;
461         if (n < MINTIMER)
462                 n = MINTIMER;
463         else if (n > MAXTIMER)
464                 n = MAXTIMER;
465
466         /* g == .25; cf. Congestion Avoidance and Control, Jacobson & Karels; 1988 */
467         n -= d->rttavg;
468         d->rttavg += n >> 2;
469 }
470
471 void
472 aoecmd_ata_rsp(struct sk_buff *skb)
473 {
474         struct aoedev *d;
475         struct aoe_hdr *hin;
476         struct aoe_atahdr *ahin, *ahout;
477         struct frame *f;
478         struct buf *buf;
479         struct sk_buff *sl;
480         register long n;
481         ulong flags;
482         char ebuf[128];
483         u16 aoemajor;
484
485         hin = (struct aoe_hdr *) skb->mac.raw;
486         aoemajor = be16_to_cpu(hin->major);
487         d = aoedev_by_aoeaddr(aoemajor, hin->minor);
488         if (d == NULL) {
489                 snprintf(ebuf, sizeof ebuf, "aoecmd_ata_rsp: ata response "
490                         "for unknown device %d.%d\n",
491                          aoemajor, hin->minor);
492                 aoechr_error(ebuf);
493                 return;
494         }
495
496         spin_lock_irqsave(&d->lock, flags);
497
498         f = getframe(d, be32_to_cpu(hin->tag));
499         if (f == NULL) {
500                 spin_unlock_irqrestore(&d->lock, flags);
501                 snprintf(ebuf, sizeof ebuf,
502                         "%15s e%d.%d    tag=%08x@%08lx\n",
503                         "unexpected rsp",
504                         be16_to_cpu(hin->major),
505                         hin->minor,
506                         be32_to_cpu(hin->tag),
507                         jiffies);
508                 aoechr_error(ebuf);
509                 return;
510         }
511
512         calc_rttavg(d, tsince(f->tag));
513
514         ahin = (struct aoe_atahdr *) (hin+1);
515         ahout = (struct aoe_atahdr *) (f->data + sizeof(struct aoe_hdr));
516         buf = f->buf;
517
518         if (ahin->cmdstat & 0xa9) {     /* these bits cleared on success */
519                 printk(KERN_CRIT "aoe: aoecmd_ata_rsp: ata error cmd=%2.2Xh "
520                         "stat=%2.2Xh from e%ld.%ld\n", 
521                         ahout->cmdstat, ahin->cmdstat,
522                         d->aoemajor, d->aoeminor);
523                 if (buf)
524                         buf->flags |= BUFFL_FAIL;
525         } else {
526                 switch (ahout->cmdstat) {
527                 case WIN_READ:
528                 case WIN_READ_EXT:
529                         n = ahout->scnt << 9;
530                         if (skb->len - sizeof *hin - sizeof *ahin < n) {
531                                 printk(KERN_CRIT "aoe: aoecmd_ata_rsp: runt "
532                                         "ata data size in read.  skb->len=%d\n",
533                                         skb->len);
534                                 /* fail frame f?  just returning will rexmit. */
535                                 spin_unlock_irqrestore(&d->lock, flags);
536                                 return;
537                         }
538                         memcpy(f->bufaddr, ahin+1, n);
539                 case WIN_WRITE:
540                 case WIN_WRITE_EXT:
541                         break;
542                 case WIN_IDENTIFY:
543                         if (skb->len - sizeof *hin - sizeof *ahin < 512) {
544                                 printk(KERN_INFO "aoe: aoecmd_ata_rsp: runt data size "
545                                         "in ataid.  skb->len=%d\n", skb->len);
546                                 spin_unlock_irqrestore(&d->lock, flags);
547                                 return;
548                         }
549                         ataid_complete(d, (char *) (ahin+1));
550                         d->flags &= ~DEVFL_PAUSE;
551                         break;
552                 default:
553                         printk(KERN_INFO "aoe: aoecmd_ata_rsp: unrecognized "
554                                "outbound ata command %2.2Xh for %d.%d\n", 
555                                ahout->cmdstat,
556                                be16_to_cpu(hin->major),
557                                hin->minor);
558                 }
559         }
560
561         if (buf) {
562                 buf->nframesout -= 1;
563                 if (buf->nframesout == 0 && buf->resid == 0) {
564                         unsigned long duration = jiffies - buf->start_time;
565                         unsigned long n_sect = buf->bio->bi_size >> 9;
566                         struct gendisk *disk = d->gd;
567                         const int rw = bio_data_dir(buf->bio);
568
569                         disk_stat_inc(disk, ios[rw]);
570                         disk_stat_add(disk, ticks[rw], duration);
571                         disk_stat_add(disk, sectors[rw], n_sect);
572                         disk_stat_add(disk, io_ticks, duration);
573                         n = (buf->flags & BUFFL_FAIL) ? -EIO : 0;
574                         bio_endio(buf->bio, buf->bio->bi_size, n);
575                         mempool_free(buf, d->bufpool);
576                 }
577         }
578
579         f->buf = NULL;
580         f->tag = FREETAG;
581
582         aoecmd_work(d);
583         sl = d->sendq_hd;
584         d->sendq_hd = d->sendq_tl = NULL;
585
586         spin_unlock_irqrestore(&d->lock, flags);
587         aoenet_xmit(sl);
588 }
589
590 void
591 aoecmd_cfg(ushort aoemajor, unsigned char aoeminor)
592 {
593         struct sk_buff *sl;
594
595         sl = aoecmd_cfg_pkts(aoemajor, aoeminor, NULL);
596
597         aoenet_xmit(sl);
598 }
599  
600 /*
601  * Since we only call this in one place (and it only prepares one frame)
602  * we just return the skb.  Usually we'd chain it up to the aoedev sendq.
603  */
604 static struct sk_buff *
605 aoecmd_ata_id(struct aoedev *d)
606 {
607         struct aoe_hdr *h;
608         struct aoe_atahdr *ah;
609         struct frame *f;
610         struct sk_buff *skb;
611
612         f = getframe(d, FREETAG);
613         if (f == NULL) {
614                 printk(KERN_CRIT "aoe: aoecmd_ata_id: can't get a frame.  "
615                         "This shouldn't happen.\n");
616                 return NULL;
617         }
618
619         /* initialize the headers & frame */
620         h = (struct aoe_hdr *) f->data;
621         ah = (struct aoe_atahdr *) (h+1);
622         f->ndata = sizeof *h + sizeof *ah;
623         memset(h, 0, f->ndata);
624         f->tag = aoehdr_atainit(d, h);
625         f->waited = 0;
626         f->writedatalen = 0;
627
628         /* set up ata header */
629         ah->scnt = 1;
630         ah->cmdstat = WIN_IDENTIFY;
631         ah->lba3 = 0xa0;
632
633         skb = skb_prepare(d, f);
634
635         d->rttavg = MAXTIMER;
636         d->timer.function = rexmit_timer;
637
638         return skb;
639 }
640  
641 void
642 aoecmd_cfg_rsp(struct sk_buff *skb)
643 {
644         struct aoedev *d;
645         struct aoe_hdr *h;
646         struct aoe_cfghdr *ch;
647         ulong flags, sysminor, aoemajor;
648         u16 bufcnt;
649         struct sk_buff *sl;
650         enum { MAXFRAMES = 8 };
651
652         h = (struct aoe_hdr *) skb->mac.raw;
653         ch = (struct aoe_cfghdr *) (h+1);
654
655         /*
656          * Enough people have their dip switches set backwards to
657          * warrant a loud message for this special case.
658          */
659         aoemajor = be16_to_cpu(h->major);
660         if (aoemajor == 0xfff) {
661                 printk(KERN_CRIT "aoe: aoecmd_cfg_rsp: Warning: shelf "
662                         "address is all ones.  Check shelf dip switches\n");
663                 return;
664         }
665
666         sysminor = SYSMINOR(aoemajor, h->minor);
667         if (sysminor * AOE_PARTITIONS + AOE_PARTITIONS > MINORMASK) {
668                 printk(KERN_INFO
669                         "aoe: e%ld.%d: minor number too large\n", 
670                         aoemajor, (int) h->minor);
671                 return;
672         }
673
674         bufcnt = be16_to_cpu(ch->bufcnt);
675         if (bufcnt > MAXFRAMES) /* keep it reasonable */
676                 bufcnt = MAXFRAMES;
677
678         d = aoedev_by_sysminor_m(sysminor, bufcnt);
679         if (d == NULL) {
680                 printk(KERN_INFO "aoe: aoecmd_cfg_rsp: device sysminor_m failure\n");
681                 return;
682         }
683
684         spin_lock_irqsave(&d->lock, flags);
685
686         /* permit device to migrate mac and network interface */
687         d->ifp = skb->dev;
688         memcpy(d->addr, h->src, sizeof d->addr);
689
690         /* don't change users' perspective */
691         if (d->nopen && !(d->flags & DEVFL_PAUSE)) {
692                 spin_unlock_irqrestore(&d->lock, flags);
693                 return;
694         }
695         d->flags |= DEVFL_PAUSE;        /* force pause */
696         d->fw_ver = be16_to_cpu(ch->fwver);
697
698         /* check for already outstanding ataid */
699         sl = aoedev_isbusy(d) == 0 ? aoecmd_ata_id(d) : NULL;
700
701         spin_unlock_irqrestore(&d->lock, flags);
702
703         aoenet_xmit(sl);
704 }
705