aoe: user can ask driver to forget previously detected devices
[deliverable/linux.git] / drivers / block / aoe / aoecmd.c
CommitLineData
2611464d 1/* Copyright (c) 2006 Coraid, Inc. See COPYING for GPL terms. */
1da177e4
LT
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>
3ae1c24e 11#include <linux/genhd.h>
68e0d42f 12#include <linux/moduleparam.h>
881d966b 13#include <net/net_namespace.h>
475172fb 14#include <asm/unaligned.h>
1da177e4
LT
15#include "aoe.h"
16
b751e8b6
EC
17static int aoe_deadsecs = 60 * 3;
18module_param(aoe_deadsecs, int, 0644);
19MODULE_PARM_DESC(aoe_deadsecs, "After aoe_deadsecs seconds, give up and fail dev.");
1da177e4 20
68e0d42f 21static struct sk_buff *
e407a7f6 22new_skb(ulong len)
1da177e4
LT
23{
24 struct sk_buff *skb;
25
26 skb = alloc_skb(len, GFP_ATOMIC);
27 if (skb) {
459a98ed 28 skb_reset_mac_header(skb);
c1d2bbe1 29 skb_reset_network_header(skb);
1da177e4
LT
30 skb->protocol = __constant_htons(ETH_P_AOE);
31 skb->priority = 0;
1da177e4
LT
32 skb->next = skb->prev = NULL;
33
34 /* tell the network layer not to perform IP checksums
35 * or to get the NIC to do it
36 */
37 skb->ip_summed = CHECKSUM_NONE;
38 }
39 return skb;
40}
41
1da177e4 42static struct frame *
68e0d42f 43getframe(struct aoetgt *t, int tag)
1da177e4
LT
44{
45 struct frame *f, *e;
46
68e0d42f
EC
47 f = t->frames;
48 e = f + t->nframes;
1da177e4
LT
49 for (; f<e; f++)
50 if (f->tag == tag)
51 return f;
52 return NULL;
53}
54
55/*
56 * Leave the top bit clear so we have tagspace for userland.
57 * The bottom 16 bits are the xmit tick for rexmit/rttavg processing.
58 * This driver reserves tag -1 to mean "unused frame."
59 */
60static int
68e0d42f 61newtag(struct aoetgt *t)
1da177e4
LT
62{
63 register ulong n;
64
65 n = jiffies & 0xffff;
68e0d42f 66 return n |= (++t->lasttag & 0x7fff) << 16;
1da177e4
LT
67}
68
69static int
68e0d42f 70aoehdr_atainit(struct aoedev *d, struct aoetgt *t, struct aoe_hdr *h)
1da177e4 71{
68e0d42f 72 u32 host_tag = newtag(t);
1da177e4 73
68e0d42f
EC
74 memcpy(h->src, t->ifp->nd->dev_addr, sizeof h->src);
75 memcpy(h->dst, t->addr, sizeof h->dst);
63e9cc5d 76 h->type = __constant_cpu_to_be16(ETH_P_AOE);
1da177e4 77 h->verfl = AOE_HVER;
63e9cc5d 78 h->major = cpu_to_be16(d->aoemajor);
1da177e4
LT
79 h->minor = d->aoeminor;
80 h->cmd = AOECMD_ATA;
63e9cc5d 81 h->tag = cpu_to_be32(host_tag);
1da177e4
LT
82
83 return host_tag;
84}
85
19bf2635
EC
86static inline void
87put_lba(struct aoe_atahdr *ah, sector_t lba)
88{
89 ah->lba0 = lba;
90 ah->lba1 = lba >>= 8;
91 ah->lba2 = lba >>= 8;
92 ah->lba3 = lba >>= 8;
93 ah->lba4 = lba >>= 8;
94 ah->lba5 = lba >>= 8;
95}
96
1da177e4 97static void
68e0d42f
EC
98ifrotate(struct aoetgt *t)
99{
100 t->ifp++;
101 if (t->ifp >= &t->ifs[NAOEIFS] || t->ifp->nd == NULL)
102 t->ifp = t->ifs;
103 if (t->ifp->nd == NULL) {
104 printk(KERN_INFO "aoe: no interface to rotate to\n");
105 BUG();
106 }
107}
108
109static struct frame *
110freeframe(struct aoedev *d)
1da177e4 111{
68e0d42f
EC
112 struct frame *f, *e;
113 struct aoetgt **t;
114 ulong n;
115
116 if (d->targets[0] == NULL) { /* shouldn't happen, but I'm paranoid */
117 printk(KERN_ERR "aoe: NULL TARGETS!\n");
118 return NULL;
119 }
120 t = d->targets;
121 do {
122 if (t != d->htgt
123 && (*t)->ifp->nd
124 && (*t)->nout < (*t)->maxout) {
125 n = (*t)->nframes;
126 f = (*t)->frames;
127 e = f + n;
128 for (; f < e; f++) {
129 if (f->tag != FREETAG)
130 continue;
131 if (atomic_read(&skb_shinfo(f->skb)->dataref)
132 != 1) {
133 n--;
134 continue;
135 }
136 skb_shinfo(f->skb)->nr_frags = 0;
137 f->skb->data_len = 0;
138 skb_trim(f->skb, 0);
139 d->tgt = t;
140 ifrotate(*t);
141 return f;
142 }
143 if (n == 0) /* slow polling network card */
144 d->flags |= DEVFL_KICKME;
145 }
146 t++;
147 } while (t < &d->targets[NTARGETS] && *t);
148 return NULL;
149}
150
151static int
152aoecmd_ata_rw(struct aoedev *d)
153{
154 struct frame *f;
1da177e4
LT
155 struct aoe_hdr *h;
156 struct aoe_atahdr *ah;
157 struct buf *buf;
68e0d42f
EC
158 struct bio_vec *bv;
159 struct aoetgt *t;
1da177e4
LT
160 struct sk_buff *skb;
161 ulong bcnt;
1da177e4
LT
162 char writebit, extbit;
163
164 writebit = 0x10;
165 extbit = 0x4;
166
68e0d42f
EC
167 f = freeframe(d);
168 if (f == NULL)
169 return 0;
170 t = *d->tgt;
1da177e4 171 buf = d->inprocess;
68e0d42f
EC
172 bv = buf->bv;
173 bcnt = t->ifp->maxbcnt;
174 if (bcnt == 0)
175 bcnt = DEFAULTBCNT;
176 if (bcnt > buf->bv_resid)
177 bcnt = buf->bv_resid;
1da177e4 178 /* initialize the headers & frame */
e407a7f6 179 skb = f->skb;
abdbf94d 180 h = (struct aoe_hdr *) skb_mac_header(skb);
1da177e4 181 ah = (struct aoe_atahdr *) (h+1);
19900cde
EC
182 skb_put(skb, sizeof *h + sizeof *ah);
183 memset(h, 0, skb->len);
68e0d42f
EC
184 f->tag = aoehdr_atainit(d, t, h);
185 t->nout++;
1da177e4
LT
186 f->waited = 0;
187 f->buf = buf;
68e0d42f 188 f->bufaddr = page_address(bv->bv_page) + buf->bv_off;
19bf2635 189 f->bcnt = bcnt;
68e0d42f 190 f->lba = buf->sector;
1da177e4
LT
191
192 /* set up ata header */
193 ah->scnt = bcnt >> 9;
68e0d42f 194 put_lba(ah, buf->sector);
1da177e4
LT
195 if (d->flags & DEVFL_EXT) {
196 ah->aflags |= AOEAFL_EXT;
1da177e4
LT
197 } else {
198 extbit = 0;
199 ah->lba3 &= 0x0f;
200 ah->lba3 |= 0xe0; /* LBA bit + obsolete 0xa0 */
201 }
1da177e4 202 if (bio_data_dir(buf->bio) == WRITE) {
68e0d42f 203 skb_fill_page_desc(skb, 0, bv->bv_page, buf->bv_off, bcnt);
1da177e4 204 ah->aflags |= AOEAFL_WRITE;
4f51dc5e
EC
205 skb->len += bcnt;
206 skb->data_len = bcnt;
68e0d42f 207 t->wpkts++;
1da177e4 208 } else {
68e0d42f 209 t->rpkts++;
1da177e4 210 writebit = 0;
1da177e4
LT
211 }
212
213 ah->cmdstat = WIN_READ | writebit | extbit;
214
215 /* mark all tracking fields and load out */
216 buf->nframesout += 1;
68e0d42f 217 buf->bv_off += bcnt;
1da177e4 218 buf->bv_resid -= bcnt;
1da177e4
LT
219 buf->resid -= bcnt;
220 buf->sector += bcnt >> 9;
221 if (buf->resid == 0) {
222 d->inprocess = NULL;
223 } else if (buf->bv_resid == 0) {
68e0d42f
EC
224 buf->bv = ++bv;
225 buf->bv_resid = bv->bv_len;
226 WARN_ON(buf->bv_resid == 0);
227 buf->bv_off = bv->bv_offset;
1da177e4
LT
228 }
229
68e0d42f 230 skb->dev = t->ifp->nd;
4f51dc5e 231 skb = skb_clone(skb, GFP_ATOMIC);
68e0d42f
EC
232 if (skb) {
233 if (d->sendq_hd)
234 d->sendq_tl->next = skb;
235 else
236 d->sendq_hd = skb;
237 d->sendq_tl = skb;
238 }
239 return 1;
1da177e4
LT
240}
241
3ae1c24e
EC
242/* some callers cannot sleep, and they can call this function,
243 * transmitting the packets later, when interrupts are on
244 */
245static struct sk_buff *
246aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail)
247{
248 struct aoe_hdr *h;
249 struct aoe_cfghdr *ch;
250 struct sk_buff *skb, *sl, *sl_tail;
251 struct net_device *ifp;
252
253 sl = sl_tail = NULL;
254
255 read_lock(&dev_base_lock);
881d966b 256 for_each_netdev(&init_net, ifp) {
3ae1c24e
EC
257 dev_hold(ifp);
258 if (!is_aoe_netif(ifp))
7562f876 259 goto cont;
3ae1c24e 260
e407a7f6 261 skb = new_skb(sizeof *h + sizeof *ch);
3ae1c24e 262 if (skb == NULL) {
a12c93f0 263 printk(KERN_INFO "aoe: skb alloc failure\n");
7562f876 264 goto cont;
3ae1c24e 265 }
19900cde 266 skb_put(skb, sizeof *h + sizeof *ch);
e407a7f6 267 skb->dev = ifp;
3ae1c24e
EC
268 if (sl_tail == NULL)
269 sl_tail = skb;
abdbf94d 270 h = (struct aoe_hdr *) skb_mac_header(skb);
3ae1c24e
EC
271 memset(h, 0, sizeof *h + sizeof *ch);
272
273 memset(h->dst, 0xff, sizeof h->dst);
274 memcpy(h->src, ifp->dev_addr, sizeof h->src);
275 h->type = __constant_cpu_to_be16(ETH_P_AOE);
276 h->verfl = AOE_HVER;
277 h->major = cpu_to_be16(aoemajor);
278 h->minor = aoeminor;
279 h->cmd = AOECMD_CFG;
280
281 skb->next = sl;
282 sl = skb;
7562f876
PE
283cont:
284 dev_put(ifp);
3ae1c24e
EC
285 }
286 read_unlock(&dev_base_lock);
287
288 if (tail != NULL)
289 *tail = sl_tail;
290 return sl;
291}
292
1da177e4 293static void
68e0d42f 294resend(struct aoedev *d, struct aoetgt *t, struct frame *f)
1da177e4
LT
295{
296 struct sk_buff *skb;
297 struct aoe_hdr *h;
19bf2635 298 struct aoe_atahdr *ah;
1da177e4
LT
299 char buf[128];
300 u32 n;
1da177e4 301
68e0d42f
EC
302 ifrotate(t);
303 n = newtag(t);
304 skb = f->skb;
305 h = (struct aoe_hdr *) skb_mac_header(skb);
306 ah = (struct aoe_atahdr *) (h+1);
1da177e4
LT
307
308 snprintf(buf, sizeof buf,
68e0d42f
EC
309 "%15s e%ld.%d oldtag=%08x@%08lx newtag=%08x "
310 "s=%012llx d=%012llx nout=%d\n",
311 "retransmit", d->aoemajor, d->aoeminor, f->tag, jiffies, n,
1eb0da4c
EC
312 mac_addr(h->src),
313 mac_addr(h->dst), t->nout);
1da177e4
LT
314 aoechr_error(buf);
315
1da177e4 316 f->tag = n;
63e9cc5d 317 h->tag = cpu_to_be32(n);
68e0d42f
EC
318 memcpy(h->dst, t->addr, sizeof h->dst);
319 memcpy(h->src, t->ifp->nd->dev_addr, sizeof h->src);
320
321 switch (ah->cmdstat) {
322 default:
323 break;
324 case WIN_READ:
325 case WIN_READ_EXT:
326 case WIN_WRITE:
327 case WIN_WRITE_EXT:
328 put_lba(ah, f->lba);
329
330 n = f->bcnt;
331 if (n > DEFAULTBCNT)
332 n = DEFAULTBCNT;
333 ah->scnt = n >> 9;
4f51dc5e 334 if (ah->aflags & AOEAFL_WRITE) {
19bf2635 335 skb_fill_page_desc(skb, 0, virt_to_page(f->bufaddr),
68e0d42f
EC
336 offset_in_page(f->bufaddr), n);
337 skb->len = sizeof *h + sizeof *ah + n;
338 skb->data_len = n;
19bf2635
EC
339 }
340 }
68e0d42f 341 skb->dev = t->ifp->nd;
4f51dc5e
EC
342 skb = skb_clone(skb, GFP_ATOMIC);
343 if (skb == NULL)
344 return;
e407a7f6
EC
345 if (d->sendq_hd)
346 d->sendq_tl->next = skb;
347 else
348 d->sendq_hd = skb;
349 d->sendq_tl = skb;
1da177e4
LT
350}
351
352static int
353tsince(int tag)
354{
355 int n;
356
357 n = jiffies & 0xffff;
358 n -= tag & 0xffff;
359 if (n < 0)
360 n += 1<<16;
361 return n;
362}
363
68e0d42f
EC
364static struct aoeif *
365getif(struct aoetgt *t, struct net_device *nd)
366{
367 struct aoeif *p, *e;
368
369 p = t->ifs;
370 e = p + NAOEIFS;
371 for (; p < e; p++)
372 if (p->nd == nd)
373 return p;
374 return NULL;
375}
376
377static struct aoeif *
378addif(struct aoetgt *t, struct net_device *nd)
379{
380 struct aoeif *p;
381
382 p = getif(t, NULL);
383 if (!p)
384 return NULL;
385 p->nd = nd;
386 p->maxbcnt = DEFAULTBCNT;
387 p->lost = 0;
388 p->lostjumbo = 0;
389 return p;
390}
391
392static void
393ejectif(struct aoetgt *t, struct aoeif *ifp)
394{
395 struct aoeif *e;
396 ulong n;
397
398 e = t->ifs + NAOEIFS - 1;
399 n = (e - ifp) * sizeof *ifp;
400 memmove(ifp, ifp+1, n);
401 e->nd = NULL;
402}
403
404static int
405sthtith(struct aoedev *d)
406{
407 struct frame *f, *e, *nf;
408 struct sk_buff *skb;
409 struct aoetgt *ht = *d->htgt;
410
411 f = ht->frames;
412 e = f + ht->nframes;
413 for (; f < e; f++) {
414 if (f->tag == FREETAG)
415 continue;
416 nf = freeframe(d);
417 if (!nf)
418 return 0;
419 skb = nf->skb;
420 *nf = *f;
421 f->skb = skb;
422 f->tag = FREETAG;
423 nf->waited = 0;
424 ht->nout--;
425 (*d->tgt)->nout++;
426 resend(d, *d->tgt, nf);
427 }
428 /* he's clean, he's useless. take away his interfaces */
429 memset(ht->ifs, 0, sizeof ht->ifs);
430 d->htgt = NULL;
431 return 1;
432}
433
434static inline unsigned char
435ata_scnt(unsigned char *packet) {
436 struct aoe_hdr *h;
437 struct aoe_atahdr *ah;
438
439 h = (struct aoe_hdr *) packet;
440 ah = (struct aoe_atahdr *) (h+1);
441 return ah->scnt;
442}
443
1da177e4
LT
444static void
445rexmit_timer(ulong vp)
446{
447 struct aoedev *d;
68e0d42f
EC
448 struct aoetgt *t, **tt, **te;
449 struct aoeif *ifp;
1da177e4
LT
450 struct frame *f, *e;
451 struct sk_buff *sl;
452 register long timeout;
453 ulong flags, n;
454
455 d = (struct aoedev *) vp;
456 sl = NULL;
457
458 /* timeout is always ~150% of the moving average */
459 timeout = d->rttavg;
460 timeout += timeout >> 1;
461
462 spin_lock_irqsave(&d->lock, flags);
463
464 if (d->flags & DEVFL_TKILL) {
1c6f3fca 465 spin_unlock_irqrestore(&d->lock, flags);
1da177e4
LT
466 return;
467 }
68e0d42f
EC
468 tt = d->targets;
469 te = tt + NTARGETS;
470 for (; tt < te && *tt; tt++) {
471 t = *tt;
472 f = t->frames;
473 e = f + t->nframes;
474 for (; f < e; f++) {
475 if (f->tag == FREETAG
476 || tsince(f->tag) < timeout)
477 continue;
1da177e4
LT
478 n = f->waited += timeout;
479 n /= HZ;
68e0d42f
EC
480 if (n > aoe_deadsecs) {
481 /* waited too long. device failure. */
1da177e4 482 aoedev_downdev(d);
1c6f3fca 483 break;
1da177e4 484 }
68e0d42f
EC
485
486 if (n > HELPWAIT /* see if another target can help */
487 && (tt != d->targets || d->targets[1]))
488 d->htgt = tt;
489
490 if (t->nout == t->maxout) {
491 if (t->maxout > 1)
492 t->maxout--;
493 t->lastwadj = jiffies;
494 }
495
496 ifp = getif(t, f->skb->dev);
497 if (ifp && ++ifp->lost > (t->nframes << 1)
498 && (ifp != t->ifs || t->ifs[1].nd)) {
499 ejectif(t, ifp);
500 ifp = NULL;
501 }
502
503 if (ata_scnt(skb_mac_header(f->skb)) > DEFAULTBCNT / 512
504 && ifp && ++ifp->lostjumbo > (t->nframes << 1)
505 && ifp->maxbcnt != DEFAULTBCNT) {
506 printk(KERN_INFO
507 "aoe: e%ld.%d: "
508 "too many lost jumbo on "
509 "%s:%012llx - "
510 "falling back to %d frames.\n",
511 d->aoemajor, d->aoeminor,
512 ifp->nd->name, mac_addr(t->addr),
513 DEFAULTBCNT);
514 ifp->maxbcnt = 0;
515 }
516 resend(d, t, f);
517 }
518
519 /* window check */
520 if (t->nout == t->maxout
521 && t->maxout < t->nframes
522 && (jiffies - t->lastwadj)/HZ > 10) {
523 t->maxout++;
524 t->lastwadj = jiffies;
1da177e4
LT
525 }
526 }
68e0d42f
EC
527
528 if (d->sendq_hd) {
529 n = d->rttavg <<= 1;
530 if (n > MAXTIMER)
531 d->rttavg = MAXTIMER;
532 }
533
534 if (d->flags & DEVFL_KICKME || d->htgt) {
4f51dc5e
EC
535 d->flags &= ~DEVFL_KICKME;
536 aoecmd_work(d);
537 }
1da177e4 538
a4b38364 539 sl = d->sendq_hd;
540 d->sendq_hd = d->sendq_tl = NULL;
1da177e4
LT
541
542 d->timer.expires = jiffies + TIMERTICK;
543 add_timer(&d->timer);
544
545 spin_unlock_irqrestore(&d->lock, flags);
546
547 aoenet_xmit(sl);
548}
549
68e0d42f
EC
550/* enters with d->lock held */
551void
552aoecmd_work(struct aoedev *d)
553{
554 struct buf *buf;
555loop:
556 if (d->htgt && !sthtith(d))
557 return;
558 if (d->inprocess == NULL) {
559 if (list_empty(&d->bufq))
560 return;
561 buf = container_of(d->bufq.next, struct buf, bufs);
562 list_del(d->bufq.next);
563 d->inprocess = buf;
564 }
565 if (aoecmd_ata_rw(d))
566 goto loop;
567}
568
3ae1c24e
EC
569/* this function performs work that has been deferred until sleeping is OK
570 */
571void
c4028958 572aoecmd_sleepwork(struct work_struct *work)
3ae1c24e 573{
c4028958 574 struct aoedev *d = container_of(work, struct aoedev, work);
3ae1c24e
EC
575
576 if (d->flags & DEVFL_GDALLOC)
577 aoeblk_gdalloc(d);
578
579 if (d->flags & DEVFL_NEWSIZE) {
580 struct block_device *bd;
581 unsigned long flags;
582 u64 ssize;
583
584 ssize = d->gd->capacity;
585 bd = bdget_disk(d->gd, 0);
586
587 if (bd) {
588 mutex_lock(&bd->bd_inode->i_mutex);
589 i_size_write(bd->bd_inode, (loff_t)ssize<<9);
590 mutex_unlock(&bd->bd_inode->i_mutex);
591 bdput(bd);
592 }
593 spin_lock_irqsave(&d->lock, flags);
594 d->flags |= DEVFL_UP;
595 d->flags &= ~DEVFL_NEWSIZE;
596 spin_unlock_irqrestore(&d->lock, flags);
597 }
598}
599
1da177e4 600static void
68e0d42f 601ataid_complete(struct aoedev *d, struct aoetgt *t, unsigned char *id)
1da177e4
LT
602{
603 u64 ssize;
604 u16 n;
605
606 /* word 83: command set supported */
475172fb 607 n = le16_to_cpu(get_unaligned((__le16 *) &id[83<<1]));
1da177e4
LT
608
609 /* word 86: command set/feature enabled */
475172fb 610 n |= le16_to_cpu(get_unaligned((__le16 *) &id[86<<1]));
1da177e4
LT
611
612 if (n & (1<<10)) { /* bit 10: LBA 48 */
613 d->flags |= DEVFL_EXT;
614
615 /* word 100: number lba48 sectors */
475172fb 616 ssize = le64_to_cpu(get_unaligned((__le64 *) &id[100<<1]));
1da177e4
LT
617
618 /* set as in ide-disk.c:init_idedisk_capacity */
619 d->geo.cylinders = ssize;
620 d->geo.cylinders /= (255 * 63);
621 d->geo.heads = 255;
622 d->geo.sectors = 63;
623 } else {
624 d->flags &= ~DEVFL_EXT;
625
626 /* number lba28 sectors */
475172fb 627 ssize = le32_to_cpu(get_unaligned((__le32 *) &id[60<<1]));
1da177e4
LT
628
629 /* NOTE: obsolete in ATA 6 */
475172fb
EC
630 d->geo.cylinders = le16_to_cpu(get_unaligned((__le16 *) &id[54<<1]));
631 d->geo.heads = le16_to_cpu(get_unaligned((__le16 *) &id[55<<1]));
632 d->geo.sectors = le16_to_cpu(get_unaligned((__le16 *) &id[56<<1]));
1da177e4 633 }
3ae1c24e
EC
634
635 if (d->ssize != ssize)
a12c93f0 636 printk(KERN_INFO "aoe: %012llx e%lu.%lu v%04x has %llu sectors\n",
1eb0da4c 637 mac_addr(t->addr),
3ae1c24e
EC
638 d->aoemajor, d->aoeminor,
639 d->fw_ver, (long long)ssize);
1da177e4
LT
640 d->ssize = ssize;
641 d->geo.start = 0;
642 if (d->gd != NULL) {
643 d->gd->capacity = ssize;
3ae1c24e 644 d->flags |= DEVFL_NEWSIZE;
68e0d42f 645 } else
3ae1c24e 646 d->flags |= DEVFL_GDALLOC;
1da177e4 647 schedule_work(&d->work);
1da177e4
LT
648}
649
650static void
651calc_rttavg(struct aoedev *d, int rtt)
652{
653 register long n;
654
655 n = rtt;
dced3a05
EC
656 if (n < 0) {
657 n = -rtt;
658 if (n < MINTIMER)
659 n = MINTIMER;
660 else if (n > MAXTIMER)
661 n = MAXTIMER;
662 d->mintimer += (n - d->mintimer) >> 1;
663 } else if (n < d->mintimer)
664 n = d->mintimer;
1da177e4
LT
665 else if (n > MAXTIMER)
666 n = MAXTIMER;
667
668 /* g == .25; cf. Congestion Avoidance and Control, Jacobson & Karels; 1988 */
669 n -= d->rttavg;
670 d->rttavg += n >> 2;
671}
672
68e0d42f
EC
673static struct aoetgt *
674gettgt(struct aoedev *d, char *addr)
675{
676 struct aoetgt **t, **e;
677
678 t = d->targets;
679 e = t + NTARGETS;
680 for (; t < e && *t; t++)
681 if (memcmp((*t)->addr, addr, sizeof((*t)->addr)) == 0)
682 return *t;
683 return NULL;
684}
685
686static inline void
687diskstats(struct gendisk *disk, struct bio *bio, ulong duration)
688{
689 unsigned long n_sect = bio->bi_size >> 9;
690 const int rw = bio_data_dir(bio);
691
692 disk_stat_inc(disk, ios[rw]);
693 disk_stat_add(disk, ticks[rw], duration);
694 disk_stat_add(disk, sectors[rw], n_sect);
695 disk_stat_add(disk, io_ticks, duration);
696}
697
1da177e4
LT
698void
699aoecmd_ata_rsp(struct sk_buff *skb)
700{
701 struct aoedev *d;
ddec63e8 702 struct aoe_hdr *hin, *hout;
1da177e4
LT
703 struct aoe_atahdr *ahin, *ahout;
704 struct frame *f;
705 struct buf *buf;
706 struct sk_buff *sl;
68e0d42f
EC
707 struct aoetgt *t;
708 struct aoeif *ifp;
1da177e4
LT
709 register long n;
710 ulong flags;
711 char ebuf[128];
32465c65 712 u16 aoemajor;
713
abdbf94d 714 hin = (struct aoe_hdr *) skb_mac_header(skb);
43ecf529 715 aoemajor = be16_to_cpu(get_unaligned(&hin->major));
32465c65 716 d = aoedev_by_aoeaddr(aoemajor, hin->minor);
1da177e4
LT
717 if (d == NULL) {
718 snprintf(ebuf, sizeof ebuf, "aoecmd_ata_rsp: ata response "
719 "for unknown device %d.%d\n",
32465c65 720 aoemajor, hin->minor);
1da177e4
LT
721 aoechr_error(ebuf);
722 return;
723 }
724
725 spin_lock_irqsave(&d->lock, flags);
726
43ecf529 727 n = be32_to_cpu(get_unaligned(&hin->tag));
68e0d42f
EC
728 t = gettgt(d, hin->src);
729 if (t == NULL) {
730 printk(KERN_INFO "aoe: can't find target e%ld.%d:%012llx\n",
1eb0da4c 731 d->aoemajor, d->aoeminor, mac_addr(hin->src));
68e0d42f
EC
732 spin_unlock_irqrestore(&d->lock, flags);
733 return;
734 }
735 f = getframe(t, n);
1da177e4 736 if (f == NULL) {
dced3a05 737 calc_rttavg(d, -tsince(n));
1da177e4
LT
738 spin_unlock_irqrestore(&d->lock, flags);
739 snprintf(ebuf, sizeof ebuf,
740 "%15s e%d.%d tag=%08x@%08lx\n",
741 "unexpected rsp",
43ecf529 742 be16_to_cpu(get_unaligned(&hin->major)),
1da177e4 743 hin->minor,
43ecf529 744 be32_to_cpu(get_unaligned(&hin->tag)),
1da177e4
LT
745 jiffies);
746 aoechr_error(ebuf);
747 return;
748 }
749
750 calc_rttavg(d, tsince(f->tag));
751
752 ahin = (struct aoe_atahdr *) (hin+1);
abdbf94d 753 hout = (struct aoe_hdr *) skb_mac_header(f->skb);
ddec63e8 754 ahout = (struct aoe_atahdr *) (hout+1);
1da177e4
LT
755 buf = f->buf;
756
757 if (ahin->cmdstat & 0xa9) { /* these bits cleared on success */
a12c93f0
EC
758 printk(KERN_ERR
759 "aoe: ata error cmd=%2.2Xh stat=%2.2Xh from e%ld.%ld\n",
1da177e4
LT
760 ahout->cmdstat, ahin->cmdstat,
761 d->aoemajor, d->aoeminor);
762 if (buf)
763 buf->flags |= BUFFL_FAIL;
764 } else {
68e0d42f
EC
765 if (d->htgt && t == *d->htgt) /* I'll help myself, thank you. */
766 d->htgt = NULL;
19bf2635 767 n = ahout->scnt << 9;
1da177e4
LT
768 switch (ahout->cmdstat) {
769 case WIN_READ:
770 case WIN_READ_EXT:
1da177e4 771 if (skb->len - sizeof *hin - sizeof *ahin < n) {
a12c93f0 772 printk(KERN_ERR
68e0d42f
EC
773 "aoe: %s. skb->len=%d need=%ld\n",
774 "runt data size in read", skb->len, n);
1da177e4
LT
775 /* fail frame f? just returning will rexmit. */
776 spin_unlock_irqrestore(&d->lock, flags);
777 return;
778 }
779 memcpy(f->bufaddr, ahin+1, n);
780 case WIN_WRITE:
781 case WIN_WRITE_EXT:
68e0d42f
EC
782 ifp = getif(t, skb->dev);
783 if (ifp) {
784 ifp->lost = 0;
785 if (n > DEFAULTBCNT)
786 ifp->lostjumbo = 0;
787 }
19bf2635 788 if (f->bcnt -= n) {
68e0d42f 789 f->lba += n >> 9;
19bf2635 790 f->bufaddr += n;
68e0d42f
EC
791 resend(d, t, f);
792 goto xmit;
19bf2635 793 }
1da177e4
LT
794 break;
795 case WIN_IDENTIFY:
796 if (skb->len - sizeof *hin - sizeof *ahin < 512) {
a12c93f0
EC
797 printk(KERN_INFO
798 "aoe: runt data size in ataid. skb->len=%d\n",
6bb6285f 799 skb->len);
1da177e4
LT
800 spin_unlock_irqrestore(&d->lock, flags);
801 return;
802 }
68e0d42f 803 ataid_complete(d, t, (char *) (ahin+1));
1da177e4
LT
804 break;
805 default:
a12c93f0
EC
806 printk(KERN_INFO
807 "aoe: unrecognized ata command %2.2Xh for %d.%d\n",
6bb6285f 808 ahout->cmdstat,
43ecf529 809 be16_to_cpu(get_unaligned(&hin->major)),
6bb6285f 810 hin->minor);
1da177e4
LT
811 }
812 }
813
68e0d42f
EC
814 if (buf && --buf->nframesout == 0 && buf->resid == 0) {
815 diskstats(d->gd, buf->bio, jiffies - buf->stime);
816 n = (buf->flags & BUFFL_FAIL) ? -EIO : 0;
817 bio_endio(buf->bio, n);
818 mempool_free(buf, d->bufpool);
1da177e4
LT
819 }
820
821 f->buf = NULL;
822 f->tag = FREETAG;
68e0d42f 823 t->nout--;
1da177e4
LT
824
825 aoecmd_work(d);
68e0d42f 826xmit:
a4b38364 827 sl = d->sendq_hd;
828 d->sendq_hd = d->sendq_tl = NULL;
1da177e4
LT
829
830 spin_unlock_irqrestore(&d->lock, flags);
1da177e4
LT
831 aoenet_xmit(sl);
832}
833
834void
835aoecmd_cfg(ushort aoemajor, unsigned char aoeminor)
836{
3ae1c24e 837 struct sk_buff *sl;
1da177e4 838
3ae1c24e 839 sl = aoecmd_cfg_pkts(aoemajor, aoeminor, NULL);
1da177e4
LT
840
841 aoenet_xmit(sl);
842}
843
68e0d42f 844struct sk_buff *
1da177e4
LT
845aoecmd_ata_id(struct aoedev *d)
846{
847 struct aoe_hdr *h;
848 struct aoe_atahdr *ah;
849 struct frame *f;
850 struct sk_buff *skb;
68e0d42f 851 struct aoetgt *t;
1da177e4 852
4f51dc5e 853 f = freeframe(d);
68e0d42f 854 if (f == NULL)
1da177e4 855 return NULL;
68e0d42f
EC
856
857 t = *d->tgt;
1da177e4
LT
858
859 /* initialize the headers & frame */
e407a7f6 860 skb = f->skb;
abdbf94d 861 h = (struct aoe_hdr *) skb_mac_header(skb);
1da177e4 862 ah = (struct aoe_atahdr *) (h+1);
19900cde
EC
863 skb_put(skb, sizeof *h + sizeof *ah);
864 memset(h, 0, skb->len);
68e0d42f
EC
865 f->tag = aoehdr_atainit(d, t, h);
866 t->nout++;
1da177e4 867 f->waited = 0;
1da177e4 868
1da177e4
LT
869 /* set up ata header */
870 ah->scnt = 1;
871 ah->cmdstat = WIN_IDENTIFY;
872 ah->lba3 = 0xa0;
873
68e0d42f 874 skb->dev = t->ifp->nd;
1da177e4 875
3ae1c24e 876 d->rttavg = MAXTIMER;
1da177e4 877 d->timer.function = rexmit_timer;
1da177e4 878
4f51dc5e 879 return skb_clone(skb, GFP_ATOMIC);
1da177e4
LT
880}
881
68e0d42f
EC
882static struct aoetgt *
883addtgt(struct aoedev *d, char *addr, ulong nframes)
884{
885 struct aoetgt *t, **tt, **te;
886 struct frame *f, *e;
887
888 tt = d->targets;
889 te = tt + NTARGETS;
890 for (; tt < te && *tt; tt++)
891 ;
892
893 if (tt == te)
894 return NULL;
895
896 t = kcalloc(1, sizeof *t, GFP_ATOMIC);
897 f = kcalloc(nframes, sizeof *f, GFP_ATOMIC);
898 if (!t || !f)
899 goto bail;
900 t->nframes = nframes;
901 t->frames = f;
902 e = f + nframes;
903 for (; f < e; f++) {
904 f->tag = FREETAG;
905 f->skb = new_skb(ETH_ZLEN);
906 if (!f->skb)
907 break;
908 }
909 if (f != e) {
910 while (f > t->frames) {
911 f--;
912 dev_kfree_skb(f->skb);
913 }
914 goto bail;
915 }
916 memcpy(t->addr, addr, sizeof t->addr);
917 t->ifp = t->ifs;
918 t->maxout = t->nframes;
919 return *tt = t;
920bail:
921 kfree(t);
922 kfree(f);
923 return NULL;
924}
925
1da177e4
LT
926void
927aoecmd_cfg_rsp(struct sk_buff *skb)
928{
929 struct aoedev *d;
930 struct aoe_hdr *h;
931 struct aoe_cfghdr *ch;
68e0d42f
EC
932 struct aoetgt *t;
933 struct aoeif *ifp;
63e9cc5d 934 ulong flags, sysminor, aoemajor;
1da177e4 935 struct sk_buff *sl;
eaf0a3cb 936 enum { MAXFRAMES = 16 };
19bf2635 937 u16 n;
1da177e4 938
abdbf94d 939 h = (struct aoe_hdr *) skb_mac_header(skb);
1da177e4
LT
940 ch = (struct aoe_cfghdr *) (h+1);
941
942 /*
943 * Enough people have their dip switches set backwards to
944 * warrant a loud message for this special case.
945 */
43ecf529 946 aoemajor = be16_to_cpu(get_unaligned(&h->major));
1da177e4 947 if (aoemajor == 0xfff) {
a12c93f0 948 printk(KERN_ERR "aoe: Warning: shelf address is all ones. "
6bb6285f 949 "Check shelf dip switches.\n");
1da177e4
LT
950 return;
951 }
952
953 sysminor = SYSMINOR(aoemajor, h->minor);
fc458dcd 954 if (sysminor * AOE_PARTITIONS + AOE_PARTITIONS > MINORMASK) {
a12c93f0 955 printk(KERN_INFO "aoe: e%ld.%d: minor number too large\n",
fc458dcd 956 aoemajor, (int) h->minor);
1da177e4
LT
957 return;
958 }
959
19bf2635
EC
960 n = be16_to_cpu(ch->bufcnt);
961 if (n > MAXFRAMES) /* keep it reasonable */
962 n = MAXFRAMES;
1da177e4 963
68e0d42f 964 d = aoedev_by_sysminor_m(sysminor);
1da177e4 965 if (d == NULL) {
a12c93f0 966 printk(KERN_INFO "aoe: device sysminor_m failure\n");
1da177e4
LT
967 return;
968 }
969
970 spin_lock_irqsave(&d->lock, flags);
971
68e0d42f
EC
972 t = gettgt(d, h->src);
973 if (!t) {
974 t = addtgt(d, h->src, n);
975 if (!t) {
976 printk(KERN_INFO
977 "aoe: device addtgt failure; "
978 "too many targets?\n");
979 spin_unlock_irqrestore(&d->lock, flags);
980 return;
981 }
982 }
983 ifp = getif(t, skb->dev);
984 if (!ifp) {
985 ifp = addif(t, skb->dev);
986 if (!ifp) {
987 printk(KERN_INFO
988 "aoe: device addif failure; "
989 "too many interfaces?\n");
990 spin_unlock_irqrestore(&d->lock, flags);
991 return;
992 }
993 }
994 if (ifp->maxbcnt) {
995 n = ifp->nd->mtu;
19bf2635
EC
996 n -= sizeof (struct aoe_hdr) + sizeof (struct aoe_atahdr);
997 n /= 512;
998 if (n > ch->scnt)
999 n = ch->scnt;
4f51dc5e 1000 n = n ? n * 512 : DEFAULTBCNT;
68e0d42f 1001 if (n != ifp->maxbcnt) {
a12c93f0 1002 printk(KERN_INFO
68e0d42f
EC
1003 "aoe: e%ld.%d: setting %d%s%s:%012llx\n",
1004 d->aoemajor, d->aoeminor, n,
1005 " byte data frames on ", ifp->nd->name,
1eb0da4c 1006 mac_addr(t->addr));
68e0d42f 1007 ifp->maxbcnt = n;
4f51dc5e 1008 }
19bf2635 1009 }
3ae1c24e
EC
1010
1011 /* don't change users' perspective */
68e0d42f 1012 if (d->nopen) {
1da177e4
LT
1013 spin_unlock_irqrestore(&d->lock, flags);
1014 return;
1015 }
63e9cc5d 1016 d->fw_ver = be16_to_cpu(ch->fwver);
1da177e4 1017
68e0d42f 1018 sl = aoecmd_ata_id(d);
1da177e4
LT
1019
1020 spin_unlock_irqrestore(&d->lock, flags);
1021
1022 aoenet_xmit(sl);
1023}
1024
68e0d42f
EC
1025void
1026aoecmd_cleanslate(struct aoedev *d)
1027{
1028 struct aoetgt **t, **te;
1029 struct aoeif *p, *e;
1030
1031 d->mintimer = MINTIMER;
1032
1033 t = d->targets;
1034 te = t + NTARGETS;
1035 for (; t < te && *t; t++) {
1036 (*t)->maxout = (*t)->nframes;
1037 p = (*t)->ifs;
1038 e = p + NAOEIFS;
1039 for (; p < e; p++) {
1040 p->lostjumbo = 0;
1041 p->lost = 0;
1042 p->maxbcnt = DEFAULTBCNT;
1043 }
1044 }
1045}
This page took 0.366316 seconds and 5 git commands to generate.