summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--hw/i386/xen/xen_platform.c31
-rw-r--r--hw/usb/xen-usb.c4
2 files changed, 32 insertions, 3 deletions
diff --git a/hw/i386/xen/xen_platform.c b/hw/i386/xen/xen_platform.c
index f85635cc9a..2e1e543881 100644
--- a/hw/i386/xen/xen_platform.c
+++ b/hw/i386/xen/xen_platform.c
@@ -114,6 +114,10 @@ static void unplug_disks(PCIBus *b, PCIDevice *d, void *o)
             PCI_CLASS_STORAGE_IDE
             && strcmp(d->name, "xen-pci-passthrough") != 0) {
         pci_piix3_xen_ide_unplug(DEVICE(d));
+    } else if (pci_get_word(d->config + PCI_CLASS_DEVICE) ==
+            PCI_CLASS_STORAGE_SCSI
+            && strcmp(d->name, "xen-pci-passthrough") != 0) {
+        object_unparent(OBJECT(d));
     }
 }
 
@@ -307,13 +311,38 @@ static void xen_platform_ioport_writeb(void *opaque, hwaddr addr,
                                        uint64_t val, unsigned int size)
 {
     PCIXenPlatformState *s = opaque;
+    PCIDevice *pci_dev = PCI_DEVICE(s);
 
     switch (addr) {
     case 0: /* Platform flags */
         platform_fixed_ioport_writeb(opaque, 0, (uint32_t)val);
         break;
+    case 4:
+        if (val == 1) {
+            /*
+             * SUSE unplug for Xenlinux
+             * xen-kmp used this since xen-3.0.4, instead the official protocol
+             * from xen-3.3+ It did an unconditional "outl(1, (ioaddr + 4));"
+             * Pre VMDP 1.7 used 4 and 8 depending on how VMDP was configured.
+             * If VMDP was to control both disk and LAN it would use 4.
+             * If it controlled just disk or just LAN, it would use 8 below.
+             */
+            pci_unplug_disks(pci_dev->bus);
+            pci_unplug_nics(pci_dev->bus);
+        }
+        break;
     case 8:
-        log_writeb(s, (uint32_t)val);
+        switch (val) {
+        case 1:
+            pci_unplug_disks(pci_dev->bus);
+            break;
+        case 2:
+            pci_unplug_nics(pci_dev->bus);
+            break;
+        default:
+            log_writeb(s, (uint32_t)val);
+            break;
+        }
         break;
     default:
         break;
diff --git a/hw/usb/xen-usb.c b/hw/usb/xen-usb.c
index 174d715e3e..de2ebd6210 100644
--- a/hw/usb/xen-usb.c
+++ b/hw/usb/xen-usb.c
@@ -160,7 +160,7 @@ static int usbback_gnttab_map(struct usbback_req *usbback_req)
 
     for (i = 0; i < nr_segs; i++) {
         if ((unsigned)usbback_req->req.seg[i].offset +
-            (unsigned)usbback_req->req.seg[i].length > PAGE_SIZE) {
+            (unsigned)usbback_req->req.seg[i].length > XC_PAGE_SIZE) {
             xen_be_printf(xendev, 0, "segment crosses page boundary\n");
             return -EINVAL;
         }
@@ -183,7 +183,7 @@ static int usbback_gnttab_map(struct usbback_req *usbback_req)
 
         for (i = 0; i < usbback_req->nr_buffer_segs; i++) {
             seg = usbback_req->req.seg + i;
-            addr = usbback_req->buffer + i * PAGE_SIZE + seg->offset;
+            addr = usbback_req->buffer + i * XC_PAGE_SIZE + seg->offset;
             qemu_iovec_add(&usbback_req->packet.iov, addr, seg->length);
         }
     }