diff options
Diffstat (limited to 'drivers/xen')
| -rw-r--r-- | drivers/xen/Kconfig | 10 | ||||
| -rw-r--r-- | drivers/xen/Makefile | 3 | ||||
| -rw-r--r-- | drivers/xen/mcelog.c | 25 | ||||
| -rw-r--r-- | drivers/xen/pci.c | 15 | ||||
| -rw-r--r-- | drivers/xen/pcpu.c | 44 | ||||
| -rw-r--r-- | drivers/xen/privcmd.c | 117 | ||||
| -rw-r--r-- | drivers/xen/xen-balloon.c | 45 | ||||
| -rw-r--r-- | drivers/xen/xen-pciback/conf_space_header.c | 15 | ||||
| -rw-r--r-- | drivers/xen/xen-pciback/pci_stub.c | 4 | ||||
| -rw-r--r-- | drivers/xen/xen-pciback/xenbus.c | 2 | ||||
| -rw-r--r-- | drivers/xen/xen-scsiback.c | 164 | ||||
| -rw-r--r-- | drivers/xen/xenbus/xenbus_client.c | 387 | ||||
| -rw-r--r-- | drivers/xen/xlate_mmu.c | 143 |
13 files changed, 680 insertions, 294 deletions
diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig index 94d96809e686..7cd226da15fe 100644 --- a/drivers/xen/Kconfig +++ b/drivers/xen/Kconfig @@ -270,4 +270,14 @@ config XEN_EFI def_bool y depends on X86_64 && EFI +config XEN_AUTO_XLATE + def_bool y + depends on ARM || ARM64 || XEN_PVHVM + help + Support for auto-translated physmap guests. + +config XEN_ACPI + def_bool y + depends on X86 && ACPI + endmenu diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile index 2ccd3592d41f..e293bc507cbc 100644 --- a/drivers/xen/Makefile +++ b/drivers/xen/Makefile @@ -13,7 +13,7 @@ CFLAGS_efi.o += -fshort-wchar dom0-$(CONFIG_PCI) += pci.o dom0-$(CONFIG_USB_SUPPORT) += dbgp.o -dom0-$(CONFIG_ACPI) += acpi.o $(xen-pad-y) +dom0-$(CONFIG_XEN_ACPI) += acpi.o $(xen-pad-y) xen-pad-$(CONFIG_X86) += xen-acpi-pad.o dom0-$(CONFIG_X86) += pcpu.o obj-$(CONFIG_XEN_DOM0) += $(dom0-y) @@ -37,6 +37,7 @@ obj-$(CONFIG_XEN_ACPI_HOTPLUG_CPU) += xen-acpi-cpuhotplug.o obj-$(CONFIG_XEN_ACPI_PROCESSOR) += xen-acpi-processor.o obj-$(CONFIG_XEN_EFI) += efi.o obj-$(CONFIG_XEN_SCSI_BACKEND) += xen-scsiback.o +obj-$(CONFIG_XEN_AUTO_XLATE) += xlate_mmu.o xen-evtchn-y := evtchn.o xen-gntdev-y := gntdev.o xen-gntalloc-y := gntalloc.o diff --git a/drivers/xen/mcelog.c b/drivers/xen/mcelog.c index 6ab6a79c38a5..a493c7315e94 100644 --- a/drivers/xen/mcelog.c +++ b/drivers/xen/mcelog.c @@ -393,14 +393,25 @@ static int bind_virq_for_mce(void) static int __init xen_late_init_mcelog(void) { + int ret; + /* Only DOM0 is responsible for MCE logging */ - if (xen_initial_domain()) { - /* register character device /dev/mcelog for xen mcelog */ - if (misc_register(&xen_mce_chrdev_device)) - return -ENODEV; - return bind_virq_for_mce(); - } + if (!xen_initial_domain()) + return -ENODEV; + + /* register character device /dev/mcelog for xen mcelog */ + ret = misc_register(&xen_mce_chrdev_device); + if (ret) + return ret; + + ret = bind_virq_for_mce(); + if (ret) + goto deregister; - return -ENODEV; + return 0; + +deregister: + misc_deregister(&xen_mce_chrdev_device); + return ret; } device_initcall(xen_late_init_mcelog); diff --git a/drivers/xen/pci.c b/drivers/xen/pci.c index 95ee4302ffb8..7494dbeb4409 100644 --- a/drivers/xen/pci.c +++ b/drivers/xen/pci.c @@ -19,6 +19,7 @@ #include <linux/pci.h> #include <linux/acpi.h> +#include <linux/pci-acpi.h> #include <xen/xen.h> #include <xen/interface/physdev.h> #include <xen/interface/xen.h> @@ -67,12 +68,22 @@ static int xen_add_device(struct device *dev) #ifdef CONFIG_ACPI handle = ACPI_HANDLE(&pci_dev->dev); - if (!handle && pci_dev->bus->bridge) - handle = ACPI_HANDLE(pci_dev->bus->bridge); #ifdef CONFIG_PCI_IOV if (!handle && pci_dev->is_virtfn) handle = ACPI_HANDLE(physfn->bus->bridge); #endif + if (!handle) { + /* + * This device was not listed in the ACPI name space at + * all. Try to get acpi handle of parent pci bus. + */ + struct pci_bus *pbus; + for (pbus = pci_dev->bus; pbus; pbus = pbus->parent) { + handle = acpi_pci_get_bridge_handle(pbus); + if (handle) + break; + } + } if (handle) { acpi_status status; diff --git a/drivers/xen/pcpu.c b/drivers/xen/pcpu.c index 0aac403d53fd..49e88f2ce7a1 100644 --- a/drivers/xen/pcpu.c +++ b/drivers/xen/pcpu.c @@ -132,6 +132,33 @@ static ssize_t __ref store_online(struct device *dev, } static DEVICE_ATTR(online, S_IRUGO | S_IWUSR, show_online, store_online); +static struct attribute *pcpu_dev_attrs[] = { + &dev_attr_online.attr, + NULL +}; + +static umode_t pcpu_dev_is_visible(struct kobject *kobj, + struct attribute *attr, int idx) +{ + struct device *dev = kobj_to_dev(kobj); + /* + * Xen never offline cpu0 due to several restrictions + * and assumptions. This basically doesn't add a sys control + * to user, one cannot attempt to offline BSP. + */ + return dev->id ? attr->mode : 0; +} + +static const struct attribute_group pcpu_dev_group = { + .attrs = pcpu_dev_attrs, + .is_visible = pcpu_dev_is_visible, +}; + +static const struct attribute_group *pcpu_dev_groups[] = { + &pcpu_dev_group, + NULL +}; + static bool xen_pcpu_online(uint32_t flags) { return !!(flags & XEN_PCPU_FLAGS_ONLINE); @@ -181,9 +208,6 @@ static void unregister_and_remove_pcpu(struct pcpu *pcpu) return; dev = &pcpu->dev; - if (dev->id) - device_remove_file(dev, &dev_attr_online); - /* pcpu remove would be implicitly done */ device_unregister(dev); } @@ -200,6 +224,7 @@ static int register_pcpu(struct pcpu *pcpu) dev->bus = &xen_pcpu_subsys; dev->id = pcpu->cpu_id; dev->release = pcpu_release; + dev->groups = pcpu_dev_groups; err = device_register(dev); if (err) { @@ -207,19 +232,6 @@ static int register_pcpu(struct pcpu *pcpu) return err; } - /* - * Xen never offline cpu0 due to several restrictions - * and assumptions. This basically doesn't add a sys control - * to user, one cannot attempt to offline BSP. - */ - if (dev->id) { - err = device_create_file(dev, &dev_attr_online); - if (err) { - device_unregister(dev); - return err; - } - } - return 0; } diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c index 59ac71c4a043..5a296161d843 100644 --- a/drivers/xen/privcmd.c +++ b/drivers/xen/privcmd.c @@ -159,6 +159,40 @@ static int traverse_pages(unsigned nelem, size_t size, return ret; } +/* + * Similar to traverse_pages, but use each page as a "block" of + * data to be processed as one unit. + */ +static int traverse_pages_block(unsigned nelem, size_t size, + struct list_head *pos, + int (*fn)(void *data, int nr, void *state), + void *state) +{ + void *pagedata; + unsigned pageidx; + int ret = 0; + + BUG_ON(size > PAGE_SIZE); + + pageidx = PAGE_SIZE; + + while (nelem) { + int nr = (PAGE_SIZE/size); + struct page *page; + if (nr > nelem) + nr = nelem; + pos = pos->next; + page = list_entry(pos, struct page, lru); + pagedata = page_address(page); + ret = (*fn)(pagedata, nr, state); + if (ret) + break; + nelem -= nr; + } + + return ret; +} + struct mmap_mfn_state { unsigned long va; struct vm_area_struct *vma; @@ -274,39 +308,25 @@ struct mmap_batch_state { /* auto translated dom0 note: if domU being created is PV, then mfn is * mfn(addr on bus). If it's auto xlated, then mfn is pfn (input to HAP). */ -static int mmap_batch_fn(void *data, void *state) +static int mmap_batch_fn(void *data, int nr, void *state) { xen_pfn_t *mfnp = data; struct mmap_batch_state *st = state; struct vm_area_struct *vma = st->vma; struct page **pages = vma->vm_private_data; - struct page *cur_page = NULL; + struct page **cur_pages = NULL; int ret; if (xen_feature(XENFEAT_auto_translated_physmap)) - cur_page = pages[st->index++]; + cur_pages = &pages[st->index]; - ret = xen_remap_domain_mfn_range(st->vma, st->va & PAGE_MASK, *mfnp, 1, - st->vma->vm_page_prot, st->domain, - &cur_page); + BUG_ON(nr < 0); + ret = xen_remap_domain_mfn_array(st->vma, st->va & PAGE_MASK, mfnp, nr, + (int *)mfnp, st->vma->vm_page_prot, + st->domain, cur_pages); - /* Store error code for second pass. */ - if (st->version == 1) { - if (ret < 0) { - /* - * V1 encodes the error codes in the 32bit top nibble of the - * mfn (with its known limitations vis-a-vis 64 bit callers). - */ - *mfnp |= (ret == -ENOENT) ? - PRIVCMD_MMAPBATCH_PAGED_ERROR : - PRIVCMD_MMAPBATCH_MFN_ERROR; - } - } else { /* st->version == 2 */ - *((int *) mfnp) = ret; - } - - /* And see if it affects the global_error. */ - if (ret < 0) { + /* Adjust the global_error? */ + if (ret != nr) { if (ret == -ENOENT) st->global_error = -ENOENT; else { @@ -315,23 +335,35 @@ static int mmap_batch_fn(void *data, void *state) st->global_error = 1; } } - st->va += PAGE_SIZE; + st->va += PAGE_SIZE * nr; + st->index += nr; return 0; } -static int mmap_return_errors(void *data, void *state) +static int mmap_return_error(int err, struct mmap_batch_state *st) { - struct mmap_batch_state *st = state; + int ret; if (st->version == 1) { - xen_pfn_t mfnp = *((xen_pfn_t *) data); - if (mfnp & PRIVCMD_MMAPBATCH_MFN_ERROR) - return __put_user(mfnp, st->user_mfn++); - else + if (err) { + xen_pfn_t mfn; + + ret = get_user(mfn, st->user_mfn); + if (ret < 0) + return ret; + /* + * V1 encodes the error codes in the 32bit top + * nibble of the mfn (with its known + * limitations vis-a-vis 64 bit callers). + */ + mfn |= (err == -ENOENT) ? + PRIVCMD_MMAPBATCH_PAGED_ERROR : + PRIVCMD_MMAPBATCH_MFN_ERROR; + return __put_user(mfn, st->user_mfn++); + } else st->user_mfn++; } else { /* st->version == 2 */ - int err = *((int *) data); if (err) return __put_user(err, st->user_err++); else @@ -341,6 +373,21 @@ static int mmap_return_errors(void *data, void *state) return 0; } +static int mmap_return_errors(void *data, int nr, void *state) +{ + struct mmap_batch_state *st = state; + int *errs = data; + int i; + int ret; + + for (i = 0; i < nr; i++) { + ret = mmap_return_error(errs[i], st); + if (ret < 0) + return ret; + } + return 0; +} + /* Allocate pfns that are then mapped with gmfns from foreign domid. Update * the vma with the page info to use later. * Returns: 0 if success, otherwise -errno @@ -472,8 +519,8 @@ static long privcmd_ioctl_mmap_batch(void __user *udata, int version) state.version = version; /* mmap_batch_fn guarantees ret == 0 */ - BUG_ON(traverse_pages(m.num, sizeof(xen_pfn_t), - &pagelist, mmap_batch_fn, &state)); + BUG_ON(traverse_pages_block(m.num, sizeof(xen_pfn_t), + &pagelist, mmap_batch_fn, &state)); up_write(&mm->mmap_sem); @@ -481,8 +528,8 @@ static long privcmd_ioctl_mmap_batch(void __user *udata, int version) /* Write back errors in second pass. */ state.user_mfn = (xen_pfn_t *)m.arr; state.user_err = m.err; - ret = traverse_pages(m.num, sizeof(xen_pfn_t), - &pagelist, mmap_return_errors, &state); + ret = traverse_pages_block(m.num, sizeof(xen_pfn_t), + &pagelist, mmap_return_errors, &state); } else ret = 0; diff --git a/drivers/xen/xen-balloon.c b/drivers/xen/xen-balloon.c index e555845d61fa..39e7ef8d3957 100644 --- a/drivers/xen/xen-balloon.c +++ b/drivers/xen/xen-balloon.c @@ -193,13 +193,18 @@ static DEVICE_ATTR(target, S_IRUGO | S_IWUSR, show_target, store_target); -static struct device_attribute *balloon_attrs[] = { - &dev_attr_target_kb, - &dev_attr_target, - &dev_attr_schedule_delay.attr, - &dev_attr_max_schedule_delay.attr, - &dev_attr_retry_count.attr, - &dev_attr_max_retry_count.attr +static struct attribute *balloon_attrs[] = { + &dev_attr_target_kb.attr, + &dev_attr_target.attr, + &dev_attr_schedule_delay.attr.attr, + &dev_attr_max_schedule_delay.attr.attr, + &dev_attr_retry_count.attr.attr, + &dev_attr_max_retry_count.attr.attr, + NULL +}; + +static const struct attribute_group balloon_group = { + .attrs = balloon_attrs }; static struct attribute *balloon_info_attrs[] = { @@ -214,6 +219,12 @@ static const struct attribute_group balloon_info_group = { .attrs = balloon_info_attrs }; +static const struct attribute_group *balloon_groups[] = { + &balloon_group, + &balloon_info_group, + NULL +}; + static struct bus_type balloon_subsys = { .name = BALLOON_CLASS_NAME, .dev_name = BALLOON_CLASS_NAME, @@ -221,7 +232,7 @@ static struct bus_type balloon_subsys = { static int register_balloon(struct device *dev) { - int i, error; + int error; error = subsys_system_register(&balloon_subsys, NULL); if (error) @@ -229,6 +240,7 @@ static int register_balloon(struct device *dev) dev->id = 0; dev->bus = &balloon_subsys; + dev->groups = balloon_groups; error = device_register(dev); if (error) { @@ -236,24 +248,7 @@ static int register_balloon(struct device *dev) return error; } - for (i = 0; i < ARRAY_SIZE(balloon_attrs); i++) { - error = device_create_file(dev, balloon_attrs[i]); - if (error) - goto fail; - } - - error = sysfs_create_group(&dev->kobj, &balloon_info_group); - if (error) - goto fail; - return 0; - - fail: - while (--i >= 0) - device_remove_file(dev, balloon_attrs[i]); - device_unregister(dev); - bus_unregister(&balloon_subsys); - return error; } MODULE_LICENSE("GPL"); diff --git a/drivers/xen/xen-pciback/conf_space_header.c b/drivers/xen/xen-pciback/conf_space_header.c index 2d7369391472..c2260a0456c9 100644 --- a/drivers/xen/xen-pciback/conf_space_header.c +++ b/drivers/xen/xen-pciback/conf_space_header.c @@ -88,9 +88,15 @@ static int command_write(struct pci_dev *dev, int offset, u16 value, void *data) printk(KERN_DEBUG DRV_NAME ": %s: set bus master\n", pci_name(dev)); pci_set_master(dev); + } else if (dev->is_busmaster && !is_master_cmd(value)) { + if (unlikely(verbose_request)) + printk(KERN_DEBUG DRV_NAME ": %s: clear bus master\n", + pci_name(dev)); + pci_clear_master(dev); } - if (value & PCI_COMMAND_INVALIDATE) { + if (!(cmd->val & PCI_COMMAND_INVALIDATE) && + (value & PCI_COMMAND_INVALIDATE)) { if (unlikely(verbose_request)) printk(KERN_DEBUG DRV_NAME ": %s: enable memory-write-invalidate\n", @@ -101,6 +107,13 @@ static int command_write(struct pci_dev *dev, int offset, u16 value, void *data) pci_name(dev), err); value &= ~PCI_COMMAND_INVALIDATE; } + } else if ((cmd->val & PCI_COMMAND_INVALIDATE) && + !(value & PCI_COMMAND_INVALIDATE)) { + if (unlikely(verbose_request)) + printk(KERN_DEBUG + DRV_NAME ": %s: disable memory-write-invalidate\n", + pci_name(dev)); + pci_clear_mwi(dev); } cmd->val = value; diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c index cc3cbb4435f8..258b7c325649 100644 --- a/drivers/xen/xen-pciback/pci_stub.c +++ b/drivers/xen/xen-pciback/pci_stub.c @@ -118,7 +118,7 @@ static void pcistub_device_release(struct kref *kref) int err = HYPERVISOR_physdev_op(PHYSDEVOP_release_msix, &ppdev); - if (err) + if (err && err != -ENOSYS) dev_warn(&dev->dev, "MSI-X release failed (%d)\n", err); } @@ -402,7 +402,7 @@ static int pcistub_init_device(struct pci_dev *dev) }; err = HYPERVISOR_physdev_op(PHYSDEVOP_prepare_msix, &ppdev); - if (err) + if (err && err != -ENOSYS) dev_err(&dev->dev, "MSI-X preparation failed (%d)\n", err); } diff --git a/drivers/xen/xen-pciback/xenbus.c b/drivers/xen/xen-pciback/xenbus.c index fe17c80ff4b7..98bc345f296e 100644 --- a/drivers/xen/xen-pciback/xenbus.c +++ b/drivers/xen/xen-pciback/xenbus.c @@ -113,7 +113,7 @@ static int xen_pcibk_do_attach(struct xen_pcibk_device *pdev, int gnt_ref, "Attaching to frontend resources - gnt_ref=%d evtchn=%d\n", gnt_ref, remote_evtchn); - err = xenbus_map_ring_valloc(pdev->xdev, gnt_ref, &vaddr); + err = xenbus_map_ring_valloc(pdev->xdev, &gnt_ref, 1, &vaddr); if (err < 0) { xenbus_dev_fatal(pdev->xdev, err, "Error mapping other domain page in ours."); diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c index 42bd55a6c237..b7f51504f85a 100644 --- a/drivers/xen/xen-scsiback.c +++ b/drivers/xen/xen-scsiback.c @@ -31,6 +31,8 @@ * IN THE SOFTWARE. */ +#define pr_fmt(fmt) "xen-pvscsi: " fmt + #include <stdarg.h> #include <linux/module.h> @@ -69,9 +71,6 @@ #include <xen/interface/grant_table.h> #include <xen/interface/io/vscsiif.h> -#define DPRINTK(_f, _a...) \ - pr_debug("(file=%s, line=%d) " _f, __FILE__ , __LINE__ , ## _a) - #define VSCSI_VERSION "v0.1" #define VSCSI_NAMELEN 32 @@ -205,8 +204,7 @@ static LIST_HEAD(scsiback_free_pages); static DEFINE_MUTEX(scsiback_mutex); static LIST_HEAD(scsiback_list); -/* Local pointer to allocated TCM configfs fabric module */ -static struct target_fabric_configfs *scsiback_fabric_configfs; +static const struct target_core_fabric_ops scsiback_ops; static void scsiback_get(struct vscsibk_info *info) { @@ -271,7 +269,7 @@ static void scsiback_print_status(char *sense_buffer, int errors, { struct scsiback_tpg *tpg = pending_req->v2p->tpg; - pr_err("xen-pvscsi[%s:%d] cmnd[0]=%02x -> st=%02x msg=%02x host=%02x drv=%02x\n", + pr_err("[%s:%d] cmnd[0]=%02x -> st=%02x msg=%02x host=%02x drv=%02x\n", tpg->tport->tport_name, pending_req->v2p->lun, pending_req->cmnd[0], status_byte(errors), msg_byte(errors), host_byte(errors), driver_byte(errors)); @@ -427,7 +425,7 @@ static int scsiback_gnttab_data_map_batch(struct gnttab_map_grant_ref *map, BUG_ON(err); for (i = 0; i < cnt; i++) { if (unlikely(map[i].status != GNTST_okay)) { - pr_err("xen-pvscsi: invalid buffer -- could not remap it\n"); + pr_err("invalid buffer -- could not remap it\n"); map[i].handle = SCSIBACK_INVALID_HANDLE; err = -ENOMEM; } else { @@ -449,7 +447,7 @@ static int scsiback_gnttab_data_map_list(struct vscsibk_pend *pending_req, for (i = 0; i < cnt; i++) { if (get_free_page(pg + mapcount)) { put_free_pages(pg, mapcount); - pr_err("xen-pvscsi: no grant page\n"); + pr_err("no grant page\n"); return -ENOMEM; } gnttab_set_map_op(&map[mapcount], vaddr_page(pg[mapcount]), @@ -492,7 +490,7 @@ static int scsiback_gnttab_data_map(struct vscsiif_request *ring_req, return 0; if (nr_segments > VSCSIIF_SG_TABLESIZE) { - DPRINTK("xen-pvscsi: invalid parameter nr_seg = %d\n", + pr_debug("invalid parameter nr_seg = %d\n", ring_req->nr_segments); return -EINVAL; } @@ -516,13 +514,12 @@ static int scsiback_gnttab_data_map(struct vscsiif_request *ring_req, nr_segments += n_segs; } if (nr_segments > SG_ALL) { - DPRINTK("xen-pvscsi: invalid nr_seg = %d\n", - nr_segments); + pr_debug("invalid nr_seg = %d\n", nr_segments); return -EINVAL; } } - /* free of (sgl) in fast_flush_area()*/ + /* free of (sgl) in fast_flush_area() */ pending_req->sgl = kmalloc_array(nr_segments, sizeof(struct scatterlist), GFP_KERNEL); if (!pending_req->sgl) @@ -679,7 +676,8 @@ static int prepare_pending_reqs(struct vscsibk_info *info, v2p = scsiback_do_translation(info, &vir); if (!v2p) { pending_req->v2p = NULL; - DPRINTK("xen-pvscsi: doesn't exist.\n"); + pr_debug("the v2p of (chn:%d, tgt:%d, lun:%d) doesn't exist.\n", + vir.chn, vir.tgt, vir.lun); return -ENODEV; } pending_req->v2p = v2p; @@ -690,14 +688,14 @@ static int prepare_pending_reqs(struct vscsibk_info *info, (pending_req->sc_data_direction != DMA_TO_DEVICE) && (pending_req->sc_data_direction != DMA_FROM_DEVICE) && (pending_req->sc_data_direction != DMA_NONE)) { - DPRINTK("xen-pvscsi: invalid parameter data_dir = %d\n", + pr_debug("invalid parameter data_dir = %d\n", pending_req->sc_data_direction); return -EINVAL; } pending_req->cmd_len = ring_req->cmd_len; if (pending_req->cmd_len > VSCSIIF_MAX_COMMAND_SIZE) { - DPRINTK("xen-pvscsi: invalid parameter cmd_len = %d\n", + pr_debug("invalid parameter cmd_len = %d\n", pending_req->cmd_len); return -EINVAL; } @@ -721,7 +719,7 @@ static int scsiback_do_cmd_fn(struct vscsibk_info *info) if (RING_REQUEST_PROD_OVERFLOW(ring, rp)) { rc = ring->rsp_prod_pvt; - pr_warn("xen-pvscsi: Dom%d provided bogus ring requests (%#x - %#x = %u). Halting ring processing\n", + pr_warn("Dom%d provided bogus ring requests (%#x - %#x = %u). Halting ring processing\n", info->domid, rp, rc, rp - rc); info->ring_error = 1; return 0; @@ -772,7 +770,7 @@ static int scsiback_do_cmd_fn(struct vscsibk_info *info) scsiback_device_action(pending_req, TMR_LUN_RESET, 0); break; default: - pr_err_ratelimited("xen-pvscsi: invalid request\n"); + pr_err_ratelimited("invalid request\n"); scsiback_do_resp_with_sense(NULL, DRIVER_ERROR << 24, 0, pending_req); kmem_cache_free(scsiback_cachep, pending_req); @@ -810,7 +808,7 @@ static int scsiback_init_sring(struct vscsibk_info *info, grant_ref_t ring_ref, if (info->irq) return -1; - err = xenbus_map_ring_valloc(info->dev, ring_ref, &area); + err = xenbus_map_ring_valloc(info->dev, &ring_ref, 1, &area); if (err) return err; @@ -874,14 +872,13 @@ static int scsiback_add_translation_entry(struct vscsibk_info *info, lunp = strrchr(phy, ':'); if (!lunp) { - pr_err("xen-pvscsi: illegal format of physical device %s\n", - phy); + pr_err("illegal format of physical device %s\n", phy); return -EINVAL; } *lunp = 0; lunp++; if (kstrtouint(lunp, 10, &lun) || lun >= TRANSPORT_MAX_LUNS_PER_TPG) { - pr_err("xen-pvscsi: lun number not valid: %s\n", lunp); + pr_err("lun number not valid: %s\n", lunp); return -EINVAL; } @@ -909,7 +906,7 @@ static int scsiback_add_translation_entry(struct vscsibk_info *info, mutex_unlock(&scsiback_mutex); if (!tpg) { - pr_err("xen-pvscsi: %s:%d %s\n", phy, lun, error); + pr_err("%s:%d %s\n", phy, lun, error); return -ENODEV; } @@ -926,7 +923,7 @@ static int scsiback_add_translation_entry(struct vscsibk_info *info, if ((entry->v.chn == v->chn) && (entry->v.tgt == v->tgt) && (entry->v.lun == v->lun)) { - pr_warn("xen-pvscsi: Virtual ID is already used. Assignment was not performed.\n"); + pr_warn("Virtual ID is already used. Assignment was not performed.\n"); err = -EEXIST; goto out; } @@ -992,15 +989,15 @@ found: } static void scsiback_do_add_lun(struct vscsibk_info *info, const char *state, - char *phy, struct ids_tuple *vir) + char *phy, struct ids_tuple *vir, int try) { if (!scsiback_add_translation_entry(info, phy, vir)) { if (xenbus_printf(XBT_NIL, info->dev->nodename, state, "%d", XenbusStateInitialised)) { - pr_err("xen-pvscsi: xenbus_printf error %s\n", state); + pr_err("xenbus_printf error %s\n", state); scsiback_del_translation_entry(info, vir); } - } else { + } else if (!try) { xenbus_printf(XBT_NIL, info->dev->nodename, state, "%d", XenbusStateClosed); } @@ -1012,7 +1009,7 @@ static void scsiback_do_del_lun(struct vscsibk_info *info, const char *state, if (!scsiback_del_translation_entry(info, vir)) { if (xenbus_printf(XBT_NIL, info->dev->nodename, state, "%d", XenbusStateClosed)) - pr_err("xen-pvscsi: xenbus_printf error %s\n", state); + pr_err("xenbus_printf error %s\n", state); } } @@ -1060,10 +1057,19 @@ static void scsiback_do_1lun_hotplug(struct vscsibk_info *info, int op, switch (op) { case VSCSIBACK_OP_ADD_OR_DEL_LUN: - if (device_state == XenbusStateInitialising) - scsiback_do_add_lun(info, state, phy, &vir); - if (device_state == XenbusStateClosing) + switch (device_state) { + case XenbusStateInitialising: + scsiback_do_add_lun(info, state, phy, &vir, 0); + break; + case XenbusStateConnected: + scsiback_do_add_lun(info, state, phy, &vir, 1); + break; + case XenbusStateClosing: scsiback_do_del_lun(info, state, &vir); + break; + default: + break; + } break; case VSCSIBACK_OP_UPDATEDEV_STATE: @@ -1071,15 +1077,14 @@ static void scsiback_do_1lun_hotplug(struct vscsibk_info *info, int op, /* modify vscsi-devs/dev-x/state */ if (xenbus_printf(XBT_NIL, dev->nodename, state, "%d", XenbusStateConnected)) { - pr_err("xen-pvscsi: xenbus_printf error %s\n", - str); + pr_err("xenbus_printf error %s\n", str); scsiback_del_translation_entry(info, &vir); xenbus_printf(XBT_NIL, dev->nodename, state, "%d", XenbusStateClosed); } } break; - /*When it is necessary, processing is added here.*/ + /* When it is necessary, processing is added here. */ default: break; } @@ -1196,7 +1201,7 @@ static int scsiback_probe(struct xenbus_device *dev, struct vscsibk_info *info = kzalloc(sizeof(struct vscsibk_info), GFP_KERNEL); - DPRINTK("%p %d\n", dev, dev->otherend_id); + pr_debug("%s %p %d\n", __func__, dev, dev->otherend_id); if (!info) { xenbus_dev_fatal(dev, -ENOMEM, "allocating backend structure"); @@ -1227,7 +1232,7 @@ static int scsiback_probe(struct xenbus_device *dev, return 0; fail: - pr_warn("xen-pvscsi: %s failed\n", __func__); + pr_warn("%s failed\n", __func__); scsiback_remove(dev); return err; @@ -1432,7 +1437,7 @@ check_len: } snprintf(&tport->tport_name[0], VSCSI_NAMELEN, "%s", &name[off]); - pr_debug("xen-pvscsi: Allocated emulated Target %s Address: %s\n", + pr_debug("Allocated emulated Target %s Address: %s\n", scsiback_dump_proto_id(tport), name); return &tport->tport_wwn; @@ -1443,7 +1448,7 @@ static void scsiback_drop_tport(struct se_wwn *wwn) struct scsiback_tport *tport = container_of(wwn, struct scsiback_tport, tport_wwn); - pr_debug("xen-pvscsi: Deallocating emulated Target %s Address: %s\n", + pr_debug("Deallocating emulated Target %s Address: %s\n", scsiback_dump_proto_id(tport), tport->tport_name); kfree(tport); @@ -1470,8 +1475,8 @@ static u32 scsiback_tpg_get_inst_index(struct se_portal_group *se_tpg) static int scsiback_check_stop_free(struct se_cmd *se_cmd) { /* - * Do not release struct se_cmd's containing a valid TMR - * pointer. These will be released directly in scsiback_device_action() + * Do not release struct se_cmd's containing a valid TMR pointer. + * These will be released directly in scsiback_device_action() * with transport_generic_free_cmd(). */ if (se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB) @@ -1637,7 +1642,7 @@ static int scsiback_make_nexus(struct scsiback_tpg *tpg, return -ENOMEM; } /* - * Initialize the struct se_session pointer + * Initialize the struct se_session pointer */ tv_nexus->tvn_se_sess = transport_init_session(TARGET_PROT_NORMAL); if (IS_ERR(tv_nexus->tvn_se_sess)) { @@ -1705,7 +1710,7 @@ static int scsiback_drop_nexus(struct scsiback_tpg *tpg) return -EBUSY; } - pr_debug("xen-pvscsi: Removing I_T Nexus to emulated %s Initiator Port: %s\n", + pr_debug("Removing I_T Nexus to emulated %s Initiator Port: %s\n", scsiback_dump_proto_id(tpg->tport), tv_nexus->tvn_se_sess->se_node_acl->initiatorname); @@ -1751,7 +1756,7 @@ static ssize_t scsiback_tpg_store_nexus(struct se_portal_group *se_tpg, unsigned char i_port[VSCSI_NAMELEN], *ptr, *port_ptr; int ret; /* - * Shutdown the active I_T nexus if 'NULL' is passed.. + * Shutdown the active I_T nexus if 'NULL' is passed. */ if (!strncmp(page, "NULL", 4)) { ret = scsiback_drop_nexus(tpg); @@ -1896,7 +1901,7 @@ scsiback_make_tpg(struct se_wwn *wwn, tpg->tport = tport; tpg->tport_tpgt = tpgt; - ret = core_tpg_register(&scsiback_fabric_configfs->tf_ops, wwn, + ret = core_tpg_register(&scsiback_ops, wwn, &tpg->se_tpg, tpg, TRANSPORT_TPG_TYPE_NORMAL); if (ret < 0) { kfree(tpg); @@ -1922,7 +1927,7 @@ static void scsiback_drop_tpg(struct se_portal_group *se_tpg) */ scsiback_drop_nexus(tpg); /* - * Deregister the se_tpg from TCM.. + * Deregister the se_tpg from TCM. */ core_tpg_deregister(se_tpg); kfree(tpg); @@ -1938,7 +1943,9 @@ static int scsiback_check_false(struct se_portal_group *se_tpg) return 0; } -static struct target_core_fabric_ops scsiback_ops = { +static const struct target_core_fabric_ops scsiback_ops = { + .module = THIS_MODULE, + .name = "xen-pvscsi", .get_fabric_name = scsiback_get_fabric_name, .get_fabric_proto_ident = scsiback_get_fabric_proto_ident, .tpg_get_wwn = scsiback_get_fabric_wwn, @@ -1985,62 +1992,10 @@ static struct target_core_fabric_ops scsiback_ops = { .fabric_make_nodeacl = scsiback_make_nodeacl, .fabric_drop_nodeacl = scsiback_drop_nodeacl, #endif -}; - -static int scsiback_register_configfs(void) -{ - struct target_fabric_configfs *fabric; - int ret; - - pr_debug("xen-pvscsi: fabric module %s on %s/%s on "UTS_RELEASE"\n", - VSCSI_VERSION, utsname()->sysname, utsname()->machine); - /* - * Register the top level struct config_item_type with TCM core - */ - fabric = target_fabric_configfs_init(THIS_MODULE, "xen-pvscsi"); - if (IS_ERR(fabric)) - return PTR_ERR(fabric); - - /* - * Setup fabric->tf_ops from our local scsiback_ops - */ - fabric->tf_ops = scsiback_ops; - /* - * Setup default attribute lists for various fabric->tf_cit_tmpl - */ - fabric->tf_cit_tmpl.tfc_wwn_cit.ct_attrs = scsiback_wwn_attrs; - fabric->tf_cit_tmpl.tfc_tpg_base_cit.ct_attrs = scsiback_tpg_attrs; - fabric->tf_cit_tmpl.tfc_tpg_attrib_cit.ct_attrs = NULL; - fabric->tf_cit_tmpl.tfc_tpg_param_cit.ct_attrs = scsiback_param_attrs; - fabric->tf_cit_tmpl.tfc_tpg_np_base_cit.ct_attrs = NULL; - fabric->tf_cit_tmpl.tfc_tpg_nacl_base_cit.ct_attrs = NULL; - fabric->tf_cit_tmpl.tfc_tpg_nacl_attrib_cit.ct_attrs = NULL; - fabric->tf_cit_tmpl.tfc_tpg_nacl_auth_cit.ct_attrs = NULL; - fabric->tf_cit_tmpl.tfc_tpg_nacl_param_cit.ct_attrs = NULL; - /* - * Register the fabric for use within TCM - */ - ret = target_fabric_configfs_register(fabric); - if (ret < 0) { - target_fabric_configfs_free(fabric); - return ret; - } - /* - * Setup our local pointer to *fabric - */ - scsiback_fabric_configfs = fabric; - pr_debug("xen-pvscsi: Set fabric -> scsiback_fabric_configfs\n"); - return 0; -}; -static void scsiback_deregister_configfs(void) -{ - if (!scsiback_fabric_configfs) - return; - - target_fabric_configfs_deregister(scsiback_fabric_configfs); - scsiback_fabric_configfs = NULL; - pr_debug("xen-pvscsi: Cleared scsiback_fabric_configfs\n"); + .tfc_wwn_attrs = scsiback_wwn_attrs, + .tfc_tpg_base_attrs = scsiback_tpg_attrs, + .tfc_tpg_param_attrs = scsiback_param_attrs, }; static const struct xenbus_device_id scsiback_ids[] = { @@ -2072,6 +2027,9 @@ static int __init scsiback_init(void) if (!xen_domain()) return -ENODEV; + pr_debug("xen-pvscsi: fabric module %s on %s/%s on "UTS_RELEASE"\n", + VSCSI_VERSION, utsname()->sysname, utsname()->machine); + scsiback_cachep = kmem_cache_create("vscsiif_cache", sizeof(struct vscsibk_pend), 0, 0, scsiback_init_pend); if (!scsiback_cachep) @@ -2081,7 +2039,7 @@ static int __init scsiback_init(void) if (ret) goto out_cache_destroy; - ret = scsiback_register_configfs(); + ret = target_register_template(&scsiback_ops); if (ret) goto out_unregister_xenbus; @@ -2091,7 +2049,7 @@ out_unregister_xenbus: xenbus_unregister_driver(&scsiback_driver); out_cache_destroy: kmem_cache_destroy(scsiback_cachep); - pr_err("xen-pvscsi: %s: error %d\n", __func__, ret); + pr_err("%s: error %d\n", __func__, ret); return ret; |
