blkfront.c (23dc5621704f73a7c853202e14e5932bdc2c1115) blkfront.c (3a6d1fcf9c8ed864c98e449a0b7696be6c838aea)
1/*-
2 * All rights reserved.
3 *
4 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
5 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
6 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
7 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
8 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL

--- 26 unchanged lines hidden (view full) ---

35#include <sys/module.h>
36
37#include <machine/bus.h>
38#include <sys/rman.h>
39#include <machine/resource.h>
40#include <machine/intr_machdep.h>
41#include <machine/vmparam.h>
42
1/*-
2 * All rights reserved.
3 *
4 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
5 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
6 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
7 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
8 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL

--- 26 unchanged lines hidden (view full) ---

35#include <sys/module.h>
36
37#include <machine/bus.h>
38#include <sys/rman.h>
39#include <machine/resource.h>
40#include <machine/intr_machdep.h>
41#include <machine/vmparam.h>
42
43#include <machine/xen/hypervisor.h>
43#include <xen/hypervisor.h>
44#include <machine/xen/xen-os.h>
44#include <machine/xen/xen-os.h>
45#include <machine/xen/xen_intr.h>
46#include <machine/xen/evtchn.h>
45#include <xen/xen_intr.h>
46#include <xen/evtchn.h>
47#include <xen/interface/grant_table.h>
48#include <xen/interface/io/protocols.h>
49#include <xen/xenbus/xenbusvar.h>
50
51#include <geom/geom_disk.h>
52#include <machine/xen/xenfunc.h>
53#include <xen/gnttab.h>
54

--- 154 unchanged lines hidden (view full) ---

209int
210xlvbd_add(device_t dev, blkif_sector_t capacity,
211 int vdevice, uint16_t vdisk_info, uint16_t sector_size,
212 struct blkfront_info *info)
213{
214 struct xb_softc *sc;
215 int unit, error = 0;
216 const char *name;
47#include <xen/interface/grant_table.h>
48#include <xen/interface/io/protocols.h>
49#include <xen/xenbus/xenbusvar.h>
50
51#include <geom/geom_disk.h>
52#include <machine/xen/xenfunc.h>
53#include <xen/gnttab.h>
54

--- 154 unchanged lines hidden (view full) ---

209int
210xlvbd_add(device_t dev, blkif_sector_t capacity,
211 int vdevice, uint16_t vdisk_info, uint16_t sector_size,
212 struct blkfront_info *info)
213{
214 struct xb_softc *sc;
215 int unit, error = 0;
216 const char *name;
217
217
218 blkfront_vdevice_to_unit(vdevice, &unit, &name);
219
220 sc = (struct xb_softc *)malloc(sizeof(*sc), M_DEVBUF, M_WAITOK|M_ZERO);
221 sc->xb_unit = unit;
222 sc->xb_info = info;
223 info->sc = sc;
224
225 if (strcmp(name, "xbd"))
226 device_printf(dev, "attaching as %s%d\n", name, unit);
227
228 memset(&sc->xb_disk, 0, sizeof(sc->xb_disk));
229 sc->xb_disk = disk_alloc();
218 blkfront_vdevice_to_unit(vdevice, &unit, &name);
219
220 sc = (struct xb_softc *)malloc(sizeof(*sc), M_DEVBUF, M_WAITOK|M_ZERO);
221 sc->xb_unit = unit;
222 sc->xb_info = info;
223 info->sc = sc;
224
225 if (strcmp(name, "xbd"))
226 device_printf(dev, "attaching as %s%d\n", name, unit);
227
228 memset(&sc->xb_disk, 0, sizeof(sc->xb_disk));
229 sc->xb_disk = disk_alloc();
230 sc->xb_disk->d_unit = unit;
230 sc->xb_disk->d_unit = sc->xb_unit;
231 sc->xb_disk->d_open = blkif_open;
232 sc->xb_disk->d_close = blkif_close;
233 sc->xb_disk->d_ioctl = blkif_ioctl;
234 sc->xb_disk->d_strategy = xb_strategy;
231 sc->xb_disk->d_open = blkif_open;
232 sc->xb_disk->d_close = blkif_close;
233 sc->xb_disk->d_ioctl = blkif_ioctl;
234 sc->xb_disk->d_strategy = xb_strategy;
235 sc->xb_disk->d_name = "xbd";
235 sc->xb_disk->d_name = name;
236 sc->xb_disk->d_drv1 = sc;
237 sc->xb_disk->d_sectorsize = sector_size;
238
239 /* XXX */
240 sc->xb_disk->d_mediasize = capacity << XBD_SECTOR_SHFT;
241#if 0
242 sc->xb_disk->d_maxsize = DFLTPHYS;
243#else /* XXX: xen can't handle large single i/o requests */

--- 80 unchanged lines hidden (view full) ---

324blkfront_attach(device_t dev)
325{
326 int err, vdevice, i, unit;
327 struct blkfront_info *info;
328 const char *name;
329
330 /* FIXME: Use dynamic device id if this is not set. */
331 err = xenbus_scanf(XBT_NIL, xenbus_get_node(dev),
236 sc->xb_disk->d_drv1 = sc;
237 sc->xb_disk->d_sectorsize = sector_size;
238
239 /* XXX */
240 sc->xb_disk->d_mediasize = capacity << XBD_SECTOR_SHFT;
241#if 0
242 sc->xb_disk->d_maxsize = DFLTPHYS;
243#else /* XXX: xen can't handle large single i/o requests */

--- 80 unchanged lines hidden (view full) ---

324blkfront_attach(device_t dev)
325{
326 int err, vdevice, i, unit;
327 struct blkfront_info *info;
328 const char *name;
329
330 /* FIXME: Use dynamic device id if this is not set. */
331 err = xenbus_scanf(XBT_NIL, xenbus_get_node(dev),
332 "virtual-device", "%i", &vdevice);
333 if (err != 1) {
332 "virtual-device", NULL, "%i", &vdevice);
333 if (err) {
334 xenbus_dev_fatal(dev, err, "reading virtual-device");
335 printf("couldn't find virtual device");
336 return (err);
337 }
338
339 blkfront_vdevice_to_unit(vdevice, &unit, &name);
340 if (!strcmp(name, "xbd"))
341 device_set_unit(dev, unit);

--- 16 unchanged lines hidden (view full) ---

358 for (i = 0; i < BLK_RING_SIZE; i++)
359 info->shadow[i].req.id = i+1;
360 info->shadow[BLK_RING_SIZE-1].req.id = 0x0fffffff;
361
362 /* Front end dir is a number, which is used as the id. */
363 info->handle = strtoul(strrchr(xenbus_get_node(dev),'/')+1, NULL, 0);
364
365 err = talk_to_backend(dev, info);
334 xenbus_dev_fatal(dev, err, "reading virtual-device");
335 printf("couldn't find virtual device");
336 return (err);
337 }
338
339 blkfront_vdevice_to_unit(vdevice, &unit, &name);
340 if (!strcmp(name, "xbd"))
341 device_set_unit(dev, unit);

--- 16 unchanged lines hidden (view full) ---

358 for (i = 0; i < BLK_RING_SIZE; i++)
359 info->shadow[i].req.id = i+1;
360 info->shadow[BLK_RING_SIZE-1].req.id = 0x0fffffff;
361
362 /* Front end dir is a number, which is used as the id. */
363 info->handle = strtoul(strrchr(xenbus_get_node(dev),'/')+1, NULL, 0);
364
365 err = talk_to_backend(dev, info);
366 if (err) {
367 return err;
368 }
366 if (err)
367 return (err);
369
370 return (0);
371}
372
373static int
374blkfront_resume(device_t dev)
375{
376 struct blkfront_info *info = device_get_softc(dev);
377 int err;
378
379 DPRINTK("blkfront_resume: %s\n", dev->nodename);
380
381 blkif_free(info, 1);
382
383 err = talk_to_backend(dev, info);
368
369 return (0);
370}
371
372static int
373blkfront_resume(device_t dev)
374{
375 struct blkfront_info *info = device_get_softc(dev);
376 int err;
377
378 DPRINTK("blkfront_resume: %s\n", dev->nodename);
379
380 blkif_free(info, 1);
381
382 err = talk_to_backend(dev, info);
384 if (!err)
383
384 if (info->connected == BLKIF_STATE_SUSPENDED && !err)
385 blkif_recover(info);
386
387 return err;
388}
389
390/* Common code used when first setting up, and when resuming. */
391static int
392talk_to_backend(device_t dev, struct blkfront_info *info)

--- 29 unchanged lines hidden (view full) ---

422 err = xenbus_printf(xbt, xenbus_get_node(dev),
423 "protocol", "%s", XEN_IO_PROTO_ABI_NATIVE);
424 if (err) {
425 message = "writing protocol";
426 goto abort_transaction;
427 }
428 err = xenbus_transaction_end(xbt, 0);
429 if (err) {
385 blkif_recover(info);
386
387 return err;
388}
389
390/* Common code used when first setting up, and when resuming. */
391static int
392talk_to_backend(device_t dev, struct blkfront_info *info)

--- 29 unchanged lines hidden (view full) ---

422 err = xenbus_printf(xbt, xenbus_get_node(dev),
423 "protocol", "%s", XEN_IO_PROTO_ABI_NATIVE);
424 if (err) {
425 message = "writing protocol";
426 goto abort_transaction;
427 }
428 err = xenbus_transaction_end(xbt, 0);
429 if (err) {
430 if (err == -EAGAIN)
430 if (err == EAGAIN)
431 goto again;
432 xenbus_dev_fatal(dev, err, "completing transaction");
433 goto destroy_blkring;
434 }
435 xenbus_set_state(dev, XenbusStateInitialised);
436
437 return 0;
438

--- 6 unchanged lines hidden (view full) ---

445 out:
446 return err;
447}
448
449static int
450setup_blkring(device_t dev, struct blkfront_info *info)
451{
452 blkif_sring_t *sring;
431 goto again;
432 xenbus_dev_fatal(dev, err, "completing transaction");
433 goto destroy_blkring;
434 }
435 xenbus_set_state(dev, XenbusStateInitialised);
436
437 return 0;
438

