summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/cam/ata/ata_xpt.c13
-rw-r--r--sys/conf/files.amd641
-rw-r--r--sys/conf/files.i3861
-rw-r--r--sys/conf/newvers.sh2
-rw-r--r--sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c122
-rw-r--r--sys/dev/pci/pci_pci.c2
-rw-r--r--sys/modules/hyperv/Makefile2
-rw-r--r--sys/sys/eventhandler.h7
-rw-r--r--sys/x86/x86/io_apic.c12
9 files changed, 135 insertions, 27 deletions
diff --git a/sys/cam/ata/ata_xpt.c b/sys/cam/ata/ata_xpt.c
index 3dab055..51be8c2 100644
--- a/sys/cam/ata/ata_xpt.c
+++ b/sys/cam/ata/ata_xpt.c
@@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
#include <sys/interrupt.h>
#include <sys/sbuf.h>
+#include <sys/eventhandler.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/sysctl.h>
@@ -824,12 +825,24 @@ noerror:
{
struct ccb_pathinq cpi;
int16_t *ptr;
+ int veto = 0;
ident_buf = &softc->ident_data;
for (ptr = (int16_t *)ident_buf;
ptr < (int16_t *)ident_buf + sizeof(struct ata_params)/2; ptr++) {
*ptr = le16toh(*ptr);
}
+
+ /*
+ * Allow others to veto this ATA disk attachment. This
+ * is mainly used by VMs, whose disk controllers may
+ * share the disks with the simulated ATA controllers.
+ */
+ EVENTHANDLER_INVOKE(ada_probe_veto, path, ident_buf, &veto);
+ if (veto) {
+ goto device_fail;
+ }
+
if (strncmp(ident_buf->model, "FX", 2) &&
strncmp(ident_buf->model, "NEC", 3) &&
strncmp(ident_buf->model, "Pioneer", 7) &&
diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64
index defd5ac..6bce341 100644
--- a/sys/conf/files.amd64
+++ b/sys/conf/files.amd64
@@ -268,7 +268,6 @@ dev/hwpmc/hwpmc_x86.c optional hwpmc
dev/hyperv/netvsc/hv_net_vsc.c optional hyperv
dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c optional hyperv
dev/hyperv/netvsc/hv_rndis_filter.c optional hyperv
-dev/hyperv/stordisengage/hv_ata_pci_disengage.c optional hyperv
dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c optional hyperv
dev/hyperv/utilities/hv_heartbeat.c optional hyperv
dev/hyperv/utilities/hv_kvp.c optional hyperv
diff --git a/sys/conf/files.i386 b/sys/conf/files.i386
index bf6f1f0..6079768 100644
--- a/sys/conf/files.i386
+++ b/sys/conf/files.i386
@@ -239,7 +239,6 @@ dev/hwpmc/hwpmc_x86.c optional hwpmc
dev/hyperv/netvsc/hv_net_vsc.c optional hyperv
dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c optional hyperv
dev/hyperv/netvsc/hv_rndis_filter.c optional hyperv
-dev/hyperv/stordisengage/hv_ata_pci_disengage.c optional hyperv
dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c optional hyperv
dev/hyperv/utilities/hv_heartbeat.c optional hyperv
dev/hyperv/utilities/hv_kvp.c optional hyperv
diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh
index 9f838ae..45f5ba1 100644
--- a/sys/conf/newvers.sh
+++ b/sys/conf/newvers.sh
@@ -32,7 +32,7 @@
TYPE="FreeBSD"
REVISION="11.0"
-BRANCH="RELEASE-p7"
+BRANCH="RELEASE-p8"
if [ -n "${BRANCH_OVERRIDE}" ]; then
BRANCH=${BRANCH_OVERRIDE}
fi
diff --git a/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c b/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c
index b79e10c..dbcf795 100644
--- a/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c
+++ b/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c
@@ -58,6 +58,7 @@ __FBSDID("$FreeBSD$");
#include <sys/lock.h>
#include <sys/sema.h>
#include <sys/sglist.h>
+#include <sys/eventhandler.h>
#include <machine/bus.h>
#include <sys/bus_dma.h>
@@ -139,6 +140,15 @@ struct storvsc_softc {
struct hv_storvsc_request hs_reset_req;
};
+static eventhandler_tag storvsc_handler_tag;
+/*
+ * The size of the vmscsi_request has changed in win8. The
+ * additional size is for the newly added elements in the
+ * structure. These elements are valid only when we are talking
+ * to a win8 host.
+ * Track the correct size we need to apply.
+ */
+static int vmscsi_size_delta = sizeof(struct vmscsi_win8_extension);
/**
* HyperV storvsc timeout testing cases:
@@ -954,21 +964,15 @@ hv_storvsc_on_channel_callback(void *context)
static int
storvsc_probe(device_t dev)
{
- int ata_disk_enable = 0;
int ret = ENXIO;
switch (storvsc_get_storage_type(dev)) {
case DRIVER_BLKVSC:
if(bootverbose)
- device_printf(dev, "DRIVER_BLKVSC-Emulated ATA/IDE probe\n");
- if (!getenv_int("hw.ata.disk_enable", &ata_disk_enable)) {
- if(bootverbose)
- device_printf(dev,
- "Enlightened ATA/IDE detected\n");
- device_set_desc(dev, g_drv_props_table[DRIVER_BLKVSC].drv_desc);
- ret = BUS_PROBE_DEFAULT;
- } else if(bootverbose)
- device_printf(dev, "Emulated ATA/IDE set (hw.ata.disk_enable set)\n");
+ device_printf(dev,
+ "Enlightened ATA/IDE detected\n");
+ device_set_desc(dev, g_drv_props_table[DRIVER_BLKVSC].drv_desc);
+ ret = BUS_PROBE_DEFAULT;
break;
case DRIVER_STORVSC:
if(bootverbose)
@@ -2018,27 +2022,45 @@ storvsc_io_done(struct hv_storvsc_request *reqp)
ccb->ccb_h.status &= ~CAM_STATUS_MASK;
if (vm_srb->scsi_status == SCSI_STATUS_OK) {
const struct scsi_generic *cmd;
-
+ cmd = (const struct scsi_generic *)
+ ((ccb->ccb_h.flags & CAM_CDB_POINTER) ?
+ csio->cdb_io.cdb_ptr : csio->cdb_io.cdb_bytes);
if (vm_srb->srb_status != SRB_STATUS_SUCCESS) {
- if (vm_srb->srb_status == SRB_STATUS_INVALID_LUN) {
- xpt_print(ccb->ccb_h.path, "invalid LUN %d\n",
- vm_srb->lun);
- } else {
- xpt_print(ccb->ccb_h.path, "Unknown SRB flag: %d\n",
- vm_srb->srb_status);
- }
/*
* If there are errors, for example, invalid LUN,
* host will inform VM through SRB status.
*/
- ccb->ccb_h.status |= CAM_SEL_TIMEOUT;
+ if (bootverbose) {
+ if (vm_srb->srb_status == SRB_STATUS_INVALID_LUN) {
+ xpt_print(ccb->ccb_h.path,
+ "invalid LUN %d for op: %s\n",
+ vm_srb->lun,
+ scsi_op_desc(cmd->opcode, NULL));
+ } else {
+ xpt_print(ccb->ccb_h.path,
+ "Unknown SRB flag: %d for op: %s\n",
+ vm_srb->srb_status,
+ scsi_op_desc(cmd->opcode, NULL));
+ }
+ }
+
+ /*
+ * XXX For a selection timeout, all of the LUNs
+ * on the target will be gone. It works for SCSI
+ * disks, but does not work for IDE disks.
+ *
+ * For CAM_DEV_NOT_THERE, CAM will only get
+ * rid of the device(s) specified by the path.
+ */
+ if (storvsc_get_storage_type(sc->hs_dev->device) ==
+ DRIVER_STORVSC)
+ ccb->ccb_h.status |= CAM_SEL_TIMEOUT;
+ else
+ ccb->ccb_h.status |= CAM_DEV_NOT_THERE;
} else {
ccb->ccb_h.status |= CAM_REQ_CMP;
}
- cmd = (const struct scsi_generic *)
- ((ccb->ccb_h.flags & CAM_CDB_POINTER) ?
- csio->cdb_io.cdb_ptr : csio->cdb_io.cdb_bytes);
if (cmd->opcode == INQUIRY) {
struct scsi_inquiry_data *inq_data =
(struct scsi_inquiry_data *)csio->data_ptr;
@@ -2059,7 +2081,7 @@ storvsc_io_done(struct hv_storvsc_request *reqp)
resp_buf[3], resp_buf[4]);
}
if (vm_srb->srb_status == SRB_STATUS_SUCCESS &&
- data_len > SHORT_INQUIRY_LENGTH) {
+ data_len >= SHORT_INQUIRY_LENGTH) {
char vendor[16];
cam_strvis(vendor, inq_data->vendor,
@@ -2152,3 +2174,57 @@ storvsc_get_storage_type(device_t dev)
return (DRIVER_UNKNOWN);
}
+#define PCI_VENDOR_INTEL 0x8086
+#define PCI_PRODUCT_PIIX4 0x7111
+
+static void
+storvsc_ada_probe_veto(void *arg __unused, struct cam_path *path,
+ struct ata_params *ident_buf __unused, int *veto)
+{
+
+ /*
+ * The ATA disks are shared with the controllers managed
+ * by this driver, so veto the ATA disks' attachment; the
+ * ATA disks will be attached as SCSI disks once this driver
+ * attached.
+ */
+ if (path->device->protocol == PROTO_ATA) {
+ struct ccb_pathinq cpi;
+
+ bzero(&cpi, sizeof(cpi));
+ xpt_setup_ccb(&cpi.ccb_h, path, CAM_PRIORITY_NONE);
+ cpi.ccb_h.func_code = XPT_PATH_INQ;
+ xpt_action((union ccb *)&cpi);
+ if (cpi.ccb_h.status == CAM_REQ_CMP &&
+ cpi.hba_vendor == PCI_VENDOR_INTEL &&
+ cpi.hba_device == PCI_PRODUCT_PIIX4) {
+ (*veto)++;
+ if (bootverbose) {
+ xpt_print(path,
+ "Disable ATA disks on "
+ "simulated ATA controller (0x%04x%04x)\n",
+ cpi.hba_device, cpi.hba_vendor);
+ }
+ }
+ }
+}
+
+static void
+storvsc_sysinit(void *arg __unused)
+{
+ if (vm_guest == VM_GUEST_HV) {
+ storvsc_handler_tag = EVENTHANDLER_REGISTER(ada_probe_veto,
+ storvsc_ada_probe_veto, NULL, EVENTHANDLER_PRI_ANY);
+ }
+}
+SYSINIT(storvsc_sys_init, SI_SUB_DRIVERS, SI_ORDER_SECOND, storvsc_sysinit,
+ NULL);
+
+static void
+storvsc_sysuninit(void *arg __unused)
+{
+ if (storvsc_handler_tag != NULL)
+ EVENTHANDLER_DEREGISTER(ada_probe_veto, storvsc_handler_tag);
+}
+SYSUNINIT(storvsc_sys_uninit, SI_SUB_DRIVERS, SI_ORDER_SECOND,
+ storvsc_sysuninit, NULL);
diff --git a/sys/dev/pci/pci_pci.c b/sys/dev/pci/pci_pci.c
index dedc55a..36f6834 100644
--- a/sys/dev/pci/pci_pci.c
+++ b/sys/dev/pci/pci_pci.c
@@ -935,6 +935,8 @@ pcib_probe_hotplug(struct pcib_softc *sc)
if ((sc->pcie_slot_cap & PCIEM_SLOT_CAP_HPC) == 0)
return;
+ if ((sc->pcie_link_cap & PCIEM_LINK_CAP_DL_ACTIVE) == 0)
+ return;
/*
* Some devices report that they have an MRL when they actually
diff --git a/sys/modules/hyperv/Makefile b/sys/modules/hyperv/Makefile
index 25b32e3..3bae26a 100644
--- a/sys/modules/hyperv/Makefile
+++ b/sys/modules/hyperv/Makefile
@@ -1,5 +1,5 @@
# $FreeBSD$
-SUBDIR = vmbus netvsc stordisengage storvsc utilities
+SUBDIR = vmbus netvsc storvsc utilities
.include <bsd.subdir.mk>
diff --git a/sys/sys/eventhandler.h b/sys/sys/eventhandler.h
index d82ece7..164b0f0 100644
--- a/sys/sys/eventhandler.h
+++ b/sys/sys/eventhandler.h
@@ -270,4 +270,11 @@ typedef void (*unregister_framebuffer_fn)(void *, struct fb_info *);
EVENTHANDLER_DECLARE(register_framebuffer, register_framebuffer_fn);
EVENTHANDLER_DECLARE(unregister_framebuffer, unregister_framebuffer_fn);
+/* Veto ada attachment */
+struct cam_path;
+struct ata_params;
+typedef void (*ada_probe_veto_fn)(void *, struct cam_path *,
+ struct ata_params *, int *);
+EVENTHANDLER_DECLARE(ada_probe_veto, ada_probe_veto_fn);
+
#endif /* _SYS_EVENTHANDLER_H_ */
diff --git a/sys/x86/x86/io_apic.c b/sys/x86/x86/io_apic.c
index 1a2cc3c..26fc9e9 100644
--- a/sys/x86/x86/io_apic.c
+++ b/sys/x86/x86/io_apic.c
@@ -412,6 +412,18 @@ ioapic_assign_cpu(struct intsrc *isrc, u_int apic_id)
u_int old_id;
/*
+ * On Hyper-V:
+ * - Stick to the first cpu for all I/O APIC pins.
+ * - And don't allow destination cpu changes.
+ */
+ if (vm_guest == VM_GUEST_HV) {
+ if (intpin->io_vector)
+ return (EINVAL);
+ else
+ apic_id = 0;
+ }
+
+ /*
* keep 1st core as the destination for NMI
*/
if (intpin->io_irq == IRQ_NMI)
OpenPOWER on IntegriCloud