Drivers: hv: vmbus: Add vendor and device atttributes
Add vendor and device attributes to VMBUS devices. These will be used by Hyper-V tools as well user-level RDMA libraries that will use the vendor/device tuple to discover the RDMA device. Signed-off-by: K. Y. Srinivasan <kys@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>steinar/wifi_calib_4_9_kernel
parent
1b807e1011
commit
7047f17d70
|
@ -27,3 +27,17 @@ Description: The mapping of which primary/sub channels are bound to which
|
||||||
Virtual Processors.
|
Virtual Processors.
|
||||||
Format: <channel's child_relid:the bound cpu's number>
|
Format: <channel's child_relid:the bound cpu's number>
|
||||||
Users: tools/hv/lsvmbus
|
Users: tools/hv/lsvmbus
|
||||||
|
|
||||||
|
What: /sys/bus/vmbus/devices/vmbus_*/device
|
||||||
|
Date: Dec. 2015
|
||||||
|
KernelVersion: 4.5
|
||||||
|
Contact: K. Y. Srinivasan <kys@microsoft.com>
|
||||||
|
Description: The 16 bit device ID of the device
|
||||||
|
Users: tools/hv/lsvmbus and user level RDMA libraries
|
||||||
|
|
||||||
|
What: /sys/bus/vmbus/devices/vmbus_*/vendor
|
||||||
|
Date: Dec. 2015
|
||||||
|
KernelVersion: 4.5
|
||||||
|
Contact: K. Y. Srinivasan <kys@microsoft.com>
|
||||||
|
Description: The 16 bit vendor ID of the device
|
||||||
|
Users: tools/hv/lsvmbus and user level RDMA libraries
|
||||||
|
|
|
@ -32,8 +32,122 @@
|
||||||
|
|
||||||
#include "hyperv_vmbus.h"
|
#include "hyperv_vmbus.h"
|
||||||
|
|
||||||
static void init_vp_index(struct vmbus_channel *channel,
|
static void init_vp_index(struct vmbus_channel *channel, u16 dev_type);
|
||||||
const uuid_le *type_guid);
|
|
||||||
|
static const struct vmbus_device vmbus_devs[] = {
|
||||||
|
/* IDE */
|
||||||
|
{ .dev_type = HV_IDE,
|
||||||
|
HV_IDE_GUID,
|
||||||
|
.perf_device = true,
|
||||||
|
},
|
||||||
|
|
||||||
|
/* SCSI */
|
||||||
|
{ .dev_type = HV_SCSI,
|
||||||
|
HV_SCSI_GUID,
|
||||||
|
.perf_device = true,
|
||||||
|
},
|
||||||
|
|
||||||
|
/* Fibre Channel */
|
||||||
|
{ .dev_type = HV_FC,
|
||||||
|
HV_SYNTHFC_GUID,
|
||||||
|
.perf_device = true,
|
||||||
|
},
|
||||||
|
|
||||||
|
/* Synthetic NIC */
|
||||||
|
{ .dev_type = HV_NIC,
|
||||||
|
HV_NIC_GUID,
|
||||||
|
.perf_device = true,
|
||||||
|
},
|
||||||
|
|
||||||
|
/* Network Direct */
|
||||||
|
{ .dev_type = HV_ND,
|
||||||
|
HV_ND_GUID,
|
||||||
|
.perf_device = true,
|
||||||
|
},
|
||||||
|
|
||||||
|
/* PCIE */
|
||||||
|
{ .dev_type = HV_PCIE,
|
||||||
|
HV_PCIE_GUID,
|
||||||
|
.perf_device = true,
|
||||||
|
},
|
||||||
|
|
||||||
|
/* Synthetic Frame Buffer */
|
||||||
|
{ .dev_type = HV_FB,
|
||||||
|
HV_SYNTHVID_GUID,
|
||||||
|
.perf_device = false,
|
||||||
|
},
|
||||||
|
|
||||||
|
/* Synthetic Keyboard */
|
||||||
|
{ .dev_type = HV_KBD,
|
||||||
|
HV_KBD_GUID,
|
||||||
|
.perf_device = false,
|
||||||
|
},
|
||||||
|
|
||||||
|
/* Synthetic MOUSE */
|
||||||
|
{ .dev_type = HV_MOUSE,
|
||||||
|
HV_MOUSE_GUID,
|
||||||
|
.perf_device = false,
|
||||||
|
},
|
||||||
|
|
||||||
|
/* KVP */
|
||||||
|
{ .dev_type = HV_KVP,
|
||||||
|
HV_KVP_GUID,
|
||||||
|
.perf_device = false,
|
||||||
|
},
|
||||||
|
|
||||||
|
/* Time Synch */
|
||||||
|
{ .dev_type = HV_TS,
|
||||||
|
HV_TS_GUID,
|
||||||
|
.perf_device = false,
|
||||||
|
},
|
||||||
|
|
||||||
|
/* Heartbeat */
|
||||||
|
{ .dev_type = HV_HB,
|
||||||
|
HV_HEART_BEAT_GUID,
|
||||||
|
.perf_device = false,
|
||||||
|
},
|
||||||
|
|
||||||
|
/* Shutdown */
|
||||||
|
{ .dev_type = HV_SHUTDOWN,
|
||||||
|
HV_SHUTDOWN_GUID,
|
||||||
|
.perf_device = false,
|
||||||
|
},
|
||||||
|
|
||||||
|
/* File copy */
|
||||||
|
{ .dev_type = HV_FCOPY,
|
||||||
|
HV_FCOPY_GUID,
|
||||||
|
.perf_device = false,
|
||||||
|
},
|
||||||
|
|
||||||
|
/* Backup */
|
||||||
|
{ .dev_type = HV_BACKUP,
|
||||||
|
HV_VSS_GUID,
|
||||||
|
.perf_device = false,
|
||||||
|
},
|
||||||
|
|
||||||
|
/* Dynamic Memory */
|
||||||
|
{ .dev_type = HV_DM,
|
||||||
|
HV_DM_GUID,
|
||||||
|
.perf_device = false,
|
||||||
|
},
|
||||||
|
|
||||||
|
/* Unknown GUID */
|
||||||
|
{ .dev_type = HV_UNKOWN,
|
||||||
|
.perf_device = false,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static u16 hv_get_dev_type(const uuid_le *guid)
|
||||||
|
{
|
||||||
|
u16 i;
|
||||||
|
|
||||||
|
for (i = HV_IDE; i < HV_UNKOWN; i++) {
|
||||||
|
if (!uuid_le_cmp(*guid, vmbus_devs[i].guid))
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
pr_info("Unknown GUID: %pUl\n", guid);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* vmbus_prep_negotiate_resp() - Create default response for Hyper-V Negotiate message
|
* vmbus_prep_negotiate_resp() - Create default response for Hyper-V Negotiate message
|
||||||
|
@ -251,6 +365,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
|
||||||
struct vmbus_channel *channel;
|
struct vmbus_channel *channel;
|
||||||
bool fnew = true;
|
bool fnew = true;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
u16 dev_type;
|
||||||
|
|
||||||
/* Make sure this is a new offer */
|
/* Make sure this is a new offer */
|
||||||
mutex_lock(&vmbus_connection.channel_mutex);
|
mutex_lock(&vmbus_connection.channel_mutex);
|
||||||
|
@ -288,7 +403,9 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
|
||||||
goto err_free_chan;
|
goto err_free_chan;
|
||||||
}
|
}
|
||||||
|
|
||||||
init_vp_index(newchannel, &newchannel->offermsg.offer.if_type);
|
dev_type = hv_get_dev_type(&newchannel->offermsg.offer.if_type);
|
||||||
|
|
||||||
|
init_vp_index(newchannel, dev_type);
|
||||||
|
|
||||||
if (newchannel->target_cpu != get_cpu()) {
|
if (newchannel->target_cpu != get_cpu()) {
|
||||||
put_cpu();
|
put_cpu();
|
||||||
|
@ -325,6 +442,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
|
||||||
if (!newchannel->device_obj)
|
if (!newchannel->device_obj)
|
||||||
goto err_deq_chan;
|
goto err_deq_chan;
|
||||||
|
|
||||||
|
newchannel->device_obj->device_id = dev_type;
|
||||||
/*
|
/*
|
||||||
* Add the new device to the bus. This will kick off device-driver
|
* Add the new device to the bus. This will kick off device-driver
|
||||||
* binding which eventually invokes the device driver's AddDevice()
|
* binding which eventually invokes the device driver's AddDevice()
|
||||||
|
@ -358,37 +476,6 @@ err_free_chan:
|
||||||
free_channel(newchannel);
|
free_channel(newchannel);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum {
|
|
||||||
IDE = 0,
|
|
||||||
SCSI,
|
|
||||||
FC,
|
|
||||||
NIC,
|
|
||||||
ND_NIC,
|
|
||||||
PCIE,
|
|
||||||
MAX_PERF_CHN,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This is an array of device_ids (device types) that are performance critical.
|
|
||||||
* We attempt to distribute the interrupt load for these devices across
|
|
||||||
* all available CPUs.
|
|
||||||
*/
|
|
||||||
static const struct hv_vmbus_device_id hp_devs[] = {
|
|
||||||
/* IDE */
|
|
||||||
{ HV_IDE_GUID, },
|
|
||||||
/* Storage - SCSI */
|
|
||||||
{ HV_SCSI_GUID, },
|
|
||||||
/* Storage - FC */
|
|
||||||
{ HV_SYNTHFC_GUID, },
|
|
||||||
/* Network */
|
|
||||||
{ HV_NIC_GUID, },
|
|
||||||
/* NetworkDirect Guest RDMA */
|
|
||||||
{ HV_ND_GUID, },
|
|
||||||
/* PCI Express Pass Through */
|
|
||||||
{ HV_PCIE_GUID, },
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We use this state to statically distribute the channel interrupt load.
|
* We use this state to statically distribute the channel interrupt load.
|
||||||
*/
|
*/
|
||||||
|
@ -405,22 +492,15 @@ static int next_numa_node_id;
|
||||||
* For pre-win8 hosts or non-performance critical channels we assign the
|
* For pre-win8 hosts or non-performance critical channels we assign the
|
||||||
* first CPU in the first NUMA node.
|
* first CPU in the first NUMA node.
|
||||||
*/
|
*/
|
||||||
static void init_vp_index(struct vmbus_channel *channel, const uuid_le *type_guid)
|
static void init_vp_index(struct vmbus_channel *channel, u16 dev_type)
|
||||||
{
|
{
|
||||||
u32 cur_cpu;
|
u32 cur_cpu;
|
||||||
int i;
|
bool perf_chn = vmbus_devs[dev_type].perf_device;
|
||||||
bool perf_chn = false;
|
|
||||||
struct vmbus_channel *primary = channel->primary_channel;
|
struct vmbus_channel *primary = channel->primary_channel;
|
||||||
int next_node;
|
int next_node;
|
||||||
struct cpumask available_mask;
|
struct cpumask available_mask;
|
||||||
struct cpumask *alloced_mask;
|
struct cpumask *alloced_mask;
|
||||||
|
|
||||||
for (i = IDE; i < MAX_PERF_CHN; i++) {
|
|
||||||
if (!uuid_le_cmp(*type_guid, hp_devs[i].guid)) {
|
|
||||||
perf_chn = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((vmbus_proto_version == VERSION_WS2008) ||
|
if ((vmbus_proto_version == VERSION_WS2008) ||
|
||||||
(vmbus_proto_version == VERSION_WIN7) || (!perf_chn)) {
|
(vmbus_proto_version == VERSION_WIN7) || (!perf_chn)) {
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -477,6 +477,24 @@ static ssize_t channel_vp_mapping_show(struct device *dev,
|
||||||
}
|
}
|
||||||
static DEVICE_ATTR_RO(channel_vp_mapping);
|
static DEVICE_ATTR_RO(channel_vp_mapping);
|
||||||
|
|
||||||
|
static ssize_t vendor_show(struct device *dev,
|
||||||
|
struct device_attribute *dev_attr,
|
||||||
|
char *buf)
|
||||||
|
{
|
||||||
|
struct hv_device *hv_dev = device_to_hv_device(dev);
|
||||||
|
return sprintf(buf, "0x%x\n", hv_dev->vendor_id);
|
||||||
|
}
|
||||||
|
static DEVICE_ATTR_RO(vendor);
|
||||||
|
|
||||||
|
static ssize_t device_show(struct device *dev,
|
||||||
|
struct device_attribute *dev_attr,
|
||||||
|
char *buf)
|
||||||
|
{
|
||||||
|
struct hv_device *hv_dev = device_to_hv_device(dev);
|
||||||
|
return sprintf(buf, "0x%x\n", hv_dev->device_id);
|
||||||
|
}
|
||||||
|
static DEVICE_ATTR_RO(device);
|
||||||
|
|
||||||
/* Set up per device attributes in /sys/bus/vmbus/devices/<bus device> */
|
/* Set up per device attributes in /sys/bus/vmbus/devices/<bus device> */
|
||||||
static struct attribute *vmbus_attrs[] = {
|
static struct attribute *vmbus_attrs[] = {
|
||||||
&dev_attr_id.attr,
|
&dev_attr_id.attr,
|
||||||
|
@ -502,6 +520,8 @@ static struct attribute *vmbus_attrs[] = {
|
||||||
&dev_attr_in_read_bytes_avail.attr,
|
&dev_attr_in_read_bytes_avail.attr,
|
||||||
&dev_attr_in_write_bytes_avail.attr,
|
&dev_attr_in_write_bytes_avail.attr,
|
||||||
&dev_attr_channel_vp_mapping.attr,
|
&dev_attr_channel_vp_mapping.attr,
|
||||||
|
&dev_attr_vendor.attr,
|
||||||
|
&dev_attr_device.attr,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
ATTRIBUTE_GROUPS(vmbus);
|
ATTRIBUTE_GROUPS(vmbus);
|
||||||
|
@ -957,6 +977,7 @@ struct hv_device *vmbus_device_create(const uuid_le *type,
|
||||||
memcpy(&child_device_obj->dev_type, type, sizeof(uuid_le));
|
memcpy(&child_device_obj->dev_type, type, sizeof(uuid_le));
|
||||||
memcpy(&child_device_obj->dev_instance, instance,
|
memcpy(&child_device_obj->dev_instance, instance,
|
||||||
sizeof(uuid_le));
|
sizeof(uuid_le));
|
||||||
|
child_device_obj->vendor_id = 0x1414; /* MSFT vendor ID */
|
||||||
|
|
||||||
|
|
||||||
return child_device_obj;
|
return child_device_obj;
|
||||||
|
|
|
@ -633,6 +633,32 @@ enum hv_signal_policy {
|
||||||
HV_SIGNAL_POLICY_EXPLICIT,
|
HV_SIGNAL_POLICY_EXPLICIT,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum vmbus_device_type {
|
||||||
|
HV_IDE = 0,
|
||||||
|
HV_SCSI,
|
||||||
|
HV_FC,
|
||||||
|
HV_NIC,
|
||||||
|
HV_ND,
|
||||||
|
HV_PCIE,
|
||||||
|
HV_FB,
|
||||||
|
HV_KBD,
|
||||||
|
HV_MOUSE,
|
||||||
|
HV_KVP,
|
||||||
|
HV_TS,
|
||||||
|
HV_HB,
|
||||||
|
HV_SHUTDOWN,
|
||||||
|
HV_FCOPY,
|
||||||
|
HV_BACKUP,
|
||||||
|
HV_DM,
|
||||||
|
HV_UNKOWN,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct vmbus_device {
|
||||||
|
u16 dev_type;
|
||||||
|
uuid_le guid;
|
||||||
|
bool perf_device;
|
||||||
|
};
|
||||||
|
|
||||||
struct vmbus_channel {
|
struct vmbus_channel {
|
||||||
/* Unique channel id */
|
/* Unique channel id */
|
||||||
int id;
|
int id;
|
||||||
|
@ -959,6 +985,8 @@ struct hv_device {
|
||||||
|
|
||||||
/* the device instance id of this device */
|
/* the device instance id of this device */
|
||||||
uuid_le dev_instance;
|
uuid_le dev_instance;
|
||||||
|
u16 vendor_id;
|
||||||
|
u16 device_id;
|
||||||
|
|
||||||
struct device device;
|
struct device device;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue