[PATCH 1/2] [Target_Core_Mod]: Complete conversion to genericREPORT_LUNS functionality

From: Nicholas A. Bellinger
Date: Tue Jan 13 2009 - 16:16:43 EST


Greetings all,

This patch is made against lio-core-2.6.git/master
and tested on v2.6.28. The lio-core-2.6.git tree can be found at:

http://git.kernel.org/?p=linux/kernel/git/nab/lio-core-2.6.git;a=summary

Thanks,

--nab

>From 01242e6614cc442b862c428d11fb593b1168b064 Mon Sep 17 00:00:00 2001
From: Nicholas Bellinger <nab@xxxxxxxxxxxxxxx>
Date: Tue, 13 Jan 2009 12:56:48 -0800
Subject: [PATCH 1/2] [Target_Core_Mod]: Complete conversion to generic REPORT_LUNS functionality

This patch completes the $FABRIC_MOD independent conversion for REPORT_LUNS in
v3.0 target_core_mod code. This patch removes the target_core_reportluns.[c,h]
files all together, and adds the following:

I) Move REPORT_LUNS response emulation support to transport_core_report_lun_response()
in target_core_device.c.
II) REPORT_LUNS support to transport_generic_cmd_sequencer()
III) New se_cmd_t->transport_emulate_cdb() to catch REPORT_LUNS in
__transport_execute_tasks()

Also, this patch fixes a BUG that was brought forward from v2.9 code for
REPORT_LUNS response emulation where the following check:

