TCM was merged and tcm's ibmvscsis driver is ready. We can remove kernel driver support and the kernel drivers now. Signed-off-by: FUJITA Tomonori <fujita.tomonori@xxxxxxxxxxxxx> --- Makefile | 2 +- doc/README.ibmvstgt | 102 ------------- usr/Makefile | 12 -- usr/bs_mmap.c | 189 ----------------------- usr/fc/fc.c | 54 ------- usr/ibmvio/Makefile | 4 - usr/ibmvio/ibmvio.c | 270 --------------------------------- usr/tgtif.c | 412 --------------------------------------------------- 8 files changed, 1 insertions(+), 1044 deletions(-) delete mode 100644 doc/README.ibmvstgt delete mode 100644 usr/bs_mmap.c delete mode 100644 usr/fc/fc.c delete mode 100644 usr/ibmvio/Makefile delete mode 100644 usr/ibmvio/ibmvio.c delete mode 100644 usr/tgtif.c diff --git a/Makefile b/Makefile index b0e9f83..39f1ac5 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ PREFIX ?= /usr export VERSION PREFIX # Export the feature switches so sub-make knows about them -export ISCSI_RDMA IBMVIO FCOE FCP +export ISCSI_RDMA FCOE .PHONY: all all: programs doc conf scripts diff --git a/doc/README.ibmvstgt b/doc/README.ibmvstgt deleted file mode 100644 index d77f932..0000000 --- a/doc/README.ibmvstgt +++ /dev/null @@ -1,102 +0,0 @@ -Starting -------------- -If you want IBM VIO target driver, get kernel version 2.6.20, rebuild -the kernel, and reboot with the new kernel. Note you need to enable -SCSI_TGT, SCSI_SRP, and SCSI_IBMVSCSIS kernel options. - -host:~/tgt/usr$ make KERNELSRC=<kernel-src-directory> IBMVIO=1 - -Make sure that everything is built successfully. - -Try the following commands: - -host:~/tgt$ su -host:~/tgt# modprobe scsi_tgt -host:~/tgt# modprobe libsrp -host:~/tgt# modprobe ibmvstgt -host:~/tgt# ./usr/tgtd - -See /var/log/kern.log (your Linux distributions may use the different -log file name) to make sure that the kernel modules are loaded -properly. You should see messages like the followings: - -Feb 27 19:37:52 lilac kernel: IBM eServer i/pSeries Virtual SCSI Target Driver -Feb 27 19:37:52 lilac kernel: vio_register_driver: driver ibmvscsi registering -Feb 27 19:37:52 lilac kernel: scsi1 : ibmvstgt - -You need the scsi host number (it is 1 in this example) in the next -stage (configuration). - - -Configuration -------------- -Everyting is configured via the tgtadm management tool. - -The following example creates a target with id 1, adds a logical unit -(backed by /dev/sdb1) with lun 0, and then bind the target with -/sys/devices/vio/30000003. - -You need to targetname to create a new target just as a reference. - -host:~/tgt# ./usr/tgtadm --lld ibmvio --mode target --op new --tid 1 --targetname volume1 -host:~/tgt# ./usr/tgtadm --lld ibmvio --mode logicalunit --op new --tid 1 --lun 0 -b /dev/sdb1 -host:~/tgt# ./usr/tgtadm --lld ibmvio --mode target --op bind --tid 1 --bus vio,30000003 - - -Please see /var/log/daemon.log (your Linux distributions may use the -different log file name again) to make sure that everything is -fine. You should see something like the followings: - -Feb 27 22:36:40 lilac tgtd: dl_init(71) istgt library is not loaded. -Feb 27 22:36:40 lilac tgtd: dl_init(71) ibmvstgt library is not loaded. -Feb 27 22:37:08 lilac tgtd: tgt_target_create(572) Succeed to create a new target 1 -Feb 27 22:37:08 lilac tgtd: tgt_target_bind(517) Succeed to bind the target 1 to the scsi host 1 -Feb 27 22:37:08 lilac tgtd: tgt_device_create(238) Succeed to add a logical unit 0 to the target 1 -Now you are ready. Boot up VIO clients. - - -History -------------- -The following description was taken from the original ibmvscsis -driver: - -http://lkml.org/lkml/2005/10/17/99 - - -This driver is a SCSI target that interoperates according to the PAPR -(POWER Architecture Platform Requirements) document. Currently it is -specific to POWER logical partitioning, however in the future it would -be nice to extend this to other virtualized environments. - -The architecture defines virtual adapters, whose configuration is -reported in the Open Firmware device tree. There area number of power -hypervisor calls (such as h_reg_crq, to register the inter-OS queue) -that support the virtual adapters. - -Messages are sent between partitions on a "Command/Response Queue" -(CRQ), which is just a buffer of 16 byte entries in the receiver's -Senders cannot access the buffer directly, but send messages by making -a hypervisor call and passing in the 16 bytes. The hypervisor puts -the message in the next 16 byte space in round-robbin fashion, turns -on the high order bit of the message (the valid bit), and generates an -interrupt to the receiver (if interrupts are turned on.) The receiver -just turns off the valid bit when they have copied out the message. - -The VSCSI client builds a SCSI Remote Protocol (SRP) Information Unit -(IU) (as defined in the T10 standard available at www.t10.org), gets a -DMA address for the message, and sends it to the target as the payload -of a CRQ message. The target DMAs the SRP IU and processes it, -including doing any additional data transfers. When it is done, it -DMAs the SRP response back to the same address as the request came -from and sends a CRQ message back to inform the client that the -request has completed. - -This target interoperates not only with the Linux client (ibmvscsi.c) -but also with AIX and OS/400 clients. Thus, while the implementation -can be changed, the underlying behaviour (protocol) is fixed. - -Configuration of the target is done via sysfs. The target driver maps -either block devices (e.g. IDE CD drive, loopback file, etc) to SCSI -LUNs, in which case it emulates the SCSI protocol and issues kernel -block device calls, or maps real SCSI devices, in which case the SCSI -commands are just passed on to the real SCSI device. diff --git a/usr/Makefile b/usr/Makefile index 3a75df4..ea175cd 100644 --- a/usr/Makefile +++ b/usr/Makefile @@ -8,12 +8,6 @@ ifneq ($(shell test -e /usr/include/sys/timerfd.h && echo 1),) CFLAGS += -DUSE_TIMERFD endif -ifneq ($(IBMVIO),) -CFLAGS += -DIBMVIO -DUSE_KERNEL -TGTD_OBJS += $(addprefix ibmvio/, ibmvio.o) -TGTD_OBJS += bs_mmap.o tgtif.o -endif - TGTD_OBJS += $(addprefix iscsi/, conn.o param.o session.o \ iscsid.o target.o chap.o sha1.o md5.o transport.o iscsi_tcp.o \ isns.o) @@ -24,12 +18,6 @@ TGTD_OBJS += iscsi/iser.o iscsi/iser_text.o LIBS += -libverbs -lrdmacm endif -ifneq ($(FCP),) -CFLAGS += -DFCP -DUSE_KERNEL -TGTD_OBJS += $(addprefix fc/, fc.o) -TGTD_OBJS += bs_mmap.o tgtif.o -endif - ifneq ($(FCOE),) TGTD_OBJS += $(addprefix fcoe/,\ openfc_target.o \ diff --git a/usr/bs_mmap.c b/usr/bs_mmap.c deleted file mode 100644 index f7718f2..0000000 --- a/usr/bs_mmap.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - * mmap file backing store routine - * - * Copyright (C) 2006-2007 FUJITA Tomonori <tomof@xxxxxxx> - * Copyright (C) 2006-2007 Mike Christie <michaelc@xxxxxxxxxxx> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2 of the - * License. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#include <errno.h> -#include <fcntl.h> -#include <inttypes.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <sys/mman.h> - -#include "list.h" -#include "util.h" -#include "tgtd.h" -#include "scsi.h" -#include "bs_thread.h" - -static void bs_mmap_request(struct scsi_cmd *cmd) -{ - int ret; - uint32_t length; - int result = SAM_STAT_GOOD; - uint8_t key; - uint16_t asc; - - ret = length = 0; - key = asc = 0; - - if (cmd->scb[0] != SYNCHRONIZE_CACHE && - cmd->scb[0] != SYNCHRONIZE_CACHE_16) - eprintf("bug %x\n", cmd->scb[0]); - - /* TODO */ - length = (cmd->scb[0] == SYNCHRONIZE_CACHE) ? 0 : 0; - - if (cmd->scb[1] & 0x2) { - result = SAM_STAT_CHECK_CONDITION; - key = ILLEGAL_REQUEST; - asc = ASC_INVALID_FIELD_IN_CDB; - } else { - ret = __sync_file_range(cmd->dev->fd, cmd->offset, length); - if (ret) { - result = SAM_STAT_CHECK_CONDITION; - key = MEDIUM_ERROR; - asc = ASC_READ_ERROR; - } - } - - dprintf("io done %p %x %d %u\n", cmd, cmd->scb[0], ret, length); - - scsi_set_result(cmd, result); - - if (result != SAM_STAT_GOOD) { - eprintf("io error %p %x %d %d %" PRIu64 ", %m\n", - cmd, cmd->scb[0], ret, length, cmd->offset); - sense_data_build(cmd, key, asc); - } -} - -static int bs_mmap_open(struct scsi_lu *lu, char *path, int *fd, uint64_t *size) -{ - *fd = backed_file_open(path, O_RDWR|O_LARGEFILE, size); - /* If we get access denied, try opening the file in readonly mode */ - if (*fd == -1 && errno == EACCES) { - *fd = backed_file_open(path, O_RDONLY|O_LARGEFILE, size); - lu->attrs.readonly = 1; - } - if (*fd < 0) - return *fd; - - return 0; -} - -static void bs_mmap_close(struct scsi_lu *lu) -{ - close(lu->fd); -} - -static int bs_mmap_init(struct scsi_lu *lu) -{ - struct bs_thread_info *info = BS_THREAD_I(lu); - return bs_thread_open(info, bs_mmap_request, NR_WORKER_THREADS); -} - -static void bs_mmap_exit(struct scsi_lu *lu) -{ - struct bs_thread_info *info = BS_THREAD_I(lu); - bs_thread_close(info); -} - -#define pgcnt(size, offset) ((((size) + ((offset) & (pagesize - 1))) + (pagesize - 1)) >> pageshift) - -static int bs_mmap_cmd_submit(struct scsi_cmd *cmd) -{ - struct scsi_lu *lu = cmd->dev; - int fd = lu->fd, ret = 0; - void *p; - uint64_t addr; - uint32_t length; - - if (cmd->scb[0] == SYNCHRONIZE_CACHE || - cmd->scb[0] == SYNCHRONIZE_CACHE_16) - return bs_thread_cmd_submit(cmd); - - length = (scsi_get_data_dir(cmd) == DATA_WRITE) ? - scsi_get_out_length(cmd) : scsi_get_in_length(cmd); - - p = mmap64(NULL, pgcnt(length, cmd->offset) << pageshift, - PROT_READ | PROT_WRITE, MAP_SHARED, fd, - cmd->offset & ~((1ULL << pageshift) - 1)); - if (p == MAP_FAILED) { - ret = -EINVAL; - eprintf("%u %" PRIu64 "\n", length, cmd->offset); - } - - addr = (unsigned long)p + (cmd->offset & (pagesize - 1)); - - if (scsi_get_data_dir(cmd) == DATA_WRITE) - scsi_set_out_buffer(cmd, (void *)(unsigned long)addr); - else if (scsi_get_data_dir(cmd) == DATA_READ) - scsi_set_in_buffer(cmd, (void *)(unsigned long)addr); - - dprintf("%" PRIx64 " %u %" PRIu64 "\n", addr, length, cmd->offset); - - return ret; -} - -static int bs_mmap_cmd_done(struct scsi_cmd *cmd) -{ - int err = 0; - uint64_t addr; - uint32_t len; - - if (scsi_get_data_dir(cmd) == DATA_WRITE) { - addr = (unsigned long)scsi_get_out_buffer(cmd); - len = scsi_get_out_length(cmd); - } else if (scsi_get_data_dir(cmd) == DATA_READ) { - addr = (unsigned long)scsi_get_in_buffer(cmd); - len = scsi_get_in_length(cmd); - } else - return 0; - - dprintf("%d %" PRIx64 " %d\n", cmd_mmapio(cmd), addr, len); - - if (cmd_mmapio(cmd)) { - len = pgcnt(len, (addr & (pagesize - 1))) << pageshift; - addr &= ~(pagesize - 1); - err = munmap((void *) (unsigned long) addr, len); - if (err) - eprintf("%" PRIx64 " %d\n", addr, len); - } - - return err; -} - -static struct backingstore_template mmap_bst = { - .bs_name = "mmap", - .bs_datasize = sizeof(struct bs_thread_info), - .bs_init = bs_mmap_init, - .bs_exit = bs_mmap_exit, - .bs_open = bs_mmap_open, - .bs_close = bs_mmap_close, - .bs_cmd_submit = bs_mmap_cmd_submit, - .bs_cmd_done = bs_mmap_cmd_done, -}; - -__attribute__((constructor)) static void bs_mmap_constructor(void) -{ - register_backingstore_template(&mmap_bst); -} diff --git a/usr/fc/fc.c b/usr/fc/fc.c deleted file mode 100644 index febb1e9..0000000 --- a/usr/fc/fc.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * SCSI command processing specific to fibre channel drivers - * - * Copyright (C) 2007 FUJITA Tomonori <tomof@xxxxxxx> - * Copyright (C) 2007 Mike Christie <michaelc@xxxxxxxxxxx> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ -#include <errno.h> -#include <fcntl.h> -#include <inttypes.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdint.h> -#include <syscall.h> -#include <unistd.h> -#include <linux/fs.h> -#include <scsi/scsi.h> -#include <sys/mman.h> - -#include "list.h" -#include "util.h" -#include "tgtd.h" -#include "target.h" -#include "driver.h" -#include "spc.h" -#include "scsi.h" - -static struct tgt_driver fc = { - .name = "fc", - .use_kernel = 1, - .cmd_end_notify = kspace_send_cmd_res, - .mgmt_end_notify = kspace_send_tsk_mgmt_res, - .default_bst = "mmap", -}; - -__attribute__((constructor)) static void fc_driver_constructor(void) -{ - register_driver(&fc); -} diff --git a/usr/ibmvio/Makefile b/usr/ibmvio/Makefile deleted file mode 100644 index 81967bf..0000000 --- a/usr/ibmvio/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -CFLAGS += -O2 -fno-inline -Wall -fPIC -Wstrict-prototypes -I$(KERNELSRC)/include -I../../usr - -clean: - rm -f *.o diff --git a/usr/ibmvio/ibmvio.c b/usr/ibmvio/ibmvio.c deleted file mode 100644 index d5abb07..0000000 --- a/usr/ibmvio/ibmvio.c +++ /dev/null @@ -1,270 +0,0 @@ -/* - * SCSI command processing specific to IBM Virtual SCSI target Driver - * - * Copyright (C) 2005-2007 FUJITA Tomonori <tomof@xxxxxxx> - * - * Based on: - * - * IBM eServer i/pSeries Virtual SCSI Target Driver - * Copyright (C) 2003-2005 Dave Boutcher (boutcher@xxxxxxxxxx) IBM Corp. - * Santiago Leon (santil@xxxxxxxxxx) IBM Corp. - * Linda Xie (lxie@xxxxxxxxxx) IBM Corp. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ -#include <errno.h> -#include <fcntl.h> -#include <inttypes.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdint.h> -#include <syscall.h> -#include <unistd.h> -#include <linux/fs.h> -#include <sys/mman.h> - -#include "list.h" -#include "util.h" -#include "tgtd.h" -#include "target.h" -#include "driver.h" -#include "spc.h" -#include "scsi.h" - -#define GETTARGET(x) ((int)((((uint64_t)(x)) >> 56) & 0x003f)) -#define GETBUS(x) ((int)((((uint64_t)(x)) >> 53) & 0x0007)) -#define GETLUN(x) ((int)((((uint64_t)(x)) >> 48) & 0x001f)) - -struct inquiry_data { - uint8_t qual_type; - uint8_t rmb_reserve; - uint8_t version; - uint8_t aerc_naca_hisup_format; - uint8_t addl_len; - uint8_t sccs_reserved; - uint8_t bque_encserv_vs_multip_mchngr_reserved; - uint8_t reladr_reserved_linked_cmdqueue_vs; - char vendor[8]; - char product[16]; - char revision[4]; - char vendor_specific[20]; - char reserved1[2]; - char version_descriptor[16]; - char reserved2[22]; - char unique[158]; -}; - -#define IBMVSTGT_HOSTDIR "/sys/class/scsi_host/host" - -static int __ibmvio_inquiry(int host_no, struct scsi_cmd *cmd, uint8_t *data) -{ - struct inquiry_data *id = (struct inquiry_data *) data; - char system_id[256], path[256], buf[32]; - int fd, err, partition_number; - unsigned int unit_address; - unsigned char device_type; - uint64_t lun = *((uint64_t *) cmd->lun); - - device_type = (cmd->dev->attrs.qualifier & 0x7 ) << 5; - device_type |= (cmd->dev->attrs.device_type & 0x1f); - - snprintf(path, sizeof(path), IBMVSTGT_HOSTDIR "%d/system_id", host_no); - fd = open(path, O_RDONLY); - memset(system_id, 0, sizeof(system_id)); - err = read(fd, system_id, sizeof(system_id)); - close(fd); - - snprintf(path, sizeof(path), IBMVSTGT_HOSTDIR "%d/partition_number", - host_no); - fd = open(path, O_RDONLY); - err = read(fd, buf, sizeof(buf)); - partition_number = strtoul(buf, NULL, 10); - close(fd); - - snprintf(path, sizeof(path), IBMVSTGT_HOSTDIR "%d/unit_address", - host_no); - fd = open(path, O_RDONLY); - err = read(fd, buf, sizeof(buf)); - unit_address = strtoul(buf, NULL, 0); - close(fd); - - dprintf("%d %s %d %x %" PRIx64 "\n", - host_no, system_id, partition_number, unit_address, lun); - - id->qual_type = device_type; - id->rmb_reserve = 0x00; - id->version = 0x84; /* ISO/IE */ - id->aerc_naca_hisup_format = 0x22;/* naca & fmt 0x02 */ - id->addl_len = sizeof(*id) - 4; - id->bque_encserv_vs_multip_mchngr_reserved = 0x00; - id->reladr_reserved_linked_cmdqueue_vs = 0x02;/*CMDQ*/ - memcpy(id->vendor, "IBM ", 8); - /* Don't even ask about the next bit. AIX uses - * hardcoded device naming to recognize device types - * and their client won't work unless we use VOPTA and - * VDASD. - */ - if (device_type) - memcpy(id->product, "VOPTA blkdev ", 16); - else - memcpy(id->product, "VDASD blkdev ", 16); - - memcpy(id->revision, "0001", 4); - snprintf(id->unique,sizeof(id->unique), - "IBM-VSCSI-%s-P%d-%x-%d-%d-%d\n", - system_id, - partition_number, - unit_address, - GETBUS(lun), - GETTARGET(lun), - GETLUN(lun)); - - return sizeof(*id); -} - -static int ibmvio_inquiry(int host_no, struct scsi_cmd *cmd) -{ - uint8_t *data, *scb = cmd->scb; - unsigned char key = ILLEGAL_REQUEST; - uint16_t asc = ASC_INVALID_FIELD_IN_CDB; - uint32_t len; - - if (((scb[1] & 0x3) == 0x3) || (!(scb[1] & 0x3) && scb[2])) - goto sense; - - dprintf("%x %x\n", scb[1], scb[2]); - - if (scb[1] & 0x3) - return spc_inquiry(host_no, cmd); - - data = scsi_get_in_buffer(cmd); - - len = __ibmvio_inquiry(host_no, cmd, data); - len = min_t(int, len, scb[4]); - - scsi_set_in_resid_by_actual(cmd, len); - - if (cmd->dev->lun != cmd->dev_id) - data[0] = TYPE_NO_LUN; - - return SAM_STAT_GOOD; -sense: - scsi_set_in_resid_by_actual(cmd, 0); - sense_data_build(cmd, key, asc); - return SAM_STAT_CHECK_CONDITION; -} - -static uint64_t make_lun(unsigned int bus, unsigned int target, unsigned int lun) -{ - uint16_t result = (0x8000 | - ((target & 0x003f) << 8) | - ((bus & 0x0007) << 5) | - (lun & 0x001f)); - return ((uint64_t) result) << 48; -} - -static int ibmvio_report_luns(int host_no, struct scsi_cmd *cmd) -{ - struct scsi_lu *lu; - struct list_head *dev_list = &cmd->c_target->device_list; - uint64_t lun, *data; - int idx, alen, oalen, nr_luns, rbuflen = 4096; - uint8_t *lun_buf = cmd->lun; - unsigned char key = ILLEGAL_REQUEST; - uint16_t asc = ASC_INVALID_FIELD_IN_CDB; - - alen = __be32_to_cpu(*(uint32_t *)&cmd->scb[6]); - if (alen < 16) - goto sense; - - data = scsi_get_in_buffer(cmd); - - alen &= ~(8 - 1); - oalen = alen; - - if ((*((uint64_t *) lun_buf))) { - nr_luns = 1; - goto done; - } - - alen -= 8; - rbuflen -= 8; /* FIXME */ - idx = 2; - nr_luns = 1; - - list_for_each_entry(lu, dev_list, device_siblings) { - lun = lu->lun; - lun = make_lun(0, lun & 0x003f, 0); - data[idx++] = __cpu_to_be64(lun); - if (!(alen -= 8)) - break; - if (!(rbuflen -= 8)) { - fprintf(stderr, "FIXME: too many luns\n"); - exit(-1); - } - nr_luns++; - } - -done: - *((uint32_t *) data) = __cpu_to_be32(nr_luns * 8); - scsi_set_in_resid_by_actual(cmd, min(oalen, nr_luns * 8 + 8)); - return SAM_STAT_GOOD; -sense: - scsi_set_in_resid_by_actual(cmd, 0); - sense_data_build(cmd, key, asc); - return SAM_STAT_CHECK_CONDITION; -} - -#define TGT_INVALID_DEV_ID ~0ULL - -static uint64_t scsi_lun_to_int(uint8_t *p) -{ - uint64_t lun = TGT_INVALID_DEV_ID; - - lun = *((uint64_t *) p); - dprintf("%" PRIx64 " %u %u %u\n", lun, GETTARGET(lun), GETBUS(lun), GETLUN(lun)); - - if (GETBUS(lun) || GETLUN(lun)) - return TGT_INVALID_DEV_ID; - else - return GETTARGET(lun); -} - -static int ibmvio_lu_create(struct scsi_lu *lu) -{ - struct device_type_operations *ops = lu->dev_type_template.ops; - - ops[INQUIRY].cmd_perform = ibmvio_inquiry; - ops[REPORT_LUNS].cmd_perform = ibmvio_report_luns; - - return 0; -} - -static struct tgt_driver ibmvio = { - .name = "ibmvio", - .use_kernel = 1, - .scsi_get_lun = scsi_lun_to_int, - .lu_create = ibmvio_lu_create, - .cmd_end_notify = kspace_send_cmd_res, - .mgmt_end_notify = kspace_send_tsk_mgmt_res, - .default_bst = "mmap", -}; - -__attribute__((constructor)) static void ibmvio_driver_constructor(void) -{ - register_driver(&ibmvio); -} diff --git a/usr/tgtif.c b/usr/tgtif.c deleted file mode 100644 index f29c11f..0000000 --- a/usr/tgtif.c +++ /dev/null @@ -1,412 +0,0 @@ -/* - * SCSI kernel and user interface - * - * Copyright (C) 2006-2007 FUJITA Tomonori <tomof@xxxxxxx> - * Copyright (C) 2006-2007 Mike Christie <michaelc@xxxxxxxxxxx> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2 of the - * License. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - */ -#include <errno.h> -#include <fcntl.h> -#include <getopt.h> -#include <inttypes.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <sys/epoll.h> -#include <sys/mman.h> -#include <sys/stat.h> -#include <sys/sysmacros.h> -#include <linux/types.h> -#ifndef aligned_u64 -#define aligned_u64 uint64_t __attribute__((aligned(8))) -#endif -#include <scsi/scsi_tgt_if.h> - -#include "list.h" -#include "util.h" -#include "tgtd.h" - -#define barrier() __asm__ __volatile__("": : :"memory") - -struct uring { - uint32_t idx; - char *buf; -}; - -static struct uring kuring, ukring; -static int chrfd; - -static unsigned long tgt_ring_pages, tgt_max_events, tgt_event_per_page; - -static inline void ring_index_inc(struct uring *ring) -{ - ring->idx = (ring->idx == tgt_max_events - 1) ? 0 : ring->idx + 1; -} - -static inline struct tgt_event *head_ring_hdr(struct uring *ring) -{ - uint32_t pidx, off, pos; - - pidx = ring->idx / tgt_event_per_page; - off = ring->idx % tgt_event_per_page; - pos = pidx * pagesize + off * sizeof(struct tgt_event); - - return (struct tgt_event *) (ring->buf + pos); -} - -static int kreq_send(struct tgt_event *p) -{ - struct tgt_event *ev; - - ev = head_ring_hdr(&ukring); - if (ev->hdr.status) - return -ENOMEM; - - ring_index_inc(&ukring); - - memcpy(ev, p, sizeof(*p)); - barrier(); - ev->hdr.status = 1; - write(chrfd, ev, 1); - - return 0; -} - -int kspace_send_tsk_mgmt_res(struct mgmt_req *mreq) -{ - struct tgt_event ev; - - memset(&ev, 0, sizeof(ev)); - - ev.hdr.type = TGT_UEVENT_TSK_MGMT_RSP; - ev.p.tsk_mgmt_rsp.host_no = mreq->host_no; - ev.p.tsk_mgmt_rsp.itn_id = mreq->itn_id; - ev.p.tsk_mgmt_rsp.mid = mreq->mid; - ev.p.tsk_mgmt_rsp.result = mreq->result; - - return kreq_send(&ev); -} - -struct kscsi_cmd { - int host_no; - struct scsi_cmd scmd; -}; - -static inline struct kscsi_cmd *KCMD(struct scsi_cmd *cmd) -{ - return container_of(cmd, struct kscsi_cmd, scmd); -} - -int kspace_send_cmd_res(uint64_t nid, int result, struct scsi_cmd *cmd) -{ - struct kscsi_cmd *kcmd; - struct tgt_event ev; - - memset(&ev, 0, sizeof(ev)); - - dprintf("%p %u %u %d %p %p %u %" PRIu64 "\n", cmd, - scsi_get_out_length(cmd), scsi_get_in_length(cmd), - result, - scsi_get_out_buffer(cmd), scsi_get_in_buffer(cmd), - cmd->data_dir, cmd->tag); - - kcmd = KCMD(cmd); - - ev.hdr.type = TGT_UEVENT_CMD_RSP; - ev.p.cmd_rsp.host_no = kcmd->host_no; - ev.p.cmd_rsp.itn_id = cmd->cmd_itn_id; - if (scsi_get_data_dir(cmd) == DATA_WRITE) { - ev.p.cmd_rsp.uaddr = (unsigned long)scsi_get_out_buffer(cmd); - ev.p.cmd_rsp.len = - scsi_get_out_length(cmd) - scsi_get_out_resid(cmd); - } else { - ev.p.cmd_rsp.uaddr = (unsigned long)scsi_get_in_buffer(cmd); - ev.p.cmd_rsp.len = - scsi_get_in_length(cmd) - scsi_get_in_resid(cmd); - } - ev.p.cmd_rsp.sense_len = cmd->sense_len; - ev.p.cmd_rsp.sense_uaddr = (unsigned long) cmd->sense_buffer; - ev.p.cmd_rsp.result = result; - ev.p.cmd_rsp.rw = cmd->data_dir; - ev.p.cmd_rsp.tag = cmd->tag; - - return kreq_send(&ev); -} - -static void kern_queue_cmd(struct tgt_event *ev) -{ - int ret = -ENOMEM, tid, scb_len = 16; - struct kscsi_cmd *kcmd; - struct scsi_cmd *cmd; - - tid = tgt_bound_target_lookup(ev->p.cmd_req.host_no); - if (tid < 0) { - eprintf("can't find a bound target %d\n", - ev->p.cmd_req.host_no); - return; - } - - /* TODO: define scsi_kcmd and move mmap stuff */ - kcmd = zalloc(sizeof(*kcmd) + scb_len); - if (!kcmd) { - eprintf("oom %d\n", ev->p.cmd_req.host_no); - return; - } - - kcmd->host_no = ev->p.cmd_req.host_no; - cmd = &kcmd->scmd; - cmd->cmd_itn_id = ev->p.cmd_req.itn_id; - cmd->scb = (unsigned char *)cmd + sizeof(*cmd); - memcpy(cmd->scb, ev->p.cmd_req.scb, scb_len); - cmd->scb_len = scb_len; - memcpy(cmd->lun, ev->p.cmd_req.lun, sizeof(cmd->lun)); - - cmd->attribute = ev->p.cmd_req.attribute; - cmd->tag = ev->p.cmd_req.tag; - - scsi_set_data_dir(cmd, scsi_data_dir_opcode(cmd->scb[0])); - - if (scsi_get_data_dir(cmd) == DATA_WRITE) - scsi_set_out_length(cmd, ev->p.cmd_req.data_len); - else - scsi_set_in_length(cmd, ev->p.cmd_req.data_len); - - if (!scsi_is_io_opcode(cmd->scb[0])) { - char *buf; - uint32_t data_len; - - data_len = ev->p.cmd_req.data_len; - /* - * fix spc, sbc, etc. they assume that buffer is long - * enough. - */ - if (data_len < 4096) - data_len = 4096; - - buf = valloc(data_len); - if (!buf) - goto free_kcmd; - - if (scsi_get_data_dir(cmd) == DATA_WRITE) - scsi_set_out_buffer(cmd, buf); - else - scsi_set_in_buffer(cmd, buf); - - memset(buf, 0, data_len); - } - - ret = target_cmd_queue(tid, cmd); - if (ret) - goto free_kcmd; - - return; -free_kcmd: - /* TODO: send sense properly */ - eprintf("can't queue this command %d\n", ret); - free(kcmd); -} - -static void kern_cmd_done(struct tgt_event *ev) -{ - int tid; - /* temp hack */ - struct scsi_cmd *cmd; - - tid = tgt_bound_target_lookup(ev->p.cmd_done.host_no); - if (tid < 0) { - eprintf("can't find a bound target %d\n", - ev->p.cmd_done.host_no); - return; - } - - cmd = target_cmd_lookup(tid, ev->p.cmd_done.itn_id, ev->p.cmd_done.tag); - if (cmd) { - target_cmd_done(cmd); - if (!cmd_mmapio(cmd)) { - if (scsi_get_data_dir(cmd) == DATA_WRITE) - free(scsi_get_out_buffer(cmd)); - else - free(scsi_get_in_buffer(cmd)); - } - free(KCMD(cmd)); - } else - eprintf("unknow command %d %" PRIu64 " %" PRIu64 "\n", - tid, ev->p.cmd_done.itn_id, ev->p.cmd_done.tag); -} - -static int kspace_send_it_nexus_res(int host_no, uint64_t itn_id, - uint32_t function, int result) -{ - struct tgt_event ev; - - memset(&ev, 0, sizeof(ev)); - - ev.hdr.type = TGT_UEVENT_IT_NEXUS_RSP; - ev.p.it_nexus_rsp.host_no = host_no; - ev.p.it_nexus_rsp.itn_id = itn_id; - ev.p.it_nexus_rsp.function = function; - ev.p.it_nexus_rsp.result = result; - - return kreq_send(&ev); -} - -static void kern_it_nexus_request(struct tgt_event *ev) -{ - int tid, ret, host_no; - uint32_t function = ev->p.it_nexus_req.function; - uint64_t itn_id = ev->p.it_nexus_req.itn_id; - - host_no = ev->p.it_nexus_req.host_no; - tid = tgt_bound_target_lookup(host_no); - if (tid < 0) { - eprintf("can't find a bound target %d\n", host_no); - return; - } - - if (function) - ret = it_nexus_destroy(tid, itn_id); - else - ret = it_nexus_create(tid, itn_id, host_no, NULL); - - kspace_send_it_nexus_res(host_no, itn_id, function, ret); -} - -static void kern_mgmt_request(struct tgt_event *ev) -{ - int tid; - - tid = tgt_bound_target_lookup(ev->p.tsk_mgmt_req.host_no); - if (tid < 0) { - eprintf("can't find a bound target %d\n", - ev->p.tsk_mgmt_req.host_no); - return; - } - - target_mgmt_request(tid, ev->p.tsk_mgmt_req.itn_id, - ev->p.tsk_mgmt_req.mid, - ev->p.tsk_mgmt_req.function, - ev->p.tsk_mgmt_req.lun, - ev->p.tsk_mgmt_req.tag, - ev->p.cmd_done.host_no); -} - -static void kern_event_handler(int fd, int events, void *data) -{ - struct tgt_event *ev; -retry: - ev = head_ring_hdr(&kuring); - if (!ev->hdr.status) - return; - - dprintf("event %u %u\n", kuring.idx, ev->hdr.type); - - switch (ev->hdr.type) { - case TGT_KEVENT_CMD_REQ: - kern_queue_cmd(ev); - break; - case TGT_KEVENT_CMD_DONE: - kern_cmd_done(ev); - break; - case TGT_KEVENT_IT_NEXUS_REQ: - kern_it_nexus_request(ev); - break; - case TGT_KEVENT_TSK_MGMT_REQ: - kern_mgmt_request(ev); - break; - default: - eprintf("unknown event %u\n", ev->hdr.type); - } - - ev->hdr.status = 0; - ring_index_inc(&kuring); - - goto retry; -} - -#define CHRDEV_PATH "/dev/tgt" - -static int tgt_miscdev_init(char *path, int *fd) -{ - int major, minor, err; - FILE *fp; - char buf[64]; - - fp = fopen("/sys/class/misc/tgt/dev", "r"); - if (!fp) { - eprintf("Cannot open control path to the driver\n"); - return -1; - } - - if (!fgets(buf, sizeof(buf), fp)) - goto out; - - if (sscanf(buf, "%d:%d", &major, &minor) != 2) - goto out; - - unlink(path); - err = mknod(path, (S_IFCHR | 0600), makedev(major, minor)); - if (err) - goto out; - - *fd = open(path, O_RDWR); - if (*fd < 0) { - eprintf("cannot open %s, %m\n", path); - goto out; - } - - fclose(fp); - - return 0; -out: - fclose(fp); - return -errno; -} - -int kreq_init(void) -{ - int err, size = TGT_RING_SIZE; - char *buf; - - err = tgt_miscdev_init(CHRDEV_PATH, &chrfd); - if (err) - return err; - - if (size < pagesize) - size = pagesize; - - buf = mmap(NULL, size * 2, PROT_READ | PROT_WRITE, MAP_SHARED, chrfd, 0); - if (buf == MAP_FAILED) { - eprintf("fail to mmap, %m\n"); - close(chrfd); - return -EINVAL; - } - - tgt_ring_pages = size >> pageshift; - tgt_event_per_page = pagesize / sizeof(struct tgt_event); - tgt_max_events = tgt_event_per_page * tgt_ring_pages; - - kuring.idx = ukring.idx = 0; - kuring.buf = buf; - ukring.buf = buf + size; - - err = tgt_event_add(chrfd, EPOLLIN, kern_event_handler, NULL); - if (err) - close(chrfd); - return err; -} -- 1.7.2.3 -- To unsubscribe from this list: send the line "unsubscribe stgt" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html