--- 6 unchanged lines hidden (view full) ---

445 out:
446 return err;
447}
448
449static int
450setup_blkring(device_t dev, struct blkfront_info *info)
451{
452 blkif_sring_t *sring;
453 int err;
453 int error;
454
455 info->ring_ref = GRANT_INVALID_REF;
456
457 sring = (blkif_sring_t *)malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT|M_ZERO);
458 if (sring == NULL) {
459 xenbus_dev_fatal(dev, ENOMEM, "allocating shared ring");
460 return ENOMEM;
461 }
462 SHARED_RING_INIT(sring);
463 FRONT_RING_INIT(&info->ring, sring, PAGE_SIZE);
464
454
455 info->ring_ref = GRANT_INVALID_REF;
456
457 sring = (blkif_sring_t *)malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT|M_ZERO);
458 if (sring == NULL) {
459 xenbus_dev_fatal(dev, ENOMEM, "allocating shared ring");
460 return ENOMEM;
461 }
462 SHARED_RING_INIT(sring);
463 FRONT_RING_INIT(&info->ring, sring, PAGE_SIZE);
464
465 err = xenbus_grant_ring(dev, (vtomach(info->ring.sring) >> PAGE_SHIFT));
466 if (err < 0) {
465 error = xenbus_grant_ring(dev, (vtomach(info->ring.sring) >> PAGE_SHIFT),
466 &info->ring_ref);
467 if (error) {
467 free(sring, M_DEVBUF);
468 info->ring.sring = NULL;
469 goto fail;
470 }
468 free(sring, M_DEVBUF);
469 info->ring.sring = NULL;
470 goto fail;
471 }
471 info->ring_ref = err;
472
472
473 err = bind_listening_port_to_irqhandler(xenbus_get_otherend_id(dev),
473 error = bind_listening_port_to_irqhandler(xenbus_get_otherend_id(dev),
474 "xbd", (driver_intr_t *)blkif_int, info,
474 "xbd", (driver_intr_t *)blkif_int, info,
475 INTR_TYPE_BIO | INTR_MPSAFE, NULL);
476 if (err <= 0) {
477 xenbus_dev_fatal(dev, err,
475 INTR_TYPE_BIO | INTR_MPSAFE, &info->irq);
476 if (error) {
477 xenbus_dev_fatal(dev, error,
478 "bind_evtchn_to_irqhandler failed");
479 goto fail;
480 }
478 "bind_evtchn_to_irqhandler failed");
479 goto fail;
480 }
481 info->irq = err;
482
481
483 return 0;
482 return (0);
484 fail:
485 blkif_free(info, 0);
483 fail:
484 blkif_free(info, 0);
486 return err;
485 return (error);
487}
488
489
490/**
491 * Callback received when the backend's state changes.
492 */
493static void
494blkfront_backend_changed(device_t dev, XenbusState backend_state)

--- 499 unchanged lines hidden (view full) ---

994 /* Free resources associated with old device channel. */
995 if (info->ring_ref != GRANT_INVALID_REF) {
996 gnttab_end_foreign_access(info->ring_ref,
997 info->ring.sring);
998 info->ring_ref = GRANT_INVALID_REF;
999 info->ring.sring = NULL;
1000 }
1001 if (info->irq)
486}
487
488
489/**
490 * Callback received when the backend's state changes.
491 */
492static void
493blkfront_backend_changed(device_t dev, XenbusState backend_state)

--- 499 unchanged lines hidden (view full) ---

993 /* Free resources associated with old device channel. */
994 if (info->ring_ref != GRANT_INVALID_REF) {
995 gnttab_end_foreign_access(info->ring_ref,
996 info->ring.sring);
997 info->ring_ref = GRANT_INVALID_REF;
998 info->ring.sring = NULL;
999 }
1000 if (info->irq)
1002 unbind_from_irqhandler(info->irq, info);
1001 unbind_from_irqhandler(info->irq);
1003 info->irq = 0;
1004
1005}
1006
1007static void
1008blkif_completion(struct blk_shadow *s)
1009{
1010 int i;

--- 97 unchanged lines hidden ---
1002 info->irq = 0;
1003
1004}
1005
1006static void
1007blkif_completion(struct blk_shadow *s)
1008{
1009 int i;

--- 97 unchanged lines hidden ---