Commit a8e37506 authored by Dexuan Cui's avatar Dexuan Cui Committed by Lorenzo Pieralisi

PCI: hv: Reorganize the code in preparation of hibernation

There is no functional change. This is just preparatory for a later
patch which adds the hibernation support for the pci-hyperv driver.
Signed-off-by: default avatarDexuan Cui <decui@microsoft.com>
Signed-off-by: default avatarLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Reviewed-by: default avatarMichael Kelley <mikelley@microsoft.com>
parent 54ecb8f7
...@@ -2379,7 +2379,9 @@ static void hv_pci_onchannelcallback(void *context) ...@@ -2379,7 +2379,9 @@ static void hv_pci_onchannelcallback(void *context)
* failing if the host doesn't support the necessary protocol * failing if the host doesn't support the necessary protocol
* level. * level.
*/ */
static int hv_pci_protocol_negotiation(struct hv_device *hdev) static int hv_pci_protocol_negotiation(struct hv_device *hdev,
enum pci_protocol_version_t version[],
int num_version)
{ {
struct pci_version_request *version_req; struct pci_version_request *version_req;
struct hv_pci_compl comp_pkt; struct hv_pci_compl comp_pkt;
...@@ -2403,8 +2405,8 @@ static int hv_pci_protocol_negotiation(struct hv_device *hdev) ...@@ -2403,8 +2405,8 @@ static int hv_pci_protocol_negotiation(struct hv_device *hdev)
version_req = (struct pci_version_request *)&pkt->message; version_req = (struct pci_version_request *)&pkt->message;
version_req->message_type.type = PCI_QUERY_PROTOCOL_VERSION; version_req->message_type.type = PCI_QUERY_PROTOCOL_VERSION;
for (i = 0; i < ARRAY_SIZE(pci_protocol_versions); i++) { for (i = 0; i < num_version; i++) {
version_req->protocol_version = pci_protocol_versions[i]; version_req->protocol_version = version[i];
ret = vmbus_sendpacket(hdev->channel, version_req, ret = vmbus_sendpacket(hdev->channel, version_req,
sizeof(struct pci_version_request), sizeof(struct pci_version_request),
(unsigned long)pkt, VM_PKT_DATA_INBAND, (unsigned long)pkt, VM_PKT_DATA_INBAND,
...@@ -2420,7 +2422,7 @@ static int hv_pci_protocol_negotiation(struct hv_device *hdev) ...@@ -2420,7 +2422,7 @@ static int hv_pci_protocol_negotiation(struct hv_device *hdev)
} }
if (comp_pkt.completion_status >= 0) { if (comp_pkt.completion_status >= 0) {
pci_protocol_version = pci_protocol_versions[i]; pci_protocol_version = version[i];
dev_info(&hdev->device, dev_info(&hdev->device,
"PCI VMBus probing: Using version %#x\n", "PCI VMBus probing: Using version %#x\n",
pci_protocol_version); pci_protocol_version);
...@@ -2930,7 +2932,8 @@ static int hv_pci_probe(struct hv_device *hdev, ...@@ -2930,7 +2932,8 @@ static int hv_pci_probe(struct hv_device *hdev,
hv_set_drvdata(hdev, hbus); hv_set_drvdata(hdev, hbus);
ret = hv_pci_protocol_negotiation(hdev); ret = hv_pci_protocol_negotiation(hdev, pci_protocol_versions,
ARRAY_SIZE(pci_protocol_versions));
if (ret) if (ret)
goto close; goto close;
...@@ -3011,7 +3014,7 @@ static int hv_pci_probe(struct hv_device *hdev, ...@@ -3011,7 +3014,7 @@ static int hv_pci_probe(struct hv_device *hdev,
return ret; return ret;
} }
static void hv_pci_bus_exit(struct hv_device *hdev) static int hv_pci_bus_exit(struct hv_device *hdev, bool hibernating)
{ {
struct hv_pcibus_device *hbus = hv_get_drvdata(hdev); struct hv_pcibus_device *hbus = hv_get_drvdata(hdev);
struct { struct {
...@@ -3027,16 +3030,20 @@ static void hv_pci_bus_exit(struct hv_device *hdev) ...@@ -3027,16 +3030,20 @@ static void hv_pci_bus_exit(struct hv_device *hdev)
* access the per-channel ringbuffer any longer. * access the per-channel ringbuffer any longer.
*/ */
if (hdev->channel->rescind) if (hdev->channel->rescind)
return; return 0;
/* Delete any children which might still exist. */ if (!hibernating) {
memset(&relations, 0, sizeof(relations)); /* Delete any children which might still exist. */
hv_pci_devices_present(hbus, &relations); memset(&relations, 0, sizeof(relations));
hv_pci_devices_present(hbus, &relations);
}
ret = hv_send_resources_released(hdev); ret = hv_send_resources_released(hdev);
if (ret) if (ret) {
dev_err(&hdev->device, dev_err(&hdev->device,
"Couldn't send resources released packet(s)\n"); "Couldn't send resources released packet(s)\n");
return ret;
}
memset(&pkt.teardown_packet, 0, sizeof(pkt.teardown_packet)); memset(&pkt.teardown_packet, 0, sizeof(pkt.teardown_packet));
init_completion(&comp_pkt.host_event); init_completion(&comp_pkt.host_event);
...@@ -3049,8 +3056,13 @@ static void hv_pci_bus_exit(struct hv_device *hdev) ...@@ -3049,8 +3056,13 @@ static void hv_pci_bus_exit(struct hv_device *hdev)
(unsigned long)&pkt.teardown_packet, (unsigned long)&pkt.teardown_packet,
VM_PKT_DATA_INBAND, VM_PKT_DATA_INBAND,
VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
if (!ret) if (ret)
wait_for_completion_timeout(&comp_pkt.host_event, 10 * HZ); return ret;
if (wait_for_completion_timeout(&comp_pkt.host_event, 10 * HZ) == 0)
return -ETIMEDOUT;
return 0;
} }
/** /**
...@@ -3062,6 +3074,7 @@ static void hv_pci_bus_exit(struct hv_device *hdev) ...@@ -3062,6 +3074,7 @@ static void hv_pci_bus_exit(struct hv_device *hdev)
static int hv_pci_remove(struct hv_device *hdev) static int hv_pci_remove(struct hv_device *hdev)
{ {
struct hv_pcibus_device *hbus; struct hv_pcibus_device *hbus;
int ret;
hbus = hv_get_drvdata(hdev); hbus = hv_get_drvdata(hdev);
if (hbus->state == hv_pcibus_installed) { if (hbus->state == hv_pcibus_installed) {
...@@ -3074,7 +3087,7 @@ static int hv_pci_remove(struct hv_device *hdev) ...@@ -3074,7 +3087,7 @@ static int hv_pci_remove(struct hv_device *hdev)
hbus->state = hv_pcibus_removed; hbus->state = hv_pcibus_removed;
} }
hv_pci_bus_exit(hdev); ret = hv_pci_bus_exit(hdev, false);
vmbus_close(hdev->channel); vmbus_close(hdev->channel);
...@@ -3091,7 +3104,7 @@ static int hv_pci_remove(struct hv_device *hdev) ...@@ -3091,7 +3104,7 @@ static int hv_pci_remove(struct hv_device *hdev)
hv_put_dom_num(hbus->sysdata.domain); hv_put_dom_num(hbus->sysdata.domain);
free_page((unsigned long)hbus); free_page((unsigned long)hbus);
return 0; return ret;
} }
static const struct hv_vmbus_device_id hv_pci_id_table[] = { static const struct hv_vmbus_device_id hv_pci_id_table[] = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment