From f0a7f4e7ce92fc645af65c69fa77278f0649ee2e Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Tue, 1 Nov 2011 10:49:46 -0400 Subject: [PATCH] xen-scsi[front|back]: Fix warnings and bugs. The porting from 2.6.32 kernel up to 3.0 requires: - Using XenBus interface API calls to setup pages - Using the granttab calls correctly - Using kzalloc for request pages. - Removed #if LINUX_VERSION_CODE... And also took advantage to clean up some whitespace issues. Signed-off-by: Konrad Rzeszutek Wilk --- drivers/scsi/xen-scsiback/common.h | 14 ++--- drivers/scsi/xen-scsiback/emulate.c | 29 +++++----- drivers/scsi/xen-scsiback/interface.c | 76 ++++++-------------------- drivers/scsi/xen-scsiback/scsiback.c | 47 ++++++++++------ drivers/scsi/xen-scsiback/translate.c | 10 ++-- drivers/scsi/xen-scsiback/xenbus.c | 28 ++++------ drivers/scsi/xen-scsifront/common.h | 14 ++--- drivers/scsi/xen-scsifront/scsifront.c | 18 ++---- drivers/scsi/xen-scsifront/xenbus.c | 48 +++++++--------- include/xen/interface/io/vscsiif.h | 10 ++-- 10 files changed, 120 insertions(+), 174 deletions(-) diff --git a/drivers/scsi/xen-scsiback/common.h b/drivers/scsi/xen-scsiback/common.h index 92e5d86689be..dafa79e2b752 100644 --- a/drivers/scsi/xen-scsiback/common.h +++ b/drivers/scsi/xen-scsiback/common.h @@ -8,17 +8,17 @@ * as published by the Free Software Foundation; or, when distributed * separately from the Linux kernel or incorporated into other * software packages, subject to the following license: - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this source file (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, modify, * merge, publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -92,9 +92,7 @@ struct vscsibk_info { int feature; struct vscsiif_back_ring ring; - struct vm_struct *ring_area; - grant_handle_t shmem_handle; - grant_ref_t shmem_ref; + void *ring_area; spinlock_t ring_lock; atomic_t nr_unreplied_reqs; @@ -116,7 +114,7 @@ typedef struct { struct scsi_device *sdev; uint16_t rqid; - + uint16_t v_chn, v_tgt; uint8_t nr_segments; @@ -125,7 +123,7 @@ typedef struct { uint8_t sc_data_direction; uint16_t timeout_per_command; - + uint32_t request_bufflen; struct scatterlist *sgl; grant_ref_t gref[VSCSIIF_SG_TABLESIZE]; diff --git a/drivers/scsi/xen-scsiback/emulate.c b/drivers/scsi/xen-scsiback/emulate.c index a74bc0cc66ed..2b35e2a0776d 100644 --- a/drivers/scsi/xen-scsiback/emulate.c +++ b/drivers/scsi/xen-scsiback/emulate.c @@ -8,17 +8,17 @@ * as published by the Free Software Foundation; or, when distributed * separately from the Linux kernel or incorporated into other * software packages, subject to the following license: - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this source file (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, modify, * merge, publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -139,7 +139,7 @@ static int __copy_to_sg(struct scatterlist *sgl, unsigned int nr_sg, if (from_rest == 0) { return 0; } - + from += copy_size; } @@ -147,7 +147,7 @@ static int __copy_to_sg(struct scatterlist *sgl, unsigned int nr_sg, __FUNCTION__); return -ENOMEM; } - +#if 0 static int __copy_from_sg(struct scatterlist *sgl, unsigned int nr_sg, void *buf, unsigned int buflen) { @@ -186,7 +186,7 @@ static int __copy_from_sg(struct scatterlist *sgl, unsigned int nr_sg, return 0; } - +#endif static int __nr_luns_under_host(struct vscsibk_info *info) { struct v2p_entry *entry; @@ -216,7 +216,7 @@ static void __report_luns(pending_req_t *pending_req, void *data) unsigned int target = pending_req->v_tgt; unsigned int nr_seg = pending_req->nr_segments; unsigned char *cmd = (unsigned char *)pending_req->cmnd; - + unsigned char *buff = NULL; unsigned char alloc_len; unsigned int alloc_luns = 0; @@ -225,11 +225,11 @@ static void __report_luns(pending_req_t *pending_req, void *data) unsigned int retry_cnt = 0; int select_report = (int)cmd[2]; int i, lun_cnt = 0, lun, upper, err = 0; - + struct v2p_entry *entry; struct list_head *head = &(info->v2p_entry_lists); unsigned long flags; - + struct scsi_lun *one_lun; req_bufflen = cmd[9] + (cmd[8] << 8) + (cmd[7] << 16) + (cmd[6] << 24); @@ -250,7 +250,6 @@ retry: list_for_each_entry(entry, head, l) { if ((entry->v.chn == channel) && (entry->v.tgt == target)) { - /* check overflow */ if (lun_cnt >= alloc_luns) { spin_unlock_irqrestore(&info->v2p_lock, @@ -280,13 +279,13 @@ retry: buff[2] = ((sizeof(struct scsi_lun) * lun_cnt) >> 8) & 0xff; buff[3] = (sizeof(struct scsi_lun) * lun_cnt) & 0xff; - actual_len = lun_cnt * sizeof(struct scsi_lun) + actual_len = lun_cnt * sizeof(struct scsi_lun) + VSCSI_REPORT_LUNS_HEADER; req_bufflen = 0; for (i = 0; i < nr_seg; i++) req_bufflen += pending_req->sgl[i].length; - err = __copy_to_sg(pending_req->sgl, nr_seg, buff, + err = __copy_to_sg(pending_req->sgl, nr_seg, buff, min(req_bufflen, actual_len)); if (err) goto fail; @@ -321,7 +320,7 @@ int __pre_do_emulation(pending_req_t *pending_req, void *data) /* 0: no need for native driver call, so should return immediately. - 1: non emulation or should call native driver + 1: non emulation or should call native driver after modifing the request buffer. */ return !!(bitmap[op_code] & VSCSIIF_NEED_CMD_EXEC); @@ -362,7 +361,7 @@ void scsiback_emulation_init(void) /* Initialize to default state */ for (i = 0; i < VSCSI_MAX_SCSI_OP_CODE; i++) { - bitmap[i] = (VSCSIIF_NEED_EMULATE_REQBUF | + bitmap[i] = (VSCSIIF_NEED_EMULATE_REQBUF | VSCSIIF_NEED_EMULATE_RSPBUF); pre_function[i] = resp_not_supported_cmd; post_function[i] = NULL; @@ -464,7 +463,7 @@ void scsiback_emulation_init(void) Following commands require emulation. */ pre_function[REPORT_LUNS] = __report_luns; - bitmap[REPORT_LUNS] = (VSCSIIF_NEED_EMULATE_REQBUF | + bitmap[REPORT_LUNS] = (VSCSIIF_NEED_EMULATE_REQBUF | VSCSIIF_NEED_EMULATE_RSPBUF); return; diff --git a/drivers/scsi/xen-scsiback/interface.c b/drivers/scsi/xen-scsiback/interface.c index b25e844f032b..663568edf0ba 100644 --- a/drivers/scsi/xen-scsiback/interface.c +++ b/drivers/scsi/xen-scsiback/interface.c @@ -10,17 +10,17 @@ * as published by the Free Software Foundation; or, when distributed * separately from the Linux kernel or incorporated into other * software packages, subject to the following license: - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this source file (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, modify, * merge, publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -59,83 +59,39 @@ struct vscsibk_info *vscsibk_info_alloc(domid_t domid) return info; } -static int map_frontend_page( struct vscsibk_info *info, - unsigned long ring_ref) -{ - struct gnttab_map_grant_ref op; - int err; - - gnttab_set_map_op(&op, (unsigned long)info->ring_area->addr, - GNTMAP_host_map, ring_ref, - info->domid); - - do { - err = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1); - BUG_ON(err); - msleep(10); - } while(op.status == GNTST_eagain); - - if (op.status) { - printk(KERN_ERR "scsiback: Grant table operation failure !\n"); - return op.status; - } - - info->shmem_ref = ring_ref; - info->shmem_handle = op.handle; - - return (GNTST_okay); -} - -static void unmap_frontend_page(struct vscsibk_info *info) -{ - struct gnttab_unmap_grant_ref op; - int err; - - gnttab_set_unmap_op(&op, (unsigned long)info->ring_area->addr, - GNTMAP_host_map, info->shmem_handle); - - err = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1); - BUG_ON(err); - -} - int scsiback_init_sring(struct vscsibk_info *info, unsigned long ring_ref, unsigned int evtchn) { struct vscsiif_sring *sring; int err; + if (!info) + return -ENODEV; + if (info->irq) { printk(KERN_ERR "scsiback: Already connected through?\n"); return -1; } - info->ring_area = alloc_vm_area(PAGE_SIZE); - if (!info) + err = xenbus_map_ring_valloc(info->dev, ring_ref, &info->ring_area); + if (err < 0) return -ENOMEM; - err = map_frontend_page(info, ring_ref); - if (err) - goto free_vm; - - sring = (struct vscsiif_sring *) info->ring_area->addr; + sring = (struct vscsiif_sring *) info->ring_area; BACK_RING_INIT(&info->ring, sring, PAGE_SIZE); err = bind_interdomain_evtchn_to_irqhandler( info->domid, evtchn, scsiback_intr, 0, "vscsiif-backend", info); - if (err < 0) goto unmap_page; - + info->irq = err; return 0; unmap_page: - unmap_frontend_page(info); -free_vm: - free_vm_area(info->ring_area); + xenbus_unmap_ring_vfree(info->dev, info->ring_area); return err; } @@ -147,7 +103,7 @@ void scsiback_disconnect(struct vscsibk_info *info) info->kthread = NULL; } - wait_event(info->waiting_to_free, + wait_event(info->waiting_to_free, atomic_read(&info->nr_unreplied_reqs) == 0); if (info->irq) { @@ -155,10 +111,10 @@ void scsiback_disconnect(struct vscsibk_info *info) info->irq = 0; } - if (info->ring.sring) { - unmap_frontend_page(info); - free_vm_area(info->ring_area); + if (info->ring.sring || info->ring_area) { + xenbus_unmap_ring_vfree(info->dev, info->ring_area); info->ring.sring = NULL; + info->ring_area = NULL; } } @@ -175,7 +131,7 @@ int __init scsiback_interface_init(void) printk(KERN_ERR "scsiback: can't init scsi cache\n"); return -ENOMEM; } - + return 0; } diff --git a/drivers/scsi/xen-scsiback/scsiback.c b/drivers/scsi/xen-scsiback/scsiback.c index d5859156b0fa..a209f87013da 100644 --- a/drivers/scsi/xen-scsiback/scsiback.c +++ b/drivers/scsi/xen-scsiback/scsiback.c @@ -54,7 +54,7 @@ int vscsiif_reqs = VSCSIIF_BACK_MAX_PENDING_REQS; module_param_named(reqs, vscsiif_reqs, int, 0); MODULE_PARM_DESC(reqs, "Number of scsiback requests to allocate"); -static unsigned int log_print_stat = 0; +static unsigned int log_print_stat; module_param(log_print_stat, int, 0644); #define SCSIBACK_INVALID_HANDLE (~0) @@ -259,7 +259,7 @@ static int scsiback_gnttab_data_map(vscsiif_request_t *ring_req, struct gnttab_map_grant_ref map[VSCSIIF_SG_TABLESIZE]; struct vscsibk_info *info = pending_req->info; - int data_dir = (int)pending_req->sc_data_direction; + int data_dir = pending_req->sc_data_direction; unsigned int nr_segments = (unsigned int)pending_req->nr_segments; write = (data_dir == DMA_TO_DEVICE); @@ -281,6 +281,7 @@ static int scsiback_gnttab_data_map(vscsiif_request_t *ring_req, flags = GNTMAP_host_map; if (write) flags |= GNTMAP_readonly; + gnttab_set_map_op(&map[i], vaddr(pending_req, i), flags, ring_req->seg[i].gref, info->domid); @@ -293,7 +294,7 @@ static int scsiback_gnttab_data_map(vscsiif_request_t *ring_req, for(i=0; i < nr_segments; i++) { while(unlikely(map[i].status == GNTST_eagain)) { - msleep(10); + msleep(10); err = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &map[i], 1); @@ -305,7 +306,8 @@ static int scsiback_gnttab_data_map(vscsiif_request_t *ring_req, struct page *pg; if (unlikely(map[i].status != 0)) { - printk(KERN_ERR "scsiback: invalid buffer -- could not remap it\n"); + printk(KERN_ERR "scsiback: invalid buffer -- could not remap it: " \ + "%d/%d, err:%d\n", i, nr_segments, map[i].status); map[i].handle = SCSIBACK_INVALID_HANDLE; err |= 1; } @@ -318,10 +320,6 @@ static int scsiback_gnttab_data_map(vscsiif_request_t *ring_req, pg = pending_pages[vaddr_pagenr(pending_req, i)]; m2p_add_override(PFN_DOWN(map[i].dev_bus_addr), pg, false); -#if 0 - set_phys_to_machine(page_to_pfn(pg), - FOREIGN_FRAME(map[i].dev_bus_addr >> PAGE_SHIFT)); -#endif sg_set_page(sg, pg, ring_req->seg[i].length, ring_req->seg[i].offset); data_len += sg->length; @@ -694,12 +692,16 @@ static int __init scsiback_init(void) if (!pending_reqs || !pending_grant_handles || !pending_pages) goto out_of_memory; - for (i = 0; i < mmap_pages; i++) + for (i = 0; i < mmap_pages; i++) { pending_grant_handles[i] = SCSIBACK_INVALID_HANDLE; - + pending_pages[i] = alloc_page(GFP_KERNEL); + if (pending_pages[i] == NULL) + goto out_of_memory; + } if (scsiback_interface_init() < 0) goto out_of_kmem; + memset(pending_reqs, 0, sizeof(pending_reqs)); INIT_LIST_HEAD(&pending_free); for (i = 0; i < vscsiif_reqs; i++) @@ -717,30 +719,39 @@ out_of_xenbus: out_of_kmem: scsiback_interface_exit(); out_of_memory: + if (pending_pages) { + for (i = 0; i < mmap_pages; i++) { + if (pending_pages[i]) + __free_page(pending_pages[i]); + } + kfree(pending_pages); + } kfree(pending_reqs); kfree(pending_grant_handles); - kfree(pending_pages); printk(KERN_ERR "scsiback: %s: out of memory\n", __FUNCTION__); return -ENOMEM; } -#if 0 + static void __exit scsiback_exit(void) { scsiback_xenbus_unregister(); scsiback_interface_exit(); kfree(pending_reqs); kfree(pending_grant_handles); - kfree(pending_pages); - + if (pending_pages) { + unsigned int i; + unsigned int mmap_pages = vscsiif_reqs * VSCSIIF_SG_TABLESIZE; + for (i = 0; i < mmap_pages; i++) { + if (pending_pages[i]) + __free_page(pending_pages[i]); + } + kfree(pending_pages); + } } -#endif module_init(scsiback_init); - -#if 0 module_exit(scsiback_exit); -#endif MODULE_DESCRIPTION("Xen SCSI backend driver"); MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/scsi/xen-scsiback/translate.c b/drivers/scsi/xen-scsiback/translate.c index 25510c5b11a4..36873cc77fcb 100644 --- a/drivers/scsi/xen-scsiback/translate.c +++ b/drivers/scsi/xen-scsiback/translate.c @@ -8,17 +8,17 @@ * as published by the Free Software Foundation; or, when distributed * separately from the Linux kernel or incorporated into other * software packages, subject to the following license: - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this source file (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, modify, * merge, publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -54,7 +54,7 @@ int scsiback_add_translation_entry(struct vscsibk_info *info, struct v2p_entry *new; struct list_head *head = &(info->v2p_entry_lists); unsigned long flags; - + spin_lock_irqsave(&info->v2p_lock, flags); /* Check double assignment to identical virtual ID */ @@ -80,7 +80,7 @@ int scsiback_add_translation_entry(struct vscsibk_info *info, new->sdev = sdev; list_add_tail(&new->l, head); -out: +out: spin_unlock_irqrestore(&info->v2p_lock, flags); return err; } diff --git a/drivers/scsi/xen-scsiback/xenbus.c b/drivers/scsi/xen-scsiback/xenbus.c index a9544ef54c34..0816c0e41b28 100644 --- a/drivers/scsi/xen-scsiback/xenbus.c +++ b/drivers/scsi/xen-scsiback/xenbus.c @@ -10,17 +10,17 @@ * as published by the Free Software Foundation; or, when distributed * separately from the Linux kernel or incorporated into other * software packages, subject to the following license: - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this source file (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, modify, * merge, publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -60,8 +60,8 @@ static int __vscsiif_name(struct backend_info *be, char *buf) static int scsiback_map(struct backend_info *be) { struct xenbus_device *dev = be->dev; - unsigned long ring_ref; - unsigned int evtchn; + unsigned long ring_ref = 0; + unsigned int evtchn = 0; int err; char name[TASK_COMM_LEN]; @@ -72,7 +72,6 @@ static int scsiback_map(struct backend_info *be) xenbus_dev_fatal(dev, err, "reading %s ring", dev->otherend); return err; } - err = scsiback_init_sring(be->info, ring_ref, evtchn); if (err) return err; @@ -138,7 +137,6 @@ static void scsiback_do_lun_hotplug(struct backend_info *be, int op) return; for (i = 0; i < dir_n; i++) { - /* read status */ snprintf(state_str, sizeof(state_str), "vscsi-devs/%s/state", dir[i]); err = xenbus_scanf(XBT_NIL, dev->nodename, state_str, "%u", @@ -171,19 +169,19 @@ static void scsiback_do_lun_hotplug(struct backend_info *be, int op) if (device_state == XenbusStateInitialising) { sdev = scsiback_get_scsi_device(&phy); if (!sdev) - xenbus_printf(XBT_NIL, dev->nodename, state_str, + xenbus_printf(XBT_NIL, dev->nodename, state_str, "%d", XenbusStateClosed); else { err = scsiback_add_translation_entry(be->info, sdev, &vir); if (!err) { - if (xenbus_printf(XBT_NIL, dev->nodename, state_str, + if (xenbus_printf(XBT_NIL, dev->nodename, state_str, "%d", XenbusStateInitialised)) { printk(KERN_ERR "scsiback: xenbus_printf error %s\n", state_str); scsiback_del_translation_entry(be->info, &vir); } } else { scsi_device_put(sdev); - xenbus_printf(XBT_NIL, dev->nodename, state_str, + xenbus_printf(XBT_NIL, dev->nodename, state_str, "%d", XenbusStateClosed); } } @@ -191,7 +189,7 @@ static void scsiback_do_lun_hotplug(struct backend_info *be, int op) if (device_state == XenbusStateClosing) { if (!scsiback_del_translation_entry(be->info, &vir)) { - if (xenbus_printf(XBT_NIL, dev->nodename, state_str, + if (xenbus_printf(XBT_NIL, dev->nodename, state_str, "%d", XenbusStateClosed)) printk(KERN_ERR "scsiback: xenbus_printf error %s\n", state_str); } @@ -201,11 +199,11 @@ static void scsiback_do_lun_hotplug(struct backend_info *be, int op) case VSCSIBACK_OP_UPDATEDEV_STATE: if (device_state == XenbusStateInitialised) { /* modify vscsi-devs/dev-x/state */ - if (xenbus_printf(XBT_NIL, dev->nodename, state_str, + if (xenbus_printf(XBT_NIL, dev->nodename, state_str, "%d", XenbusStateConnected)) { printk(KERN_ERR "scsiback: xenbus_printf error %s\n", state_str); scsiback_del_translation_entry(be->info, &vir); - xenbus_printf(XBT_NIL, dev->nodename, state_str, + xenbus_printf(XBT_NIL, dev->nodename, state_str, "%d", XenbusStateClosed); } } @@ -306,8 +304,6 @@ static int scsiback_probe(struct xenbus_device *dev, struct backend_info *be = kzalloc(sizeof(struct backend_info), GFP_KERNEL); - DPRINTK("%p %d\n", dev, dev->otherend_id); - if (!be) { xenbus_dev_fatal(dev, -ENOMEM, "allocating backend structure"); @@ -346,7 +342,7 @@ static int scsiback_probe(struct xenbus_device *dev, fail: - printk(KERN_WARNING "scsiback: %s failed\n",__FUNCTION__); + printk(KERN_WARNING "scsiback: %s failed\n",__func__); scsiback_remove(dev); return err; diff --git a/drivers/scsi/xen-scsifront/common.h b/drivers/scsi/xen-scsifront/common.h index 338f45e2157c..cfa1c32208e1 100644 --- a/drivers/scsi/xen-scsifront/common.h +++ b/drivers/scsi/xen-scsifront/common.h @@ -8,17 +8,17 @@ * as published by the Free Software Foundation; or, when distributed * separately from the Linux kernel or incorporated into other * software packages, subject to the following license: - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this source file (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, modify, * merge, publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -77,21 +77,21 @@ struct vscsifrnt_shadow { uint16_t next_free; - + /* command between backend and frontend * VSCSIIF_ACT_SCSI_CDB or VSCSIIF_ACT_SCSI_RESET */ unsigned char act; - + /* do reset function */ wait_queue_head_t wq_reset; /* reset work queue */ int wait_reset; /* reset work queue condition */ int32_t rslt_reset; /* reset response status */ /* (SUCESS or FAILED) */ - /* for DMA_TO_DEVICE(1), DMA_FROM_DEVICE(2), DMA_NONE(3) + /* for DMA_TO_DEVICE(1), DMA_FROM_DEVICE(2), DMA_NONE(3) requests */ unsigned int sc_data_direction; - + /* Number of pieces of scatter-gather */ unsigned int nr_segments; diff --git a/drivers/scsi/xen-scsifront/scsifront.c b/drivers/scsi/xen-scsifront/scsifront.c index 062e7997ba52..2d5e25f52f01 100644 --- a/drivers/scsi/xen-scsifront/scsifront.c +++ b/drivers/scsi/xen-scsifront/scsifront.c @@ -244,11 +244,10 @@ static int map_data_for_request(struct vscsifrnt_info *info, struct scsi_cmnd *sc, vscsiif_request_t *ring_req, uint32_t id) { grant_ref_t gref_head; - struct page *page; int err, ref, ref_cnt = 0; int write = (sc->sc_data_direction == DMA_TO_DEVICE); unsigned int i, nr_pages, off, len, bytes; - unsigned long buffer_pfn; + unsigned long buffer_mfn, buffer_pfn; if (sc->sc_data_direction == DMA_NONE) return 0; @@ -272,12 +271,10 @@ static int map_data_for_request(struct vscsifrnt_info *info, } for_each_sg (sgl, sg, scsi_sg_count(sc), i) { - page = sg_page(sg); off = sg->offset; len = sg->length; - buffer_pfn = page_to_phys(page) >> PAGE_SHIFT; - + buffer_pfn = page_to_pfn(sg_page(sg)); while (len > 0 && data_len > 0) { /* * sg sends a scatterlist that is larger than @@ -290,15 +287,16 @@ static int map_data_for_request(struct vscsifrnt_info *info, ref = gnttab_claim_grant_reference(&gref_head); BUG_ON(ref == -ENOSPC); + buffer_mfn = pfn_to_mfn(buffer_pfn); gnttab_grant_foreign_access_ref(ref, info->dev->otherend_id, - buffer_pfn, write); + buffer_mfn, write); info->shadow[id].gref[ref_cnt] = ref; ring_req->seg[ref_cnt].gref = ref; ring_req->seg[ref_cnt].offset = (uint16_t)off; ring_req->seg[ref_cnt].length = (uint16_t)bytes; - buffer_pfn++; + buffer_pfn ++; len -= bytes; data_len -= bytes; off = 0; @@ -339,7 +337,7 @@ static int scsifront_queuecommand(struct Scsi_Host *h, struct scsi_cmnd *sc) BUG_ON(sc->cmd_len > VSCSIIF_MAX_COMMAND_SIZE); - if ( sc->cmd_len ) + if (sc->cmd_len) memcpy(ring_req->cmnd, sc->cmnd, sc->cmd_len); else memset(ring_req->cmnd, 0, VSCSIIF_MAX_COMMAND_SIZE); @@ -394,9 +392,7 @@ static int scsifront_dev_reset_handler(struct scsi_cmnd *sc) uint16_t rqid; int err; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12) spin_lock_irq(host->host_lock); -#endif ring_req = scsifront_pre_request(info); ring_req->act = VSCSIIF_ACT_SCSI_RESET; @@ -429,9 +425,7 @@ static int scsifront_dev_reset_handler(struct scsi_cmnd *sc) add_id_to_freelist(info, rqid); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12) spin_unlock_irq(host->host_lock); -#endif return (err); } diff --git a/drivers/scsi/xen-scsifront/xenbus.c b/drivers/scsi/xen-scsifront/xenbus.c index aa5f4fad926c..de70c533f2ae 100644 --- a/drivers/scsi/xen-scsifront/xenbus.c +++ b/drivers/scsi/xen-scsifront/xenbus.c @@ -8,17 +8,17 @@ * as published by the Free Software Foundation; or, when distributed * separately from the Linux kernel or incorporated into other * software packages, subject to the following license: - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this source file (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, modify, * merge, publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -27,30 +27,18 @@ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ - #include #include "common.h" -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) - #define DEFAULT_TASK_COMM_LEN 16 -#else - #define DEFAULT_TASK_COMM_LEN TASK_COMM_LEN -#endif - extern struct scsi_host_template scsifront_sht; static void scsifront_free(struct vscsifrnt_info *info) { struct Scsi_Host *host = info->host; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14) - if (host->shost_state != SHOST_DEL) { -#else - if (!test_bit(SHOST_DEL, &host->shost_state)) { -#endif + if (host->shost_state != SHOST_DEL) scsi_remove_host(info->host); - } if (info->ring_ref != GRANT_INVALID_REF) { gnttab_end_foreign_access(info->ring_ref, @@ -94,8 +82,12 @@ static int scsifront_alloc_ring(struct vscsifrnt_info *info) } info->ring_ref = err; + err = xenbus_alloc_evtchn(dev, &info->evtchn); + if (err) + goto free_sring; + err = bind_evtchn_to_irqhandler( - dev->otherend_id, scsifront_intr, + info->evtchn, scsifront_intr, IRQF_SAMPLE_RANDOM, "scsifront", info); if (err <= 0) { @@ -163,7 +155,7 @@ fail: free_sring: /* free resource */ scsifront_free(info); - + return err; } @@ -174,7 +166,7 @@ static int scsifront_probe(struct xenbus_device *dev, struct vscsifrnt_info *info; struct Scsi_Host *host; int i, err = -ENOMEM; - char name[DEFAULT_TASK_COMM_LEN]; + char name[TASK_COMM_LEN]; host = scsi_host_alloc(&scsifront_sht, sizeof(*info)); if (!host) { @@ -205,7 +197,7 @@ static int scsifront_probe(struct xenbus_device *dev, spin_lock_init(&info->io_lock); spin_lock_init(&info->shadow_lock); - snprintf(name, DEFAULT_TASK_COMM_LEN, "vscsiif.%d", info->host->host_no); + snprintf(name, TASK_COMM_LEN, "vscsiif.%d", info->host->host_no); info->kthread = kthread_run(scsifront_schedule, info, name); if (IS_ERR(info->kthread)) { @@ -248,7 +240,7 @@ static int scsifront_remove(struct xenbus_device *dev) } scsifront_free(info); - + return 0; } @@ -260,9 +252,9 @@ static int scsifront_disconnect(struct vscsifrnt_info *info) DPRINTK("%s: %s disconnect\n",__FUNCTION__ ,dev->nodename); - /* - When this function is executed, all devices of - Frontend have been deleted. + /* + When this function is executed, all devices of + Frontend have been deleted. Therefore, it need not block I/O before remove_host. */ @@ -297,7 +289,7 @@ static void scsifront_do_lun_hotplug(struct vscsifrnt_info *info, int op) &device_state); if (XENBUS_EXIST_ERR(err)) continue; - + /* virtual SCSI device */ snprintf(str, sizeof(str), "vscsi-devs/%s/v-dev", dir[i]); err = xenbus_scanf(XBT_NIL, dev->otherend, str, @@ -339,7 +331,7 @@ static void scsifront_do_lun_hotplug(struct vscsifrnt_info *info, int op) break; } } - + kfree(dir); return; } @@ -369,10 +361,10 @@ static void scsifront_backend_changed(struct xenbus_device *dev, XenbusStateInitialised) { scsifront_do_lun_hotplug(info, VSCSIFRONT_OP_ADD_LUN); } - + if (dev->state == XenbusStateConnected) break; - + xenbus_switch_state(dev, XenbusStateConnected); break; diff --git a/include/xen/interface/io/vscsiif.h b/include/xen/interface/io/vscsiif.h index 3ce2914ff430..7fbe68839dfd 100644 --- a/include/xen/interface/io/vscsiif.h +++ b/include/xen/interface/io/vscsiif.h @@ -1,8 +1,8 @@ /****************************************************************************** * vscsiif.h - * + * * Based on the blkif.h code. - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the @@ -42,7 +42,7 @@ * Maximum scatter/gather segments per request. * * Considering balance between allocating al least 16 "vscsiif_request" - * structures on one page (4096bytes) and number of scatter gather + * structures on one page (4096bytes) and number of scatter gather * needed, we decided to use 26 as a magic number. */ #define VSCSIIF_SG_TABLESIZE 26 @@ -60,7 +60,7 @@ struct vscsiif_request { uint8_t cmd_len; uint8_t cmnd[VSCSIIF_MAX_COMMAND_SIZE]; - uint16_t timeout_per_command; /* The command is issued by twice + uint16_t timeout_per_command; /* The command is issued by twice the value in Backend. */ uint16_t channel, id, lun; uint16_t padding; @@ -84,7 +84,7 @@ struct vscsiif_response { uint8_t sense_len; uint8_t sense_buffer[VSCSIIF_SENSE_BUFFERSIZE]; int32_t rslt; - uint32_t residual_len; /* request bufflen - + uint32_t residual_len; /* request bufflen - return the value from physical device */ uint32_t reserved[36]; }; -- 2.50.1