lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <1239930560.4176.577.camel@haakon2.linux-iscsi.org>
Date:	Thu, 16 Apr 2009 18:09:20 -0700
From:	"Nicholas A. Bellinger" <nab@...ux-iscsi.org>
To:	linux-scsi <linux-scsi@...r.kernel.org>,
	LKML <linux-kernel@...r.kernel.org>
Cc:	James Bottomley <James.Bottomley@...senPartnership.com>,
	FUJITA Tomonori <fujita.tomonori@....ntt.co.jp>,
	Mike Christie <michaelc@...wisc.edu>,
	Jens Axboe <jens.axboe@...cle.com>,
	Geert Uytterhoeven <Geert.Uytterhoeven@...ycom.com>,
	Geoff Levand <geoffrey.levand@...sony.com>,
	Douglas Gilbert <dgilbert@...erlog.com>,
	Christoph Hellwig <hch@....de>,
	Paul Mundt <lethal@...ux-sh.org>
Subject: [PATCH] [Target_Core_Mod/pSCSI]: Add optional legacy
	scsi_execute_async() usage for Linux/SCSI passthrough

Greetings all,

This patch modifies the Target_Core_Mod/ConfigFS v3.0 PSCSI subsystem plugin for target_core_mod v3.0 to add
a configurable method of choosing legacy scsi_execute_async() usage for underlying SCSI HTCL struct scsi_device.
This method is still the only method of issuing I/O to the Linux SCSI subsystem is used for non TYPE_DISK hardware
SCSI and SATA devices that appear under Linux-SCSI, but have not yet been updated to accept raw struct request
operations directly.  Some of these include TYPE_ROM, TYPE_TYPE and TYPE_MEDIUM_CHANGER hardware.

This method can be used be used via ConfigFS as follows:

	export TARGET=/sys/kernel/config/target/core/
        # load target_core_mod
	modprobe target_core_mod
	# The Linux/SCSI scsi host id is part of pscsi_$HOST_ID HBA name..
	mkdir -p $TARGET/pscsi_0/sr0
	# echo CTL to the control configfs attribute
	echo scsi_channel_id=0,scsi_target_id=0,scsi_lun_id=0 > $TARGET/pscsi_0/sr0/control
        # Activate the target_core_mod/ConfigFS PSCSI storage object
	echo 1 > $TARGET/pscsi_0/sr0/enable

At this point, creating symlinks for SCSI target ports to configfs enabled fabric modules
against PSCSI hardware passthrough using te HCTL reference will work.

This patch are made against lio-core-2.6.git/master and tested on
v2.6.29 x86 32-bit HVM with TYPE_DISK and v2.6.29 ppc64 with TYPE_ROM.
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

:-)

Signed-off-by: Nicholas A. Bellinger <nab@...ux-iscsi.org>
---
 drivers/target/target_core_pscsi.c |   88 +++++++++++++++++++++++++++++++-----
 include/target/target_core_pscsi.h |    2 +
 2 files changed, 79 insertions(+), 11 deletions(-)

diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c
index 0962563..66510f4 100644
--- a/drivers/target/target_core_pscsi.c
+++ b/drivers/target/target_core_pscsi.c
@@ -399,6 +399,8 @@ void *pscsi_allocate_virtdevice(se_hba_t *hba, const char *name)
 		return NULL;
 	}
 	pdv->pdv_se_hba = hba;
+	/* Use legacy path unless using ConfigFS FD method */
+	pdv->pdv_legacy = 1;
 
 	printk(KERN_INFO "PSCSI: Allocated pdv: %p for %s\n", pdv, name);
 	return (void *)pdv;
@@ -555,9 +557,10 @@ int pscsi_activate_device(se_device_t *dev)
 	struct scsi_device *sd = (struct scsi_device *) pdv->pdv_sd;
 	struct Scsi_Host *sh = sd->host;
 
-	printk(KERN_INFO "CORE_PSCSI[%d] - Activating Device with TCQ: %d at"
+	printk(KERN_INFO "CORE_PSCSI[%d] - Activating %s Device with TCQ: %d at"
 		" SCSI Location (Channel/Target/LUN) %d/%d/%d\n", sh->host_no,
-		 sd->queue_depth, sd->channel, sd->id, sd->lun);
+		(pdv->pdv_legacy) ? "Legacy" : "REQ",  sd->queue_depth,
+		sd->channel, sd->id, sd->lun);
 
 	return 0;
 }
@@ -572,8 +575,9 @@ void pscsi_deactivate_device(se_device_t *dev)
 	struct scsi_device *sd = (struct scsi_device *) pdv->pdv_sd;
 	struct Scsi_Host *sh = sd->host;
 
-	printk(KERN_INFO "CORE_PSCSI[%d] - Deactivating Device with TCQ: %d at"
-		" SCSI Location (Channel/Target/LUN) %d/%d/%d\n", sh->host_no,
+	printk(KERN_INFO "CORE_PSCSI[%d] - Deactivating %s Device with TCQ: %d"
+		" at SCSI Location (Channel/Target/LUN) %d/%d/%d\n",
+		sh->host_no, (pdv->pdv_legacy) ? "Legacy" : "REQ",
 		sd->queue_depth, sd->channel, sd->id, sd->lun);
 }
 
@@ -843,6 +847,30 @@ static int pscsi_blk_get_request(se_task_t *task)
 	return 0;
 }
 
+static int pscsi_do_task_legacy(
+	se_task_t *task,
+	pscsi_plugin_task_t *pt,
+	pscsi_dev_virt_t *pdv)
+{
+	se_cmd_t *cmd = TASK_CMD(task);
+	void *pscsi_buf = (task->task_sg_num != 0) ? task->task_sg :
+			T_TASK(cmd)->t_task_buf;
+	int ret;
+
+	ret = scsi_execute_async(pdv->pdv_sd, pt->pscsi_cdb,
+			COMMAND_SIZE(pt->pscsi_cdb[0]), pt->pscsi_direction,
+			pscsi_buf, task->task_size, task->task_sg_num,
+			(pdv->pdv_sd->type == TYPE_DISK) ? PS_TIMEOUT_DISK :
+			PS_TIMEOUT_OTHER, PS_RETRY, (void *)task,
+			pscsi_req_done_legacy, GFP_KERNEL);
+	if (ret != 0) {
+		printk(KERN_ERR "PSCSI Execute(): returned: %d\n", ret);
+		return PYX_TRANSPORT_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+	}
+
+	return 0;
+}
+
 /*      pscsi_do_task(): (Part of se_subsystem_api_t template)
  *
  *
@@ -852,6 +880,9 @@ int pscsi_do_task(se_task_t *task)
 	pscsi_plugin_task_t *pt = (pscsi_plugin_task_t *) task->transport_req;
 	pscsi_dev_virt_t *pdv = (pscsi_dev_virt_t *) task->se_dev->dev_ptr;
 	struct gendisk *gd = NULL;
+
+	if (pdv->pdv_legacy)
+		return pscsi_do_task_legacy(task, pt, pdv);
 	/*
 	 * Grab pointer to struct gendisk for TYPE_DISK and TYPE_ROM
 	 * cases (eg: cases where struct scsi_device has a backing
@@ -1104,6 +1135,7 @@ se_device_t *pscsi_create_virtdevice_from_fd(
 		 * Keep track of the struct block_device for now..
 		 */
 		pdv->pdv_bd = bd;
+		pdv->pdv_legacy = 0;
 		/*
 		 * pscsi_create_type_[disk,rom]() will release host_lock..
 		 */
@@ -1286,6 +1318,9 @@ int pscsi_map_task_SG(se_task_t *task)
 			PAGE_SIZE - 1) >> PAGE_SHIFT;
 	int nr_vecs = 0, ret = 0;
 