spin_lock_bh(&SE_NODE_ACL(se_sess)->device_list_lock);
for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) {
deve = &SE_NODE_ACL(se_sess)->device_list[i];
if (!(deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS))
continue;
se_lun = deve->se_lun;
/*
* We determine the correct LUN LIST LENGTH even once we
* have reached the initial allocation length.
* See SPC2-R20 7.19.
*/
lun_count++;
if ((cdb_offset + 8) > se_cmd->data_length)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
continue;

would overflow the REPORT_LUNS reponse buffer by 1 LUN Listing (8 bytes)
when the cdb_offset + 8 exceeded the received data length. This patch correctly
changes the conditional test to:

if ((cdb_offset + 8) >= se_cmd->data_length)

Signed-off-by: Nicholas A. Bellinger <nab@xxxxxxxxxxxxxxx>
---
drivers/lio-core/Makefile | 1 -
drivers/lio-core/target_core_base.h | 36 ++--
drivers/lio-core/target_core_device.c | 99 +++++++--
drivers/lio-core/target_core_device.h | 1 +
drivers/lio-core/target_core_reportluns.c | 340 -----------------------------
drivers/lio-core/target_core_reportluns.h | 55 -----
drivers/lio-core/target_core_transport.c | 44 +++--
7 files changed, 129 insertions(+), 447 deletions(-)
delete mode 100644 drivers/lio-core/target_core_reportluns.c
delete mode 100644 drivers/lio-core/target_core_reportluns.h

diff --git a/drivers/lio-core/Makefile b/drivers/lio-core/Makefile
index 7bab803..7e18cae 100644
--- a/drivers/lio-core/Makefile
+++ b/drivers/lio-core/Makefile
@@ -33,7 +33,6 @@ target_core_mod-objs := target_core_configfs.o \
target_core_device.o \
target_core_hba.o \
target_core_plugin.o \
- target_core_reportluns.o \
target_core_scdb.o \
target_core_seobj.o \
target_core_tpg.o \
diff --git a/drivers/lio-core/target_core_base.h b/drivers/lio-core/target_core_base.h
index 7349131..058173e 100644
--- a/drivers/lio-core/target_core_base.h
+++ b/drivers/lio-core/target_core_base.h
@@ -166,24 +166,23 @@
#define TRANSPORT_FREE 255

#define SCF_SUPPORTED_SAM_OPCODE 0x00000001
-#define SCF_REPORT_LUNS 0x00000002
-#define SCF_TRANSPORT_TASK_SENSE 0x00000004
-#define SCF_EMULATED_TASK_SENSE 0x00000008
-#define SCF_SCSI_DATA_SG_IO_CDB 0x00000010
-#define SCF_SCSI_CONTROL_SG_IO_CDB 0x00000020
-#define SCF_SCSI_CONTROL_NONSG_IO_CDB 0x00000040
-#define SCF_SCSI_NON_DATA_CDB 0x00000080
-#define SCF_SCSI_CDB_EXCEPTION 0x00000100
-#define SCF_SCSI_RESERVATION_CONFLICT 0x00000200
-#define SCF_CMD_PASSTHROUGH 0x00000400
-#define SCF_CMD_PASSTHROUGH_NOALLOC 0x00000800
-#define SCF_SE_CMD_FAILED 0x00001000
-#define SCF_SE_LUN_CMD 0x00002000
-#define SCF_SE_ALLOW_EOO 0x00004000
-#define SCF_SE_DISABLE_ONLINE_CHECK 0x00008000
-#define SCF_SENT_CHECK_CONDITION 0x00010000
-#define SCF_OVERFLOW_BIT 0x00020000
-#define SCF_UNDERFLOW_BIT 0x00040000
+#define SCF_TRANSPORT_TASK_SENSE 0x00000002
+#define SCF_EMULATED_TASK_SENSE 0x00000004
+#define SCF_SCSI_DATA_SG_IO_CDB 0x00000008
+#define SCF_SCSI_CONTROL_SG_IO_CDB 0x00000010
+#define SCF_SCSI_CONTROL_NONSG_IO_CDB 0x00000020
+#define SCF_SCSI_NON_DATA_CDB 0x00000040
+#define SCF_SCSI_CDB_EXCEPTION 0x00000080
+#define SCF_SCSI_RESERVATION_CONFLICT 0x00000100
+#define SCF_CMD_PASSTHROUGH 0x00000200
+#define SCF_CMD_PASSTHROUGH_NOALLOC 0x00000400
+#define SCF_SE_CMD_FAILED 0x00000800
+#define SCF_SE_LUN_CMD 0x00001000
+#define SCF_SE_ALLOW_EOO 0x00002000
+#define SCF_SE_DISABLE_ONLINE_CHECK 0x00004000
+#define SCF_SENT_CHECK_CONDITION 0x00008000
+#define SCF_OVERFLOW_BIT 0x00010000
+#define SCF_UNDERFLOW_BIT 0x00020000

/* se_device_t->type */
#define PSCSI 1
@@ -414,6 +413,7 @@ typedef struct se_cmd_s {
int (*transport_allocate_resources)(struct se_cmd_s *, u32, u32);
int (*transport_cdb_transform)(struct se_cmd_s *, struct se_transform_info_s *);
int (*transport_do_transform)(struct se_cmd_s *, struct se_transform_info_s *);
+ int (*transport_emulate_cdb)(struct se_cmd_s *);
void (*transport_free_resources)(struct se_cmd_s *);
u32 (*transport_get_lba)(unsigned char *);
unsigned long long (*transport_get_long_lba)(unsigned char *);
diff --git a/drivers/lio-core/target_core_device.c b/drivers/lio-core/target_core_device.c
index 9aa2f51..95dd89d 100644
--- a/drivers/lio-core/target_core_device.c
+++ b/drivers/lio-core/target_core_device.c
@@ -40,6 +40,7 @@
#include <linux/in.h>
#include <net/sock.h>
#include <net/tcp.h>
+#include <scsi/scsi.h>

#include <iscsi_linux_os.h>
#include <iscsi_linux_defs.h>
@@ -55,9 +56,6 @@

#include <target_core_plugin.h>
#include <target_core_seobj.h>
-#define RL_INCLUDE_STRUCTS
-#include <target_core_reportluns.h>
-#undef RL_INCLUDE_STRUCTS

#undef TARGET_CORE_DEVICE_C

@@ -315,12 +313,6 @@ out:
spin_unlock(&dev->stats_lock);
}
#endif /* SNMP_SUPPORT */
- /*
- * REPORT_LUN never gets added to the LUN list because it never makes
- * it to the storage engine queue.
- */
- if (se_cmd->se_cmd_flags & SCF_REPORT_LUNS)
- return(1);

/*
* Add the iscsi_cmd_t to the se_lun_t's cmd list. This list is used
@@ -498,6 +490,87 @@ extern void core_clear_lun_from_tpg (se_lun_t *lun, se_portal_group_t *tpg)
return;
}

+extern int transport_core_report_lun_response (se_cmd_t *se_cmd)
+{
+ se_dev_entry_t *deve;
+ se_lun_t *se_lun;
+ se_session_t *se_sess = SE_SESS(se_cmd);
+ se_task_t *se_task;
+ unsigned char *buf = (unsigned char *)T_TASK(se_cmd)->t_task_buf;
+ u32 cdb_offset = 0, lun_count = 0, offset = 8;
+ u64 i, lun;
+
+ list_for_each_entry(se_task, &T_TASK(se_cmd)->t_task_list, t_list)
+ break;
+
+ if (!(se_task)) {
+ printk(KERN_ERR "Unable to locate se_task_t for se_cmd_t\n");
+ return(PYX_TRANSPORT_LOGICAL_UNIT_COMMUNICATION_FAILURE);
+ }
+
+ /*
+ * If no se_session_t pointer is present, this se_cmd_t is
+ * coming via a target_core_mod PASSTHROUGH op, and not through
+ * a $FABRIC_MOD. In that case, report LUN=0 only.
+ */
+ if (!(se_sess)) {
+ lun = 0;
+ buf[offset++] = ((lun >> 56) & 0xff);
+ buf[offset++] = ((lun >> 48) & 0xff);
+ buf[offset++] = ((lun >> 40) & 0xff);
+ buf[offset++] = ((lun >> 32) & 0xff);
+ buf[offset++] = ((lun >> 24) & 0xff);
+ buf[offset++] = ((lun >> 16) & 0xff);
+ buf[offset++] = ((lun >> 8) & 0xff);
+ buf[offset++] = (lun & 0xff);
+ lun_count = 1;
+ goto done;
+ }
+
+ spin_lock_bh(&SE_NODE_ACL(se_sess)->device_list_lock);
+ for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) {
+ deve = &SE_NODE_ACL(se_sess)->device_list[i];
+ if (!(deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS))
+ continue;
+ se_lun = deve->se_lun;
+ /*
+ * We determine the correct LUN LIST LENGTH even once we
+ * have reached the initial allocation length.
+ * See SPC2-R20 7.19.
+ */
+ lun_count++;
+ if ((cdb_offset + 8) >= se_cmd->data_length)
+ continue;
+
+ lun = cpu_to_be64(CMD_TFO(se_cmd)->pack_lun(deve->mapped_lun));
+ buf[offset++] = ((lun >> 56) & 0xff);
+ buf[offset++] = ((lun >> 48) & 0xff);
+ buf[offset++] = ((lun >> 40) & 0xff);
+ buf[offset++] = ((lun >> 32) & 0xff);
+ buf[offset++] = ((lun >> 24) & 0xff);
+ buf[offset++] = ((lun >> 16) & 0xff);
+ buf[offset++] = ((lun >> 8) & 0xff);
+ buf[offset++] = (lun & 0xff);
+ cdb_offset += 8;
+ }
+ spin_unlock_bh(&SE_NODE_ACL(se_sess)->device_list_lock);
+
+ /*
+ * See SPC3 r07, page 159.
+ */
+done:
+ lun_count *= 8;
+ buf[0] = ((lun_count >> 24) & 0xff);
+ buf[1] = ((lun_count >> 16) & 0xff);
+ buf[2] = ((lun_count >> 8) & 0xff);
+ buf[3] = (lun_count & 0xff);
+
+ se_task->task_scsi_status = GOOD;
+ transport_complete_task(se_task, 1);
+
+ return(PYX_TRANSPORT_SENT_TO_TRANSPORT);
+}
+
/* se_release_device_for_hba():
*
*
@@ -532,14 +605,6 @@ extern int transport_get_lun_for_cmd (
unsigned char *cdb,
u32 unpacked_lun)
{
- /*
- * REPORT_LUNS never actually goes to the transport layer.
- */
- if (cdb[0] == REPORT_LUNS) {
- if (se_allocate_rl_cmd(se_cmd, cdb, unpacked_lun) < 0)
- return(PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES);
- }
-
return(__transport_get_lun_for_cmd(se_cmd, unpacked_lun));
}

