Blame view

drivers/virtio/virtio_pci.c 22.1 KB
3343660d8   Anthony Liguori   virtio: PCI device
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  /*
   * Virtio PCI driver
   *
   * This module allows virtio devices to be used over a virtual PCI device.
   * This can be used with QEMU based VMMs like KVM or Xen.
   *
   * Copyright IBM Corp. 2007
   *
   * Authors:
   *  Anthony Liguori  <aliguori@us.ibm.com>
   *
   * This work is licensed under the terms of the GNU GPL, version 2 or later.
   * See the COPYING file in the top-level directory.
   *
   */
  
  #include <linux/module.h>
  #include <linux/list.h>
  #include <linux/pci.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
20
  #include <linux/slab.h>
3343660d8   Anthony Liguori   virtio: PCI device
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
  #include <linux/interrupt.h>
  #include <linux/virtio.h>
  #include <linux/virtio_config.h>
  #include <linux/virtio_ring.h>
  #include <linux/virtio_pci.h>
  #include <linux/highmem.h>
  #include <linux/spinlock.h>
  
  MODULE_AUTHOR("Anthony Liguori <aliguori@us.ibm.com>");
  MODULE_DESCRIPTION("virtio-pci");
  MODULE_LICENSE("GPL");
  MODULE_VERSION("1");
  
  /* Our device structure */
  struct virtio_pci_device
  {
  	struct virtio_device vdev;
  	struct pci_dev *pci_dev;
  
  	/* the IO mapping for the PCI config space */
97968358a   Al Viro   virtio_pci iomem ...
41
  	void __iomem *ioaddr;
3343660d8   Anthony Liguori   virtio: PCI device
42
43
44
45
  
  	/* a list of queues so we can dispatch IRQs */
  	spinlock_t lock;
  	struct list_head virtqueues;
82af8ce84   Michael S. Tsirkin   virtio_pci: optio...
46
47
48
49
50
51
52
53
54
55
  
  	/* MSI-X support */
  	int msix_enabled;
  	int intx_enabled;
  	struct msix_entry *msix_entries;
  	/* Name strings for interrupts. This size should be enough,
  	 * and I'm too lazy to allocate each name separately. */
  	char (*msix_names)[256];
  	/* Number of available vectors */
  	unsigned msix_vectors;
e969fed54   Michael S. Tsirkin   virtio: refactor ...
56
  	/* Vectors allocated, excluding per-vq vectors if any */
82af8ce84   Michael S. Tsirkin   virtio_pci: optio...
57
  	unsigned msix_used_vectors;
f0fe6f115   Amit Shah   virtio: pci: add ...
58
59
60
  
  	/* Status saved during hibernate/restore */
  	u8 saved_status;
e969fed54   Michael S. Tsirkin   virtio: refactor ...
61
62
  	/* Whether we have vector per vq */
  	bool per_vq_vectors;
82af8ce84   Michael S. Tsirkin   virtio_pci: optio...
63
64
65
66
67
68
69
70
  };
  
  /* Constants for MSI-X */
  /* Use first vector for configuration changes, second and the rest for
   * virtqueues Thus, we need at least 2 vectors for MSI. */
  enum {
  	VP_MSIX_CONFIG_VECTOR = 0,
  	VP_MSIX_VQ_VECTOR = 1,
3343660d8   Anthony Liguori   virtio: PCI device
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
  };
  
  struct virtio_pci_vq_info
  {
  	/* the actual virtqueue */
  	struct virtqueue *vq;
  
  	/* the number of entries in the queue */
  	int num;
  
  	/* the index of the queue */
  	int queue_index;
  
  	/* the virtual address of the ring queue */
  	void *queue;
  
  	/* the list node for the virtqueues list */
  	struct list_head node;
82af8ce84   Michael S. Tsirkin   virtio_pci: optio...
89
90
  
  	/* MSI-X vector (or none) */
f68d24082   Rusty Russell   virtio_pci: minor...
91
  	unsigned msix_vector;
3343660d8   Anthony Liguori   virtio: PCI device
92
93
94
95
96
97
98
99
100
  };
  
  /* Qumranet donated their vendor ID for devices 0x1000 thru 0x10FF. */
  static struct pci_device_id virtio_pci_id_table[] = {
  	{ 0x1af4, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
  	{ 0 },
  };
  
  MODULE_DEVICE_TABLE(pci, virtio_pci_id_table);
3343660d8   Anthony Liguori   virtio: PCI device
101
102
103
104
105
  /* Convert a generic virtio device to our structure */
  static struct virtio_pci_device *to_vp_device(struct virtio_device *vdev)
  {
  	return container_of(vdev, struct virtio_pci_device, vdev);
  }
c45a6816c   Rusty Russell   virtio: explicit ...
106
107
108
109
110
111
112
113
114
  /* virtio config->get_features() implementation */
  static u32 vp_get_features(struct virtio_device *vdev)
  {
  	struct virtio_pci_device *vp_dev = to_vp_device(vdev);
  
  	/* When someone needs more than 32 feature bits, we'll need to
  	 * steal a bit to indicate that the rest are somewhere else. */
  	return ioread32(vp_dev->ioaddr + VIRTIO_PCI_HOST_FEATURES);
  }
c624896e4   Rusty Russell   virtio: Rename se...
115
116
  /* virtio config->finalize_features() implementation */
  static void vp_finalize_features(struct virtio_device *vdev)
3343660d8   Anthony Liguori   virtio: PCI device
117
118
  {
  	struct virtio_pci_device *vp_dev = to_vp_device(vdev);
3343660d8   Anthony Liguori   virtio: PCI device
119

e34f87256   Rusty Russell   virtio: Add trans...
120
121
  	/* Give virtio_ring a chance to accept features. */
  	vring_transport_features(vdev);
c624896e4   Rusty Russell   virtio: Rename se...
122
123
124
  	/* We only support 32 feature bits. */
  	BUILD_BUG_ON(ARRAY_SIZE(vdev->features) != 1);
  	iowrite32(vdev->features[0], vp_dev->ioaddr+VIRTIO_PCI_GUEST_FEATURES);
3343660d8   Anthony Liguori   virtio: PCI device
125
126
127
128
129
130
131
  }
  
  /* virtio config->get() implementation */
  static void vp_get(struct virtio_device *vdev, unsigned offset,
  		   void *buf, unsigned len)
  {
  	struct virtio_pci_device *vp_dev = to_vp_device(vdev);
82af8ce84   Michael S. Tsirkin   virtio_pci: optio...
132
133
  	void __iomem *ioaddr = vp_dev->ioaddr +
  				VIRTIO_PCI_CONFIG(vp_dev) + offset;
3343660d8   Anthony Liguori   virtio: PCI device
134
135
136
137
138
139
140
141
142
143
144
145
146
  	u8 *ptr = buf;
  	int i;
  
  	for (i = 0; i < len; i++)
  		ptr[i] = ioread8(ioaddr + i);
  }
  
  /* the config->set() implementation.  it's symmetric to the config->get()
   * implementation */
  static void vp_set(struct virtio_device *vdev, unsigned offset,
  		   const void *buf, unsigned len)
  {
  	struct virtio_pci_device *vp_dev = to_vp_device(vdev);
82af8ce84   Michael S. Tsirkin   virtio_pci: optio...
147
148
  	void __iomem *ioaddr = vp_dev->ioaddr +
  				VIRTIO_PCI_CONFIG(vp_dev) + offset;
3343660d8   Anthony Liguori   virtio: PCI device
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
  	const u8 *ptr = buf;
  	int i;
  
  	for (i = 0; i < len; i++)
  		iowrite8(ptr[i], ioaddr + i);
  }
  
  /* config->{get,set}_status() implementations */
  static u8 vp_get_status(struct virtio_device *vdev)
  {
  	struct virtio_pci_device *vp_dev = to_vp_device(vdev);
  	return ioread8(vp_dev->ioaddr + VIRTIO_PCI_STATUS);
  }
  
  static void vp_set_status(struct virtio_device *vdev, u8 status)
  {
  	struct virtio_pci_device *vp_dev = to_vp_device(vdev);
  	/* We should never be setting status to 0. */
  	BUG_ON(status == 0);
597d56e4b   Harvey Harrison   virtio: fix spars...
168
  	iowrite8(status, vp_dev->ioaddr + VIRTIO_PCI_STATUS);
3343660d8   Anthony Liguori   virtio: PCI device
169
  }
e6af578c5   Michael S. Tsirkin   virtio-pci: make ...
170
171
172
173
174
175
176
177
178
179
180
181
  /* wait for pending irq handlers */
  static void vp_synchronize_vectors(struct virtio_device *vdev)
  {
  	struct virtio_pci_device *vp_dev = to_vp_device(vdev);
  	int i;
  
  	if (vp_dev->intx_enabled)
  		synchronize_irq(vp_dev->pci_dev->irq);
  
  	for (i = 0; i < vp_dev->msix_vectors; ++i)
  		synchronize_irq(vp_dev->msix_entries[i].vector);
  }
3343660d8   Anthony Liguori   virtio: PCI device
182
183
184
185
  static void vp_reset(struct virtio_device *vdev)
  {
  	struct virtio_pci_device *vp_dev = to_vp_device(vdev);
  	/* 0 status means a reset. */
597d56e4b   Harvey Harrison   virtio: fix spars...
186
  	iowrite8(0, vp_dev->ioaddr + VIRTIO_PCI_STATUS);
e6af578c5   Michael S. Tsirkin   virtio-pci: make ...
187
188
189
190
191
  	/* Flush out the status write, and flush in device writes,
  	 * including MSi-X interrupts, if any. */
  	ioread8(vp_dev->ioaddr + VIRTIO_PCI_STATUS);
  	/* Flush pending VQ/configuration callbacks. */
  	vp_synchronize_vectors(vdev);
3343660d8   Anthony Liguori   virtio: PCI device
192
193
194
195
196
197
198
199
200
201
202
203
  }
  
  /* the notify function used when creating a virt queue */
  static void vp_notify(struct virtqueue *vq)
  {
  	struct virtio_pci_device *vp_dev = to_vp_device(vq->vdev);
  	struct virtio_pci_vq_info *info = vq->priv;
  
  	/* we write the queue's selector into the notification register to
  	 * signal the other end */
  	iowrite16(info->queue_index, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_NOTIFY);
  }
77cf52465   Michael S. Tsirkin   virtio_pci: split...
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
  /* Handle a configuration change: Tell driver if it wants to know. */
  static irqreturn_t vp_config_changed(int irq, void *opaque)
  {
  	struct virtio_pci_device *vp_dev = opaque;
  	struct virtio_driver *drv;
  	drv = container_of(vp_dev->vdev.dev.driver,
  			   struct virtio_driver, driver);
  
  	if (drv && drv->config_changed)
  		drv->config_changed(&vp_dev->vdev);
  	return IRQ_HANDLED;
  }
  
  /* Notify all virtqueues on an interrupt. */
  static irqreturn_t vp_vring_interrupt(int irq, void *opaque)
  {
  	struct virtio_pci_device *vp_dev = opaque;
  	struct virtio_pci_vq_info *info;
  	irqreturn_t ret = IRQ_NONE;
  	unsigned long flags;
  
  	spin_lock_irqsave(&vp_dev->lock, flags);
  	list_for_each_entry(info, &vp_dev->virtqueues, node) {
  		if (vring_interrupt(irq, info->vq) == IRQ_HANDLED)
  			ret = IRQ_HANDLED;
  	}
  	spin_unlock_irqrestore(&vp_dev->lock, flags);
  
  	return ret;
  }
3343660d8   Anthony Liguori   virtio: PCI device
234
235
236
237
238
239
240
241
242
  /* A small wrapper to also acknowledge the interrupt when it's handled.
   * I really need an EIO hook for the vring so I can ack the interrupt once we
   * know that we'll be handling the IRQ but before we invoke the callback since
   * the callback may notify the host which results in the host attempting to
   * raise an interrupt that we would then mask once we acknowledged the
   * interrupt. */
  static irqreturn_t vp_interrupt(int irq, void *opaque)
  {
  	struct virtio_pci_device *vp_dev = opaque;
3343660d8   Anthony Liguori   virtio: PCI device
243
244
245
246
247
248
249
250
251
252
253
  	u8 isr;
  
  	/* reading the ISR has the effect of also clearing it so it's very
  	 * important to save off the value. */
  	isr = ioread8(vp_dev->ioaddr + VIRTIO_PCI_ISR);
  
  	/* It's definitely not us if the ISR was not high */
  	if (!isr)
  		return IRQ_NONE;
  
  	/* Configuration change?  Tell driver if it wants to know. */
77cf52465   Michael S. Tsirkin   virtio_pci: split...
254
255
  	if (isr & VIRTIO_PCI_ISR_CONFIG)
  		vp_config_changed(irq, opaque);
3343660d8   Anthony Liguori   virtio: PCI device
256

77cf52465   Michael S. Tsirkin   virtio_pci: split...
257
  	return vp_vring_interrupt(irq, opaque);
3343660d8   Anthony Liguori   virtio: PCI device
258
  }
82af8ce84   Michael S. Tsirkin   virtio_pci: optio...
259
260
261
262
263
264
265
266
267
268
269
270
  static void vp_free_vectors(struct virtio_device *vdev)
  {
  	struct virtio_pci_device *vp_dev = to_vp_device(vdev);
  	int i;
  
  	if (vp_dev->intx_enabled) {
  		free_irq(vp_dev->pci_dev->irq, vp_dev);
  		vp_dev->intx_enabled = 0;
  	}
  
  	for (i = 0; i < vp_dev->msix_used_vectors; ++i)
  		free_irq(vp_dev->msix_entries[i].vector, vp_dev);
82af8ce84   Michael S. Tsirkin   virtio_pci: optio...
271
272
273
274
275
276
277
  
  	if (vp_dev->msix_enabled) {
  		/* Disable the vector used for configuration */
  		iowrite16(VIRTIO_MSI_NO_VECTOR,
  			  vp_dev->ioaddr + VIRTIO_MSI_CONFIG_VECTOR);
  		/* Flush the write out to device */
  		ioread16(vp_dev->ioaddr + VIRTIO_MSI_CONFIG_VECTOR);
82af8ce84   Michael S. Tsirkin   virtio_pci: optio...
278
  		pci_disable_msix(vp_dev->pci_dev);
ff52c3fc7   Michael S. Tsirkin   virtio: fix memor...
279
280
  		vp_dev->msix_enabled = 0;
  		vp_dev->msix_vectors = 0;
82af8ce84   Michael S. Tsirkin   virtio_pci: optio...
281
  	}
ff52c3fc7   Michael S. Tsirkin   virtio: fix memor...
282
283
284
285
286
287
  
  	vp_dev->msix_used_vectors = 0;
  	kfree(vp_dev->msix_names);
  	vp_dev->msix_names = NULL;
  	kfree(vp_dev->msix_entries);
  	vp_dev->msix_entries = NULL;
82af8ce84   Michael S. Tsirkin   virtio_pci: optio...
288
  }
f68d24082   Rusty Russell   virtio_pci: minor...
289
290
  static int vp_request_msix_vectors(struct virtio_device *vdev, int nvectors,
  				   bool per_vq_vectors)
82af8ce84   Michael S. Tsirkin   virtio_pci: optio...
291
292
293
294
295
  {
  	struct virtio_pci_device *vp_dev = to_vp_device(vdev);
  	const char *name = dev_name(&vp_dev->vdev.dev);
  	unsigned i, v;
  	int err = -ENOMEM;
e969fed54   Michael S. Tsirkin   virtio: refactor ...
296

82af8ce84   Michael S. Tsirkin   virtio_pci: optio...
297
298
299
  	vp_dev->msix_entries = kmalloc(nvectors * sizeof *vp_dev->msix_entries,
  				       GFP_KERNEL);
  	if (!vp_dev->msix_entries)
ff52c3fc7   Michael S. Tsirkin   virtio: fix memor...
300
  		goto error;
82af8ce84   Michael S. Tsirkin   virtio_pci: optio...
301
302
303
  	vp_dev->msix_names = kmalloc(nvectors * sizeof *vp_dev->msix_names,
  				     GFP_KERNEL);
  	if (!vp_dev->msix_names)
ff52c3fc7   Michael S. Tsirkin   virtio: fix memor...
304
  		goto error;
82af8ce84   Michael S. Tsirkin   virtio_pci: optio...
305
306
307
  
  	for (i = 0; i < nvectors; ++i)
  		vp_dev->msix_entries[i].entry = i;
f68d24082   Rusty Russell   virtio_pci: minor...
308
  	/* pci_enable_msix returns positive if we can't get this many. */
e969fed54   Michael S. Tsirkin   virtio: refactor ...
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
  	err = pci_enable_msix(vp_dev->pci_dev, vp_dev->msix_entries, nvectors);
  	if (err > 0)
  		err = -ENOSPC;
  	if (err)
  		goto error;
  	vp_dev->msix_vectors = nvectors;
  	vp_dev->msix_enabled = 1;
  
  	/* Set the vector used for configuration */
  	v = vp_dev->msix_used_vectors;
  	snprintf(vp_dev->msix_names[v], sizeof *vp_dev->msix_names,
  		 "%s-config", name);
  	err = request_irq(vp_dev->msix_entries[v].vector,
  			  vp_config_changed, 0, vp_dev->msix_names[v],
  			  vp_dev);
  	if (err)
  		goto error;
  	++vp_dev->msix_used_vectors;
82af8ce84   Michael S. Tsirkin   virtio_pci: optio...
327

e969fed54   Michael S. Tsirkin   virtio: refactor ...
328
329
330
331
332
333
  	iowrite16(v, vp_dev->ioaddr + VIRTIO_MSI_CONFIG_VECTOR);
  	/* Verify we had enough resources to assign the vector */
  	v = ioread16(vp_dev->ioaddr + VIRTIO_MSI_CONFIG_VECTOR);
  	if (v == VIRTIO_MSI_NO_VECTOR) {
  		err = -EBUSY;
  		goto error;
82af8ce84   Michael S. Tsirkin   virtio_pci: optio...
334
  	}
e969fed54   Michael S. Tsirkin   virtio: refactor ...
335
  	if (!per_vq_vectors) {
82af8ce84   Michael S. Tsirkin   virtio_pci: optio...
336
337
338
339
340
341
342
343
  		/* Shared vector for all VQs */
  		v = vp_dev->msix_used_vectors;
  		snprintf(vp_dev->msix_names[v], sizeof *vp_dev->msix_names,
  			 "%s-virtqueues", name);
  		err = request_irq(vp_dev->msix_entries[v].vector,
  				  vp_vring_interrupt, 0, vp_dev->msix_names[v],
  				  vp_dev);
  		if (err)
ff52c3fc7   Michael S. Tsirkin   virtio: fix memor...
344
  			goto error;
82af8ce84   Michael S. Tsirkin   virtio_pci: optio...
345
346
347
  		++vp_dev->msix_used_vectors;
  	}
  	return 0;
ff52c3fc7   Michael S. Tsirkin   virtio: fix memor...
348
  error:
82af8ce84   Michael S. Tsirkin   virtio_pci: optio...
349
  	vp_free_vectors(vdev);
82af8ce84   Michael S. Tsirkin   virtio_pci: optio...
350
351
  	return err;
  }
f68d24082   Rusty Russell   virtio_pci: minor...
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
  static int vp_request_intx(struct virtio_device *vdev)
  {
  	int err;
  	struct virtio_pci_device *vp_dev = to_vp_device(vdev);
  
  	err = request_irq(vp_dev->pci_dev->irq, vp_interrupt,
  			  IRQF_SHARED, dev_name(&vdev->dev), vp_dev);
  	if (!err)
  		vp_dev->intx_enabled = 1;
  	return err;
  }
  
  static struct virtqueue *setup_vq(struct virtio_device *vdev, unsigned index,
  				  void (*callback)(struct virtqueue *vq),
  				  const char *name,
  				  u16 msix_vec)
3343660d8   Anthony Liguori   virtio: PCI device
368
369
370
371
  {
  	struct virtio_pci_device *vp_dev = to_vp_device(vdev);
  	struct virtio_pci_vq_info *info;
  	struct virtqueue *vq;
13b1eb333   Hollis Blanchard   virtio-pci queue ...
372
  	unsigned long flags, size;
e969fed54   Michael S. Tsirkin   virtio: refactor ...
373
  	u16 num;
3343660d8   Anthony Liguori   virtio: PCI device
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
  	int err;
  
  	/* Select the queue we're interested in */
  	iowrite16(index, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_SEL);
  
  	/* Check if queue is either not available or already active. */
  	num = ioread16(vp_dev->ioaddr + VIRTIO_PCI_QUEUE_NUM);
  	if (!num || ioread32(vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN))
  		return ERR_PTR(-ENOENT);
  
  	/* allocate and fill out our structure the represents an active
  	 * queue */
  	info = kmalloc(sizeof(struct virtio_pci_vq_info), GFP_KERNEL);
  	if (!info)
  		return ERR_PTR(-ENOMEM);
  
  	info->queue_index = index;
  	info->num = num;
f68d24082   Rusty Russell   virtio_pci: minor...
392
  	info->msix_vector = msix_vec;
3343660d8   Anthony Liguori   virtio: PCI device
393

498af1478   Rusty Russell   virtio: Don't use...
394
  	size = PAGE_ALIGN(vring_size(num, VIRTIO_PCI_VRING_ALIGN));
13b1eb333   Hollis Blanchard   virtio-pci queue ...
395
  	info->queue = alloc_pages_exact(size, GFP_KERNEL|__GFP_ZERO);
3343660d8   Anthony Liguori   virtio: PCI device
396
397
398
399
400
401
  	if (info->queue == NULL) {
  		err = -ENOMEM;
  		goto out_info;
  	}
  
  	/* activate the queue */
480daab42   Rusty Russell   virtio: Don't use...
402
  	iowrite32(virt_to_phys(info->queue) >> VIRTIO_PCI_QUEUE_ADDR_SHIFT,
3343660d8   Anthony Liguori   virtio: PCI device
403
404
405
  		  vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN);
  
  	/* create the vring */
7b21e34fd   Rusty Russell   virtio: harsher b...
406
407
  	vq = vring_new_virtqueue(info->num, VIRTIO_PCI_VRING_ALIGN, vdev,
  				 true, info->queue, vp_notify, callback, name);
3343660d8   Anthony Liguori   virtio: PCI device
408
409
410
411
412
413
414
  	if (!vq) {
  		err = -ENOMEM;
  		goto out_activate_queue;
  	}
  
  	vq->priv = info;
  	info->vq = vq;
f68d24082   Rusty Russell   virtio_pci: minor...
415
416
417
418
  	if (msix_vec != VIRTIO_MSI_NO_VECTOR) {
  		iowrite16(msix_vec, vp_dev->ioaddr + VIRTIO_MSI_QUEUE_VECTOR);
  		msix_vec = ioread16(vp_dev->ioaddr + VIRTIO_MSI_QUEUE_VECTOR);
  		if (msix_vec == VIRTIO_MSI_NO_VECTOR) {
82af8ce84   Michael S. Tsirkin   virtio_pci: optio...
419
420
421
422
  			err = -EBUSY;
  			goto out_assign;
  		}
  	}
005b20a8e   Krishna Kumar   virtio: Dont add ...
423
424
425
426
427
428
429
  	if (callback) {
  		spin_lock_irqsave(&vp_dev->lock, flags);
  		list_add(&info->node, &vp_dev->virtqueues);
  		spin_unlock_irqrestore(&vp_dev->lock, flags);
  	} else {
  		INIT_LIST_HEAD(&info->node);
  	}
3343660d8   Anthony Liguori   virtio: PCI device
430
431
  
  	return vq;
82af8ce84   Michael S. Tsirkin   virtio_pci: optio...
432
  out_assign:
82af8ce84   Michael S. Tsirkin   virtio_pci: optio...
433
  	vring_del_virtqueue(vq);
3343660d8   Anthony Liguori   virtio: PCI device
434
435
  out_activate_queue:
  	iowrite32(0, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN);
13b1eb333   Hollis Blanchard   virtio-pci queue ...
436
  	free_pages_exact(info->queue, size);
3343660d8   Anthony Liguori   virtio: PCI device
437
438
439
440
  out_info:
  	kfree(info);
  	return ERR_PTR(err);
  }
3343660d8   Anthony Liguori   virtio: PCI device
441
442
443
444
  static void vp_del_vq(struct virtqueue *vq)
  {
  	struct virtio_pci_device *vp_dev = to_vp_device(vq->vdev);
  	struct virtio_pci_vq_info *info = vq->priv;
f6c825070   Michael S. Tsirkin   virtio: delete vq...
445
446
447
448
449
  	unsigned long flags, size;
  
  	spin_lock_irqsave(&vp_dev->lock, flags);
  	list_del(&info->node);
  	spin_unlock_irqrestore(&vp_dev->lock, flags);
3343660d8   Anthony Liguori   virtio: PCI device
450

82af8ce84   Michael S. Tsirkin   virtio_pci: optio...
451
  	iowrite16(info->queue_index, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_SEL);
82af8ce84   Michael S. Tsirkin   virtio_pci: optio...
452
453
454
455
456
457
  	if (vp_dev->msix_enabled) {
  		iowrite16(VIRTIO_MSI_NO_VECTOR,
  			  vp_dev->ioaddr + VIRTIO_MSI_QUEUE_VECTOR);
  		/* Flush the write out to device */
  		ioread8(vp_dev->ioaddr + VIRTIO_PCI_ISR);
  	}
3343660d8   Anthony Liguori   virtio: PCI device
458
459
460
  	vring_del_virtqueue(vq);
  
  	/* Select and deactivate the queue */
3343660d8   Anthony Liguori   virtio: PCI device
461
  	iowrite32(0, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN);
498af1478   Rusty Russell   virtio: Don't use...
462
  	size = PAGE_ALIGN(vring_size(info->num, VIRTIO_PCI_VRING_ALIGN));
13b1eb333   Hollis Blanchard   virtio-pci queue ...
463
  	free_pages_exact(info->queue, size);
3343660d8   Anthony Liguori   virtio: PCI device
464
465
  	kfree(info);
  }
82af8ce84   Michael S. Tsirkin   virtio_pci: optio...
466
  /* the config->del_vqs() implementation */
d2a7ddda9   Michael S. Tsirkin   virtio: find_vqs/...
467
468
  static void vp_del_vqs(struct virtio_device *vdev)
  {
e969fed54   Michael S. Tsirkin   virtio: refactor ...
469
  	struct virtio_pci_device *vp_dev = to_vp_device(vdev);
d2a7ddda9   Michael S. Tsirkin   virtio: find_vqs/...
470
  	struct virtqueue *vq, *n;
e969fed54   Michael S. Tsirkin   virtio: refactor ...
471
  	struct virtio_pci_vq_info *info;
d2a7ddda9   Michael S. Tsirkin   virtio: find_vqs/...
472

e969fed54   Michael S. Tsirkin   virtio: refactor ...
473
474
  	list_for_each_entry_safe(vq, n, &vdev->vqs, list) {
  		info = vq->priv;
311981591   Michael S. Tsirkin   virtio: fix out o...
475
476
  		if (vp_dev->per_vq_vectors &&
  			info->msix_vector != VIRTIO_MSI_NO_VECTOR)
f68d24082   Rusty Russell   virtio_pci: minor...
477
478
  			free_irq(vp_dev->msix_entries[info->msix_vector].vector,
  				 vq);
d2a7ddda9   Michael S. Tsirkin   virtio: find_vqs/...
479
  		vp_del_vq(vq);
e969fed54   Michael S. Tsirkin   virtio: refactor ...
480
481
  	}
  	vp_dev->per_vq_vectors = false;
82af8ce84   Michael S. Tsirkin   virtio_pci: optio...
482
483
  
  	vp_free_vectors(vdev);
d2a7ddda9   Michael S. Tsirkin   virtio: find_vqs/...
484
  }
e969fed54   Michael S. Tsirkin   virtio: refactor ...
485
486
487
488
  static int vp_try_to_find_vqs(struct virtio_device *vdev, unsigned nvqs,
  			      struct virtqueue *vqs[],
  			      vq_callback_t *callbacks[],
  			      const char *names[],
f68d24082   Rusty Russell   virtio_pci: minor...
489
  			      bool use_msix,
e969fed54   Michael S. Tsirkin   virtio: refactor ...
490
  			      bool per_vq_vectors)
d2a7ddda9   Michael S. Tsirkin   virtio: find_vqs/...
491
  {
e969fed54   Michael S. Tsirkin   virtio: refactor ...
492
  	struct virtio_pci_device *vp_dev = to_vp_device(vdev);
f68d24082   Rusty Russell   virtio_pci: minor...
493
494
  	u16 msix_vec;
  	int i, err, nvectors, allocated_vectors;
82af8ce84   Michael S. Tsirkin   virtio_pci: optio...
495

f68d24082   Rusty Russell   virtio_pci: minor...
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
  	if (!use_msix) {
  		/* Old style: one normal interrupt for change and all vqs. */
  		err = vp_request_intx(vdev);
  		if (err)
  			goto error_request;
  	} else {
  		if (per_vq_vectors) {
  			/* Best option: one for change interrupt, one per vq. */
  			nvectors = 1;
  			for (i = 0; i < nvqs; ++i)
  				if (callbacks[i])
  					++nvectors;
  		} else {
  			/* Second best: one for change, shared for all vqs. */
  			nvectors = 2;
  		}
  
  		err = vp_request_msix_vectors(vdev, nvectors, per_vq_vectors);
  		if (err)
  			goto error_request;
  	}
d2a7ddda9   Michael S. Tsirkin   virtio: find_vqs/...
517

e969fed54   Michael S. Tsirkin   virtio: refactor ...
518
519
  	vp_dev->per_vq_vectors = per_vq_vectors;
  	allocated_vectors = vp_dev->msix_used_vectors;
d2a7ddda9   Michael S. Tsirkin   virtio: find_vqs/...
520
  	for (i = 0; i < nvqs; ++i) {
e969fed54   Michael S. Tsirkin   virtio: refactor ...
521
  		if (!callbacks[i] || !vp_dev->msix_enabled)
f68d24082   Rusty Russell   virtio_pci: minor...
522
  			msix_vec = VIRTIO_MSI_NO_VECTOR;
e969fed54   Michael S. Tsirkin   virtio: refactor ...
523
  		else if (vp_dev->per_vq_vectors)
f68d24082   Rusty Russell   virtio_pci: minor...
524
  			msix_vec = allocated_vectors++;
e969fed54   Michael S. Tsirkin   virtio: refactor ...
525
  		else
f68d24082   Rusty Russell   virtio_pci: minor...
526
527
  			msix_vec = VP_MSIX_VQ_VECTOR;
  		vqs[i] = setup_vq(vdev, i, callbacks[i], names[i], msix_vec);
e969fed54   Michael S. Tsirkin   virtio: refactor ...
528
529
  		if (IS_ERR(vqs[i])) {
  			err = PTR_ERR(vqs[i]);
82af8ce84   Michael S. Tsirkin   virtio_pci: optio...
530
  			goto error_find;
e969fed54   Michael S. Tsirkin   virtio: refactor ...
531
  		}
0b22bd0ba   Michael S. Tsirkin   virtio-pci: fix p...
532
533
534
  
  		if (!vp_dev->per_vq_vectors || msix_vec == VIRTIO_MSI_NO_VECTOR)
  			continue;
e969fed54   Michael S. Tsirkin   virtio: refactor ...
535
  		/* allocate per-vq irq if available and necessary */
0b22bd0ba   Michael S. Tsirkin   virtio-pci: fix p...
536
537
538
539
540
541
542
543
544
545
546
  		snprintf(vp_dev->msix_names[msix_vec],
  			 sizeof *vp_dev->msix_names,
  			 "%s-%s",
  			 dev_name(&vp_dev->vdev.dev), names[i]);
  		err = request_irq(vp_dev->msix_entries[msix_vec].vector,
  				  vring_interrupt, 0,
  				  vp_dev->msix_names[msix_vec],
  				  vqs[i]);
  		if (err) {
  			vp_del_vq(vqs[i]);
  			goto error_find;
e969fed54   Michael S. Tsirkin   virtio: refactor ...
547
  		}
d2a7ddda9   Michael S. Tsirkin   virtio: find_vqs/...
548
549
  	}
  	return 0;
82af8ce84   Michael S. Tsirkin   virtio_pci: optio...
550
  error_find:
d2a7ddda9   Michael S. Tsirkin   virtio: find_vqs/...
551
  	vp_del_vqs(vdev);
82af8ce84   Michael S. Tsirkin   virtio_pci: optio...
552
553
  
  error_request:
e969fed54   Michael S. Tsirkin   virtio: refactor ...
554
555
556
557
558
559
560
561
562
  	return err;
  }
  
  /* the config->find_vqs() implementation */
  static int vp_find_vqs(struct virtio_device *vdev, unsigned nvqs,
  		       struct virtqueue *vqs[],
  		       vq_callback_t *callbacks[],
  		       const char *names[])
  {
f68d24082   Rusty Russell   virtio_pci: minor...
563
  	int err;
e969fed54   Michael S. Tsirkin   virtio: refactor ...
564

f68d24082   Rusty Russell   virtio_pci: minor...
565
566
  	/* Try MSI-X with one vector per queue. */
  	err = vp_try_to_find_vqs(vdev, nvqs, vqs, callbacks, names, true, true);
e969fed54   Michael S. Tsirkin   virtio: refactor ...
567
568
  	if (!err)
  		return 0;
f68d24082   Rusty Russell   virtio_pci: minor...
569
  	/* Fallback: MSI-X with one vector for config, one shared for queues. */
e969fed54   Michael S. Tsirkin   virtio: refactor ...
570
  	err = vp_try_to_find_vqs(vdev, nvqs, vqs, callbacks, names,
f68d24082   Rusty Russell   virtio_pci: minor...
571
  				 true, false);
e969fed54   Michael S. Tsirkin   virtio: refactor ...
572
573
574
  	if (!err)
  		return 0;
  	/* Finally fall back to regular interrupts. */
f68d24082   Rusty Russell   virtio_pci: minor...
575
576
  	return vp_try_to_find_vqs(vdev, nvqs, vqs, callbacks, names,
  				  false, false);
d2a7ddda9   Michael S. Tsirkin   virtio: find_vqs/...
577
  }
66846048f   Rick Jones   enable virtio_net...
578
579
580
581
582
583
  static const char *vp_bus_name(struct virtio_device *vdev)
  {
  	struct virtio_pci_device *vp_dev = to_vp_device(vdev);
  
  	return pci_name(vp_dev->pci_dev);
  }
3343660d8   Anthony Liguori   virtio: PCI device
584
  static struct virtio_config_ops virtio_pci_config_ops = {
3343660d8   Anthony Liguori   virtio: PCI device
585
586
587
588
589
  	.get		= vp_get,
  	.set		= vp_set,
  	.get_status	= vp_get_status,
  	.set_status	= vp_set_status,
  	.reset		= vp_reset,
d2a7ddda9   Michael S. Tsirkin   virtio: find_vqs/...
590
591
  	.find_vqs	= vp_find_vqs,
  	.del_vqs	= vp_del_vqs,
c45a6816c   Rusty Russell   virtio: explicit ...
592
  	.get_features	= vp_get_features,
c624896e4   Rusty Russell   virtio: Rename se...
593
  	.finalize_features = vp_finalize_features,
66846048f   Rick Jones   enable virtio_net...
594
  	.bus_name	= vp_bus_name,
3343660d8   Anthony Liguori   virtio: PCI device
595
  };
29f9f12ec   Mark McLoughlin   virtio: add PCI d...
596
597
  static void virtio_pci_release_dev(struct device *_d)
  {
72103bd12   Michael S. Tsirkin   virtio-pci: fix u...
598
599
600
601
602
  	/*
  	 * No need for a release method as we allocate/free
  	 * all devices together with the pci devices.
  	 * Provide an empty one to avoid getting a warning from core.
  	 */
29f9f12ec   Mark McLoughlin   virtio: add PCI d...
603
  }
3343660d8   Anthony Liguori   virtio: PCI device
604
605
606
607
608
609
610
611
612
613
  /* the PCI probing function */
  static int __devinit virtio_pci_probe(struct pci_dev *pci_dev,
  				      const struct pci_device_id *id)
  {
  	struct virtio_pci_device *vp_dev;
  	int err;
  
  	/* We only own devices >= 0x1000 and <= 0x103f: leave the rest. */
  	if (pci_dev->device < 0x1000 || pci_dev->device > 0x103f)
  		return -ENODEV;
55a7c0660   Anthony Liguori   virtio: Use PCI r...
614
615
616
617
618
619
  	if (pci_dev->revision != VIRTIO_PCI_ABI_VERSION) {
  		printk(KERN_ERR "virtio_pci: expected ABI version %d, got %d
  ",
  		       VIRTIO_PCI_ABI_VERSION, pci_dev->revision);
  		return -ENODEV;
  	}
3343660d8   Anthony Liguori   virtio: PCI device
620
621
622
623
  	/* allocate our structure and fill it out */
  	vp_dev = kzalloc(sizeof(struct virtio_pci_device), GFP_KERNEL);
  	if (vp_dev == NULL)
  		return -ENOMEM;
8b3bb3ecf   Milton Miller   virtio: remove vi...
624
  	vp_dev->vdev.dev.parent = &pci_dev->dev;
29f9f12ec   Mark McLoughlin   virtio: add PCI d...
625
  	vp_dev->vdev.dev.release = virtio_pci_release_dev;
3343660d8   Anthony Liguori   virtio: PCI device
626
627
628
629
  	vp_dev->vdev.config = &virtio_pci_config_ops;
  	vp_dev->pci_dev = pci_dev;
  	INIT_LIST_HEAD(&vp_dev->virtqueues);
  	spin_lock_init(&vp_dev->lock);
b03214d55   Michael S. Tsirkin   virtio-pci: disab...
630
631
  	/* Disable MSI/MSIX to bring device to a known good state. */
  	pci_msi_off(pci_dev);
3343660d8   Anthony Liguori   virtio: PCI device
632
633
634
635
636
637
638
639
640
641
642
643
644
645
  	/* enable the device */
  	err = pci_enable_device(pci_dev);
  	if (err)
  		goto out;
  
  	err = pci_request_regions(pci_dev, "virtio-pci");
  	if (err)
  		goto out_enable_device;
  
  	vp_dev->ioaddr = pci_iomap(pci_dev, 0, 0);
  	if (vp_dev->ioaddr == NULL)
  		goto out_req_regions;
  
  	pci_set_drvdata(pci_dev, vp_dev);
bc505f373   Michael S. Tsirkin   virtio: set pci b...
646
  	pci_set_master(pci_dev);
3343660d8   Anthony Liguori   virtio: PCI device
647
648
649
650
  
  	/* we use the subsystem vendor/device id as the virtio vendor/device
  	 * id.  this allows us to use the same PCI vendor/device id for all
  	 * virtio devices and to identify the particular virtio driver by
883931612   Thomas Weber   Fix typos in comm...
651
  	 * the subsystem ids */
3343660d8   Anthony Liguori   virtio: PCI device
652
653
  	vp_dev->vdev.id.vendor = pci_dev->subsystem_vendor;
  	vp_dev->vdev.id.device = pci_dev->subsystem_device;
3343660d8   Anthony Liguori   virtio: PCI device
654
655
656
  	/* finally register the virtio device */
  	err = register_virtio_device(&vp_dev->vdev);
  	if (err)
82af8ce84   Michael S. Tsirkin   virtio_pci: optio...
657
  		goto out_set_drvdata;
3343660d8   Anthony Liguori   virtio: PCI device
658
659
  
  	return 0;
3343660d8   Anthony Liguori   virtio: PCI device
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
  out_set_drvdata:
  	pci_set_drvdata(pci_dev, NULL);
  	pci_iounmap(pci_dev, vp_dev->ioaddr);
  out_req_regions:
  	pci_release_regions(pci_dev);
  out_enable_device:
  	pci_disable_device(pci_dev);
  out:
  	kfree(vp_dev);
  	return err;
  }
  
  static void __devexit virtio_pci_remove(struct pci_dev *pci_dev)
  {
  	struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev);
bd6c26900   Anthony Liguori   virtio_pci: unreg...
675
  	unregister_virtio_device(&vp_dev->vdev);
31a3ddda1   Amit Shah   virtio_pci: Preve...
676
677
678
679
680
681
  
  	vp_del_vqs(&vp_dev->vdev);
  	pci_set_drvdata(pci_dev, NULL);
  	pci_iounmap(pci_dev, vp_dev->ioaddr);
  	pci_release_regions(pci_dev);
  	pci_disable_device(pci_dev);
72103bd12   Michael S. Tsirkin   virtio-pci: fix u...
682
  	kfree(vp_dev);
3343660d8   Anthony Liguori   virtio: PCI device
683
684
685
  }
  
  #ifdef CONFIG_PM
