17
17
18
18
#include "vfio_ccw_private.h"
19
19
20
+ static const struct vfio_device_ops vfio_ccw_dev_ops ;
21
+
20
22
static int vfio_ccw_mdev_reset (struct vfio_ccw_private * private )
21
23
{
22
24
struct subchannel * sch ;
@@ -111,17 +113,21 @@ static struct attribute_group *mdev_type_groups[] = {
111
113
NULL ,
112
114
};
113
115
114
- static int vfio_ccw_mdev_create (struct mdev_device * mdev )
116
+ static int vfio_ccw_mdev_probe (struct mdev_device * mdev )
115
117
{
116
- struct vfio_ccw_private * private =
117
- dev_get_drvdata ( mdev_parent_dev ( mdev )) ;
118
+ struct vfio_ccw_private * private = dev_get_drvdata ( mdev -> dev . parent );
119
+ int ret ;
118
120
119
121
if (private -> state == VFIO_CCW_STATE_NOT_OPER )
120
122
return - ENODEV ;
121
123
122
124
if (atomic_dec_if_positive (& private -> avail ) < 0 )
123
125
return - EPERM ;
124
126
127
+ memset (& private -> vdev , 0 , sizeof (private -> vdev ));
128
+ vfio_init_group_dev (& private -> vdev , & mdev -> dev ,
129
+ & vfio_ccw_dev_ops );
130
+
125
131
private -> mdev = mdev ;
126
132
private -> state = VFIO_CCW_STATE_IDLE ;
127
133
@@ -130,43 +136,54 @@ static int vfio_ccw_mdev_create(struct mdev_device *mdev)
130
136
private -> sch -> schid .ssid ,
131
137
private -> sch -> schid .sch_no );
132
138
139
+ ret = vfio_register_emulated_iommu_dev (& private -> vdev );
140
+ if (ret )
141
+ goto err_atomic ;
142
+ dev_set_drvdata (& mdev -> dev , private );
133
143
return 0 ;
144
+
145
+ err_atomic :
146
+ vfio_uninit_group_dev (& private -> vdev );
147
+ atomic_inc (& private -> avail );
148
+ private -> mdev = NULL ;
149
+ private -> state = VFIO_CCW_STATE_IDLE ;
150
+ return ret ;
134
151
}
135
152
136
- static int vfio_ccw_mdev_remove (struct mdev_device * mdev )
153
+ static void vfio_ccw_mdev_remove (struct mdev_device * mdev )
137
154
{
138
- struct vfio_ccw_private * private =
139
- dev_get_drvdata (mdev_parent_dev (mdev ));
155
+ struct vfio_ccw_private * private = dev_get_drvdata (mdev -> dev .parent );
140
156
141
157
VFIO_CCW_MSG_EVENT (2 , "mdev %pUl, sch %x.%x.%04x: remove\n" ,
142
158
mdev_uuid (mdev ), private -> sch -> schid .cssid ,
143
159
private -> sch -> schid .ssid ,
144
160
private -> sch -> schid .sch_no );
145
161
162
+ vfio_unregister_group_dev (& private -> vdev );
163
+
146
164
if ((private -> state != VFIO_CCW_STATE_NOT_OPER ) &&
147
165
(private -> state != VFIO_CCW_STATE_STANDBY )) {
148
166
if (!vfio_ccw_sch_quiesce (private -> sch ))
149
167
private -> state = VFIO_CCW_STATE_STANDBY ;
150
168
/* The state will be NOT_OPER on error. */
151
169
}
152
170
171
+ vfio_uninit_group_dev (& private -> vdev );
153
172
cp_free (& private -> cp );
154
173
private -> mdev = NULL ;
155
174
atomic_inc (& private -> avail );
156
-
157
- return 0 ;
158
175
}
159
176
160
- static int vfio_ccw_mdev_open_device (struct mdev_device * mdev )
177
+ static int vfio_ccw_mdev_open_device (struct vfio_device * vdev )
161
178
{
162
179
struct vfio_ccw_private * private =
163
- dev_get_drvdata ( mdev_parent_dev ( mdev ) );
180
+ container_of ( vdev , struct vfio_ccw_private , vdev );
164
181
unsigned long events = VFIO_IOMMU_NOTIFY_DMA_UNMAP ;
165
182
int ret ;
166
183
167
184
private -> nb .notifier_call = vfio_ccw_mdev_notifier ;
168
185
169
- ret = vfio_register_notifier (mdev_dev ( mdev ) , VFIO_IOMMU_NOTIFY ,
186
+ ret = vfio_register_notifier (vdev -> dev , VFIO_IOMMU_NOTIFY ,
170
187
& events , & private -> nb );
171
188
if (ret )
172
189
return ret ;
@@ -187,15 +204,15 @@ static int vfio_ccw_mdev_open_device(struct mdev_device *mdev)
187
204
188
205
out_unregister :
189
206
vfio_ccw_unregister_dev_regions (private );
190
- vfio_unregister_notifier (mdev_dev ( mdev ) , VFIO_IOMMU_NOTIFY ,
207
+ vfio_unregister_notifier (vdev -> dev , VFIO_IOMMU_NOTIFY ,
191
208
& private -> nb );
192
209
return ret ;
193
210
}
194
211
195
- static void vfio_ccw_mdev_close_device (struct mdev_device * mdev )
212
+ static void vfio_ccw_mdev_close_device (struct vfio_device * vdev )
196
213
{
197
214
struct vfio_ccw_private * private =
198
- dev_get_drvdata ( mdev_parent_dev ( mdev ) );
215
+ container_of ( vdev , struct vfio_ccw_private , vdev );
199
216
200
217
if ((private -> state != VFIO_CCW_STATE_NOT_OPER ) &&
201
218
(private -> state != VFIO_CCW_STATE_STANDBY )) {
@@ -206,8 +223,7 @@ static void vfio_ccw_mdev_close_device(struct mdev_device *mdev)
206
223
207
224
cp_free (& private -> cp );
208
225
vfio_ccw_unregister_dev_regions (private );
209
- vfio_unregister_notifier (mdev_dev (mdev ), VFIO_IOMMU_NOTIFY ,
210
- & private -> nb );
226
+ vfio_unregister_notifier (vdev -> dev , VFIO_IOMMU_NOTIFY , & private -> nb );
211
227
}
212
228
213
229
static ssize_t vfio_ccw_mdev_read_io_region (struct vfio_ccw_private * private ,
@@ -231,15 +247,14 @@ static ssize_t vfio_ccw_mdev_read_io_region(struct vfio_ccw_private *private,
231
247
return ret ;
232
248
}
233
249
234
- static ssize_t vfio_ccw_mdev_read (struct mdev_device * mdev ,
250
+ static ssize_t vfio_ccw_mdev_read (struct vfio_device * vdev ,
235
251
char __user * buf ,
236
252
size_t count ,
237
253
loff_t * ppos )
238
254
{
255
+ struct vfio_ccw_private * private =
256
+ container_of (vdev , struct vfio_ccw_private , vdev );
239
257
unsigned int index = VFIO_CCW_OFFSET_TO_INDEX (* ppos );
240
- struct vfio_ccw_private * private ;
241
-
242
- private = dev_get_drvdata (mdev_parent_dev (mdev ));
243
258
244
259
if (index >= VFIO_CCW_NUM_REGIONS + private -> num_regions )
245
260
return - EINVAL ;
@@ -284,15 +299,14 @@ static ssize_t vfio_ccw_mdev_write_io_region(struct vfio_ccw_private *private,
284
299
return ret ;
285
300
}
286
301
287
- static ssize_t vfio_ccw_mdev_write (struct mdev_device * mdev ,
302
+ static ssize_t vfio_ccw_mdev_write (struct vfio_device * vdev ,
288
303
const char __user * buf ,
289
304
size_t count ,
290
305
loff_t * ppos )
291
306
{
307
+ struct vfio_ccw_private * private =
308
+ container_of (vdev , struct vfio_ccw_private , vdev );
292
309
unsigned int index = VFIO_CCW_OFFSET_TO_INDEX (* ppos );
293
- struct vfio_ccw_private * private ;
294
-
295
- private = dev_get_drvdata (mdev_parent_dev (mdev ));
296
310
297
311
if (index >= VFIO_CCW_NUM_REGIONS + private -> num_regions )
298
312
return - EINVAL ;
@@ -510,12 +524,12 @@ void vfio_ccw_unregister_dev_regions(struct vfio_ccw_private *private)
510
524
private -> region = NULL ;
511
525
}
512
526
513
- static ssize_t vfio_ccw_mdev_ioctl (struct mdev_device * mdev ,
527
+ static ssize_t vfio_ccw_mdev_ioctl (struct vfio_device * vdev ,
514
528
unsigned int cmd ,
515
529
unsigned long arg )
516
530
{
517
531
struct vfio_ccw_private * private =
518
- dev_get_drvdata ( mdev_parent_dev ( mdev ) );
532
+ container_of ( vdev , struct vfio_ccw_private , vdev );
519
533
int ret = 0 ;
520
534
unsigned long minsz ;
521
535
@@ -606,37 +620,48 @@ static ssize_t vfio_ccw_mdev_ioctl(struct mdev_device *mdev,
606
620
}
607
621
608
622
/* Request removal of the device*/
609
- static void vfio_ccw_mdev_request (struct mdev_device * mdev , unsigned int count )
623
+ static void vfio_ccw_mdev_request (struct vfio_device * vdev , unsigned int count )
610
624
{
611
- struct vfio_ccw_private * private = dev_get_drvdata (mdev_parent_dev (mdev ));
612
-
613
- if (!private )
614
- return ;
625
+ struct vfio_ccw_private * private =
626
+ container_of (vdev , struct vfio_ccw_private , vdev );
627
+ struct device * dev = vdev -> dev ;
615
628
616
629
if (private -> req_trigger ) {
617
630
if (!(count % 10 ))
618
- dev_notice_ratelimited (mdev_dev ( private -> mdev ) ,
631
+ dev_notice_ratelimited (dev ,
619
632
"Relaying device request to user (#%u)\n" ,
620
633
count );
621
634
622
635
eventfd_signal (private -> req_trigger , 1 );
623
636
} else if (count == 0 ) {
624
- dev_notice (mdev_dev ( private -> mdev ) ,
637
+ dev_notice (dev ,
625
638
"No device request channel registered, blocked until released by user\n" );
626
639
}
627
640
}
628
641
642
+ static const struct vfio_device_ops vfio_ccw_dev_ops = {
643
+ .open_device = vfio_ccw_mdev_open_device ,
644
+ .close_device = vfio_ccw_mdev_close_device ,
645
+ .read = vfio_ccw_mdev_read ,
646
+ .write = vfio_ccw_mdev_write ,
647
+ .ioctl = vfio_ccw_mdev_ioctl ,
648
+ .request = vfio_ccw_mdev_request ,
649
+ };
650
+
651
+ struct mdev_driver vfio_ccw_mdev_driver = {
652
+ .driver = {
653
+ .name = "vfio_ccw_mdev" ,
654
+ .owner = THIS_MODULE ,
655
+ .mod_name = KBUILD_MODNAME ,
656
+ },
657
+ .probe = vfio_ccw_mdev_probe ,
658
+ .remove = vfio_ccw_mdev_remove ,
659
+ };
660
+
629
661
static const struct mdev_parent_ops vfio_ccw_mdev_ops = {
630
662
.owner = THIS_MODULE ,
663
+ .device_driver = & vfio_ccw_mdev_driver ,
631
664
.supported_type_groups = mdev_type_groups ,
632
- .create = vfio_ccw_mdev_create ,
633
- .remove = vfio_ccw_mdev_remove ,
634
- .open_device = vfio_ccw_mdev_open_device ,
635
- .close_device = vfio_ccw_mdev_close_device ,
636
- .read = vfio_ccw_mdev_read ,
637
- .write = vfio_ccw_mdev_write ,
638
- .ioctl = vfio_ccw_mdev_ioctl ,
639
- .request = vfio_ccw_mdev_request ,
640
665
};
641
666
642
667
int vfio_ccw_mdev_reg (struct subchannel * sch )
0 commit comments