aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/aoe/aoecmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/aoe/aoecmd.c')
-rw-r--r--drivers/block/aoe/aoecmd.c77
1 files changed, 63 insertions, 14 deletions
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
index 1aeb2969987f..666797d646d6 100644
--- a/drivers/block/aoe/aoecmd.c
+++ b/drivers/block/aoe/aoecmd.c
@@ -83,6 +83,17 @@ aoehdr_atainit(struct aoedev *d, struct aoe_hdr *h)
83 return host_tag; 83 return host_tag;
84} 84}
85 85
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
86static void 97static void
87aoecmd_ata_rw(struct aoedev *d, struct frame *f) 98aoecmd_ata_rw(struct aoedev *d, struct frame *f)
88{ 99{
@@ -101,8 +112,8 @@ aoecmd_ata_rw(struct aoedev *d, struct frame *f)
101 112
102 sector = buf->sector; 113 sector = buf->sector;
103 bcnt = buf->bv_resid; 114 bcnt = buf->bv_resid;
104 if (bcnt > MAXATADATA) 115 if (bcnt > d->maxbcnt)
105 bcnt = MAXATADATA; 116 bcnt = d->maxbcnt;
106 117
107 /* initialize the headers & frame */ 118 /* initialize the headers & frame */
108 skb = f->skb; 119 skb = f->skb;
@@ -114,17 +125,14 @@ aoecmd_ata_rw(struct aoedev *d, struct frame *f)
114 f->waited = 0; 125 f->waited = 0;
115 f->buf = buf; 126 f->buf = buf;
116 f->bufaddr = buf->bufaddr; 127 f->bufaddr = buf->bufaddr;
128 f->bcnt = bcnt;
129 f->lba = sector;
117 130
118 /* set up ata header */ 131 /* set up ata header */
119 ah->scnt = bcnt >> 9; 132 ah->scnt = bcnt >> 9;
120 ah->lba0 = sector; 133 put_lba(ah, sector);
121 ah->lba1 = sector >>= 8;
122 ah->lba2 = sector >>= 8;
123 ah->lba3 = sector >>= 8;
124 if (d->flags & DEVFL_EXT) { 134 if (d->flags & DEVFL_EXT) {
125 ah->aflags |= AOEAFL_EXT; 135 ah->aflags |= AOEAFL_EXT;
126 ah->lba4 = sector >>= 8;
127 ah->lba5 = sector >>= 8;
128 } else { 136 } else {
129 extbit = 0; 137 extbit = 0;
130 ah->lba3 &= 0x0f; 138 ah->lba3 &= 0x0f;
@@ -251,6 +259,7 @@ rexmit(struct aoedev *d, struct frame *f)
251{ 259{
252 struct sk_buff *skb; 260 struct sk_buff *skb;
253 struct aoe_hdr *h; 261 struct aoe_hdr *h;
262 struct aoe_atahdr *ah;
254 char buf[128]; 263 char buf[128];
255 u32 n; 264 u32 n;
256 265
@@ -264,11 +273,27 @@ rexmit(struct aoedev *d, struct frame *f)
264 273
265 skb = f->skb; 274 skb = f->skb;
266 h = (struct aoe_hdr *) skb->mac.raw; 275 h = (struct aoe_hdr *) skb->mac.raw;
276 ah = (struct aoe_atahdr *) (h+1);
267 f->tag = n; 277 f->tag = n;
268 h->tag = cpu_to_be32(n); 278 h->tag = cpu_to_be32(n);
269 memcpy(h->dst, d->addr, sizeof h->dst); 279 memcpy(h->dst, d->addr, sizeof h->dst);
270 memcpy(h->src, d->ifp->dev_addr, sizeof h->src); 280 memcpy(h->src, d->ifp->dev_addr, sizeof h->src);
271 281
282 n = DEFAULTBCNT / 512;
283 if (ah->scnt > n) {
284 ah->scnt = n;
285 if (ah->aflags & AOEAFL_WRITE)
286 skb_fill_page_desc(skb, 0, virt_to_page(f->bufaddr),
287 offset_in_page(f->bufaddr), DEFAULTBCNT);
288 if (++d->lostjumbo > (d->nframes << 1))
289 if (d->maxbcnt != DEFAULTBCNT) {
290 printk(KERN_INFO "aoe: rexmit: too many lost jumbo. "
291 "dropping back to 1KB frames.\n");
292 d->maxbcnt = DEFAULTBCNT;
293 d->flags |= DEVFL_MAXBCNT;
294 }
295 }
296
272 skb->dev = d->ifp; 297 skb->dev = d->ifp;
273 skb_get(skb); 298 skb_get(skb);
274 skb->next = NULL; 299 skb->next = NULL;
@@ -506,10 +531,10 @@ aoecmd_ata_rsp(struct sk_buff *skb)
506 if (buf) 531 if (buf)
507 buf->flags |= BUFFL_FAIL; 532 buf->flags |= BUFFL_FAIL;
508 } else { 533 } else {
534 n = ahout->scnt << 9;
509 switch (ahout->cmdstat) { 535 switch (ahout->cmdstat) {
510 case WIN_READ: 536 case WIN_READ:
511 case WIN_READ_EXT: 537 case WIN_READ_EXT:
512 n = ahout->scnt << 9;
513 if (skb->len - sizeof *hin - sizeof *ahin < n) { 538 if (skb->len - sizeof *hin - sizeof *ahin < n) {
514 printk(KERN_CRIT "aoe: aoecmd_ata_rsp: runt " 539 printk(KERN_CRIT "aoe: aoecmd_ata_rsp: runt "
515 "ata data size in read. skb->len=%d\n", 540 "ata data size in read. skb->len=%d\n",
@@ -521,6 +546,22 @@ aoecmd_ata_rsp(struct sk_buff *skb)
521 memcpy(f->bufaddr, ahin+1, n); 546 memcpy(f->bufaddr, ahin+1, n);
522 case WIN_WRITE: 547 case WIN_WRITE:
523 case WIN_WRITE_EXT: 548 case WIN_WRITE_EXT:
549 if (f->bcnt -= n) {
550 f->bufaddr += n;
551 put_lba(ahout, f->lba += ahout->scnt);
552 n = f->bcnt > DEFAULTBCNT ? DEFAULTBCNT : f->bcnt;
553 ahout->scnt = n >> 9;
554 if (ahout->aflags & AOEAFL_WRITE)
555 skb_fill_page_desc(f->skb, 0, virt_to_page(f->bufaddr),
556 offset_in_page(f->bufaddr), n);
557 skb_get(f->skb);
558 f->skb->next = NULL;
559 spin_unlock_irqrestore(&d->lock, flags);
560 aoenet_xmit(f->skb);
561 return;
562 }
563 if (n > DEFAULTBCNT)
564 d->lostjumbo = 0;
524 break; 565 break;
525 case WIN_IDENTIFY: 566 case WIN_IDENTIFY:
526 if (skb->len - sizeof *hin - sizeof *ahin < 512) { 567 if (skb->len - sizeof *hin - sizeof *ahin < 512) {
@@ -628,9 +669,9 @@ aoecmd_cfg_rsp(struct sk_buff *skb)
628 struct aoe_hdr *h; 669 struct aoe_hdr *h;
629 struct aoe_cfghdr *ch; 670 struct aoe_cfghdr *ch;
630 ulong flags, sysminor, aoemajor; 671 ulong flags, sysminor, aoemajor;
631 u16 bufcnt;
632 struct sk_buff *sl; 672 struct sk_buff *sl;
633 enum { MAXFRAMES = 16 }; 673 enum { MAXFRAMES = 16 };
674 u16 n;
634 675
635 h = (struct aoe_hdr *) skb->mac.raw; 676 h = (struct aoe_hdr *) skb->mac.raw;
636 ch = (struct aoe_cfghdr *) (h+1); 677 ch = (struct aoe_cfghdr *) (h+1);
@@ -654,11 +695,11 @@ aoecmd_cfg_rsp(struct sk_buff *skb)
654 return; 695 return;
655 } 696 }
656 697
657 bufcnt = be16_to_cpu(ch->bufcnt); 698 n = be16_to_cpu(ch->bufcnt);
658 if (bufcnt > MAXFRAMES) /* keep it reasonable */ 699 if (n > MAXFRAMES) /* keep it reasonable */
659 bufcnt = MAXFRAMES; 700 n = MAXFRAMES;
660 701
661 d = aoedev_by_sysminor_m(sysminor, bufcnt); 702 d = aoedev_by_sysminor_m(sysminor, n);
662 if (d == NULL) { 703 if (d == NULL) {
663 printk(KERN_INFO "aoe: aoecmd_cfg_rsp: device sysminor_m failure\n"); 704 printk(KERN_INFO "aoe: aoecmd_cfg_rsp: device sysminor_m failure\n");
664 return; 705 return;
@@ -669,6 +710,14 @@ aoecmd_cfg_rsp(struct sk_buff *skb)
669 /* permit device to migrate mac and network interface */ 710 /* permit device to migrate mac and network interface */
670 d->ifp = skb->dev; 711 d->ifp = skb->dev;
671 memcpy(d->addr, h->src, sizeof d->addr); 712 memcpy(d->addr, h->src, sizeof d->addr);
713 if (!(d->flags & DEVFL_MAXBCNT)) {
714 n = d->ifp->mtu;
715 n -= sizeof (struct aoe_hdr) + sizeof (struct aoe_atahdr);
716 n /= 512;
717 if (n > ch->scnt)
718 n = ch->scnt;
719 d->maxbcnt = n ? n * 512 : DEFAULTBCNT;
720 }
672 721
673 /* don't change users' perspective */ 722 /* don't change users' perspective */
674 if (d->nopen && !(d->flags & DEVFL_PAUSE)) { 723 if (d->nopen && !(d->flags & DEVFL_PAUSE)) {