* 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
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;
struct scsi_device *sdev;
uint16_t rqid;
-
+
uint16_t v_chn, v_tgt;
uint8_t nr_segments;
uint8_t sc_data_direction;
uint16_t timeout_per_command;
-
+
uint32_t request_bufflen;
struct scatterlist *sgl;
grant_ref_t gref[VSCSIIF_SG_TABLESIZE];
* 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
if (from_rest == 0) {
return 0;
}
-
+
from += copy_size;
}
__FUNCTION__);
return -ENOMEM;
}
-
+#if 0
static int __copy_from_sg(struct scatterlist *sgl, unsigned int nr_sg,
void *buf, unsigned int buflen)
{
return 0;
}
-
+#endif
static int __nr_luns_under_host(struct vscsibk_info *info)
{
struct v2p_entry *entry;
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;
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);
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,
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;
/*
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);
/* 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;
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;
* 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
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;
}
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) {
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;
}
}
printk(KERN_ERR "scsiback: can't init scsi cache\n");
return -ENOMEM;
}
-
+
return 0;
}
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)
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);
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);
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);
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;
}
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;
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++)
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");
* 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
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 */
new->sdev = sdev;
list_add_tail(&new->l, head);
-out:
+out:
spin_unlock_irqrestore(&info->v2p_lock, flags);
return err;
}
* 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
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];
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;
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",
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);
}
}
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);
}
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);
}
}
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");
fail:
- printk(KERN_WARNING "scsiback: %s failed\n",__FUNCTION__);
+ printk(KERN_WARNING "scsiback: %s failed\n",__func__);
scsiback_remove(dev);
return err;
* 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
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;
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;
}
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
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;
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);
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;
add_id_to_freelist(info, rqid);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12)
spin_unlock_irq(host->host_lock);
-#endif
return (err);
}
* 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
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
-
#include <linux/version.h>
#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,
}
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) {
free_sring:
/* free resource */
scsifront_free(info);
-
+
return err;
}
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) {
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)) {
}
scsifront_free(info);
-
+
return 0;
}
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.
*/
&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,
break;
}
}
-
+
kfree(dir);
return;
}
XenbusStateInitialised) {
scsifront_do_lun_hotplug(info, VSCSIFRONT_OP_ADD_LUN);
}
-
+
if (dev->state == XenbusStateConnected)
break;
-
+
xenbus_switch_state(dev, XenbusStateConnected);
break;
/******************************************************************************
* 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
* 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
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;
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];
};