+	if (pdv->pdv_legacy)
+		return 0;
+
 	if (!task->task_size)
 		return 0;
 	/*
@@ -1387,6 +1422,9 @@ int pscsi_map_task_non_SG(se_task_t *task)
 	pscsi_dev_virt_t *pdv = (pscsi_dev_virt_t *) task->se_dev->dev_ptr;
 	int ret = 0;
 
+	if (pdv->pdv_legacy)
+		return 0;
+
 	if (!task->task_size)
 		return 0;
 
@@ -1407,8 +1445,12 @@ int pscsi_map_task_non_SG(se_task_t *task)
 int pscsi_CDB_inquiry(se_task_t *task, u32 size)
 {
 	pscsi_plugin_task_t *pt = (pscsi_plugin_task_t *) task->transport_req;
+	pscsi_dev_virt_t *pdv = (pscsi_dev_virt_t *) task->se_dev->dev_ptr;
 
 	pt->pscsi_direction = DMA_FROM_DEVICE;
+	if (pdv->pdv_legacy)
+		return pscsi_map_task_non_SG(task);
+
 	if (pscsi_blk_get_request(task) < 0)
 		return -1;
 
@@ -1418,10 +1460,11 @@ int pscsi_CDB_inquiry(se_task_t *task, u32 size)
 int pscsi_CDB_none(se_task_t *task, u32 size)
 {
 	pscsi_plugin_task_t *pt = (pscsi_plugin_task_t *) task->transport_req;
+	pscsi_dev_virt_t *pdv = (pscsi_dev_virt_t *) task->se_dev->dev_ptr;
 
 	pt->pscsi_direction = DMA_NONE;
 
-	return pscsi_blk_get_request(task);
+	return (pdv->pdv_legacy) ? 0 : pscsi_blk_get_request(task);
 }
 
 /*	pscsi_CDB_read_non_SG():
@@ -1431,8 +1474,11 @@ int pscsi_CDB_none(se_task_t *task, u32 size)
 int pscsi_CDB_read_non_SG(se_task_t *task, u32 size)
 {
 	pscsi_plugin_task_t *pt = (pscsi_plugin_task_t *) task->transport_req;
+	pscsi_dev_virt_t *pdv = (pscsi_dev_virt_t *) task->se_dev->dev_ptr;
 
 	pt->pscsi_direction = DMA_FROM_DEVICE;
+	if (pdv->pdv_legacy)
+		return pscsi_map_task_non_SG(task);
 
 	if (pscsi_blk_get_request(task) < 0)
 		return PYX_TRANSPORT_LOGICAL_UNIT_COMMUNICATION_FAILURE;
@@ -1447,11 +1493,13 @@ int pscsi_CDB_read_non_SG(se_task_t *task, u32 size)
 int pscsi_CDB_read_SG(se_task_t *task, u32 size)
 {
 	pscsi_plugin_task_t *pt = (pscsi_plugin_task_t *) task->transport_req;
+	pscsi_dev_virt_t *pdv = (pscsi_dev_virt_t *) task->se_dev->dev_ptr;
 
 	pt->pscsi_direction = DMA_FROM_DEVICE;
 
-	if (pscsi_blk_get_request(task) < 0)
-		return PYX_TRANSPORT_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+	if (!(pdv->pdv_legacy))
+		if (pscsi_blk_get_request(task) < 0)
+			return PYX_TRANSPORT_LOGICAL_UNIT_COMMUNICATION_FAILURE;
 
 	if (pscsi_map_task_SG(task) < 0)
 		return PYX_TRANSPORT_LOGICAL_UNIT_COMMUNICATION_FAILURE;
@@ -1466,11 +1514,13 @@ int pscsi_CDB_read_SG(se_task_t *task, u32 size)
 int pscsi_CDB_write_non_SG(se_task_t *task, u32 size)
 {
 	pscsi_plugin_task_t *pt = (pscsi_plugin_task_t *) task->transport_req;
+	pscsi_dev_virt_t *pdv = (pscsi_dev_virt_t *) task->se_dev->dev_ptr;
 
 	pt->pscsi_direction = DMA_TO_DEVICE;
 
-	if (pscsi_blk_get_request(task) < 0)
-		return PYX_TRANSPORT_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+	if (!(pdv->pdv_legacy))
+		if (pscsi_blk_get_request(task) < 0)
+			return PYX_TRANSPORT_LOGICAL_UNIT_COMMUNICATION_FAILURE;
 
 	return pscsi_map_task_non_SG(task);
 }
@@ -1482,11 +1532,13 @@ int pscsi_CDB_write_non_SG(se_task_t *task, u32 size)
 int pscsi_CDB_write_SG(se_task_t *task, u32 size)
 {
 	pscsi_plugin_task_t *pt = (pscsi_plugin_task_t *) task->transport_req;
+	pscsi_dev_virt_t *pdv = (pscsi_dev_virt_t *) task->se_dev->dev_ptr;
 
 	pt->pscsi_direction = DMA_TO_DEVICE;
 
-	if (pscsi_blk_get_request(task) < 0)
-		return PYX_TRANSPORT_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+	if (!(pdv->pdv_legacy))
+		if (pscsi_blk_get_request(task) < 0)
+			return PYX_TRANSPORT_LOGICAL_UNIT_COMMUNICATION_FAILURE;
 
 	if (pscsi_map_task_SG(task) < 0)
 		return PYX_TRANSPORT_LOGICAL_UNIT_COMMUNICATION_FAILURE;
@@ -1643,6 +1695,20 @@ static inline void pscsi_process_SAM_status(
 	return;
 }
 
+void pscsi_req_done_legacy(void *data, char *sense, int result, int data_len)
+{
+	se_task_t *task = (se_task_t *)data;
+	pscsi_plugin_task_t *pt = (pscsi_plugin_task_t *)task->transport_req;
+
+	pt->pscsi_result = result;
+	pt->pscsi_resid = data_len;
+
+	if (result != 0)
+		memcpy(pt->pscsi_sense, sense, SCSI_SENSE_BUFFERSIZE);	
+
+	pscsi_process_SAM_status(task, pt);
+}
+
 void pscsi_req_done(struct request *req, int uptodate)
 {
 	se_task_t *task = (se_task_t *)req->end_io_data;
diff --git a/include/target/target_core_pscsi.h b/include/target/target_core_pscsi.h
index b05b793..0e1d6cf 100644
--- a/include/target/target_core_pscsi.h
+++ b/include/target/target_core_pscsi.h
@@ -94,6 +94,7 @@ extern u32 pscsi_get_dma_length(u32, se_device_t *);
 extern u32 pscsi_get_max_sectors(se_device_t *);
 extern u32 pscsi_get_queue_depth(se_device_t *);
 extern void pscsi_shutdown_hba(struct se_hba_s *);
+extern void pscsi_req_done_legacy(void *, char *, int, int);
 extern void pscsi_req_done(struct request *, int);
 #endif
 
@@ -120,6 +121,7 @@ typedef struct pscsi_plugin_task_s {
 
 typedef struct pscsi_dev_virt_s {
 	int	pdv_flags;
+	int	pdv_legacy; /* Use scsi_execute_async() from HTCL */
 	int	pdv_channel_id;
 	int	pdv_target_id;
 	int	pdv_lun_id;
-- 
1.5.4.1



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

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