Skip to content

Commit a8e3750

Browse files
dcuiLorenzo Pieralisi
authored andcommitted
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: Dexuan Cui <[email protected]> Signed-off-by: Lorenzo Pieralisi <[email protected]> Reviewed-by: Michael Kelley <[email protected]>
1 parent 54ecb8f commit a8e3750

File tree

1 file changed

+28
-15
lines changed

1 file changed

+28
-15
lines changed

drivers/pci/controller/pci-hyperv.c

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2379,7 +2379,9 @@ static void hv_pci_onchannelcallback(void *context)
23792379
* failing if the host doesn't support the necessary protocol
23802380
* level.
23812381
*/
2382-
static int hv_pci_protocol_negotiation(struct hv_device *hdev)
2382+
static int hv_pci_protocol_negotiation(struct hv_device *hdev,
2383+
enum pci_protocol_version_t version[],
2384+
int num_version)
23832385
{
23842386
struct pci_version_request *version_req;
23852387
struct hv_pci_compl comp_pkt;
@@ -2403,8 +2405,8 @@ static int hv_pci_protocol_negotiation(struct hv_device *hdev)
24032405
version_req = (struct pci_version_request *)&pkt->message;
24042406
version_req->message_type.type = PCI_QUERY_PROTOCOL_VERSION;
24052407

2406-
for (i = 0; i < ARRAY_SIZE(pci_protocol_versions); i++) {
2407-
version_req->protocol_version = pci_protocol_versions[i];
2408+
for (i = 0; i < num_version; i++) {
2409+
version_req->protocol_version = version[i];
24082410
ret = vmbus_sendpacket(hdev->channel, version_req,
24092411
sizeof(struct pci_version_request),
24102412
(unsigned long)pkt, VM_PKT_DATA_INBAND,
@@ -2420,7 +2422,7 @@ static int hv_pci_protocol_negotiation(struct hv_device *hdev)
24202422
}
24212423

24222424
if (comp_pkt.completion_status >= 0) {
2423-
pci_protocol_version = pci_protocol_versions[i];
2425+
pci_protocol_version = version[i];
24242426
dev_info(&hdev->device,
24252427
"PCI VMBus probing: Using version %#x\n",
24262428
pci_protocol_version);
@@ -2930,7 +2932,8 @@ static int hv_pci_probe(struct hv_device *hdev,
29302932

29312933
hv_set_drvdata(hdev, hbus);
29322934

2933-
ret = hv_pci_protocol_negotiation(hdev);
2935+
ret = hv_pci_protocol_negotiation(hdev, pci_protocol_versions,
2936+
ARRAY_SIZE(pci_protocol_versions));
29342937
if (ret)
29352938
goto close;
29362939

@@ -3011,7 +3014,7 @@ static int hv_pci_probe(struct hv_device *hdev,
30113014
return ret;
30123015
}
30133016

3014-
static void hv_pci_bus_exit(struct hv_device *hdev)
3017+
static int hv_pci_bus_exit(struct hv_device *hdev, bool hibernating)
30153018
{
30163019
struct hv_pcibus_device *hbus = hv_get_drvdata(hdev);
30173020
struct {
@@ -3027,16 +3030,20 @@ static void hv_pci_bus_exit(struct hv_device *hdev)
30273030
* access the per-channel ringbuffer any longer.
30283031
*/
30293032
if (hdev->channel->rescind)
3030-
return;
3033+
return 0;
30313034

3032-
/* Delete any children which might still exist. */
3033-
memset(&relations, 0, sizeof(relations));
3034-
hv_pci_devices_present(hbus, &relations);
3035+
if (!hibernating) {
3036+
/* Delete any children which might still exist. */
3037+
memset(&relations, 0, sizeof(relations));
3038+
hv_pci_devices_present(hbus, &relations);
3039+
}
30353040

30363041
ret = hv_send_resources_released(hdev);
3037-
if (ret)
3042+
if (ret) {
30383043
dev_err(&hdev->device,
30393044
"Couldn't send resources released packet(s)\n");
3045+
return ret;
3046+
}
30403047

30413048
memset(&pkt.teardown_packet, 0, sizeof(pkt.teardown_packet));
30423049
init_completion(&comp_pkt.host_event);
@@ -3049,8 +3056,13 @@ static void hv_pci_bus_exit(struct hv_device *hdev)
30493056
(unsigned long)&pkt.teardown_packet,
30503057
VM_PKT_DATA_INBAND,
30513058
VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
3052-
if (!ret)
3053-
wait_for_completion_timeout(&comp_pkt.host_event, 10 * HZ);
3059+
if (ret)
3060+
return ret;
3061+
3062+
if (wait_for_completion_timeout(&comp_pkt.host_event, 10 * HZ) == 0)
3063+
return -ETIMEDOUT;
3064+
3065+
return 0;
30543066
}
30553067

30563068
/**
@@ -3062,6 +3074,7 @@ static void hv_pci_bus_exit(struct hv_device *hdev)
30623074
static int hv_pci_remove(struct hv_device *hdev)
30633075
{
30643076
struct hv_pcibus_device *hbus;
3077+
int ret;
30653078

30663079
hbus = hv_get_drvdata(hdev);
30673080
if (hbus->state == hv_pcibus_installed) {
@@ -3074,7 +3087,7 @@ static int hv_pci_remove(struct hv_device *hdev)
30743087
hbus->state = hv_pcibus_removed;
30753088
}
30763089

3077-
hv_pci_bus_exit(hdev);
3090+
ret = hv_pci_bus_exit(hdev, false);
30783091

30793092
vmbus_close(hdev->channel);
30803093

@@ -3091,7 +3104,7 @@ static int hv_pci_remove(struct hv_device *hdev)
30913104
hv_put_dom_num(hbus->sysdata.domain);
30923105

30933106
free_page((unsigned long)hbus);
3094-
return 0;
3107+
return ret;
30953108
}
30963109

30973110
static const struct hv_vmbus_device_id hv_pci_id_table[] = {

0 commit comments

Comments
 (0)