@@ -28,6 +28,60 @@ static irqreturn_t ifcvf_intr_handler(int irq, void *arg)
28
28
return IRQ_HANDLED ;
29
29
}
30
30
31
+ static void ifcvf_free_irq_vectors (void * data )
32
+ {
33
+ pci_free_irq_vectors (data );
34
+ }
35
+
36
+ static void ifcvf_free_irq (struct ifcvf_adapter * adapter , int queues )
37
+ {
38
+ struct pci_dev * pdev = adapter -> pdev ;
39
+ struct ifcvf_hw * vf = & adapter -> vf ;
40
+ int i ;
41
+
42
+
43
+ for (i = 0 ; i < queues ; i ++ )
44
+ devm_free_irq (& pdev -> dev , vf -> vring [i ].irq , & vf -> vring [i ]);
45
+
46
+ ifcvf_free_irq_vectors (pdev );
47
+ }
48
+
49
+ static int ifcvf_request_irq (struct ifcvf_adapter * adapter )
50
+ {
51
+ struct pci_dev * pdev = adapter -> pdev ;
52
+ struct ifcvf_hw * vf = & adapter -> vf ;
53
+ int vector , i , ret , irq ;
54
+
55
+ ret = pci_alloc_irq_vectors (pdev , IFCVF_MAX_INTR ,
56
+ IFCVF_MAX_INTR , PCI_IRQ_MSIX );
57
+ if (ret < 0 ) {
58
+ IFCVF_ERR (pdev , "Failed to alloc IRQ vectors\n" );
59
+ return ret ;
60
+ }
61
+
62
+ for (i = 0 ; i < IFCVF_MAX_QUEUE_PAIRS * 2 ; i ++ ) {
63
+ snprintf (vf -> vring [i ].msix_name , 256 , "ifcvf[%s]-%d\n" ,
64
+ pci_name (pdev ), i );
65
+ vector = i + IFCVF_MSI_QUEUE_OFF ;
66
+ irq = pci_irq_vector (pdev , vector );
67
+ ret = devm_request_irq (& pdev -> dev , irq ,
68
+ ifcvf_intr_handler , 0 ,
69
+ vf -> vring [i ].msix_name ,
70
+ & vf -> vring [i ]);
71
+ if (ret ) {
72
+ IFCVF_ERR (pdev ,
73
+ "Failed to request irq for vq %d\n" , i );
74
+ ifcvf_free_irq (adapter , i );
75
+
76
+ return ret ;
77
+ }
78
+
79
+ vf -> vring [i ].irq = irq ;
80
+ }
81
+
82
+ return 0 ;
83
+ }
84
+
31
85
static int ifcvf_start_datapath (void * private )
32
86
{
33
87
struct ifcvf_hw * vf = ifcvf_private_to_vf (private );
@@ -118,17 +172,34 @@ static void ifcvf_vdpa_set_status(struct vdpa_device *vdpa_dev, u8 status)
118
172
{
119
173
struct ifcvf_adapter * adapter ;
120
174
struct ifcvf_hw * vf ;
175
+ u8 status_old ;
176
+ int ret ;
121
177
122
178
vf = vdpa_to_vf (vdpa_dev );
123
179
adapter = dev_get_drvdata (vdpa_dev -> dev .parent );
180
+ status_old = ifcvf_get_status (vf );
124
181
125
- if (status == 0 ) {
182
+ if ((status_old & VIRTIO_CONFIG_S_DRIVER_OK ) &&
183
+ !(status & VIRTIO_CONFIG_S_DRIVER_OK )) {
126
184
ifcvf_stop_datapath (adapter );
185
+ ifcvf_free_irq (adapter , IFCVF_MAX_QUEUE_PAIRS * 2 );
186
+ }
187
+
188
+ if (status == 0 ) {
127
189
ifcvf_reset_vring (adapter );
128
190
return ;
129
191
}
130
192
131
- if (status & VIRTIO_CONFIG_S_DRIVER_OK ) {
193
+ if ((status & VIRTIO_CONFIG_S_DRIVER_OK ) &&
194
+ !(status_old & VIRTIO_CONFIG_S_DRIVER_OK )) {
195
+ ret = ifcvf_request_irq (adapter );
196
+ if (ret ) {
197
+ status = ifcvf_get_status (vf );
198
+ status |= VIRTIO_CONFIG_S_FAILED ;
199
+ ifcvf_set_status (vf , status );
200
+ return ;
201
+ }
202
+
132
203
if (ifcvf_start_datapath (adapter ) < 0 )
133
204
IFCVF_ERR (adapter -> pdev ,
134
205
"Failed to set ifcvf vdpa status %u\n" ,
@@ -284,38 +355,6 @@ static const struct vdpa_config_ops ifc_vdpa_ops = {
284
355
.set_config_cb = ifcvf_vdpa_set_config_cb ,
285
356
};
286
357
287
- static int ifcvf_request_irq (struct ifcvf_adapter * adapter )
288
- {
289
- struct pci_dev * pdev = adapter -> pdev ;
290
- struct ifcvf_hw * vf = & adapter -> vf ;
291
- int vector , i , ret , irq ;
292
-
293
-
294
- for (i = 0 ; i < IFCVF_MAX_QUEUE_PAIRS * 2 ; i ++ ) {
295
- snprintf (vf -> vring [i ].msix_name , 256 , "ifcvf[%s]-%d\n" ,
296
- pci_name (pdev ), i );
297
- vector = i + IFCVF_MSI_QUEUE_OFF ;
298
- irq = pci_irq_vector (pdev , vector );
299
- ret = devm_request_irq (& pdev -> dev , irq ,
300
- ifcvf_intr_handler , 0 ,
301
- vf -> vring [i ].msix_name ,
302
- & vf -> vring [i ]);
303
- if (ret ) {
304
- IFCVF_ERR (pdev ,
305
- "Failed to request irq for vq %d\n" , i );
306
- return ret ;
307
- }
308
- vf -> vring [i ].irq = irq ;
309
- }
310
-
311
- return 0 ;
312
- }
313
-
314
- static void ifcvf_free_irq_vectors (void * data )
315
- {
316
- pci_free_irq_vectors (data );
317
- }
318
-
319
358
static int ifcvf_probe (struct pci_dev * pdev , const struct pci_device_id * id )
320
359
{
321
360
struct device * dev = & pdev -> dev ;
@@ -349,13 +388,6 @@ static int ifcvf_probe(struct pci_dev *pdev, const struct pci_device_id *id)
349
388
return ret ;
350
389
}
351
390
352
- ret = pci_alloc_irq_vectors (pdev , IFCVF_MAX_INTR ,
353
- IFCVF_MAX_INTR , PCI_IRQ_MSIX );
354
- if (ret < 0 ) {
355
- IFCVF_ERR (pdev , "Failed to alloc irq vectors\n" );
356
- return ret ;
357
- }
358
-
359
391
ret = devm_add_action_or_reset (dev , ifcvf_free_irq_vectors , pdev );
360
392
if (ret ) {
361
393
IFCVF_ERR (pdev ,
@@ -379,12 +411,6 @@ static int ifcvf_probe(struct pci_dev *pdev, const struct pci_device_id *id)
379
411
adapter -> pdev = pdev ;
380
412
adapter -> vdpa .dma_dev = & pdev -> dev ;
381
413
382
- ret = ifcvf_request_irq (adapter );
383
- if (ret ) {
384
- IFCVF_ERR (pdev , "Failed to request MSI-X irq\n" );
385
- goto err ;
386
- }
387
-
388
414
ret = ifcvf_init_hw (vf , pdev );
389
415
if (ret ) {
390
416
IFCVF_ERR (pdev , "Failed to init IFCVF hw\n" );
0 commit comments