diff options
Diffstat (limited to 'drivers/block/aoe/aoecmd.c')
-rw-r--r-- | drivers/block/aoe/aoecmd.c | 108 |
1 files changed, 63 insertions, 45 deletions
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c index fb6d942a4565..b5be4b7d7b5b 100644 --- a/drivers/block/aoe/aoecmd.c +++ b/drivers/block/aoe/aoecmd.c | |||
@@ -90,19 +90,16 @@ newtag(struct aoedev *d) | |||
90 | static int | 90 | static int |
91 | aoehdr_atainit(struct aoedev *d, struct aoe_hdr *h) | 91 | aoehdr_atainit(struct aoedev *d, struct aoe_hdr *h) |
92 | { | 92 | { |
93 | u16 type = __constant_cpu_to_be16(ETH_P_AOE); | ||
94 | u16 aoemajor = __cpu_to_be16(d->aoemajor); | ||
95 | u32 host_tag = newtag(d); | 93 | u32 host_tag = newtag(d); |
96 | u32 tag = __cpu_to_be32(host_tag); | ||
97 | 94 | ||
98 | memcpy(h->src, d->ifp->dev_addr, sizeof h->src); | 95 | memcpy(h->src, d->ifp->dev_addr, sizeof h->src); |
99 | memcpy(h->dst, d->addr, sizeof h->dst); | 96 | memcpy(h->dst, d->addr, sizeof h->dst); |
100 | memcpy(h->type, &type, sizeof type); | 97 | h->type = __constant_cpu_to_be16(ETH_P_AOE); |
101 | h->verfl = AOE_HVER; | 98 | h->verfl = AOE_HVER; |
102 | memcpy(h->major, &aoemajor, sizeof aoemajor); | 99 | h->major = cpu_to_be16(d->aoemajor); |
103 | h->minor = d->aoeminor; | 100 | h->minor = d->aoeminor; |
104 | h->cmd = AOECMD_ATA; | 101 | h->cmd = AOECMD_ATA; |
105 | memcpy(h->tag, &tag, sizeof tag); | 102 | h->tag = cpu_to_be32(host_tag); |
106 | 103 | ||
107 | return host_tag; | 104 | return host_tag; |
108 | } | 105 | } |
@@ -181,8 +178,12 @@ aoecmd_ata_rw(struct aoedev *d, struct frame *f) | |||
181 | 178 | ||
182 | skb = skb_prepare(d, f); | 179 | skb = skb_prepare(d, f); |
183 | if (skb) { | 180 | if (skb) { |
184 | skb->next = d->skblist; | 181 | skb->next = NULL; |
185 | d->skblist = skb; | 182 | if (d->sendq_hd) |
183 | d->sendq_tl->next = skb; | ||
184 | else | ||
185 | d->sendq_hd = skb; | ||
186 | d->sendq_tl = skb; | ||
186 | } | 187 | } |
187 | } | 188 | } |
188 | 189 | ||
@@ -215,7 +216,6 @@ rexmit(struct aoedev *d, struct frame *f) | |||
215 | struct aoe_hdr *h; | 216 | struct aoe_hdr *h; |
216 | char buf[128]; | 217 | char buf[128]; |
217 | u32 n; | 218 | u32 n; |
218 | u32 net_tag; | ||
219 | 219 | ||
220 | n = newtag(d); | 220 | n = newtag(d); |
221 | 221 | ||
@@ -227,13 +227,16 @@ rexmit(struct aoedev *d, struct frame *f) | |||
227 | 227 | ||
228 | h = (struct aoe_hdr *) f->data; | 228 | h = (struct aoe_hdr *) f->data; |
229 | f->tag = n; | 229 | f->tag = n; |
230 | net_tag = __cpu_to_be32(n); | 230 | h->tag = cpu_to_be32(n); |
231 | memcpy(h->tag, &net_tag, sizeof net_tag); | ||
232 | 231 | ||
233 | skb = skb_prepare(d, f); | 232 | skb = skb_prepare(d, f); |
234 | if (skb) { | 233 | if (skb) { |
235 | skb->next = d->skblist; | 234 | skb->next = NULL; |
236 | d->skblist = skb; | 235 | if (d->sendq_hd) |
236 | d->sendq_tl->next = skb; | ||
237 | else | ||
238 | d->sendq_hd = skb; | ||
239 | d->sendq_tl = skb; | ||
237 | } | 240 | } |
238 | } | 241 | } |
239 | 242 | ||
@@ -285,8 +288,8 @@ tdie: spin_unlock_irqrestore(&d->lock, flags); | |||
285 | } | 288 | } |
286 | } | 289 | } |
287 | 290 | ||
288 | sl = d->skblist; | 291 | sl = d->sendq_hd; |
289 | d->skblist = NULL; | 292 | d->sendq_hd = d->sendq_tl = NULL; |
290 | if (sl) { | 293 | if (sl) { |
291 | n = d->rttavg <<= 1; | 294 | n = d->rttavg <<= 1; |
292 | if (n > MAXTIMER) | 295 | if (n > MAXTIMER) |
@@ -308,16 +311,16 @@ ataid_complete(struct aoedev *d, unsigned char *id) | |||
308 | u16 n; | 311 | u16 n; |
309 | 312 | ||
310 | /* word 83: command set supported */ | 313 | /* word 83: command set supported */ |
311 | n = __le16_to_cpu(*((u16 *) &id[83<<1])); | 314 | n = le16_to_cpup((__le16 *) &id[83<<1]); |
312 | 315 | ||
313 | /* word 86: command set/feature enabled */ | 316 | /* word 86: command set/feature enabled */ |
314 | n |= __le16_to_cpu(*((u16 *) &id[86<<1])); | 317 | n |= le16_to_cpup((__le16 *) &id[86<<1]); |
315 | 318 | ||
316 | if (n & (1<<10)) { /* bit 10: LBA 48 */ | 319 | if (n & (1<<10)) { /* bit 10: LBA 48 */ |
317 | d->flags |= DEVFL_EXT; | 320 | d->flags |= DEVFL_EXT; |
318 | 321 | ||
319 | /* word 100: number lba48 sectors */ | 322 | /* word 100: number lba48 sectors */ |
320 | ssize = __le64_to_cpu(*((u64 *) &id[100<<1])); | 323 | ssize = le64_to_cpup((__le64 *) &id[100<<1]); |
321 | 324 | ||
322 | /* set as in ide-disk.c:init_idedisk_capacity */ | 325 | /* set as in ide-disk.c:init_idedisk_capacity */ |
323 | d->geo.cylinders = ssize; | 326 | d->geo.cylinders = ssize; |
@@ -328,12 +331,12 @@ ataid_complete(struct aoedev *d, unsigned char *id) | |||
328 | d->flags &= ~DEVFL_EXT; | 331 | d->flags &= ~DEVFL_EXT; |
329 | 332 | ||
330 | /* number lba28 sectors */ | 333 | /* number lba28 sectors */ |
331 | ssize = __le32_to_cpu(*((u32 *) &id[60<<1])); | 334 | ssize = le32_to_cpup((__le32 *) &id[60<<1]); |
332 | 335 | ||
333 | /* NOTE: obsolete in ATA 6 */ | 336 | /* NOTE: obsolete in ATA 6 */ |
334 | d->geo.cylinders = __le16_to_cpu(*((u16 *) &id[54<<1])); | 337 | d->geo.cylinders = le16_to_cpup((__le16 *) &id[54<<1]); |
335 | d->geo.heads = __le16_to_cpu(*((u16 *) &id[55<<1])); | 338 | d->geo.heads = le16_to_cpup((__le16 *) &id[55<<1]); |
336 | d->geo.sectors = __le16_to_cpu(*((u16 *) &id[56<<1])); | 339 | d->geo.sectors = le16_to_cpup((__le16 *) &id[56<<1]); |
337 | } | 340 | } |
338 | d->ssize = ssize; | 341 | d->ssize = ssize; |
339 | d->geo.start = 0; | 342 | d->geo.start = 0; |
@@ -380,29 +383,30 @@ aoecmd_ata_rsp(struct sk_buff *skb) | |||
380 | register long n; | 383 | register long n; |
381 | ulong flags; | 384 | ulong flags; |
382 | char ebuf[128]; | 385 | char ebuf[128]; |
383 | 386 | u16 aoemajor; | |
387 | |||
384 | hin = (struct aoe_hdr *) skb->mac.raw; | 388 | hin = (struct aoe_hdr *) skb->mac.raw; |
385 | d = aoedev_bymac(hin->src); | 389 | aoemajor = be16_to_cpu(hin->major); |
390 | d = aoedev_by_aoeaddr(aoemajor, hin->minor); | ||
386 | if (d == NULL) { | 391 | if (d == NULL) { |
387 | snprintf(ebuf, sizeof ebuf, "aoecmd_ata_rsp: ata response " | 392 | snprintf(ebuf, sizeof ebuf, "aoecmd_ata_rsp: ata response " |
388 | "for unknown device %d.%d\n", | 393 | "for unknown device %d.%d\n", |
389 | __be16_to_cpu(*((u16 *) hin->major)), | 394 | aoemajor, hin->minor); |
390 | hin->minor); | ||
391 | aoechr_error(ebuf); | 395 | aoechr_error(ebuf); |
392 | return; | 396 | return; |
393 | } | 397 | } |
394 | 398 | ||
395 | spin_lock_irqsave(&d->lock, flags); | 399 | spin_lock_irqsave(&d->lock, flags); |
396 | 400 | ||
397 | f = getframe(d, __be32_to_cpu(*((u32 *) hin->tag))); | 401 | f = getframe(d, be32_to_cpu(hin->tag)); |
398 | if (f == NULL) { | 402 | if (f == NULL) { |
399 | spin_unlock_irqrestore(&d->lock, flags); | 403 | spin_unlock_irqrestore(&d->lock, flags); |
400 | snprintf(ebuf, sizeof ebuf, | 404 | snprintf(ebuf, sizeof ebuf, |
401 | "%15s e%d.%d tag=%08x@%08lx\n", | 405 | "%15s e%d.%d tag=%08x@%08lx\n", |
402 | "unexpected rsp", | 406 | "unexpected rsp", |
403 | __be16_to_cpu(*((u16 *) hin->major)), | 407 | be16_to_cpu(hin->major), |
404 | hin->minor, | 408 | hin->minor, |
405 | __be32_to_cpu(*((u32 *) hin->tag)), | 409 | be32_to_cpu(hin->tag), |
406 | jiffies); | 410 | jiffies); |
407 | aoechr_error(ebuf); | 411 | aoechr_error(ebuf); |
408 | return; | 412 | return; |
@@ -452,7 +456,7 @@ aoecmd_ata_rsp(struct sk_buff *skb) | |||
452 | printk(KERN_INFO "aoe: aoecmd_ata_rsp: unrecognized " | 456 | printk(KERN_INFO "aoe: aoecmd_ata_rsp: unrecognized " |
453 | "outbound ata command %2.2Xh for %d.%d\n", | 457 | "outbound ata command %2.2Xh for %d.%d\n", |
454 | ahout->cmdstat, | 458 | ahout->cmdstat, |
455 | __be16_to_cpu(*((u16 *) hin->major)), | 459 | be16_to_cpu(hin->major), |
456 | hin->minor); | 460 | hin->minor); |
457 | } | 461 | } |
458 | } | 462 | } |
@@ -460,6 +464,20 @@ aoecmd_ata_rsp(struct sk_buff *skb) | |||
460 | if (buf) { | 464 | if (buf) { |
461 | buf->nframesout -= 1; | 465 | buf->nframesout -= 1; |
462 | if (buf->nframesout == 0 && buf->resid == 0) { | 466 | if (buf->nframesout == 0 && buf->resid == 0) { |
467 | unsigned long duration = jiffies - buf->start_time; | ||
468 | unsigned long n_sect = buf->bio->bi_size >> 9; | ||
469 | struct gendisk *disk = d->gd; | ||
470 | |||
471 | if (bio_data_dir(buf->bio) == WRITE) { | ||
472 | disk_stat_inc(disk, writes); | ||
473 | disk_stat_add(disk, write_ticks, duration); | ||
474 | disk_stat_add(disk, write_sectors, n_sect); | ||
475 | } else { | ||
476 | disk_stat_inc(disk, reads); | ||
477 | disk_stat_add(disk, read_ticks, duration); | ||
478 | disk_stat_add(disk, read_sectors, n_sect); | ||
479 | } | ||
480 | disk_stat_add(disk, io_ticks, duration); | ||
463 | n = (buf->flags & BUFFL_FAIL) ? -EIO : 0; | 481 | n = (buf->flags & BUFFL_FAIL) ? -EIO : 0; |
464 | bio_endio(buf->bio, buf->bio->bi_size, n); | 482 | bio_endio(buf->bio, buf->bio->bi_size, n); |
465 | mempool_free(buf, d->bufpool); | 483 | mempool_free(buf, d->bufpool); |
@@ -471,8 +489,8 @@ aoecmd_ata_rsp(struct sk_buff *skb) | |||
471 | 489 | ||
472 | aoecmd_work(d); | 490 | aoecmd_work(d); |
473 | 491 | ||
474 | sl = d->skblist; | 492 | sl = d->sendq_hd; |
475 | d->skblist = NULL; | 493 | d->sendq_hd = d->sendq_tl = NULL; |
476 | 494 | ||
477 | spin_unlock_irqrestore(&d->lock, flags); | 495 | spin_unlock_irqrestore(&d->lock, flags); |
478 | 496 | ||
@@ -486,8 +504,6 @@ aoecmd_cfg(ushort aoemajor, unsigned char aoeminor) | |||
486 | struct aoe_cfghdr *ch; | 504 | struct aoe_cfghdr *ch; |
487 | struct sk_buff *skb, *sl; | 505 | struct sk_buff *skb, *sl; |
488 | struct net_device *ifp; | 506 | struct net_device *ifp; |
489 | u16 aoe_type = __constant_cpu_to_be16(ETH_P_AOE); | ||
490 | u16 net_aoemajor = __cpu_to_be16(aoemajor); | ||
491 | 507 | ||
492 | sl = NULL; | 508 | sl = NULL; |
493 | 509 | ||
@@ -507,9 +523,9 @@ aoecmd_cfg(ushort aoemajor, unsigned char aoeminor) | |||
507 | 523 | ||
508 | memset(h->dst, 0xff, sizeof h->dst); | 524 | memset(h->dst, 0xff, sizeof h->dst); |
509 | memcpy(h->src, ifp->dev_addr, sizeof h->src); | 525 | memcpy(h->src, ifp->dev_addr, sizeof h->src); |
510 | memcpy(h->type, &aoe_type, sizeof aoe_type); | 526 | h->type = __constant_cpu_to_be16(ETH_P_AOE); |
511 | h->verfl = AOE_HVER; | 527 | h->verfl = AOE_HVER; |
512 | memcpy(h->major, &net_aoemajor, sizeof net_aoemajor); | 528 | h->major = cpu_to_be16(aoemajor); |
513 | h->minor = aoeminor; | 529 | h->minor = aoeminor; |
514 | h->cmd = AOECMD_CFG; | 530 | h->cmd = AOECMD_CFG; |
515 | 531 | ||
@@ -523,7 +539,7 @@ aoecmd_cfg(ushort aoemajor, unsigned char aoeminor) | |||
523 | 539 | ||
524 | /* | 540 | /* |
525 | * Since we only call this in one place (and it only prepares one frame) | 541 | * Since we only call this in one place (and it only prepares one frame) |
526 | * we just return the skb. Usually we'd chain it up to the d->skblist. | 542 | * we just return the skb. Usually we'd chain it up to the aoedev sendq. |
527 | */ | 543 | */ |
528 | static struct sk_buff * | 544 | static struct sk_buff * |
529 | aoecmd_ata_id(struct aoedev *d) | 545 | aoecmd_ata_id(struct aoedev *d) |
@@ -575,9 +591,10 @@ aoecmd_cfg_rsp(struct sk_buff *skb) | |||
575 | struct aoedev *d; | 591 | struct aoedev *d; |
576 | struct aoe_hdr *h; | 592 | struct aoe_hdr *h; |
577 | struct aoe_cfghdr *ch; | 593 | struct aoe_cfghdr *ch; |
578 | ulong flags, bufcnt, sysminor, aoemajor; | 594 | ulong flags, sysminor, aoemajor; |
595 | u16 bufcnt; | ||
579 | struct sk_buff *sl; | 596 | struct sk_buff *sl; |
580 | enum { MAXFRAMES = 8, MAXSYSMINOR = 255 }; | 597 | enum { MAXFRAMES = 8 }; |
581 | 598 | ||
582 | h = (struct aoe_hdr *) skb->mac.raw; | 599 | h = (struct aoe_hdr *) skb->mac.raw; |
583 | ch = (struct aoe_cfghdr *) (h+1); | 600 | ch = (struct aoe_cfghdr *) (h+1); |
@@ -586,7 +603,7 @@ aoecmd_cfg_rsp(struct sk_buff *skb) | |||
586 | * Enough people have their dip switches set backwards to | 603 | * Enough people have their dip switches set backwards to |
587 | * warrant a loud message for this special case. | 604 | * warrant a loud message for this special case. |
588 | */ | 605 | */ |
589 | aoemajor = __be16_to_cpu(*((u16 *) h->major)); | 606 | aoemajor = be16_to_cpu(h->major); |
590 | if (aoemajor == 0xfff) { | 607 | if (aoemajor == 0xfff) { |
591 | printk(KERN_CRIT "aoe: aoecmd_cfg_rsp: Warning: shelf " | 608 | printk(KERN_CRIT "aoe: aoecmd_cfg_rsp: Warning: shelf " |
592 | "address is all ones. Check shelf dip switches\n"); | 609 | "address is all ones. Check shelf dip switches\n"); |
@@ -594,13 +611,14 @@ aoecmd_cfg_rsp(struct sk_buff *skb) | |||
594 | } | 611 | } |
595 | 612 | ||
596 | sysminor = SYSMINOR(aoemajor, h->minor); | 613 | sysminor = SYSMINOR(aoemajor, h->minor); |
597 | if (sysminor > MAXSYSMINOR) { | 614 | if (sysminor * AOE_PARTITIONS + AOE_PARTITIONS > MINORMASK) { |
598 | printk(KERN_INFO "aoe: aoecmd_cfg_rsp: sysminor %ld too " | 615 | printk(KERN_INFO |
599 | "large\n", sysminor); | 616 | "aoe: e%ld.%d: minor number too large\n", |
617 | aoemajor, (int) h->minor); | ||
600 | return; | 618 | return; |
601 | } | 619 | } |
602 | 620 | ||
603 | bufcnt = __be16_to_cpu(*((u16 *) ch->bufcnt)); | 621 | bufcnt = be16_to_cpu(ch->bufcnt); |
604 | if (bufcnt > MAXFRAMES) /* keep it reasonable */ | 622 | if (bufcnt > MAXFRAMES) /* keep it reasonable */ |
605 | bufcnt = MAXFRAMES; | 623 | bufcnt = MAXFRAMES; |
606 | 624 | ||
@@ -617,7 +635,7 @@ aoecmd_cfg_rsp(struct sk_buff *skb) | |||
617 | return; | 635 | return; |
618 | } | 636 | } |
619 | 637 | ||
620 | d->fw_ver = __be16_to_cpu(*((u16 *) ch->fwver)); | 638 | d->fw_ver = be16_to_cpu(ch->fwver); |
621 | 639 | ||
622 | /* we get here only if the device is new */ | 640 | /* we get here only if the device is new */ |
623 | sl = aoecmd_ata_id(d); | 641 | sl = aoecmd_ata_id(d); |