18 #include <linux/module.h>
20 #include <xen/events.h>
36 static void backend_changed(
struct xenbus_watch *,
const char **,
44 static int blkback_name(
struct xen_blkif *blkif,
char *
buf)
46 char *devpath, *devname;
51 return PTR_ERR(devpath);
53 devname =
strstr(devpath,
"/dev/");
55 devname +=
strlen(
"/dev/");
65 static void xen_update_blkif_status(
struct xen_blkif *blkif)
71 if (!blkif->
irq || !blkif->
vbd.bdev)
83 err = blkback_name(blkif, name);
108 blkif = kmem_cache_zalloc(xen_blkif_cachep,
GFP_KERNEL);
124 static int xen_blkif_map(
struct xen_blkif *blkif,
unsigned long shared_page,
140 struct blkif_sring *sring;
141 sring = (
struct blkif_sring *)blkif->
blk_ring;
147 struct blkif_x86_32_sring *sring_x86_32;
148 sring_x86_32 = (
struct blkif_x86_32_sring *)blkif->
blk_ring;
154 struct blkif_x86_64_sring *sring_x86_64;
155 sring_x86_64 = (
struct blkif_x86_64_sring *)blkif->
blk_ring;
165 "blkif-backend", blkif);
176 static void xen_blkif_disconnect(
struct xen_blkif *blkif)
198 static void xen_blkif_free(
struct xen_blkif *blkif)
210 if (!xen_blkif_cachep)
220 #define VBD_SHOW(name, format, args...) \
221 static ssize_t show_##name(struct device *_dev, \
222 struct device_attribute *attr, \
225 struct xenbus_device *dev = to_xenbus_device(_dev); \
226 struct backend_info *be = dev_get_drvdata(&dev->dev); \
228 return sprintf(buf, format, ##args); \
230 static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
232 VBD_SHOW(oo_req,
"%d\n", be->blkif->st_oo_req);
233 VBD_SHOW(rd_req,
"%d\n", be->blkif->st_rd_req);
234 VBD_SHOW(wr_req,
"%d\n", be->blkif->st_wr_req);
235 VBD_SHOW(f_req,
"%d\n", be->blkif->st_f_req);
236 VBD_SHOW(ds_req,
"%d\n", be->blkif->st_ds_req);
237 VBD_SHOW(rd_sect,
"%d\n", be->blkif->st_rd_sect);
238 VBD_SHOW(wr_sect,
"%d\n", be->blkif->st_wr_sect);
240 static struct attribute *xen_vbdstat_attrs[] = {
241 &dev_attr_oo_req.attr,
242 &dev_attr_rd_req.attr,
243 &dev_attr_wr_req.attr,
244 &dev_attr_f_req.attr,
245 &dev_attr_ds_req.attr,
246 &dev_attr_rd_sect.attr,
247 &dev_attr_wr_sect.attr,
252 .name =
"statistics",
253 .attrs = xen_vbdstat_attrs,
256 VBD_SHOW(physical_device,
"%x:%x\n", be->major, be->minor);
291 static void xen_vbd_free(
struct xen_vbd *vbd)
299 unsigned major,
unsigned minor,
int readonly,
317 DPRINTK(
"xen_vbd_create: device %08x could not be opened.\n",
324 DPRINTK(
"xen_vbd_create: device %08x doesn't exist.\n",
331 if (vbd->
bdev->bd_disk->flags & GENHD_FL_CD || cdrom)
333 if (vbd->
bdev->bd_disk->flags & GENHD_FL_REMOVABLE)
336 q = bdev_get_queue(bdev);
337 if (q && q->flush_flags)
340 if (q && blk_queue_secdiscard(q))
343 DPRINTK(
"Successful creation of handle=%04x (dom=%u)\n",
344 handle, blkif->
domid);
354 xenvbd_sysfs_delif(dev);
363 xen_blkif_disconnect(be->
blkif);
364 xen_vbd_free(&be->
blkif->vbd);
365 xen_blkif_free(be->
blkif);
383 dev_warn(&dev->
dev,
"writing feature-flush-cache (%d)", err);
397 if (blk_queue_discard(q)) {
399 "discard-granularity",
"%u",
400 q->limits.discard_granularity);
402 dev_warn(&dev->
dev,
"writing discard-granularity (%d)", err);
406 "discard-alignment",
"%u",
407 q->limits.discard_alignment);
409 dev_warn(&dev->
dev,
"writing discard-alignment (%d)", err);
415 "discard-secure",
"%d",
416 blkif->
vbd.discard_secure);
418 dev_warn(&dev->
dev,
"writing discard-secure (%d)", err);
425 dev_warn(&dev->
dev,
"writing feature-discard (%d)", err);
436 dev_warn(&dev->
dev,
"writing feature-barrier (%d)", err);
454 "allocating backend structure");
461 if (IS_ERR(be->
blkif)) {
462 err = PTR_ERR(be->
blkif);
472 "%s/%s", dev->
nodename,
"physical-device");
484 xen_blkbk_remove(dev);
495 const char **vec,
unsigned int len)
524 ((be->
major != major) || (be->
minor != minor))) {
525 pr_warn(
DRV_PFX "changing physical device (from %x:%x to %x:%x) not supported.\n",
531 if (IS_ERR(be->
mode)) {
532 err = PTR_ERR(be->
mode);
539 if (!IS_ERR(device_type)) {
540 cdrom =
strcmp(device_type,
"cdrom") == 0;
556 err = xen_vbd_create(be->
blkif, handle, major, minor,
565 err = xenvbd_sysfs_addif(dev);
567 xen_vbd_free(&be->
blkif->vbd);
575 xen_update_blkif_status(be->
blkif);
591 switch (frontend_state) {
614 xen_blkif_disconnect(be->
blkif);
616 err = connect_ring(be);
619 xen_update_blkif_status(be->
blkif);
627 xen_blkif_disconnect(be->
blkif);
671 xen_blkbk_discard(xbt, be);
685 be->
blkif->vbd.type |
694 bdev_logical_block_size(be->
blkif->vbd.bdev));
721 unsigned long ring_ref;
729 &ring_ref,
"event-channel",
"%u", &evtchn,
NULL);
732 "reading %s/ring-ref and event-channel",
739 "%63s", protocol,
NULL);
741 strcpy(protocol,
"unspecified, assuming native");
742 else if (0 ==
strcmp(protocol, XEN_IO_PROTO_ABI_NATIVE))
752 pr_info(
DRV_PFX "ring-ref %ld, event-channel %d, protocol %d (%s)\n",
753 ring_ref, evtchn, be->
blkif->blk_protocol, protocol);
756 err = xen_blkif_map(be->
blkif, ring_ref, evtchn);
777 .probe = xen_blkbk_probe,
778 .
remove = xen_blkbk_remove,
779 .otherend_changed = frontend_changed