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 --- |