31
31
32
32
#define VMCI_UTIL_NUM_RESOURCES 1
33
33
34
+ /*
35
+ * Datagram buffers for DMA send/receive must accommodate at least
36
+ * a maximum sized datagram and the header.
37
+ */
38
+ #define VMCI_DMA_DG_BUFFER_SIZE (VMCI_MAX_DG_SIZE + PAGE_SIZE)
39
+
34
40
static bool vmci_disable_msi ;
35
41
module_param_named (disable_msi , vmci_disable_msi , bool , 0 );
36
42
MODULE_PARM_DESC (disable_msi , "Disable MSI use in driver - (default=0)" );
@@ -53,6 +59,9 @@ struct vmci_guest_device {
53
59
struct tasklet_struct bm_tasklet ;
54
60
55
61
void * data_buffer ;
62
+ dma_addr_t data_buffer_base ;
63
+ void * tx_buffer ;
64
+ dma_addr_t tx_buffer_base ;
56
65
void * notification_bitmap ;
57
66
dma_addr_t notification_base ;
58
67
};
@@ -451,6 +460,24 @@ static irqreturn_t vmci_interrupt_dma_datagram(int irq, void *_dev)
451
460
return IRQ_HANDLED ;
452
461
}
453
462
463
+ static void vmci_free_dg_buffers (struct vmci_guest_device * vmci_dev )
464
+ {
465
+ if (vmci_dev -> mmio_base != NULL ) {
466
+ if (vmci_dev -> tx_buffer != NULL )
467
+ dma_free_coherent (vmci_dev -> dev ,
468
+ VMCI_DMA_DG_BUFFER_SIZE ,
469
+ vmci_dev -> tx_buffer ,
470
+ vmci_dev -> tx_buffer_base );
471
+ if (vmci_dev -> data_buffer != NULL )
472
+ dma_free_coherent (vmci_dev -> dev ,
473
+ VMCI_DMA_DG_BUFFER_SIZE ,
474
+ vmci_dev -> data_buffer ,
475
+ vmci_dev -> data_buffer_base );
476
+ } else {
477
+ vfree (vmci_dev -> data_buffer );
478
+ }
479
+ }
480
+
454
481
/*
455
482
* Most of the initialization at module load time is done here.
456
483
*/
@@ -517,11 +544,27 @@ static int vmci_guest_probe_device(struct pci_dev *pdev,
517
544
tasklet_init (& vmci_dev -> bm_tasklet ,
518
545
vmci_process_bitmap , (unsigned long )vmci_dev );
519
546
520
- vmci_dev -> data_buffer = vmalloc (VMCI_MAX_DG_SIZE );
547
+ if (mmio_base != NULL ) {
548
+ vmci_dev -> tx_buffer = dma_alloc_coherent (& pdev -> dev , VMCI_DMA_DG_BUFFER_SIZE ,
549
+ & vmci_dev -> tx_buffer_base ,
550
+ GFP_KERNEL );
551
+ if (!vmci_dev -> tx_buffer ) {
552
+ dev_err (& pdev -> dev ,
553
+ "Can't allocate memory for datagram tx buffer\n" );
554
+ return - ENOMEM ;
555
+ }
556
+
557
+ vmci_dev -> data_buffer = dma_alloc_coherent (& pdev -> dev , VMCI_DMA_DG_BUFFER_SIZE ,
558
+ & vmci_dev -> data_buffer_base ,
559
+ GFP_KERNEL );
560
+ } else {
561
+ vmci_dev -> data_buffer = vmalloc (VMCI_MAX_DG_SIZE );
562
+ }
521
563
if (!vmci_dev -> data_buffer ) {
522
564
dev_err (& pdev -> dev ,
523
565
"Can't allocate memory for datagram buffer\n" );
524
- return - ENOMEM ;
566
+ error = - ENOMEM ;
567
+ goto err_free_data_buffers ;
525
568
}
526
569
527
570
pci_set_master (pdev ); /* To enable queue_pair functionality. */
@@ -539,7 +582,7 @@ static int vmci_guest_probe_device(struct pci_dev *pdev,
539
582
if (!(capabilities & VMCI_CAPS_DATAGRAM )) {
540
583
dev_err (& pdev -> dev , "Device does not support datagrams\n" );
541
584
error = - ENXIO ;
542
- goto err_free_data_buffer ;
585
+ goto err_free_data_buffers ;
543
586
}
544
587
caps_in_use = VMCI_CAPS_DATAGRAM ;
545
588
@@ -583,7 +626,7 @@ static int vmci_guest_probe_device(struct pci_dev *pdev,
583
626
dev_err (& pdev -> dev ,
584
627
"Missing capability: VMCI_CAPS_DMA_DATAGRAM\n" );
585
628
error = - ENXIO ;
586
- goto err_free_data_buffer ;
629
+ goto err_free_data_buffers ;
587
630
}
588
631
}
589
632
@@ -592,10 +635,17 @@ static int vmci_guest_probe_device(struct pci_dev *pdev,
592
635
/* Let the host know which capabilities we intend to use. */
593
636
vmci_write_reg (vmci_dev , caps_in_use , VMCI_CAPS_ADDR );
594
637
595
- /* Let the device know the size for pages passed down. */
596
- if ( caps_in_use & VMCI_CAPS_DMA_DATAGRAM )
638
+ if ( caps_in_use & VMCI_CAPS_DMA_DATAGRAM ) {
639
+ /* Let the device know the size for pages passed down. */
597
640
vmci_write_reg (vmci_dev , PAGE_SHIFT , VMCI_GUEST_PAGE_SHIFT );
598
641
642
+ /* Configure the high order parts of the data in/out buffers. */
643
+ vmci_write_reg (vmci_dev , upper_32_bits (vmci_dev -> data_buffer_base ),
644
+ VMCI_DATA_IN_HIGH_ADDR );
645
+ vmci_write_reg (vmci_dev , upper_32_bits (vmci_dev -> tx_buffer_base ),
646
+ VMCI_DATA_OUT_HIGH_ADDR );
647
+ }
648
+
599
649
/* Set up global device so that we can start sending datagrams */
600
650
spin_lock_irq (& vmci_dev_spinlock );
601
651
vmci_dev_g = vmci_dev ;
@@ -747,8 +797,8 @@ static int vmci_guest_probe_device(struct pci_dev *pdev,
747
797
vmci_dev_g = NULL ;
748
798
spin_unlock_irq (& vmci_dev_spinlock );
749
799
750
- err_free_data_buffer :
751
- vfree (vmci_dev -> data_buffer );
800
+ err_free_data_buffers :
801
+ vmci_free_dg_buffers (vmci_dev );
752
802
753
803
/* The rest are managed resources and will be freed by PCI core */
754
804
return error ;
@@ -806,7 +856,10 @@ static void vmci_guest_remove_device(struct pci_dev *pdev)
806
856
vmci_dev -> notification_base );
807
857
}
808
858
809
- vfree (vmci_dev -> data_buffer );
859
+ vmci_free_dg_buffers (vmci_dev );
860
+
861
+ if (vmci_dev -> mmio_base != NULL )
862
+ pci_iounmap (pdev , vmci_dev -> mmio_base );
810
863
811
864
/* The rest are managed resources and will be freed by PCI core */
812
865
}
0 commit comments