diff --git a/drivers/lio-core/target_core_device.h b/drivers/lio-core/target_core_device.h
index 128aae8..ea3046b 100644
--- a/drivers/lio-core/target_core_device.h
+++ b/drivers/lio-core/target_core_device.h
@@ -40,6 +40,7 @@ extern void core_dec_lacl_count (struct se_node_acl_s *, struct se_cmd_s *);
extern void core_update_device_list_access (u32, u32, se_node_acl_t *);
extern void core_update_device_list_for_node (se_lun_t *lun, u32, u32, se_node_acl_t *, se_portal_group_t *, int);
extern void core_clear_lun_from_tpg (se_lun_t *, se_portal_group_t *);
+extern int transport_core_report_lun_response (se_cmd_t *);
extern void se_release_device_for_hba (se_device_t *);
extern void se_clear_dev_ports (se_device_t *);
extern int se_free_virtual_device (se_device_t *, se_hba_t *);
diff --git a/drivers/lio-core/target_core_reportluns.c b/drivers/lio-core/target_core_reportluns.c
deleted file mode 100644
index 57401e4..0000000
--- a/drivers/lio-core/target_core_reportluns.c
+++ /dev/null
@@ -1,340 +0,0 @@
-/*********************************************************************************
- * Filename: target_core_reportluns.c
- *
- * Copyright (c) 2004 PyX Technologies, Inc.
- * Copyright (c) 2005, 2006, 2007 SBE, Inc.
- * Copyright (c) 2007 Rising Tide Software, Inc.
- *
- * Nicholas A. Bellinger <nab@xxxxxxxxxx>
- *
- * 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.
- *
- *********************************************************************************/
-
-
-#define TARGET_CORE_REPORTLUNS_C
-
-#include <linux/net.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
-#include <linux/in.h>
-#include <net/sock.h>
-#include <net/tcp.h>
-
-#include <iscsi_linux_os.h>
-#include <iscsi_linux_defs.h>
-
-#include <iscsi_debug.h>
-#include <iscsi_protocol.h>
-#include <iscsi_debug_opcodes.h>
-#include <iscsi_debug.h>
-#include <iscsi_target_core.h>
-#include <target_core_base.h>
-#include <iscsi_target_device.h>
-#include <target_core_transport.h>
-#include <iscsi_target_util.h>
-#include <target_core_reportluns.h>
-
-#include <target_core_fabric_ops.h>
-
-#undef TARGET_CORE_REPORTLUNS_C
-
-static se_subsystem_api_t *rl_template = &_rl_template;
-
-/* rl_set_iovec_ptrs():
- *
- * Assumes non-scatterlist buffers.
- */
-static int rl_set_iovec_ptrs (
- se_map_sg_t *map_sg,
- se_unmap_sg_t *unmap_sg)
-{
- se_cmd_t *se_cmd = map_sg->se_cmd;
- se_task_t *task = NULL;
- rl_cmd_t *rl_cmd = NULL;
- struct iovec *iov = map_sg->iov;
-
- list_for_each_entry(task, &T_TASK(se_cmd)->t_task_list, t_list) {
- rl_cmd = (rl_cmd_t *) task->transport_req;
- }
-
- iov[0].iov_base = (unsigned char *) rl_cmd->rl_buf + map_sg->data_offset;
- iov[0].iov_len = map_sg->data_length;
-
- return(1);
-}
-
-/* rl_wait_for_tasks():
- *
- *
- */
-static void rl_wait_for_tasks (se_cmd_t *cmd, int remove_cmd, int session_reinstatement)
-{
- return;
-}
-
-static void rl_nop_SG_segments (se_unmap_sg_t *unmap_sg)
-{
- return;
-}
-
-/* rl_allocate_cmd():
- *
- *
- */
-static rl_cmd_t *rl_allocate_cmd (se_cmd_t *cmd, u32 size)
-{
- rl_cmd_t *rl_cmd;
-
- if (!(rl_cmd = (rl_cmd_t *) kzalloc(sizeof(rl_cmd_t), GFP_KERNEL))) {
- TRACE_ERROR("Unable to allocate rl_cmd_t for REPORT_LUNS\n");
- return(NULL);
- }
-
- if (!(rl_cmd->rl_buf = (unsigned char *) kzalloc(cmd->data_length, GFP_KERNEL))) {
- TRACE_ERROR("Unable to allocate buffer for REPORT_LUNS\n");
- return(NULL);
- }
-
- rl_cmd->rl_size = cmd->data_length;
- /*
- * Setup any additional transport related function pointers now.
- */
- cmd->transport_set_iovec_ptrs = &rl_set_iovec_ptrs;
- cmd->transport_wait_for_tasks = &rl_wait_for_tasks;
- cmd->transport_map_SG_segments = &rl_nop_SG_segments;
- cmd->transport_unmap_SG_segments = &rl_nop_SG_segments;
-
- return(rl_cmd);
-}
-
-/* rl_allocate_fake_lun():
- *
- *
- */
-static int rl_allocate_fake_lun (se_cmd_t *cmd, u32 lun)
-{
- se_lun_t *lun_p;
-
- if (!(cmd->se_lun = (se_lun_t *)
- kzalloc(sizeof(se_lun_t), GFP_KERNEL))) {
- TRACE_ERROR("Unable to allocate se_lun_t\n");
- return(-1);
- }
- ISCSI_LUN(cmd)->unpacked_lun = lun;
- lun_p = ISCSI_LUN(cmd);
-
- if (!(lun_p->se_dev = (se_device_t *)
- kzalloc(sizeof(se_device_t), GFP_KERNEL))) {
- TRACE_ERROR("Unable to allocate se_device_t\n");
- kfree(ISCSI_LUN(cmd));
- return(-1);
- }
- ISCSI_DEV(cmd)->transport = rl_template;
-
- return(0);
-}
-
-/* se_allocate_rl_cmd():
- *
- *
- */
-extern int se_allocate_rl_cmd (
- se_cmd_t *cmd,
- unsigned char *cdb,
- u32 unpacked_lun)
-{
- rl_cmd_t *rl_cmd = NULL;
- se_task_t *task = NULL;
- unsigned long flags;
-
- cmd->se_cmd_flags |= SCF_REPORT_LUNS;
- cmd->data_length = (cdb[6] << 24) + (cdb[7] << 16) +
- (cdb[8] << 8) + cdb[9];
-
- if (rl_allocate_fake_lun(cmd, unpacked_lun) < 0)
- goto failure;
-
- if (!(rl_cmd = rl_allocate_cmd(cmd, cmd->data_length)))
- goto failure;
-
- rl_cmd->rl_se_cmd = cmd;
-
- if (!(cmd->t_task = (se_transport_task_t *) kzalloc(
- sizeof(se_transport_task_t), GFP_KERNEL))) {
- TRACE_ERROR("Unable to allocate se_transport_task_t\n");
- goto failure;
- }
-
- init_MUTEX_LOCKED(&T_TASK(cmd)->t_transport_stop_sem);
- spin_lock_init(&T_TASK(cmd)->t_state_lock);
- INIT_LIST_HEAD(&T_TASK(cmd)->t_task_list);
-
- memcpy(T_TASK(cmd)->t_task_cdb, cdb, SCSI_CDB_SIZE);
-
- if (!(task = kzalloc(sizeof(se_task_t), GFP_KERNEL))) {
- TRACE_ERROR("Unable to allocate se_task_t\n");
- goto failure;
- }
-
- INIT_LIST_HEAD(&task->t_list);
- init_MUTEX_LOCKED(&task->task_stop_sem);
- task->task_no = 0;
- task->task_se_cmd = cmd;
- task->se_dev = ISCSI_DEV(cmd);
- task->transport_req = (void *) rl_cmd;
-
- spin_lock_irqsave(&T_TASK(cmd)->t_state_lock, flags);
- list_add(&task->t_list, &T_TASK(cmd)->t_task_list);
- spin_unlock_irqrestore(&T_TASK(cmd)->t_state_lock, flags);
-
- if (transport_allocate_iovecs_for_cmd(cmd, TRANSPORT_IOV_DATA_BUFFER + 1) < 0)
- goto failure;
-
- transport_set_supported_SAM_opcode(cmd);
-
- return(0);
-failure:
- if (ISCSI_LUN(cmd)) {
- if (ISCSI_DEV(cmd)) {
- kfree(ISCSI_DEV(cmd));
- cmd->se_lun->se_dev = NULL;
- }
- kfree(ISCSI_LUN(cmd));
- cmd->se_lun = NULL;
- }
- if (T_TASK(cmd)) {
- kfree(cmd->t_task);
- cmd->t_task = NULL;
- }
- kfree(task);
-
- if (rl_cmd) {
- if (rl_cmd->rl_buf) {
- kfree(rl_cmd->rl_buf);
- rl_cmd->rl_buf = NULL;
- }
- kfree(rl_cmd);
- }
- return(-1);
-}
-
-/* iscsi_build_report_luns_response():
- *
- *
- */
-extern int iscsi_build_report_luns_response (
- se_cmd_t *se_cmd)
-{
- unsigned char *buf = NULL;
- u32 cdb_offset = 0, lun_count = 0, offset = 8;
- u64 i, lun;
- se_dev_entry_t *deve;
- se_lun_t *se_lun;
- se_session_t *sess = SE_SESS(se_cmd);
- se_task_t *task;
- rl_cmd_t *rl_cmd;
-
- list_for_each_entry(task, &T_TASK(se_cmd)->t_task_list, t_list) {
- rl_cmd = (rl_cmd_t *) task->transport_req;
- buf = rl_cmd->rl_buf;
- }
-
- spin_lock_bh(&SE_NODE_ACL(sess)->device_list_lock);
- for (i = 0; i < ISCSI_MAX_LUNS_PER_TPG; i++) {
- deve = &SE_NODE_ACL(sess)->device_list[i];
- if (!(deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS))
- continue;
- se_lun = deve->se_lun;
-
- /*
- * We determine the correct LUN LIST LENGTH even once we
- * have reached the initial allocation length.
- * See SPC2-R20 7.19.
- */
- lun_count++;
- if ((cdb_offset + 8) > se_cmd->data_length)
- continue;
-
- lun = cpu_to_be64(CMD_TFO(se_cmd)->pack_lun(deve->mapped_lun));
- buf[offset++] = ((lun >> 56) & 0xff);
- buf[offset++] = ((lun >> 48) & 0xff);
- buf[offset++] = ((lun >> 40) & 0xff);
- buf[offset++] = ((lun >> 32) & 0xff);
- buf[offset++] = ((lun >> 24) & 0xff);
- buf[offset++] = ((lun >> 16) & 0xff);
- buf[offset++] = ((lun >> 8) & 0xff);
- buf[offset++] = (lun & 0xff);
- cdb_offset += 8;
- }
- spin_unlock_bh(&SE_NODE_ACL(sess)->device_list_lock);
-
- /*
- * See SPC3 r07, page 159.
- */
- lun_count *= 8;
- buf[0] = ((lun_count >> 24) & 0xff);
- buf[1] = ((lun_count >> 16) & 0xff);
- buf[2] = ((lun_count >> 8) & 0xff);
- buf[3] = (lun_count & 0xff);
-
- CMD_TFO(se_cmd)->queue_data_in(se_cmd);
-
- return(0);
-}
-
-/* rl_check_for_SG():
- *
- *
- */
-extern int rl_check_for_SG (se_task_t *task)
-{
- return(0);
-}
-
-/* rl_free_task():
- *
- *
- */
-extern void rl_free_task (se_task_t *task)
-{
- rl_cmd_t *rl_cmd = (rl_cmd_t *) task->transport_req;
- se_cmd_t *se_cmd = rl_cmd->rl_se_cmd;
-
- /*
- * Free the pseudo device.
- */
- if (task->se_dev) {
- kfree(task->se_dev);
- task->se_dev = NULL;
- }
-
- if (se_cmd->se_lun) {
- kfree(se_cmd->se_lun);
- se_cmd->se_lun = NULL;
- }
-
- if (rl_cmd->rl_buf) {
- kfree(rl_cmd->rl_buf);
- rl_cmd->rl_buf = NULL;
- }
-
- kfree(rl_cmd);
-
- return;
-}
diff --git a/drivers/lio-core/target_core_reportluns.h b/drivers/lio-core/target_core_reportluns.h
deleted file mode 100644
index 3296675..0000000
--- a/drivers/lio-core/target_core_reportluns.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*********************************************************************************
- * Filename: target_core_reportluns.h
- *
- * This file contains the iSCSI Target REPORT_LUNS definitions.
- *
- * Copyright (c) 2004 PyX Technologies, Inc.
- * Copyright (c) 2005, 2006, 2007 SBE, Inc.
- * Copyright (c) 2007 Rising Tide Software, Inc.
- *
- * Nicholas A. Bellinger <nab@xxxxxxxxxx>
- *
- * 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.
- *
- *********************************************************************************/
-
-
-#ifndef TARGET_CORE_REPORTLUNS_H
-#define TARGET_CORE_REPORTLUNS_H
-
-typedef struct rl_cmd_s {
- struct se_cmd_s *rl_se_cmd;
- unsigned char *rl_buf;
- u32 rl_size;
-} rl_cmd_t;
-
-extern int se_allocate_rl_cmd (se_cmd_t *, unsigned char *, u32);
-extern int se_build_report_luns_response (se_cmd_t *);
-
-#ifndef RL_INCLUDE_STRUCTS
-extern int rl_check_for_SG (se_task_t *);
-extern void rl_free_task (se_task_t *);
-
-#define TARGET_CORE_RL { \
- name: "RL", \
- check_for_SG: rl_check_for_SG, \
- free_task: rl_free_task, \
-};
-
-se_subsystem_api_t _rl_template = TARGET_CORE_RL;
-#endif /* RL_INCLUDE_STRUCTS */
-
-#endif /*** TARGET_CORE_REPORTLUNS_H ***/
-
diff --git a/drivers/lio-core/target_core_transport.c b/drivers/lio-core/target_core_transport.c
index 83727d2..f02bf56 100644
--- a/drivers/lio-core/target_core_transport.c
+++ b/drivers/lio-core/target_core_transport.c
@@ -904,13 +904,6 @@ static void transport_lun_remove_cmd (se_cmd_t *cmd)
if (cmd->se_cmd_flags & SCF_CMD_PASSTHROUGH)
return;