d07753638   Amit Shah   virtio: pci: swit...
686
  static int virtio_pci_suspend(struct device *dev)
3343660d8   Anthony Liguori   virtio: PCI device
687
  {
d07753638   Amit Shah   virtio: pci: swit...
688
  	struct pci_dev *pci_dev = to_pci_dev(dev);
3343660d8   Anthony Liguori   virtio: PCI device
689
690
691
692
  	pci_save_state(pci_dev);
  	pci_set_power_state(pci_dev, PCI_D3hot);
  	return 0;
  }
d07753638   Amit Shah   virtio: pci: swit...
693
  static int virtio_pci_resume(struct device *dev)
3343660d8   Anthony Liguori   virtio: PCI device
694
  {
d07753638   Amit Shah   virtio: pci: swit...
695
  	struct pci_dev *pci_dev = to_pci_dev(dev);
3343660d8   Anthony Liguori   virtio: PCI device
696
697
698
699
  	pci_restore_state(pci_dev);
  	pci_set_power_state(pci_dev, PCI_D0);
  	return 0;
  }
d07753638   Amit Shah   virtio: pci: swit...
700

f0fe6f115   Amit Shah   virtio: pci: add ...
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
  static int virtio_pci_freeze(struct device *dev)
  {
  	struct pci_dev *pci_dev = to_pci_dev(dev);
  	struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev);
  	struct virtio_driver *drv;
  	int ret;
  
  	drv = container_of(vp_dev->vdev.dev.driver,
  			   struct virtio_driver, driver);
  
  	ret = 0;
  	vp_dev->saved_status = vp_get_status(&vp_dev->vdev);
  	if (drv && drv->freeze)
  		ret = drv->freeze(&vp_dev->vdev);
  
  	if (!ret)
  		pci_disable_device(pci_dev);
  	return ret;
  }
  
  static int restore_common(struct device *dev)
  {
  	struct pci_dev *pci_dev = to_pci_dev(dev);
  	struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev);
  	int ret;
  
  	ret = pci_enable_device(pci_dev);
  	if (ret)
  		return ret;
  	pci_set_master(pci_dev);
  	vp_finalize_features(&vp_dev->vdev);
  
  	return ret;
  }
  
  static int virtio_pci_thaw(struct device *dev)
  {
  	struct pci_dev *pci_dev = to_pci_dev(dev);
  	struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev);
  	struct virtio_driver *drv;
  	int ret;
  
  	ret = restore_common(dev);
  	if (ret)
  		return ret;
  
  	drv = container_of(vp_dev->vdev.dev.driver,
  			   struct virtio_driver, driver);
  
  	if (drv && drv->thaw)
  		ret = drv->thaw(&vp_dev->vdev);
  	else if (drv && drv->restore)
  		ret = drv->restore(&vp_dev->vdev);
  
  	/* Finally, tell the device we're all set */
  	if (!ret)
  		vp_set_status(&vp_dev->vdev, vp_dev->saved_status);
  
  	return ret;
  }
  
  static int virtio_pci_restore(struct device *dev)
  {
  	struct pci_dev *pci_dev = to_pci_dev(dev);
  	struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev);
  	struct virtio_driver *drv;
  	int ret;
  
  	drv = container_of(vp_dev->vdev.dev.driver,
  			   struct virtio_driver, driver);
  
  	ret = restore_common(dev);
  	if (!ret && drv && drv->restore)
  		ret = drv->restore(&vp_dev->vdev);
  
  	/* Finally, tell the device we're all set */
  	if (!ret)
  		vp_set_status(&vp_dev->vdev, vp_dev->saved_status);
  
  	return ret;
  }
d07753638   Amit Shah   virtio: pci: swit...
782
  static const struct dev_pm_ops virtio_pci_pm_ops = {
f0fe6f115   Amit Shah   virtio: pci: add ...
783
784
785
786
787
788
  	.suspend	= virtio_pci_suspend,
  	.resume		= virtio_pci_resume,
  	.freeze		= virtio_pci_freeze,
  	.thaw		= virtio_pci_thaw,
  	.restore	= virtio_pci_restore,
  	.poweroff	= virtio_pci_suspend,
d07753638   Amit Shah   virtio: pci: swit...
789
  };
3343660d8   Anthony Liguori   virtio: PCI device
790
791
792
793
794
795
  #endif
  
  static struct pci_driver virtio_pci_driver = {
  	.name		= "virtio-pci",
  	.id_table	= virtio_pci_id_table,
  	.probe		= virtio_pci_probe,
1f08b833d   Jamie Lokier   Add __devexit_p a...
796
  	.remove		= __devexit_p(virtio_pci_remove),
3343660d8   Anthony Liguori   virtio: PCI device
797
  #ifdef CONFIG_PM
d07753638   Amit Shah   virtio: pci: swit...
798
  	.driver.pm	= &virtio_pci_pm_ops,
3343660d8   Anthony Liguori   virtio: PCI device
799
800
801
802
803
  #endif
  };
  
  static int __init virtio_pci_init(void)
  {
8b3bb3ecf   Milton Miller   virtio: remove vi...
804
  	return pci_register_driver(&virtio_pci_driver);
3343660d8   Anthony Liguori   virtio: PCI device
805
806
807
808
809
810
  }
  
  module_init(virtio_pci_init);
  
  static void __exit virtio_pci_exit(void)
  {
3343660d8   Anthony Liguori   virtio: PCI device
811
812
813
814
  	pci_unregister_driver(&virtio_pci_driver);
  }
  
  module_exit(virtio_pci_exit);