diff options
Diffstat (limited to 'drivers/virtio/virtio_pci_legacy.c')
-rw-r--r-- | drivers/virtio/virtio_pci_legacy.c | 76 |
1 files changed, 8 insertions, 68 deletions
diff --git a/drivers/virtio/virtio_pci_legacy.c b/drivers/virtio/virtio_pci_legacy.c index a5486e65e04b..256a5278a515 100644 --- a/drivers/virtio/virtio_pci_legacy.c +++ b/drivers/virtio/virtio_pci_legacy.c | |||
@@ -211,23 +211,10 @@ static const struct virtio_config_ops virtio_pci_config_ops = { | |||
211 | .set_vq_affinity = vp_set_vq_affinity, | 211 | .set_vq_affinity = vp_set_vq_affinity, |
212 | }; | 212 | }; |
213 | 213 | ||
214 | static void virtio_pci_release_dev(struct device *_d) | ||
215 | { | ||
216 | struct virtio_device *vdev = dev_to_virtio(_d); | ||
217 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); | ||
218 | |||
219 | /* As struct device is a kobject, it's not safe to | ||
220 | * free the memory (including the reference counter itself) | ||
221 | * until it's release callback. */ | ||
222 | kfree(vp_dev); | ||
223 | } | ||
224 | |||
225 | /* the PCI probing function */ | 214 | /* the PCI probing function */ |
226 | int virtio_pci_legacy_probe(struct pci_dev *pci_dev, | 215 | int virtio_pci_legacy_probe(struct virtio_pci_device *vp_dev) |
227 | const struct pci_device_id *id) | ||
228 | { | 216 | { |
229 | struct virtio_pci_device *vp_dev; | 217 | struct pci_dev *pci_dev = vp_dev->pci_dev; |
230 | int err; | ||
231 | 218 | ||
232 | /* We only own devices >= 0x1000 and <= 0x103f: leave the rest. */ | 219 | /* We only own devices >= 0x1000 and <= 0x103f: leave the rest. */ |
233 | if (pci_dev->device < 0x1000 || pci_dev->device > 0x103f) | 220 | if (pci_dev->device < 0x1000 || pci_dev->device > 0x103f) |
@@ -239,41 +226,12 @@ int virtio_pci_legacy_probe(struct pci_dev *pci_dev, | |||
239 | return -ENODEV; | 226 | return -ENODEV; |
240 | } | 227 | } |
241 | 228 | ||
242 | /* allocate our structure and fill it out */ | ||
243 | vp_dev = kzalloc(sizeof(struct virtio_pci_device), GFP_KERNEL); | ||
244 | if (vp_dev == NULL) | ||
245 | return -ENOMEM; | ||
246 | |||
247 | vp_dev->vdev.dev.parent = &pci_dev->dev; | ||
248 | vp_dev->vdev.dev.release = virtio_pci_release_dev; | ||
249 | vp_dev->vdev.config = &virtio_pci_config_ops; | ||
250 | vp_dev->pci_dev = pci_dev; | ||
251 | INIT_LIST_HEAD(&vp_dev->virtqueues); | ||
252 | spin_lock_init(&vp_dev->lock); | ||
253 | |||
254 | /* Disable MSI/MSIX to bring device to a known good state. */ | ||
255 | pci_msi_off(pci_dev); | ||
256 | |||
257 | /* enable the device */ | ||
258 | err = pci_enable_device(pci_dev); | ||
259 | if (err) | ||
260 | goto out; | ||
261 | |||
262 | err = pci_request_regions(pci_dev, "virtio-pci"); | ||
263 | if (err) | ||
264 | goto out_enable_device; | ||
265 | |||
266 | vp_dev->ioaddr = pci_iomap(pci_dev, 0, 0); | 229 | vp_dev->ioaddr = pci_iomap(pci_dev, 0, 0); |
267 | if (vp_dev->ioaddr == NULL) { | 230 | if (!vp_dev->ioaddr) |
268 | err = -ENOMEM; | 231 | return -ENOMEM; |
269 | goto out_req_regions; | ||
270 | } | ||
271 | 232 | ||
272 | vp_dev->isr = vp_dev->ioaddr + VIRTIO_PCI_ISR; | 233 | vp_dev->isr = vp_dev->ioaddr + VIRTIO_PCI_ISR; |
273 | 234 | ||
274 | pci_set_drvdata(pci_dev, vp_dev); | ||
275 | pci_set_master(pci_dev); | ||
276 | |||
277 | /* we use the subsystem vendor/device id as the virtio vendor/device | 235 | /* we use the subsystem vendor/device id as the virtio vendor/device |
278 | * id. this allows us to use the same PCI vendor/device id for all | 236 | * id. this allows us to use the same PCI vendor/device id for all |
279 | * virtio devices and to identify the particular virtio driver by | 237 | * virtio devices and to identify the particular virtio driver by |
@@ -281,36 +239,18 @@ int virtio_pci_legacy_probe(struct pci_dev *pci_dev, | |||
281 | vp_dev->vdev.id.vendor = pci_dev->subsystem_vendor; | 239 | vp_dev->vdev.id.vendor = pci_dev->subsystem_vendor; |
282 | vp_dev->vdev.id.device = pci_dev->subsystem_device; | 240 | vp_dev->vdev.id.device = pci_dev->subsystem_device; |
283 | 241 | ||
242 | vp_dev->vdev.config = &virtio_pci_config_ops; | ||
243 | |||
284 | vp_dev->config_vector = vp_config_vector; | 244 | vp_dev->config_vector = vp_config_vector; |
285 | vp_dev->setup_vq = setup_vq; | 245 | vp_dev->setup_vq = setup_vq; |
286 | vp_dev->del_vq = del_vq; | 246 | vp_dev->del_vq = del_vq; |
287 | 247 | ||
288 | /* finally register the virtio device */ | ||
289 | err = register_virtio_device(&vp_dev->vdev); | ||
290 | if (err) | ||
291 | goto out_set_drvdata; | ||
292 | |||
293 | return 0; | 248 | return 0; |
294 | |||
295 | out_set_drvdata: | ||
296 | pci_iounmap(pci_dev, vp_dev->ioaddr); | ||
297 | out_req_regions: | ||
298 | pci_release_regions(pci_dev); | ||
299 | out_enable_device: | ||
300 | pci_disable_device(pci_dev); | ||
301 | out: | ||
302 | kfree(vp_dev); | ||
303 | return err; | ||
304 | } | 249 | } |
305 | 250 | ||
306 | void virtio_pci_legacy_remove(struct pci_dev *pci_dev) | 251 | void virtio_pci_legacy_remove(struct virtio_pci_device *vp_dev) |
307 | { | 252 | { |
308 | struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev); | 253 | struct pci_dev *pci_dev = vp_dev->pci_dev; |
309 | |||
310 | unregister_virtio_device(&vp_dev->vdev); | ||
311 | 254 | ||
312 | vp_del_vqs(&vp_dev->vdev); | ||
313 | pci_iounmap(pci_dev, vp_dev->ioaddr); | 255 | pci_iounmap(pci_dev, vp_dev->ioaddr); |
314 | pci_release_regions(pci_dev); | ||
315 | pci_disable_device(pci_dev); | ||
316 | } | 256 | } |