6969#include <linux/virtio_config.h>
7070#include <uapi/linux/virtio_mmio.h>
7171#include <linux/virtio_ring.h>
72+ #include <linux/delay.h>
7273
7374
7475
@@ -87,27 +88,58 @@ struct virtio_mmio_device {
8788
8889 void __iomem * base ;
8990 unsigned long version ;
91+ unsigned long sw_impl ;
9092};
9193
9294/* Configuration interface */
9395
96+ static int wait_sel_generation_update (struct virtio_device * vdev , u32 prev_sel_generation ){
97+ struct virtio_mmio_device * vm_dev = to_virtio_mmio_device (vdev );
98+ unsigned long timeout = jiffies + msecs_to_jiffies (1000 ); // 1 second timeout
99+ writel (prev_sel_generation + 1 , vm_dev -> base + VIRTIO_MMIO_SEL_GENERATION );
100+
101+ while (readl (vm_dev -> base + VIRTIO_MMIO_SEL_GENERATION ) == prev_sel_generation + 1 ) {
102+ if (time_after (jiffies , timeout )) {
103+ dev_err (& vdev -> dev , "Timeout waiting for sel_generation value to update\n" );
104+ return - ETIMEDOUT ;
105+ }
106+ cpu_relax (); // or udelay(1), or cond_resched() if appropriate
107+ }
108+ return 0 ;
109+ }
110+
94111static int vm_get_features (struct virtio_device * vdev , u64 * features_out )
95112{
96113 struct virtio_mmio_device * vm_dev = to_virtio_mmio_device (vdev );
114+ u32 sel_generation ;
97115
116+ if (vm_dev -> sw_impl ) {
117+ sel_generation = readl (vm_dev -> base + VIRTIO_MMIO_SEL_GENERATION );
118+ }
98119 writel (1 , vm_dev -> base + VIRTIO_MMIO_DEVICE_FEATURES_SEL );
120+ if (vm_dev -> sw_impl && wait_sel_generation_update (vdev , sel_generation )) {
121+ return - ETIMEDOUT ;
122+ }
99123 * features_out = readl (vm_dev -> base + VIRTIO_MMIO_DEVICE_FEATURES );
100124 * features_out <<= 32 ;
101125
126+ if (vm_dev -> sw_impl ) {
127+ sel_generation = readl (vm_dev -> base + VIRTIO_MMIO_SEL_GENERATION );
128+ }
102129 writel (0 , vm_dev -> base + VIRTIO_MMIO_DEVICE_FEATURES_SEL );
130+ if (vm_dev -> sw_impl && wait_sel_generation_update (vdev , sel_generation )) {
131+ return - ETIMEDOUT ;
132+ }
103133 * features_out |= readl (vm_dev -> base + VIRTIO_MMIO_DEVICE_FEATURES );
134+ pr_err ("Device Features %llx" , * features_out );
104135
105136 return 0 ;
106137}
107138
108139static int vm_finalize_features (struct virtio_device * vdev )
109140{
110141 struct virtio_mmio_device * vm_dev = to_virtio_mmio_device (vdev );
142+ u32 sel_generation ;
111143
112144 /* Give virtio_ring a chance to accept features. */
113145 vring_transport_features (vdev );
@@ -119,13 +151,38 @@ static int vm_finalize_features(struct virtio_device *vdev)
119151 return - EINVAL ;
120152 }
121153
154+ if (vm_dev -> sw_impl ) {
155+ sel_generation = readl (vm_dev -> base + VIRTIO_MMIO_SEL_GENERATION );
156+ }
122157 writel (1 , vm_dev -> base + VIRTIO_MMIO_DRIVER_FEATURES_SEL );
158+ if (vm_dev -> sw_impl && wait_sel_generation_update (vdev , sel_generation )) {
159+ return - ETIMEDOUT ;
160+ }
161+ if (vm_dev -> sw_impl ) {
162+ sel_generation = readl (vm_dev -> base + VIRTIO_MMIO_SEL_GENERATION );
163+ }
123164 writel ((u32 )(vdev -> features >> 32 ),
124165 vm_dev -> base + VIRTIO_MMIO_DRIVER_FEATURES );
166+ if (vm_dev -> sw_impl && wait_sel_generation_update (vdev , sel_generation )) {
167+ return - ETIMEDOUT ;
168+ }
125169
170+ if (vm_dev -> sw_impl ) {
171+ sel_generation = readl (vm_dev -> base + VIRTIO_MMIO_SEL_GENERATION );
172+ }
126173 writel (0 , vm_dev -> base + VIRTIO_MMIO_DRIVER_FEATURES_SEL );
174+ if (vm_dev -> sw_impl && wait_sel_generation_update (vdev , sel_generation )) {
175+ return - ETIMEDOUT ;
176+ }
177+ if (vm_dev -> sw_impl ) {
178+ sel_generation = readl (vm_dev -> base + VIRTIO_MMIO_SEL_GENERATION );
179+ }
127180 writel ((u32 )vdev -> features ,
128181 vm_dev -> base + VIRTIO_MMIO_DRIVER_FEATURES );
182+ if (vm_dev -> sw_impl && wait_sel_generation_update (vdev , sel_generation )) {
183+ return - ETIMEDOUT ;
184+ }
185+ pr_err ("Driver Features %llx" , vdev -> features );
129186
130187 return 0 ;
131188}
@@ -351,6 +408,7 @@ static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned int in
351408 struct virtqueue * vq ;
352409 unsigned int num ;
353410 int err ;
411+ u32 sel_generation ;
354412
355413 if (__virtio_test_bit (vdev , VIRTIO_F_NOTIFICATION_DATA ))
356414 notify = vm_notify_with_data ;
@@ -386,6 +444,9 @@ static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned int in
386444
387445 vq -> num_max = num ;
388446
447+ if (vm_dev -> sw_impl ) {
448+ sel_generation = readl (vm_dev -> base + VIRTIO_MMIO_SEL_GENERATION );
449+ }
389450 /* Activate the queue */
390451 writel (virtqueue_get_vring_size (vq ), vm_dev -> base + VIRTIO_MMIO_QUEUE_NUM );
391452 if (vm_dev -> version == 1 ) {
@@ -426,6 +487,10 @@ static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned int in
426487
427488 writel (1 , vm_dev -> base + VIRTIO_MMIO_QUEUE_READY );
428489 }
490+ if (vm_dev -> sw_impl && wait_sel_generation_update (vdev , sel_generation )) {
491+ err = - ETIMEDOUT ;
492+ goto error_new_virtqueue ;
493+ }
429494
430495 return vq ;
431496
@@ -606,6 +671,14 @@ static int virtio_mmio_probe(struct platform_device *pdev)
606671 goto free_vm_dev ;
607672 }
608673
674+ vm_dev -> sw_impl = readl (vm_dev -> base + VIRTIO_MMIO_SW_IMPL );
675+ if (vm_dev -> sw_impl != 0 && vm_dev -> sw_impl != 1 ) {
676+ dev_err (& pdev -> dev , "SW_IMPL value must be 0 or 1, not %ld\n" ,
677+ vm_dev -> sw_impl );
678+ rc = - ENODEV ;
679+ goto free_vm_dev ;
680+ }
681+
609682 vm_dev -> vdev .id .device = readl (vm_dev -> base + VIRTIO_MMIO_DEVICE_ID );
610683 if (vm_dev -> vdev .id .device == 0 ) {
611684 /*
0 commit comments