- /*
- * REPORT_LUNS will be coming from the FE, and should not
- * be tracked.
- */
- if (cmd->se_cmd_flags & SCF_REPORT_LUNS)
- return;
-
spin_lock_irqsave(&lun->lun_cmd_lock, flags);
if (atomic_read(&T_TASK(cmd)->transport_lun_active)) {
REMOVE_ENTRY_FROM_LIST_PREFIX(l, cmd,
@@ -3560,13 +3553,27 @@ check_depth:

transport_start_task_timer(task);
spin_unlock_irqrestore(&T_TASK(cmd)->t_state_lock, flags);
-
- if ((error = TRANSPORT(dev)->do_task(task)) != 0) {
- cmd->transport_error_status = error;
- atomic_set(&task->task_active, 0);
- atomic_set(&cmd->transport_sent, 0);
- transport_stop_tasks_for_cmd(cmd);
- transport_generic_request_failure(cmd, dev, 0, 1);
+ /*
+ * The se_cmd_t->transport_emulate_cdb() function pointer is used
+ * to grab REPORT_LUNS CDBs before they hit the
+ * se_subsystem_api_t->do_task() caller below.
+ */
+ if (cmd->transport_emulate_cdb) {
+ if ((error = cmd->transport_emulate_cdb(cmd)) != 0) {
+ cmd->transport_error_status = error;
+ atomic_set(&task->task_active, 0);
+ atomic_set(&cmd->transport_sent, 0);
+ transport_stop_tasks_for_cmd(cmd);
+ transport_generic_request_failure(cmd, dev, 0, 1);
+ }
+ } else {
+ if ((error = TRANSPORT(dev)->do_task(task)) != 0) {
+ cmd->transport_error_status = error;
+ atomic_set(&task->task_active, 0);
+ atomic_set(&cmd->transport_sent, 0);
+ transport_stop_tasks_for_cmd(cmd);
+ transport_generic_request_failure(cmd, dev, 0, 1);
+ }
}

goto check_depth;
@@ -4363,8 +4370,13 @@ static int transport_generic_cmd_sequencer (
ret = 3;
break;
case REPORT_LUNS:
- TRACE_ERROR("Huh? REPORT_LUNS in sequencer.\n");
- BUG();
+ SET_GENERIC_PYX_TRANSPORT_FUNCTIONS(cmd);
+ cmd->transport_emulate_cdb = &transport_core_report_lun_response;
+ size = (cdb[6] << 24) | (cdb[7] << 16) | (cdb[8] << 8) | cdb[9];
+ CMD_ORIG_OBJ_API(cmd)->get_mem_buf(cmd->se_orig_obj_ptr, cmd);
+ transport_get_maps(cmd);
+ ret = 2;
+ break;
default:
TRACE_ERROR("Unsupported SCSI Opcode 0x%02x, sending"
" CHECK_CONDITION.\n", cdb[0]);
--
1.5.4.1



--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/