diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-15 13:59:09 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-15 13:59:09 -0400 |
commit | 76ca07832842100b14a31ad8996dab7b0c28aa42 (patch) | |
tree | 496df81083fda9be38f8ff88cdc3ef59c2d72a8d /drivers/block | |
parent | 27d2a8b97ebc4467e47722415b81ebe72d5f654f (diff) | |
parent | b056b6a0144de90707cd22cf7b4f60bf69c86d59 (diff) |
Merge branch 'for-linus' of git://xenbits.xen.org/people/sstabellini/linux-pvhvm
* 'for-linus' of git://xenbits.xen.org/people/sstabellini/linux-pvhvm:
xen: suspend: remove xen_hvm_suspend
xen: suspend: pull pre/post suspend hooks out into suspend_info
xen: suspend: move arch specific pre/post suspend hooks into generic hooks
xen: suspend: refactor non-arch specific pre/post suspend hooks
xen: suspend: add "arch" to pre/post suspend hooks
xen: suspend: pass extra hypercall argument via suspend_info struct
xen: suspend: refactor cancellation flag into a structure
xen: suspend: use HYPERVISOR_suspend for PVHVM case instead of open coding
xen: switch to new schedop hypercall by default.
xen: use new schedop interface for suspend
xen: do not respond to unknown xenstore control requests
xen: fix compile issue if XEN is enabled but XEN_PVHVM is disabled
xen: PV on HVM: support PV spinlocks and IPIs
xen: make the ballon driver work for hvm domains
xen-blkfront: handle Xen major numbers other than XENVBD
xen: do not use xen_info on HVM, set pv_info name to "Xen HVM"
xen: no need to delay xen_setup_shutdown_event for hvm guests anymore
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/xen-blkfront.c | 79 |
1 files changed, 74 insertions, 5 deletions
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index cc4514c9d8a6..9cb8668ff5f4 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c | |||
@@ -120,6 +120,10 @@ static DEFINE_SPINLOCK(minor_lock); | |||
120 | #define EXTENDED (1<<EXT_SHIFT) | 120 | #define EXTENDED (1<<EXT_SHIFT) |
121 | #define VDEV_IS_EXTENDED(dev) ((dev)&(EXTENDED)) | 121 | #define VDEV_IS_EXTENDED(dev) ((dev)&(EXTENDED)) |
122 | #define BLKIF_MINOR_EXT(dev) ((dev)&(~EXTENDED)) | 122 | #define BLKIF_MINOR_EXT(dev) ((dev)&(~EXTENDED)) |
123 | #define EMULATED_HD_DISK_MINOR_OFFSET (0) | ||
124 | #define EMULATED_HD_DISK_NAME_OFFSET (EMULATED_HD_DISK_MINOR_OFFSET / 256) | ||
125 | #define EMULATED_SD_DISK_MINOR_OFFSET (EMULATED_HD_DISK_MINOR_OFFSET + (4 * 16)) | ||
126 | #define EMULATED_SD_DISK_NAME_OFFSET (EMULATED_HD_DISK_NAME_OFFSET + 4) | ||
123 | 127 | ||
124 | #define DEV_NAME "xvd" /* name in /dev */ | 128 | #define DEV_NAME "xvd" /* name in /dev */ |
125 | 129 | ||
@@ -434,6 +438,65 @@ static void xlvbd_flush(struct blkfront_info *info) | |||
434 | info->feature_flush ? "enabled" : "disabled"); | 438 | info->feature_flush ? "enabled" : "disabled"); |
435 | } | 439 | } |
436 | 440 | ||
441 | static int xen_translate_vdev(int vdevice, int *minor, unsigned int *offset) | ||
442 | { | ||
443 | int major; | ||
444 | major = BLKIF_MAJOR(vdevice); | ||
445 | *minor = BLKIF_MINOR(vdevice); | ||
446 | switch (major) { | ||
447 | case XEN_IDE0_MAJOR: | ||
448 | *offset = (*minor / 64) + EMULATED_HD_DISK_NAME_OFFSET; | ||
449 | *minor = ((*minor / 64) * PARTS_PER_DISK) + | ||
450 | EMULATED_HD_DISK_MINOR_OFFSET; | ||
451 | break; | ||
452 | case XEN_IDE1_MAJOR: | ||
453 | *offset = (*minor / 64) + 2 + EMULATED_HD_DISK_NAME_OFFSET; | ||
454 | *minor = (((*minor / 64) + 2) * PARTS_PER_DISK) + | ||
455 | EMULATED_HD_DISK_MINOR_OFFSET; | ||
456 | break; | ||
457 | case XEN_SCSI_DISK0_MAJOR: | ||
458 | *offset = (*minor / PARTS_PER_DISK) + EMULATED_SD_DISK_NAME_OFFSET; | ||
459 | *minor = *minor + EMULATED_SD_DISK_MINOR_OFFSET; | ||
460 | break; | ||
461 | case XEN_SCSI_DISK1_MAJOR: | ||
462 | case XEN_SCSI_DISK2_MAJOR: | ||
463 | case XEN_SCSI_DISK3_MAJOR: | ||
464 | case XEN_SCSI_DISK4_MAJOR: | ||
465 | case XEN_SCSI_DISK5_MAJOR: | ||
466 | case XEN_SCSI_DISK6_MAJOR: | ||
467 | case XEN_SCSI_DISK7_MAJOR: | ||
468 | *offset = (*minor / PARTS_PER_DISK) + | ||
469 | ((major - XEN_SCSI_DISK1_MAJOR + 1) * 16) + | ||
470 | EMULATED_SD_DISK_NAME_OFFSET; | ||
471 | *minor = *minor + | ||
472 | ((major - XEN_SCSI_DISK1_MAJOR + 1) * 16 * PARTS_PER_DISK) + | ||
473 | EMULATED_SD_DISK_MINOR_OFFSET; | ||
474 | break; | ||
475 | case XEN_SCSI_DISK8_MAJOR: | ||
476 | case XEN_SCSI_DISK9_MAJOR: | ||
477 | case XEN_SCSI_DISK10_MAJOR: | ||
478 | case XEN_SCSI_DISK11_MAJOR: | ||
479 | case XEN_SCSI_DISK12_MAJOR: | ||
480 | case XEN_SCSI_DISK13_MAJOR: | ||
481 | case XEN_SCSI_DISK14_MAJOR: | ||
482 | case XEN_SCSI_DISK15_MAJOR: | ||
483 | *offset = (*minor / PARTS_PER_DISK) + | ||
484 | ((major - XEN_SCSI_DISK8_MAJOR + 8) * 16) + | ||
485 | EMULATED_SD_DISK_NAME_OFFSET; | ||
486 | *minor = *minor + | ||
487 | ((major - XEN_SCSI_DISK8_MAJOR + 8) * 16 * PARTS_PER_DISK) + | ||
488 | EMULATED_SD_DISK_MINOR_OFFSET; | ||
489 | break; | ||
490 | case XENVBD_MAJOR: | ||
491 | *offset = *minor / PARTS_PER_DISK; | ||
492 | break; | ||
493 | default: | ||
494 | printk(KERN_WARNING "blkfront: your disk configuration is " | ||
495 | "incorrect, please use an xvd device instead\n"); | ||
496 | return -ENODEV; | ||
497 | } | ||
498 | return 0; | ||
499 | } | ||
437 | 500 | ||
438 | static int xlvbd_alloc_gendisk(blkif_sector_t capacity, | 501 | static int xlvbd_alloc_gendisk(blkif_sector_t capacity, |
439 | struct blkfront_info *info, | 502 | struct blkfront_info *info, |
@@ -441,7 +504,7 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity, | |||
441 | { | 504 | { |
442 | struct gendisk *gd; | 505 | struct gendisk *gd; |
443 | int nr_minors = 1; | 506 | int nr_minors = 1; |
444 | int err = -ENODEV; | 507 | int err; |
445 | unsigned int offset; | 508 | unsigned int offset; |
446 | int minor; | 509 | int minor; |
447 | int nr_parts; | 510 | int nr_parts; |
@@ -456,12 +519,20 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity, | |||
456 | } | 519 | } |
457 | 520 | ||
458 | if (!VDEV_IS_EXTENDED(info->vdevice)) { | 521 | if (!VDEV_IS_EXTENDED(info->vdevice)) { |
459 | minor = BLKIF_MINOR(info->vdevice); | 522 | err = xen_translate_vdev(info->vdevice, &minor, &offset); |
460 | nr_parts = PARTS_PER_DISK; | 523 | if (err) |
524 | return err; | ||
525 | nr_parts = PARTS_PER_DISK; | ||
461 | } else { | 526 | } else { |
462 | minor = BLKIF_MINOR_EXT(info->vdevice); | 527 | minor = BLKIF_MINOR_EXT(info->vdevice); |
463 | nr_parts = PARTS_PER_EXT_DISK; | 528 | nr_parts = PARTS_PER_EXT_DISK; |
529 | offset = minor / nr_parts; | ||
530 | if (xen_hvm_domain() && offset <= EMULATED_HD_DISK_NAME_OFFSET + 4) | ||
531 | printk(KERN_WARNING "blkfront: vdevice 0x%x might conflict with " | ||
532 | "emulated IDE disks,\n\t choose an xvd device name" | ||
533 | "from xvde on\n", info->vdevice); | ||
464 | } | 534 | } |
535 | err = -ENODEV; | ||
465 | 536 | ||
466 | if ((minor % nr_parts) == 0) | 537 | if ((minor % nr_parts) == 0) |
467 | nr_minors = nr_parts; | 538 | nr_minors = nr_parts; |
@@ -475,8 +546,6 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity, | |||
475 | if (gd == NULL) | 546 | if (gd == NULL) |
476 | goto release; | 547 | goto release; |
477 | 548 | ||
478 | offset = minor / nr_parts; | ||
479 | |||
480 | if (nr_minors > 1) { | 549 | if (nr_minors > 1) { |
481 | if (offset < 26) | 550 | if (offset < 26) |
482 | sprintf(gd->disk_name, "%s%c", DEV_NAME, 'a' + offset); | 551 | sprintf(gd->disk_name, "%s%c", DEV_NAME, 'a' + offset); |