[PATCH 1/8] qla4xxx: Take E-port out of reset before disabling pause frames

2013-03-07 Thread vikas . chaudhary
From: Manish Dusane manish.dus...@qlogic.com

Problem Description:
Disabling pause frames might cause hardware wedging needing a power cycle.
This might happen if the Eport is not initialized and is in reset.

Solution:
Before disabling pause frames ensure that eport is out of reset.

Signed-off-by: Manish Dusane manish.dus...@qlogic.com
Signed-off-by: Vikas Chaudhary vikas.chaudh...@qlogic.com
---
 drivers/scsi/qla4xxx/ql4_83xx.c | 28 
 drivers/scsi/qla4xxx/ql4_83xx.h | 10 ++
 2 files changed, 38 insertions(+)

diff --git a/drivers/scsi/qla4xxx/ql4_83xx.c b/drivers/scsi/qla4xxx/ql4_83xx.c
index 5d8fe4f..d607eb8 100644
--- a/drivers/scsi/qla4xxx/ql4_83xx.c
+++ b/drivers/scsi/qla4xxx/ql4_83xx.c
@@ -1629,9 +1629,37 @@ static void __qla4_83xx_disable_pause(struct 
scsi_qla_host *ha)
ql4_printk(KERN_INFO, ha, Disabled pause frames successfully.\n);
 }
 
+/**
+ * qla4_83xx_eport_init - Initialize EPort.
+ * @ha: Pointer to host adapter structure.
+ *
+ * If EPort hardware is in reset state before disabling pause, there would be
+ * serious hardware wedging issues. To prevent this perform eport init 
everytime
+ * before disabling pause frames.
+ **/
+static void qla4_83xx_eport_init(struct scsi_qla_host *ha)
+{
+   /* Clear the 8 registers */
+   qla4_83xx_wr_reg_indirect(ha, QLA83XX_RESET_REG, 0x0);
+   qla4_83xx_wr_reg_indirect(ha, QLA83XX_RESET_PORT0, 0x0);
+   qla4_83xx_wr_reg_indirect(ha, QLA83XX_RESET_PORT1, 0x0);
+   qla4_83xx_wr_reg_indirect(ha, QLA83XX_RESET_PORT2, 0x0);
+   qla4_83xx_wr_reg_indirect(ha, QLA83XX_RESET_PORT3, 0x0);
+   qla4_83xx_wr_reg_indirect(ha, QLA83XX_RESET_SRE_SHIM, 0x0);
+   qla4_83xx_wr_reg_indirect(ha, QLA83XX_RESET_EPG_SHIM, 0x0);
+   qla4_83xx_wr_reg_indirect(ha, QLA83XX_RESET_ETHER_PCS, 0x0);
+
+   /* Write any value to Reset Control register */
+   qla4_83xx_wr_reg_indirect(ha, QLA83XX_RESET_CONTROL, 0xFF);
+
+   ql4_printk(KERN_INFO, ha, EPORT is out of reset.\n);
+}
+
 void qla4_83xx_disable_pause(struct scsi_qla_host *ha)
 {
ha-isp_ops-idc_lock(ha);
+   /* Before disabling pause frames, ensure that eport is not in reset */
+   qla4_83xx_eport_init(ha);
qla4_83xx_dump_pause_control_regs(ha);
__qla4_83xx_disable_pause(ha);
ha-isp_ops-idc_unlock(ha);
diff --git a/drivers/scsi/qla4xxx/ql4_83xx.h b/drivers/scsi/qla4xxx/ql4_83xx.h
index 6a00f90..fab237f 100644
--- a/drivers/scsi/qla4xxx/ql4_83xx.h
+++ b/drivers/scsi/qla4xxx/ql4_83xx.h
@@ -55,6 +55,16 @@
 #define QLA83XX_SET_PAUSE_VAL  0x0
 #define QLA83XX_SET_TC_MAX_CELL_VAL0x03FF03FF
 
+#define QLA83XX_RESET_CONTROL  0x28084E50
+#define QLA83XX_RESET_REG  0x28084E60
+#define QLA83XX_RESET_PORT00x28084E70
+#define QLA83XX_RESET_PORT10x28084E80
+#define QLA83XX_RESET_PORT20x28084E90
+#define QLA83XX_RESET_PORT30x28084EA0
+#define QLA83XX_RESET_SRE_SHIM 0x28084EB0
+#define QLA83XX_RESET_EPG_SHIM 0x28084EC0
+#define QLA83XX_RESET_ETHER_PCS0x28084ED0
+
 /* qla_83xx_reg_tbl registers */
 #define QLA83XX_PEG_HALT_STATUS1   0x34A8
 #define QLA83XX_PEG_HALT_STATUS2   0x34AC
-- 
1.8.0

--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/8] qla4xxx: Boot from SAN fix for ISP83XX

2013-03-07 Thread vikas . chaudhary
From: Vikas Chaudhary vikas.chaudh...@qlogic.com

Issue:
ISP83XX check is missing in function get_fw_boot_info() because of this
qla4xxx will not export boot target to sysfs and iscsistart cannot issue
login to boot target.

Fix:
Added check for ISP83XX in function get_fw_boot_info()

Signed-off-by: Vikas Chaudhary vikas.chaudh...@qlogic.com
---
 drivers/scsi/qla4xxx/ql4_os.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index 6142729..1c387e7 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -4005,7 +4005,7 @@ static int get_fw_boot_info(struct scsi_qla_host *ha, 
uint16_t ddb_index[])
if (val  BIT_7)
ddb_index[1] = (val  0x7f);
 
-   } else if (is_qla8022(ha)) {
+   } else if (is_qla80XX(ha)) {
buf = dma_alloc_coherent(ha-pdev-dev, size,
 buf_dma, GFP_KERNEL);
if (!buf) {
-- 
1.8.0

--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 4/8] qla4xxx: Fix double reset in case of firmware hung for ISP83XX

2013-03-07 Thread vikas . chaudhary
From: Vikas Chaudhary vikas.chaudh...@qlogic.com

In case of firmware hung we need to call mailbox_premature_completion to
complete any pending mbox command as firmware is not alive.

Signed-off-by: Vikas Chaudhary vikas.chaudh...@qlogic.com
---
 drivers/scsi/qla4xxx/ql4_os.c | 18 --
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index b3ccb1a..ade1ba6 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -2543,6 +2543,7 @@ static void qla4_8xxx_process_fw_error(struct 
scsi_qla_host *ha)
 void qla4_8xxx_watchdog(struct scsi_qla_host *ha)
 {
uint32_t dev_state;
+   uint32_t idc_ctrl;
 
/* don't poll if reset is going on */
if (!(test_bit(DPC_RESET_ACTIVE, ha-dpc_flags) ||
@@ -2561,10 +2562,23 @@ void qla4_8xxx_watchdog(struct scsi_qla_host *ha)
qla4xxx_wake_dpc(ha);
} else if (dev_state == QLA8XXX_DEV_NEED_RESET 
   !test_bit(DPC_RESET_HA, ha-dpc_flags)) {
+
+   ql4_printk(KERN_INFO, ha, %s: HW State: NEED RESET!\n,
+  __func__);
+
+   if (is_qla8032(ha)) {
+   idc_ctrl = qla4_83xx_rd_reg(ha,
+   QLA83XX_IDC_DRV_CTRL);
+   if (!(idc_ctrl  GRACEFUL_RESET_BIT1)) {
+   ql4_printk(KERN_INFO, ha, %s: Graceful 
reset bit is not set\n,
+  __func__);
+   qla4xxx_mailbox_premature_completion(
+   ha);
+   }
+   }
+
if (is_qla8032(ha) ||
(is_qla8022(ha)  !ql4xdontresethba)) {
-   ql4_printk(KERN_INFO, ha, %s: HW State: 
-   NEED RESET!\n, __func__);
set_bit(DPC_RESET_HA, ha-dpc_flags);
qla4xxx_wake_dpc(ha);
}
-- 
1.8.0

--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 7/8] qla4xxx: Fixed request queue count manipulation on response path

2013-03-07 Thread vikas . chaudhary
From: Tej Parkash tej.park...@qlogic.com

Issue:
Request queue count holds the information about free space in request queue
which has to be manipulated based on request in and out pointer.
But in driver response path, this count was incremented unconditionally,
which could move req_in pointer beyond req_out pointer.
This scenario leads fw hang during IO.

Solution:
Request queue count manipulation has to be done in IO path only, keeping
req_in and req_out pointer two IOCB count away

Signed-off-by: Tej Parkash tej.park...@qlogic.com
Signed-off-by: Shyam Sundar shyam.sun...@qlogic.com
Signed-off-by: Vikas Chaudhary vikas.chaudh...@qlogic.com
---
 drivers/scsi/qla4xxx/ql4_glbl.h |  2 --
 drivers/scsi/qla4xxx/ql4_isr.c  |  2 --
 drivers/scsi/qla4xxx/ql4_os.c   | 15 ++-
 3 files changed, 2 insertions(+), 17 deletions(-)

diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h
index 982293e..22706f6 100644
--- a/drivers/scsi/qla4xxx/ql4_glbl.h
+++ b/drivers/scsi/qla4xxx/ql4_glbl.h
@@ -224,8 +224,6 @@ void qla4_83xx_interrupt_service_routine(struct 
scsi_qla_host *ha,
 int qla4_83xx_isp_reset(struct scsi_qla_host *ha);
 void qla4_83xx_queue_iocb(struct scsi_qla_host *ha);
 void qla4_83xx_complete_iocb(struct scsi_qla_host *ha);
-uint16_t qla4_83xx_rd_shdw_req_q_out(struct scsi_qla_host *ha);
-uint16_t qla4_83xx_rd_shdw_rsp_q_in(struct scsi_qla_host *ha);
 uint32_t qla4_83xx_rd_reg(struct scsi_qla_host *ha, ulong addr);
 void qla4_83xx_wr_reg(struct scsi_qla_host *ha, ulong addr, uint32_t val);
 int qla4_83xx_rd_reg_indirect(struct scsi_qla_host *ha, uint32_t addr,
diff --git a/drivers/scsi/qla4xxx/ql4_isr.c b/drivers/scsi/qla4xxx/ql4_isr.c
index e02a884..7bef448 100644
--- a/drivers/scsi/qla4xxx/ql4_isr.c
+++ b/drivers/scsi/qla4xxx/ql4_isr.c
@@ -396,7 +396,6 @@ static void qla4xxx_passthru_status_entry(struct 
scsi_qla_host *ha,
 
task_data = task-dd_data;
memcpy(task_data-sts, sts_entry, sizeof(struct passthru_status));
-   ha-req_q_count += task_data-iocb_req_cnt;
ha-iocb_cnt -= task_data-iocb_req_cnt;
queue_work(ha-task_wq, task_data-task_work);
 }
@@ -416,7 +415,6 @@ static struct mrb *qla4xxx_del_mrb_from_active_array(struct 
scsi_qla_host *ha,
return mrb;
 
/* update counters */
-   ha-req_q_count += mrb-iocb_cnt;
ha-iocb_cnt -= mrb-iocb_cnt;
 
return mrb;
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index ade1ba6..a6ce04d 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -3751,8 +3751,8 @@ static struct isp_operations qla4_83xx_isp_ops = {
.reset_firmware = qla4_8xxx_stop_firmware,
.queue_iocb = qla4_83xx_queue_iocb,
.complete_iocb  = qla4_83xx_complete_iocb,
-   .rd_shdw_req_q_out  = qla4_83xx_rd_shdw_req_q_out,
-   .rd_shdw_rsp_q_in   = qla4_83xx_rd_shdw_rsp_q_in,
+   .rd_shdw_req_q_out  = qla4xxx_rd_shdw_req_q_out,
+   .rd_shdw_rsp_q_in   = qla4xxx_rd_shdw_rsp_q_in,
.get_sys_info   = qla4_8xxx_get_sys_info,
.rd_reg_direct  = qla4_83xx_rd_reg,
.wr_reg_direct  = qla4_83xx_wr_reg,
@@ -3775,11 +3775,6 @@ uint16_t qla4_82xx_rd_shdw_req_q_out(struct 
scsi_qla_host *ha)
return (uint16_t)le32_to_cpu(readl(ha-qla4_82xx_reg-req_q_out));
 }
 
-uint16_t qla4_83xx_rd_shdw_req_q_out(struct scsi_qla_host *ha)
-{
-   return (uint16_t)le32_to_cpu(readl(ha-qla4_83xx_reg-req_q_out));
-}
-
 uint16_t qla4xxx_rd_shdw_rsp_q_in(struct scsi_qla_host *ha)
 {
return (uint16_t)le32_to_cpu(ha-shadow_regs-rsp_q_in);
@@ -3790,11 +3785,6 @@ uint16_t qla4_82xx_rd_shdw_rsp_q_in(struct scsi_qla_host 
*ha)
return (uint16_t)le32_to_cpu(readl(ha-qla4_82xx_reg-rsp_q_in));
 }
 
-uint16_t qla4_83xx_rd_shdw_rsp_q_in(struct scsi_qla_host *ha)
-{
-   return (uint16_t)le32_to_cpu(readl(ha-qla4_83xx_reg-rsp_q_in));
-}
-
 static ssize_t qla4xxx_show_boot_eth_info(void *data, int type, char *buf)
 {
struct scsi_qla_host *ha = data;
@@ -5683,7 +5673,6 @@ struct srb *qla4xxx_del_from_active_array(struct 
scsi_qla_host *ha,
 
/* update counters */
if (srb-flags  SRB_DMA_VALID) {
-   ha-req_q_count += srb-iocb_cnt;
ha-iocb_cnt -= srb-iocb_cnt;
if (srb-cmd)
srb-cmd-host_scribble =
-- 
1.8.0

--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 8/8] qla4xxx: Update driver version to 5.03.00-k5

2013-03-07 Thread vikas . chaudhary
From: Vikas Chaudhary vikas.chaudh...@qlogic.com

Signed-off-by: Vikas Chaudhary vikas.chaudh...@qlogic.com
---
 drivers/scsi/qla4xxx/ql4_version.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/qla4xxx/ql4_version.h 
b/drivers/scsi/qla4xxx/ql4_version.h
index 6775a45..4540028 100644
--- a/drivers/scsi/qla4xxx/ql4_version.h
+++ b/drivers/scsi/qla4xxx/ql4_version.h
@@ -5,4 +5,4 @@
  * See LICENSE.qla4xxx for copyright and licensing details.
  */
 
-#define QLA4XXX_DRIVER_VERSION 5.03.00-k4
+#define QLA4XXX_DRIVER_VERSION 5.03.00-k5
-- 
1.8.0

--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 6/8] qla4xxx: Fix debug level to avoid floods of same message

2013-03-07 Thread vikas . chaudhary
From: Vikas Chaudhary vikas.chaudh...@qlogic.com

Move Incorrect function ID print message in case INTX interrupt
from DEBUG2 to DEBUG7. This will avoid floods of this message if
DEBUG2 is enabled.

Signed-off-by: Vikas Chaudhary vikas.chaudh...@qlogic.com
---
 drivers/scsi/qla4xxx/ql4_dbg.h | 7 +++
 drivers/scsi/qla4xxx/ql4_isr.c | 8 
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/qla4xxx/ql4_dbg.h b/drivers/scsi/qla4xxx/ql4_dbg.h
index 5b0afc1..51c365b 100644
--- a/drivers/scsi/qla4xxx/ql4_dbg.h
+++ b/drivers/scsi/qla4xxx/ql4_dbg.h
@@ -12,6 +12,7 @@
 /* #define QL_DEBUG_LEVEL_3  *//* Output function tracing */
 /* #define QL_DEBUG_LEVEL_4  */
 /* #define QL_DEBUG_LEVEL_5  */
+/* #define QL_DEBUG_LEVEL_7  */
 /* #define QL_DEBUG_LEVEL_9  */
 
 #define QL_DEBUG_LEVEL_2   /* ALways enable error messagess */
@@ -48,6 +49,12 @@
 #define DEBUG5(x)  do {} while (0);
 #endif /*  */
 
+#if defined(QL_DEBUG_LEVEL_7)
+#define DEBUG7(x)  do {x; } while (0)
+#else  /*  */
+#define DEBUG7(x)  do {} while (0)
+#endif /*  */
+
 #if defined(QL_DEBUG_LEVEL_9)
 #define DEBUG9(x)  do {x;} while (0);
 #else  /*  */
diff --git a/drivers/scsi/qla4xxx/ql4_isr.c b/drivers/scsi/qla4xxx/ql4_isr.c
index 1b83dc2..e02a884 100644
--- a/drivers/scsi/qla4xxx/ql4_isr.c
+++ b/drivers/scsi/qla4xxx/ql4_isr.c
@@ -1099,8 +1099,8 @@ irqreturn_t qla4_82xx_intr_handler(int irq, void *dev_id)
 
status = qla4_82xx_rd_32(ha, ISR_INT_STATE_REG);
if (!ISR_IS_LEGACY_INTR_TRIGGERED(status)) {
-   DEBUG2(ql4_printk(KERN_INFO, ha,
-   %s legacy Int not triggered\n, __func__));
+   DEBUG7(ql4_printk(KERN_INFO, ha,
+ %s legacy Int not triggered\n, __func__));
return IRQ_NONE;
}
 
@@ -1158,7 +1158,7 @@ irqreturn_t qla4_83xx_intr_handler(int irq, void *dev_id)
 
/* Legacy interrupt is valid if bit31 of leg_int_ptr is set */
if (!(leg_int_ptr  LEG_INT_PTR_B31)) {
-   DEBUG2(ql4_printk(KERN_ERR, ha,
+   DEBUG7(ql4_printk(KERN_ERR, ha,
  %s: Legacy Interrupt Bit 31 not set, 
spurious interrupt!\n,
  __func__));
return IRQ_NONE;
@@ -1166,7 +1166,7 @@ irqreturn_t qla4_83xx_intr_handler(int irq, void *dev_id)
 
/* Validate the PCIE function ID set in leg_int_ptr bits [19..16] */
if ((leg_int_ptr  PF_BITS_MASK) != ha-pf_bit) {
-   DEBUG2(ql4_printk(KERN_ERR, ha,
+   DEBUG7(ql4_printk(KERN_ERR, ha,
  %s: Incorrect function ID 0x%x in legacy 
interrupt register, ha-pf_bit = 0x%x\n,
  __func__, (leg_int_ptr  PF_BITS_MASK),
  ha-pf_bit));
-- 
1.8.0

--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/8] qla4xxx: Updates for scsi misc branch

2013-03-07 Thread vikas . chaudhary
From: Vikas Chaudhary vikas.chaudh...@qlogic.com

James,

Please apply the following patches to the scsi tree at your earliest
convenience.

Thanks,
Vikas.

Manish Dusane (1):
  qla4xxx: Take E-port out of reset before disabling pause frames

Tej Parkash (1):
  qla4xxx: Fixed request queue count manipulation on response path

Vikas Chaudhary (6):
  qla4xxx: Boot from SAN fix for ISP83XX
  qla4xxx: Set graceful reset bit for ISP83XX
  qla4xxx: Fix double reset in case of firmware hung for ISP83XX
  qla4xxx: Pass correct LUN address to firmware in case of lun_reset
  qla4xxx: Fix debug level to avoid floods of same message
  qla4xxx: Update driver version to 5.03.00-k5

--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 5/8] qla4xxx: Pass correct LUN address to firmware in case of lun_reset

2013-03-07 Thread vikas . chaudhary
From: Vikas Chaudhary vikas.chaudh...@qlogic.com

Use function int_to_scsilun() in qla4xxx_reset_lun() to convert
integer value comming from scsi_transport to scsi LUN address format.

Signed-off-by: Vikas Chaudhary vikas.chaudh...@qlogic.com
---
 drivers/scsi/qla4xxx/ql4_mbx.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c
index 160d336..446511d 100644
--- a/drivers/scsi/qla4xxx/ql4_mbx.c
+++ b/drivers/scsi/qla4xxx/ql4_mbx.c
@@ -1129,6 +1129,7 @@ int qla4xxx_reset_lun(struct scsi_qla_host * ha, struct 
ddb_entry * ddb_entry,
 {
uint32_t mbox_cmd[MBOX_REG_COUNT];
uint32_t mbox_sts[MBOX_REG_COUNT];
+   uint32_t scsi_lun[2];
int status = QLA_SUCCESS;
 
DEBUG2(printk(scsi%ld:%d:%d: lun reset issued\n, ha-host_no,
@@ -1140,10 +1141,16 @@ int qla4xxx_reset_lun(struct scsi_qla_host * ha, struct 
ddb_entry * ddb_entry,
 */
memset(mbox_cmd, 0, sizeof(mbox_cmd));
memset(mbox_sts, 0, sizeof(mbox_sts));
+   int_to_scsilun(lun, (struct scsi_lun *) scsi_lun);
 
mbox_cmd[0] = MBOX_CMD_LUN_RESET;
mbox_cmd[1] = ddb_entry-fw_ddb_index;
-   mbox_cmd[2] = lun  8;
+   /* FW expects LUN bytes 0-3 in Incoming Mailbox 2
+* (LUN byte 0 is LSByte, byte 3 is MSByte) */
+   mbox_cmd[2] = cpu_to_le32(scsi_lun[0]);
+   /* FW expects LUN bytes 4-7 in Incoming Mailbox 3
+* (LUN byte 4 is LSByte, byte 7 is MSByte) */
+   mbox_cmd[3] = cpu_to_le32(scsi_lun[1]);
mbox_cmd[5] = 0x01; /* Immediate Command Enable */
 
qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, mbox_cmd[0], 
mbox_sts[0]);
-- 
1.8.0

--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] block: modify __bio_add_page check to accept pages that don't start a new segment

2013-03-07 Thread Jan Vesely

Hi Jens,

I have added you to cc, I'm not sure who to bug to get this patch 
merged.


thanks,
Jan Vesely

On Thu 21 Feb 2013 09:30:26 CET, Jan Vesely wrote:

The original behavior was to refuse all pages after the maximum number of
segments has been reached. However, some drivers (like st) craft their buffers
to potentially require exactly max segments and multiple pages in the last
segment. This patch modifies the check to allow pages that can be merged into
the last segment.

This change fixes EBUSY failures when using large (1mb) tape block size in high
memory fragmentation condition.

Signed-off-by: Jan Vesely jves...@redhat.com
---
 fs/bio.c |   26 --
 1 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/fs/bio.c b/fs/bio.c
index b96fc6c..02efbd5 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -500,7 +500,6 @@ static int __bio_add_page(struct request_queue *q, struct
bio *bio, struct page
   *page, unsigned int len, unsigned int offset,
   unsigned short max_sectors)
 {
-int retried_segments = 0;
 struct bio_vec *bvec;

 /*
@@ -551,18 +550,12 @@ static int __bio_add_page(struct request_queue *q,
struct bio *bio, struct page
 return 0;

 /*
- * we might lose a segment or two here, but rather that than
- * make this too complex.
+ * prepare segment count check, reduce segment count if possible
  */

-while (bio-bi_phys_segments = queue_max_segments(q)) {
-
-if (retried_segments)
-return 0;
-
-retried_segments = 1;
+if (bio-bi_phys_segments = queue_max_segments(q))
 blk_recount_segments(q, bio);
-}
+

 /*
  * setup the new entry, we might clear it again later if we
@@ -572,6 +565,19 @@ static int __bio_add_page(struct request_queue *q, struct
bio *bio, struct page
 bvec-bv_page = page;
 bvec-bv_len = len;
 bvec-bv_offset = offset;
+
+/*
+ * the other part of the segment count check, allow mergeable pages
+ */
+if ((bio-bi_phys_segments  queue_max_segments(q)) ||
+( (bio-bi_phys_segments == queue_max_segments(q)) 
+!BIOVEC_PHYS_MERGEABLE(bvec - 1, bvec))) {
+bvec-bv_page = NULL;
+bvec-bv_len = 0;
+bvec-bv_offset = 0;
+return 0;
+}
+

 /*
  * if queue has other restrictions (eg varying max sector size


--
Jan Vesely jves...@redhat.com
--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Kernel oops on st module cycling

2013-03-07 Thread Jean Delvare
Hi Joe,

Thanks for your fast answer.

Le vendredi 22 février 2013 à 10:30 -0500, Joe Lawrence a écrit :
 I remember finding an st module load/unload kref accounting bug a while 
 ago: http://thread.gmane.org/gmane.linux.scsi/77539  I replied to the 
 report with a hack-patch that grabbed an extra reference to avoid the 
 crash.
 
 There was an attempt at fixing this up in the block layer [1] but that 
 change was pulled when problems were found with that patch [2].
 
 [1] https://lkml.org/lkml/2012/8/27/354
 [2] https://lkml.org/lkml/2012/9/22/113
 
 Maybe this is the same bug?

Seems so. Meanwhile I saw you posted an update at:
http://marc.info/?l=linux-scsim=136249932603011w=2

I have tested this patch successfully, and apparently others have as
well, so I would suggest to get this upstream ASAP. I think this fix is
a candidate for stable kernel series as well.

Note for backporters: the value returned by blk_get_queue() changed in
kernel 3.3, so care must be taken when backporting the fix to kernel 3.2
or older, otherwise success becomes failure and vice versa.

Thanks,
-- 
Jean Delvare
Suse L3

--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH V3 0/4] Configure number of LUs reported by 'report-luns'

2013-03-07 Thread Rob Evers
This patch set retrieves the number of LUs available on a target
using the report-luns command.  The initial size of the report-luns
command is 512 entries, as the previous default initial number was.
If more LUs than 511 are present on a target, the report-luns is
re-issued with the size indicated in the result of the original
report-luns, up to max_report_luns.

The default value of max_report_luns is increased to 16k-1 from 512-1.

3rd version changes from 2nd posting:

 - add a patch to use get/put_unaligned_be32() in report-luns code

2nd version changes from first posting:

 - Minor tweak added in 2nd patch to use the number of luns
   reported in the 2nd report-luns command, if it is executed.
   There is a chance that the number changed between the
   1st and 2nd report-luns.

 - Add 3rd patch changing kmalloc flag in report luns from
   GFP_ATOMIC to GFP_KERNEL, as this is more consistent with
   the allocation flag in blk_alloc_queue_node()

Rob Evers (4):
  Encapsulate scsi_do_report_luns
  Configure reported luns
  Change kmallocs in report_luns to use GFP_KERNEL
  Use set/get_unaligned_be32 in report_luns

 drivers/scsi/scsi_scan.c | 192 +--
 1 file changed, 120 insertions(+), 72 deletions(-)

-- 
1.7.11.7

--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH V3 1/4] Encapsulate scsi_do_report_luns

2013-03-07 Thread Rob Evers
---
 drivers/scsi/scsi_scan.c | 109 +--
 1 file changed, 59 insertions(+), 50 deletions(-)

diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 3e58b22..b2abf22 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -1282,6 +1282,64 @@ void int_to_scsilun(unsigned int lun, struct scsi_lun 
*scsilun)
 }
 EXPORT_SYMBOL(int_to_scsilun);
 
+int scsi_do_report_luns(struct scsi_device *sdev, int length,
+   struct scsi_lun *lun_data, char *devname)
+{
+   unsigned int retries;
+   unsigned char scsi_cmd[MAX_COMMAND_SIZE];
+   struct scsi_sense_hdr sshdr;
+   int result;
+
+   scsi_cmd[0] = REPORT_LUNS;
+
+   /*
+* bytes 1 - 5: reserved, set to zero.
+*/
+   memset(scsi_cmd[1], 0, 5);
+
+   /*
+* bytes 6 - 9: length of the command.
+*/
+   scsi_cmd[6] = (unsigned char) (length  24)  0xff;
+   scsi_cmd[7] = (unsigned char) (length  16)  0xff;
+   scsi_cmd[8] = (unsigned char) (length  8)  0xff;
+   scsi_cmd[9] = (unsigned char) length  0xff;
+
+   scsi_cmd[10] = 0;   /* reserved */
+   scsi_cmd[11] = 0;   /* control */
+
+   /*
+* We can get a UNIT ATTENTION, for example a power on/reset, so
+* retry a few times (like sd.c does for TEST UNIT READY).
+* Experience shows some combinations of adapter/devices get at
+* least two power on/resets.
+*
+* Illegal requests (for devices that do not support REPORT LUNS)
+* should come through as a check condition, and will not generate
+* a retry.
+*/
+   for (retries = 0; retries  3; retries++) {
+   SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO scsi scan: Sending
+  REPORT LUNS to %s (try %d)\n, devname,
+ retries));
+   result = scsi_execute_req(sdev, scsi_cmd, DMA_FROM_DEVICE,
+ lun_data, length, sshdr,
+ SCSI_TIMEOUT + 4 * HZ, 3, NULL);
+
+   SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO scsi scan: REPORT LUNS
+  %s (try %d) result 0x%x\n, result
+ ?  failed : successful, retries, result));
+   if (result == 0)
+   break;
+   else if (scsi_sense_valid(sshdr)) {
+   if (sshdr.sense_key != UNIT_ATTENTION)
+   break;
+   }
+   }
+
+   return result;
+}
+
 /**
  * scsi_report_lun_scan - Scan using SCSI REPORT LUN results
  * @starget: which target
@@ -1306,15 +1364,12 @@ static int scsi_report_lun_scan(struct scsi_target 
*starget, int bflags,
int rescan)
 {
char devname[64];
-   unsigned char scsi_cmd[MAX_COMMAND_SIZE];
unsigned int length;
unsigned int lun;
unsigned int num_luns;
-   unsigned int retries;
int result;
struct scsi_lun *lunp, *lun_data;
u8 *data;
-   struct scsi_sense_hdr sshdr;
struct scsi_device *sdev;
struct Scsi_Host *shost = dev_to_shost(starget-dev);
int ret = 0;
@@ -1369,53 +1424,7 @@ static int scsi_report_lun_scan(struct scsi_target 
*starget, int bflags,
goto out;
}
 
-   scsi_cmd[0] = REPORT_LUNS;
-
-   /*
-* bytes 1 - 5: reserved, set to zero.
-*/
-   memset(scsi_cmd[1], 0, 5);
-
-   /*
-* bytes 6 - 9: length of the command.
-*/
-   scsi_cmd[6] = (unsigned char) (length  24)  0xff;
-   scsi_cmd[7] = (unsigned char) (length  16)  0xff;
-   scsi_cmd[8] = (unsigned char) (length  8)  0xff;
-   scsi_cmd[9] = (unsigned char) length  0xff;
-
-   scsi_cmd[10] = 0;   /* reserved */
-   scsi_cmd[11] = 0;   /* control */
-
-   /*
-* We can get a UNIT ATTENTION, for example a power on/reset, so
-* retry a few times (like sd.c does for TEST UNIT READY).
-* Experience shows some combinations of adapter/devices get at
-* least two power on/resets.
-*
-* Illegal requests (for devices that do not support REPORT LUNS)
-* should come through as a check condition, and will not generate
-* a retry.
-*/
-   for (retries = 0; retries  3; retries++) {
-   SCSI_LOG_SCAN_BUS(3, printk (KERN_INFO scsi scan: Sending
-REPORT LUNS to %s (try %d)\n, devname,
-   retries));
-
-   result = scsi_execute_req(sdev, scsi_cmd, DMA_FROM_DEVICE,
- lun_data, length, sshdr,
- SCSI_TIMEOUT + 4 * HZ, 3, NULL);
-
-   SCSI_LOG_SCAN_BUS(3, printk (KERN_INFO scsi scan: REPORT LUNS
-

[PATCH V3 2/4] Configure reported luns

2013-03-07 Thread Rob Evers
Change default value of max_report_luns to 16k-1.

Use data returned from max report luns command to configure the number
of logical units present if previous default of 511 isn't enough.
---
 drivers/scsi/scsi_scan.c | 89 
 1 file changed, 68 insertions(+), 21 deletions(-)

diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index b2abf22..671ff58 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -109,12 +109,13 @@ MODULE_PARM_DESC(scan, sync, async or none);
  * in practice, the maximum number of LUNs suppored by any device
  * is about 16k.
  */
-static unsigned int max_scsi_report_luns = 511;
+static unsigned int max_scsi_report_luns = 16383;
 
 module_param_named(max_report_luns, max_scsi_report_luns, uint, 
S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(max_report_luns,
 REPORT LUNS maximum number of LUNS received (should be
- between 1 and 16384));
+ between 1 and 16383));
+#define INITIAL_MAX_REPORT_LUNS 511
 
 static unsigned int scsi_inq_timeout = SCSI_TIMEOUT/HZ + 18;
 
@@ -1366,9 +1367,10 @@ static int scsi_report_lun_scan(struct scsi_target 
*starget, int bflags,
char devname[64];
unsigned int length;
unsigned int lun;
-   unsigned int num_luns;
+   unsigned int num_luns, num_luns_reported;
int result;
struct scsi_lun *lunp, *lun_data;
+   struct scsi_lun *first_lun_data, *second_lun_data;
u8 *data;
struct scsi_device *sdev;
struct Scsi_Host *shost = dev_to_shost(starget-dev);
@@ -1409,45 +1411,90 @@ static int scsi_report_lun_scan(struct scsi_target 
*starget, int bflags,
/*
 * Allocate enough to hold the header (the same size as one scsi_lun)
 * plus the max number of luns we are requesting.
-*
-* Reallocating and trying again (with the exact amount we need)
-* would be nice, but then we need to somehow limit the size
-* allocated based on the available memory and the limits of
-* kmalloc - we don't want a kmalloc() failure of a huge value to
-* prevent us from finding any LUNs on this target.
 */
-   length = (max_scsi_report_luns + 1) * sizeof(struct scsi_lun);
-   lun_data = kmalloc(length, GFP_ATOMIC |
-  (sdev-host-unchecked_isa_dma ? __GFP_DMA : 0));
-   if (!lun_data) {
+   if (max_scsi_report_luns  INITIAL_MAX_REPORT_LUNS)
+   length = (INITIAL_MAX_REPORT_LUNS + 1) *
+   sizeof(struct scsi_lun);
+   else
+   length = (max_scsi_report_luns + 1) *
+   sizeof(struct scsi_lun);
+
+   first_lun_data = kmalloc(length, GFP_ATOMIC |
+(sdev-host-unchecked_isa_dma ?
+__GFP_DMA : 0));
+   if (!first_lun_data) {
printk(ALLOC_FAILURE_MSG, __func__);
goto out;
}
 
-   result = scsi_do_report_luns(sdev, length, lun_data, devname);
+   result = scsi_do_report_luns(sdev, length, first_lun_data, devname);
 
if (result) {
/*
 * The device probably does not support a REPORT LUN command
 */
+   lun_data = first_lun_data;
ret = 1;
goto out_err;
}
 
/*
-* Get the length from the first four bytes of lun_data.
+* Get the length from the first four bytes of first_lun_data.
 */
-   data = (u8 *) lun_data-scsi_lun;
+   data = (u8 *) first_lun_data-scsi_lun;
length = ((data[0]  24) | (data[1]  16) |
  (data[2]  8) | (data[3]  0));
 
-   num_luns = (length / sizeof(struct scsi_lun));
-   if (num_luns  max_scsi_report_luns) {
+   num_luns_reported = (length / sizeof(struct scsi_lun));
+
+   if (num_luns_reported  max_scsi_report_luns) {
+   num_luns = max_scsi_report_luns;
+   length = num_luns * sizeof(struct scsi_lun);
printk(KERN_WARNING scsi: On %s only %d (max_scsi_report_luns)
of %d luns reported, try increasing
-   max_scsi_report_luns.\n, devname,
-  max_scsi_report_luns, num_luns);
-   num_luns = max_scsi_report_luns;
+   max_report_luns parameter.\n, devname,
+  max_scsi_report_luns, num_luns_reported);
+   } else {
+   num_luns = num_luns_reported;
+   }
+
+   if (num_luns  INITIAL_MAX_REPORT_LUNS) {
+   /*
+* add one for the header
+*/
+   length = length + sizeof(struct scsi_lun);
+   second_lun_data = kmalloc(length, GFP_ATOMIC |
+ (sdev-host-unchecked_isa_dma ?
+ __GFP_DMA : 0));
+   if 

[PATCH V3 4/4] Use set/get_unaligned_be32 in report_luns

2013-03-07 Thread Rob Evers
---
 drivers/scsi/scsi_scan.c | 16 
 1 file changed, 4 insertions(+), 12 deletions(-)

diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 1d41730..31bda4b 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -34,6 +34,7 @@
 #include linux/spinlock.h
 #include linux/async.h
 #include linux/slab.h
+#include asm/unaligned.h
 
 #include scsi/scsi.h
 #include scsi/scsi_cmnd.h
@@ -1301,10 +1302,7 @@ int scsi_do_report_luns(struct scsi_device *sdev, int 
length,
/*
 * bytes 6 - 9: length of the command.
 */
-   scsi_cmd[6] = (unsigned char) (length  24)  0xff;
-   scsi_cmd[7] = (unsigned char) (length  16)  0xff;
-   scsi_cmd[8] = (unsigned char) (length  8)  0xff;
-   scsi_cmd[9] = (unsigned char) length  0xff;
+   put_unaligned_be32(0x, scsi_cmd[6]);
 
scsi_cmd[10] = 0;   /* reserved */
scsi_cmd[11] = 0;   /* control */
@@ -1441,10 +1439,7 @@ static int scsi_report_lun_scan(struct scsi_target 
*starget, int bflags,
/*
 * Get the length from the first four bytes of first_lun_data.
 */
-   data = (u8 *) first_lun_data-scsi_lun;
-   length = ((data[0]  24) | (data[1]  16) |
- (data[2]  8) | (data[3]  0));
-
+   length = get_unaligned_be32(first_lun_data-scsi_lun);
num_luns_reported = (length / sizeof(struct scsi_lun));
 
if (num_luns_reported  max_scsi_report_luns) {
@@ -1486,10 +1481,7 @@ static int scsi_report_lun_scan(struct scsi_target 
*starget, int bflags,
 * Get the length from the first four bytes
 * of second_lun_data.
 */
-   data = (u8 *) lun_data-scsi_lun;
-   length = ((data[0]  24) | (data[1]  16) |
- (data[2]  8) | (data[3]  0));
-
+   length = get_unaligned_be32(lun_data-scsi_lun);
num_luns = (length / sizeof(struct scsi_lun));
}
}
-- 
1.7.11.7

--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH V3 3/4] Change kmallocs in report_luns to use GFP_KERNEL

2013-03-07 Thread Rob Evers
---
 drivers/scsi/scsi_scan.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 671ff58..1d41730 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -1419,7 +1419,7 @@ static int scsi_report_lun_scan(struct scsi_target 
*starget, int bflags,
length = (max_scsi_report_luns + 1) *
sizeof(struct scsi_lun);
 
-   first_lun_data = kmalloc(length, GFP_ATOMIC |
+   first_lun_data = kmalloc(length, GFP_KERNEL |
 (sdev-host-unchecked_isa_dma ?
 __GFP_DMA : 0));
if (!first_lun_data) {
@@ -1463,7 +1463,7 @@ static int scsi_report_lun_scan(struct scsi_target 
*starget, int bflags,
 * add one for the header
 */
length = length + sizeof(struct scsi_lun);
-   second_lun_data = kmalloc(length, GFP_ATOMIC |
+   second_lun_data = kmalloc(length, GFP_KERNEL |
  (sdev-host-unchecked_isa_dma ?
  __GFP_DMA : 0));
if (!second_lun_data) {
-- 
1.7.11.7

--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH V3 0/4] Configure number of LUs reported by 'report-luns'

2013-03-07 Thread Ewan Milne
On Thu, 2013-03-07 at 08:38 -0500, Rob Evers wrote:
 This patch set retrieves the number of LUs available on a target
 using the report-luns command.  The initial size of the report-luns
 command is 512 entries, as the previous default initial number was.
 If more LUs than 511 are present on a target, the report-luns is
 re-issued with the size indicated in the result of the original
 report-luns, up to max_report_luns.
 
 The default value of max_report_luns is increased to 16k-1 from 512-1.
 
 3rd version changes from 2nd posting:
 
  - add a patch to use get/put_unaligned_be32() in report-luns code
 
 2nd version changes from first posting:
 
  - Minor tweak added in 2nd patch to use the number of luns
reported in the 2nd report-luns command, if it is executed.
There is a chance that the number changed between the
1st and 2nd report-luns.
 
  - Add 3rd patch changing kmalloc flag in report luns from
GFP_ATOMIC to GFP_KERNEL, as this is more consistent with
the allocation flag in blk_alloc_queue_node()
 
 Rob Evers (4):
   Encapsulate scsi_do_report_luns
   Configure reported luns
   Change kmallocs in report_luns to use GFP_KERNEL
   Use set/get_unaligned_be32 in report_luns
 
  drivers/scsi/scsi_scan.c | 192 
 +--
  1 file changed, 120 insertions(+), 72 deletions(-)
 

For all 4 patches in the series:

Acked-by: Ewan D. Milne emi...@redhat.com


--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH V3 1/4] Encapsulate scsi_do_report_luns

2013-03-07 Thread Elliott, Robert (Server Storage)


 -Original Message-
 From: linux-scsi-ow...@vger.kernel.org [mailto:linux-scsi-
 ow...@vger.kernel.org] On Behalf Of Rob Evers
 Sent: Thursday, 07 March, 2013 7:39 AM
 To: linux-scsi@vger.kernel.org
 Cc: rev...@redhat.com; micha...@cs.wisc.edu; bvanass...@acm.org;
 emi...@redhat.com
 Subject: [PATCH V3 1/4] Encapsulate scsi_do_report_luns
 
 ---
  drivers/scsi/scsi_scan.c | 109 
 +--
  1 file changed, 59 insertions(+), 50 deletions(-)
 
 diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
 index 3e58b22..b2abf22 100644
 --- a/drivers/scsi/scsi_scan.c
 +++ b/drivers/scsi/scsi_scan.c
 +int scsi_do_report_luns(struct scsi_device *sdev, int length,
 + struct scsi_lun *lun_data, char *devname)
 +{
 + unsigned int retries;
 + unsigned char scsi_cmd[MAX_COMMAND_SIZE];
 + struct scsi_sense_hdr sshdr;
 + int result;
 +
 + scsi_cmd[0] = REPORT_LUNS;
 +
...
 + /*
 +  * We can get a UNIT ATTENTION, for example a power on/reset, so
 +  * retry a few times (like sd.c does for TEST UNIT READY).
 +  * Experience shows some combinations of adapter/devices get at
 +  * least two power on/resets.
 +  *
 +  * Illegal requests (for devices that do not support REPORT LUNS)
 +  * should come through as a check condition, and will not generate
 +  * a retry.
 +  */
 + for (retries = 0; retries  3; retries++) {
 + SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO scsi scan: Sending
 +REPORT LUNS to %s (try %d)\n, devname,
 +   retries));
 + result = scsi_execute_req(sdev, scsi_cmd,
 DMA_FROM_DEVICE,
 +   lun_data, length, sshdr,
 +   SCSI_TIMEOUT + 4 * HZ, 3, NULL);

There's no guarantee that you'll get no more than two unit attention conditions 
at any particular time; a magic number of 3 retries isn't very robust.  Could 
this code retry until it stops getting CHECK CONDITION/UNIT ATTENTION?  It 
should include a much larger worst case number to avoid hangs if the device is 
truly stuck - maybe 20 times.  For CHECK CONDITION with other sense keys, an 
early exit is fine.

This may apply to other code too, since the comment mentions it is modeled 
after sd.c TEST UNIT READY handling.

---
Rob ElliottHP Server Storage




--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH RESEND] qla2xxx: Update firmware link in Kconfig file.

2013-03-07 Thread Chad Dupuis
Signed-off-by: Giridhar Malavali giridhar.malav...@qlogic.com
Signed-off-by: Chad Dupuis chad.dup...@qlogic.com
---
 drivers/scsi/qla2xxx/Kconfig |4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/qla2xxx/Kconfig b/drivers/scsi/qla2xxx/Kconfig
index 317a7fd..23d6072 100644
--- a/drivers/scsi/qla2xxx/Kconfig
+++ b/drivers/scsi/qla2xxx/Kconfig
@@ -24,7 +24,9 @@ config SCSI_QLA_FC
 
Firmware images can be retrieved from:
 
-   ftp://ftp.qlogic.com/outgoing/linux/firmware/
+   http://ldriver.qlogic.com/firmware/
+
+   They are also included in the linux-firmware tree as well.
 
 config TCM_QLA2XXX
tristate TCM_QLA2XXX fabric module for Qlogic 2xxx series target mode 
HBAs
-- 
1.7.7

--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH V3 1/4] Encapsulate scsi_do_report_luns

2013-03-07 Thread Jeremy Linton
On 3/7/2013 9:47 AM, Elliott, Robert (Server Storage) wrote:

 +int scsi_do_report_luns(struct scsi_device *sdev, int length, +  * We
 can get a UNIT ATTENTION, for example a power on/reset, so +  * retry a
 few times (like sd.c does for TEST UNIT READY). + * Experience shows
 some combinations of adapter/devices get at + * least two power
 on/resets. + for (retries = 0; retries  3; retries++) { +
 SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO scsi scan: Sending + 
   
 REPORT LUNS to %s (try %d)\n, devname, +  
 retries)); +  result =
 scsi_execute_req(sdev, scsi_cmd, DMA_FROM_DEVICE, +  
   lun_data,
 length, sshdr, +  SCSI_TIMEOUT + 4 * 
 HZ, 3, NULL);
 
 There's no guarantee that you'll get no more than two unit attention
 conditions at any particular time;

Actually, if your getting any unit attentions from a report luns the 
device
is broken. SAM5 5.14

if a REPORT LUNS command enters the enabled command state, the device server
shall process the REPORTS LUNS command and shall not report any unit attention
conditions

This is not new behavior either.


There are a couple other places that say similar things, INQUIRY and REPORT
LUNS get special status for UA. Which is how you can scan a target/lun
configuration without interfering with its operation. Personally, I think the
TUR in the mid layer is incorrect as the TUR functionality needs to be hoisted
higher up the stack and the mid layer needs to use inquiry to validate device
communications. (got a patch for that too, but no point in posting it, as it
will be ignored).


--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH V3 1/4] Encapsulate scsi_do_report_luns

2013-03-07 Thread James Bottomley
On Thu, 2013-03-07 at 17:01 +, Elliott, Robert (Server Storage)
wrote:
 Good point; INQUIRY, REPORT LUNS, REQUEST SENSE, and NOTIFY DATA
 TRANSFER DEVICE do not report unit attention conditions.

Well, yes they do, at least on several devices I have here.

Can I point out again that we can't code to SAM ... we have to code to
what already exists. SAM is useful as a guideline, but it isn't gospel.
In particular where the real world does something SAM says it shouldn't
(like sending UA to INQUIRY), we have to go with the real world.

This also means we can't go through the linux SCSI subsystem changing
behaviour based on what SAM says the behaviour should be.  Most of what
the SCSI subsystem does is an accumulation based on years of trying to
fix it for annoying and out of spec devices.

James


--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH V3 1/4] Encapsulate scsi_do_report_luns

2013-03-07 Thread Elliott, Robert (Server Storage)
So far the T10 Base feature set proposal has not been restating requirements 
already required by the core standards - it's just upgrading mays and 
shoulds to shalls.  Should we also include a list of shall rules like 
this that have had known violations in the past?


 -Original Message-
 From: James Bottomley [mailto:james.bottom...@hansenpartnership.com]
 Sent: Thursday, 07 March, 2013 11:31 AM
 To: Elliott, Robert (Server Storage)
 Cc: Jeremy Linton; Rob Evers; linux-scsi@vger.kernel.org;
 micha...@cs.wisc.edu; bvanass...@acm.org; emi...@redhat.com
 Subject: Re: [PATCH V3 1/4] Encapsulate scsi_do_report_luns
 
 On Thu, 2013-03-07 at 17:01 +, Elliott, Robert (Server Storage)
 wrote:
  Good point; INQUIRY, REPORT LUNS, REQUEST SENSE, and NOTIFY DATA
  TRANSFER DEVICE do not report unit attention conditions.
 
 Well, yes they do, at least on several devices I have here.
 
 Can I point out again that we can't code to SAM ... we have to code to
 what already exists. SAM is useful as a guideline, but it isn't gospel.
 In particular where the real world does something SAM says it shouldn't
 (like sending UA to INQUIRY), we have to go with the real world.
 
 This also means we can't go through the linux SCSI subsystem changing
 behaviour based on what SAM says the behaviour should be.  Most of what
 the SCSI subsystem does is an accumulation based on years of trying to
 fix it for annoying and out of spec devices.
 
 James
 

--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH V3 1/4] Encapsulate scsi_do_report_luns

2013-03-07 Thread Jeremy Linton
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

On 3/7/2013 11:30 AM, James Bottomley wrote:

 This also means we can't go through the linux SCSI subsystem changing 
 behaviour based on what SAM says the behaviour should be.  Most of what the
 SCSI subsystem does is an accumulation based on years of trying to fix it
 for annoying and out of spec devices.

Well, I wasn't suggesting removing the retries for this patch, cause yes
there are a lot of non complaint devices, but I was complaining about a case
where there are known problems with the way the code is executing on non
broken devices.

Basically, prioritizing the functionality of a broken device, of the
functionality of a working one.

-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.10 (MingW32)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQEcBAEBAgAGBQJRONGAAAoJEL5i86xrzcy7a6QH/16EQyMQ3DzLrX2a3OdtSD4Q
QdHInok1SAyGKDGHTHXGu0RKuvpzgdSLjORKfEdbok/ZyNXd7qSi57czRV7R5U4b
nTLoaP8maXxJsJ1ko11sTEfZNT4cgO4+hLMjcZk9LBJZhNC+WqsszYaOVVLFtSIJ
xpBaowSjxLpkhi5cTdZ6p4+Tr2xgZxBXd+5NUZuB1s6ZJ99yNYcn97Q/3VVeFmW9
sprBP3kkiWv3LOIN6ZNTkKRDtgJYzf2LVTogjtNfCQsB/ZUHr5ITzZ1fMBkVrR7c
yVe4kdq26RDC57oSJMqAHA8QXBQ2ll8l8fz1X1mebb2TeyOI57/U8ZbPyfGvzxo=
=yZvD
-END PGP SIGNATURE-
--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH V3 1/4] Encapsulate scsi_do_report_luns

2013-03-07 Thread James Bottomley
On Thu, 2013-03-07 at 17:38 +, Elliott, Robert (Server Storage)
wrote:
 So far the T10 Base feature set proposal has not been restating
 requirements already required by the core standards - it's just
 upgrading mays and shoulds to shalls.  Should we also include a
 list of shall rules like this that have had known violations in the
 past?

You mean trying to catalogue known broken behaviour?  That's a pretty
monumental task, particularly when you have to deal with all the USB
SCSI implementations, which is where a lot of our current violations
come from.

James


--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v1] lpfc 8.3.37: Remove redundant NULL check before kfree

2013-03-07 Thread James Smart
I don't disagree.My intent would be it is all one way - with my 
leaning toward being explicit.  Unfortunately, it's a low priority task.


-- james s


On 3/6/2013 6:32 PM, Elliott, Robert (Server Storage) wrote:

If the other approach is taken, then not all kfree() calls are protected by a 
NULL check.

One example in lpfc_els.c (from 3.7-rc5):
if (!pbuflist || !pbuflist-virt)
goto els_iocb_free_pbuf_exit;
...
els_iocb_free_pbuf_exit:
if (expectRsp)
lpfc_mbuf_free(phba, prsp-virt, prsp-phys);
kfree(pbuflist);





-Original Message-
From: linux-scsi-ow...@vger.kernel.org [mailto:linux-scsi-
ow...@vger.kernel.org] On Behalf Of James Smart
Sent: Wednesday, 06 March, 2013 3:10 PM
To: syamsidha...@gmail.com
Cc: linux-scsi@vger.kernel.org; jbottom...@parallels.com; Syam Sidhardhan;
Smart, James
Subject: Re: [PATCH v1] lpfc 8.3.37: Remove redundant NULL check before
kfree

Syam,

Thank you for the patch - it is valid.

However, I prefer not to merge this.  I would rather force the coder to
think about the pointer value explicitly rather than depending on the
convenience/one line optimization.  We've had errors in the past covered
up by this gracious behavior.  Additionally, we have coders that work on
linux and vmware, and the semantics of the kfree() routine differ.   For
now, I'd prefer to stay as is and force good habits.

-- james s


On 3/6/2013 3:12 PM, syamsidha...@gmail.com wrote:

From: Syam Sidhardhan s.s...@samsung.com

kfree on NULL pointer is a no-op.

Signed-off-by: Syam Sidhardhan s.s...@samsung.com
---
v1- Corrected the from address.

   drivers/scsi/lpfc/lpfc_bsg.c |3 +--
   1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c
index 32d5683..2166097 100644
--- a/drivers/scsi/lpfc/lpfc_bsg.c
+++ b/drivers/scsi/lpfc/lpfc_bsg.c
@@ -1129,8 +1129,7 @@ lpfc_bsg_hba_set_event(struct fc_bsg_job *job)
return 0; /* call job done later */

   job_error:
-   if (dd_data != NULL)
-   kfree(dd_data);
+   kfree(dd_data);

job-dd_data = NULL;
return rc;

--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html




--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2][RFC] scsi_transport_fc: Implement I_T nexus reset

2013-03-07 Thread Mike Christie
Sorry for the late reply.

On 12/11/2012 02:23 AM, Hannes Reinecke wrote:
 @@ -793,7 +793,8 @@ struct scsi_host_template bfad_im_scsi_host_template = {
   .queuecommand = bfad_im_queuecommand,
   .eh_abort_handler = bfad_im_abort_handler,
   .eh_device_reset_handler = bfad_im_reset_lun_handler,
 - .eh_bus_reset_handler = bfad_im_reset_bus_handler,
 + .eh_target_reset_handler = fc_eh_it_nexus_loss_handler,
 + .eh_bus_reset_handler = NULL,

Don't need to set to NULL in the final patch, and don't forget to send a
patch to remove all the code we do not need anymore :)


 +fc_eh_it_nexus_loss_handler(struct scsi_cmnd *cmnd)
 +{
 + struct fc_internal *i = to_fc_internal(cmnd-device-host-transportt);
 + struct scsi_target *starget = scsi_target(cmnd-device);
 + struct fc_rport *rport = starget_to_rport(starget);
 + int ret;
 +
 + ret = fc_block_scsi_eh(cmnd);
 + if (i-f-eh_it_nexus_loss)
 + ret = i-f-eh_it_nexus_loss(cmnd);
 +
 + /* FAST_IO_FAIL indicates the port is already blocked */
 + if (ret == FAST_IO_FAIL)
 + return ret;
 + if (ret == SUCCESS)
 + /* All outstanding I/O has been aborted */
 + __fc_remote_port_delete(rport, -1);
 + else {
 + /* Failed to abort outstanding I/O, trigger FAST_IO_FAIL */
 + __fc_remote_port_delete(rport, 0);

I think it looks ok from a high level, but I am not sure how the drivers
are working here.

What happens for lpfc? It seems __fc_remote_port_delete ends up calling
the fast io fail code right away and that sets
FC_RPORT_FAST_FAIL_TIMEDOUT. We will then call lpfc_terminate_rport_io
which only will send aborts for the commands. We will then call
fc_block_scsi_eh above and that returns FAST_IO_FAIL and we will pass
that back up to the scsi eh right away.

But it seems lpfc_terminate_rport_io does not wait for the abort
reposnses and clean up the affected scsi_cmnds, and it does not seem to
do something to prevent lpfc from touching affected scsi_cmnds, does it
(I could not find the code)? If lpfc ends up touching a scsi_cmnd after
we have return FAST_IO_FAIL from this function then both lpfc and some
other code could be using the same scsi_cmnd struct.


For qla2xxx, it seems qla2x00_terminate_rport_io aborts commands, but it
looks like there is a small race where if some other thread was actually
completing the command already, then that thread could be touching the
scsi command, but this function could return and the scsi eh could end
up giving the command to some other driver or retrying while the other
thread was still touching it.

It also seems like there is a race where since
qla2x00_terminate_rport_io also calls the logout functions for the port,
then if that path was fast enough it could it lead to
fc_remote_port_delete getting called by qla2xxx while
fc_eh_it_nexus_loss_handler's call to __fc_remote_port_delete was still
running?


 + ret = fc_block_scsi_eh(cmnd);
 + }
 + if (ret != FAST_IO_FAIL) {
 + if (rport-port_state == FC_PORTSTATE_ONLINE)
 + ret = SUCCESS;
 + else
 + ret = FAILED;
 + }
 + return ret;
 +}
--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2][RFC] scsi_transport_fc: Implement I_T nexus reset

2013-03-07 Thread Jeremy Linton
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

On 3/7/2013 1:19 PM, Mike Christie wrote:
 What happens for lpfc? It seems __fc_remote_port_delete ends up calling the
 fast io fail code right away and that sets FC_RPORT_FAST_FAIL_TIMEDOUT. We
 will then call lpfc_terminate_rport_io which only will send aborts for the
 commands. We will then call fc_block_scsi_eh above and that returns
 FAST_IO_FAIL and we will pass that back up to the scsi eh right away.


For lpfc, you never get to the code. Or rather when I was testing it, I
couldn't find any way to propagate an error beyond the initial
lpfc_reset_flush_io_context() call in lpfc_device_reset_handler().

That call pretty much always returns success indpependent of the remote
device because the firmware acks the context clear aborts, resulting in the
outstanding iocb count being zero (independent of both the mid layer status
and the actual device state).

Result: all the code beyond the device reset handler never gets called.

-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.10 (MingW32)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQEcBAEBAgAGBQJROPTfAAoJEL5i86xrzcy7MSMIAKaUZV1sfE55/n95b28WTdAS
7HdUechq5JRh2jqW+PVQub3iADgjl5RZkj8T3vNTZgzR9pcQ6NE/qdkwho+p29Wx
enBa68HMosO+oiqPVSz7mmyuOsubB/DxPC3D+5ODu3nTJNMBxE4wYgdfGYsXVZS7
f/HCLo0Ysg7SBzTBQKvk0E1UtMJv1miEsIgxxqYSvOAOcHtKwUaYtCclE2z9egby
AnyVV1UrVa/cI8R4w0nArnyLCrLzG4IVAMByyb0KAQ3NKOdxGPqxPTkoY6GEpcQ9
GxzoZVWerGbzdjYXz2gckiN8oonBIB3esrrOTyq14sTqfOxtynH+8X3qS2uRFhg=
=t9Gx
-END PGP SIGNATURE-
--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2][RFC] scsi_transport_fc: Implement I_T nexus reset

2013-03-07 Thread Mike Christie
On 03/07/2013 02:20 PM, Mike Christie wrote:
 On 03/07/2013 02:13 PM, Jeremy Linton wrote:
 -BEGIN PGP SIGNED MESSAGE-
 Hash: SHA1

 On 3/7/2013 1:19 PM, Mike Christie wrote:
 What happens for lpfc? It seems __fc_remote_port_delete ends up calling the
 fast io fail code right away and that sets FC_RPORT_FAST_FAIL_TIMEDOUT. We
 will then call lpfc_terminate_rport_io which only will send aborts for the
 commands. We will then call fc_block_scsi_eh above and that returns
 FAST_IO_FAIL and we will pass that back up to the scsi eh right away.

  
  For lpfc, you never get to the code. Or rather when I was testing it, I
 couldn't find any way to propagate an error beyond the initial
 lpfc_reset_flush_io_context() call in lpfc_device_reset_handler().

  That call pretty much always returns success indpependent of the remote
 device because the firmware acks the context clear aborts, resulting in the
 outstanding iocb count being zero (independent of both the mid layer status
 and the actual device state).
  
 
 Your lpfc patch fixes that right?
 

Nevermind. Found your patch. It looks like it does fix that problem.

--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2][RFC] scsi_transport_fc: Implement I_T nexus reset

2013-03-07 Thread Jeremy Linton
On 3/7/2013 2:20 PM, Mike Christie wrote:
 On 03/07/2013 02:13 PM, Jeremy Linton wrote:
  For lpfc, you never get to the code. Or rather when I was testing it, I
 couldn't find any way to propagate an error beyond the initial
 lpfc_reset_flush_io_context() call in lpfc_device_reset_handler().

  That call pretty much always returns success indpependent of the remote
 device because the firmware acks the context clear aborts, resulting in the
 outstanding iocb count being zero (independent of both the mid layer status
 and the actual device state).
  
 
 Your lpfc patch fixes that right?


Yes. It allows the device reset to fail if the device doesn't respond 
to the
task mgmt request, or rejects it, etc.

It doesn't unjam the commands that get aborted by the 
flush_io_context() call.
Those have to depend on their timeouts. That is another patch...







--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2][RFC] scsi_transport_fc: Implement I_T nexus reset

2013-03-07 Thread Douglas Gilbert

On 13-03-07 03:13 PM, Jeremy Linton wrote:

-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

On 3/7/2013 1:19 PM, Mike Christie wrote:

What happens for lpfc? It seems __fc_remote_port_delete ends up calling the
fast io fail code right away and that sets FC_RPORT_FAST_FAIL_TIMEDOUT. We
will then call lpfc_terminate_rport_io which only will send aborts for the
commands. We will then call fc_block_scsi_eh above and that returns
FAST_IO_FAIL and we will pass that back up to the scsi eh right away.



For lpfc, you never get to the code. Or rather when I was testing it, I
couldn't find any way to propagate an error beyond the initial
lpfc_reset_flush_io_context() call in lpfc_device_reset_handler().

That call pretty much always returns success indpependent of the remote
device because the firmware acks the context clear aborts, resulting in the
outstanding iocb count being zero (independent of both the mid layer status
and the actual device state).

Result: all the code beyond the device reset handler never gets called.


Unsurprisingly, I found pretty well the same thing with
megaraid and mpt2sas (SAS) drivers. A big thumbs up from
the drivers if a LU reset was sent when there was
no way through the expander (due to zoning) to the LU (disk)
in question. Further, when that LU (disk) was viewed from
another initiator, no UA condition had been set; more
evidence that the LU reset did not get through.

Fire and forget task management functions ...

Doug Gilbert



--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC 00/11] Add support for iSCSI Extentions for RDMA (ISER) target

2013-03-07 Thread Nicholas A. Bellinger
From: Nicholas Bellinger n...@linux-iscsi.org

Hi Folks,

This series is first RFC for iSCSI Extentions for RDMA (ISER) target
support with existing iscsi-target TCP based socket code for a future
v3.10 merge.

This code is available in git here:

  git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending.git 
iser_target-rfcv1

Ths includes a basic iscsit_transport API that allows different transports
to reside under a single iscsi-target configfs control plane, using an
pre-defined network portal attribute to enable a rdma_cm listener on top
of existing ipoib portals.

The review patches are broken down into:

Patch #1 - #3 include iscsi-target API template, conversion of iscsi/tcp
login path to use API template, plus add iser RFC parameter keys.

Patch #4 - #5 allow external iscsi_cmd descriptor allocation / free, and
refactoring of RX side PDU request handling to allow incoming PDU logic
to be called by external ib_isert workqueue process context.

Patch #6 allows iscsi-target to use per transport API template immediate /
response callbacks in the per-connection TX thread completion path, and
refactoring of response PDU creation for export to external ib_isert code.

Patch #7 adds the pre-defined iser network portal attribute under the
existing iscsi-target configfs tree.

Patch #8 - #11 is the external ib_isert.ko module code seperated into
individual commits for review.

So at this point this code is functional and pushing sustained RDMA_WRITE +
RDMA_READ traffic using open-iscsi on top of v3.8-rc7 code.  Thus far we're
using Mellanox IB HCAs for initial development, and will be verfiying using
RCoE capable NICs as well in the near future.

Note there are still plently of performance tuning, active I/O shutdown
testing, and various exception path hardening left to be done over the
upcoming weeks.  The branch at target-pending.git/iser_target-wip will be
updated as review comments + regressions + new bugs are addressed.

Many thanks to Or Gerlitz and Mellanox for their support.

Thank you,

--nab

Nicholas Bellinger (11):
  iscsi-target: Add iscsit_transport API template
  iscsi-target: Initial traditional TCP conversion to iscsit_transport
  iscsi-target: Add iser-target parameter keys + setup during login
  iscsi-target: Add per transport iscsi_cmd alloc/free
  iscsi-target: Refactor RX PDU logic + export request PDU handling
  iscsi-target: Refactor TX queue logic + export response PDU creation
  iscsi-target: Add iser network portal attribute
  iser-target: Add base + proto includes
  iser-target: Add logic for verbs
  iser-target: Add logic for core
  iser-target: Add Makefile + Kconfig

 drivers/infiniband/Kconfig |1 +
 drivers/infiniband/Makefile|1 +
 drivers/infiniband/ulp/isert/Kconfig   |6 +
 drivers/infiniband/ulp/isert/Makefile  |5 +
 drivers/infiniband/ulp/isert/isert_base.h  |  123 ++
 drivers/infiniband/ulp/isert/isert_core.c  | 1720 
 drivers/infiniband/ulp/isert/isert_core.h  |   12 +
 drivers/infiniband/ulp/isert/isert_proto.h |   47 +
 drivers/infiniband/ulp/isert/isert_verbs.c |  476 +++
 drivers/infiniband/ulp/isert/isert_verbs.h |5 +
 drivers/target/iscsi/Makefile  |3 +-
 drivers/target/iscsi/iscsi_target.c| 1119 +---
 drivers/target/iscsi/iscsi_target.h|1 +
 drivers/target/iscsi/iscsi_target_configfs.c   |   75 +
 drivers/target/iscsi/iscsi_target_core.h   |   25 +-
 drivers/target/iscsi/iscsi_target_device.c |1 +
 drivers/target/iscsi/iscsi_target_erl1.c   |8 +-
 drivers/target/iscsi/iscsi_target_login.c  |  466 +--
 drivers/target/iscsi/iscsi_target_login.h  |6 +
 drivers/target/iscsi/iscsi_target_nego.c   |  185 +---
 drivers/target/iscsi/iscsi_target_nego.h   |   11 +-
 drivers/target/iscsi/iscsi_target_parameters.c |   87 ++-
 drivers/target/iscsi/iscsi_target_parameters.h |   16 +-
 drivers/target/iscsi/iscsi_target_tmr.c|1 +
 drivers/target/iscsi/iscsi_target_tpg.c|6 +-
 drivers/target/iscsi/iscsi_target_transport.c  |   57 +
 drivers/target/iscsi/iscsi_target_util.c   |   62 +-
 drivers/target/iscsi/iscsi_target_util.h   |2 +
 include/target/iscsi/iscsi_transport.h |   77 ++
 29 files changed, 3803 insertions(+), 801 deletions(-)
 create mode 100644 drivers/infiniband/ulp/isert/Kconfig
 create mode 100644 drivers/infiniband/ulp/isert/Makefile
 create mode 100644 drivers/infiniband/ulp/isert/isert_base.h
 create mode 100644 drivers/infiniband/ulp/isert/isert_core.c
 create mode 100644 drivers/infiniband/ulp/isert/isert_core.h
 create mode 100644 drivers/infiniband/ulp/isert/isert_proto.h
 create mode 100644 drivers/infiniband/ulp/isert/isert_verbs.c
 create mode 100644 drivers/infiniband/ulp/isert/isert_verbs.h
 create mode 100644 drivers/target/iscsi/iscsi_target_transport.c
 create mode 

[RFC 01/11] iscsi-target: Add iscsit_transport API template

2013-03-07 Thread Nicholas A. Bellinger
From: Nicholas Bellinger n...@linux-iscsi.org

Add basic struct iscsit_transport API template to allow iscsi-target for
running with external transport modules using existing iscsi_target_core.h
code.

For all external modules, this calls try_module_get() and module_put()
to obtain + release an external iscsit_transport module reference count.

Also include the iscsi-target symbols necessary in iscsi_transport.h to
allow external transport modules to function.

Signed-off-by: Nicholas Bellinger n...@linux-iscsi.org
---
 drivers/target/iscsi/Makefile |3 +-
 drivers/target/iscsi/iscsi_target_transport.c |   57 ++
 include/target/iscsi/iscsi_transport.h|   77 +
 3 files changed, 136 insertions(+), 1 deletions(-)
 create mode 100644 drivers/target/iscsi/iscsi_target_transport.c
 create mode 100644 include/target/iscsi/iscsi_transport.h

diff --git a/drivers/target/iscsi/Makefile b/drivers/target/iscsi/Makefile
index 5b9a2cf..13a9240 100644
--- a/drivers/target/iscsi/Makefile
+++ b/drivers/target/iscsi/Makefile
@@ -15,6 +15,7 @@ iscsi_target_mod-y += iscsi_target_parameters.o \
iscsi_target_util.o \
iscsi_target.o \
iscsi_target_configfs.o \
-   iscsi_target_stat.o
+   iscsi_target_stat.o \
+   iscsi_target_transport.o
 
 obj-$(CONFIG_ISCSI_TARGET) += iscsi_target_mod.o
diff --git a/drivers/target/iscsi/iscsi_target_transport.c 
b/drivers/target/iscsi/iscsi_target_transport.c
new file mode 100644
index 000..4ffd965
--- /dev/null
+++ b/drivers/target/iscsi/iscsi_target_transport.c
@@ -0,0 +1,57 @@
+#include linux/spinlock.h
+#include linux/list.h
+#include target/iscsi/iscsi_transport.h
+
+static LIST_HEAD(g_transport_list);
+static DEFINE_MUTEX(transport_mutex);
+
+struct iscsit_transport *iscsit_get_transport(int type)
+{
+   struct iscsit_transport *t;
+
+   mutex_lock(transport_mutex);
+   list_for_each_entry(t, g_transport_list, t_node) {
+   if (t-transport_type == type) {
+   if (t-owner  !try_module_get(t-owner)) {
+   t = NULL;
+   }
+   mutex_unlock(transport_mutex);
+   return t;
+   }
+   }
+   mutex_unlock(transport_mutex);
+
+   return NULL;
+}
+EXPORT_SYMBOL(iscsit_get_transport);
+
+void iscsit_put_transport(struct iscsit_transport *t)
+{
+   if (t-owner)
+   module_put(t-owner);
+}
+EXPORT_SYMBOL(iscsit_put_transport);
+
+int iscsit_create_transport(struct iscsit_transport *t)
+{
+   INIT_LIST_HEAD(t-t_node);
+
+   mutex_lock(transport_mutex);
+   list_add_tail(t-t_node, g_transport_list);
+   mutex_unlock(transport_mutex);
+
+   printk(Created iSCSI transport: %s\n, t-name);
+
+   return 0;
+}
+EXPORT_SYMBOL(iscsit_create_transport);
+
+void iscsit_destroy_transport(struct iscsit_transport *t)
+{
+   mutex_lock(transport_mutex);
+   list_del(t-t_node);
+   mutex_unlock(transport_mutex);
+
+   printk(Destroyed iSCSI transport: %s\n, t-name);
+}
+EXPORT_SYMBOL(iscsit_destroy_transport);
diff --git a/include/target/iscsi/iscsi_transport.h 
b/include/target/iscsi/iscsi_transport.h
new file mode 100644
index 000..c885376
--- /dev/null
+++ b/include/target/iscsi/iscsi_transport.h
@@ -0,0 +1,77 @@
+#include linux/module.h
+#include linux/list.h
+#include ../../../drivers/target/iscsi/iscsi_target_core.h
+
+struct iscsit_transport {
+#define ISCSIT_TRANSPORT_NAME  16
+   char name[ISCSIT_TRANSPORT_NAME];
+   int transport_type;
+   struct module *owner;
+   struct list_head t_node;
+   int (*iscsit_setup_np)(struct iscsi_np *, struct 
__kernel_sockaddr_storage *);
+   int (*iscsit_accept_np)(struct iscsi_np *, struct iscsi_conn *);
+   void (*iscsit_free_np)(struct iscsi_np *);
+   void (*iscsit_free_conn)(struct iscsi_conn *);
+   struct iscsi_cmd *(*iscsit_alloc_cmd)(struct iscsi_conn *, gfp_t);
+   void (*iscsit_unmap_cmd)(struct iscsi_cmd *, struct iscsi_conn *);
+   void (*iscsit_free_cmd)(struct iscsi_cmd *);
+   int (*iscsit_get_login_rx)(struct iscsi_conn *, struct iscsi_login *);
+   int (*iscsit_put_login_tx)(struct iscsi_conn *, struct iscsi_login *, 
u32);
+   int (*iscsit_immediate_queue)(struct iscsi_conn *, struct iscsi_cmd *, 
int);
+   int (*iscsit_response_queue)(struct iscsi_conn *, struct iscsi_cmd *, 
int);
+};
+
+/*
+ * From iscsi_target_transport.c
+ */
+
+extern int iscsit_create_transport(struct iscsit_transport *);
+extern void iscsit_destroy_transport(struct iscsit_transport *);
+extern struct iscsit_transport *iscsit_get_transport(int);
+extern void iscsit_put_transport(struct iscsit_transport *);
+
+/*
+ * From iscsi_target.c
+ */
+extern int 

[RFC 02/11] iscsi-target: Initial traditional TCP conversion to iscsit_transport

2013-03-07 Thread Nicholas A. Bellinger
From: Nicholas Bellinger n...@linux-iscsi.org

This patch performs the initial conversion of existing traditional iscsi
to use iscsit_transport API callers.  This includes:

- iscsi-np cleanups for iscsit_transport_type
- Add iscsi-np transport calls w/ -iscsit_setup_up() and -iscsit_free_np()
- Convert login thread process context to use -iscsit_accept_np() for
  connections with pre-allocated struct iscsi_conn
- Convert existing socket accept code to iscsit_accept_np()
- Convert login RX/TX callers to use -iscsit_get_login_rx() and
  -iscsit_put_login_tx() to exchange request/response PDUs
- Convert existing socket login RX/TX calls into iscsit_get_login_rx()
  and iscsit_put_login_tx()
- Change iscsit_close_connection() to invoke -iscsit_free_conn() +
  iscsit_put_transport() calls.
- Add iscsit_create_transport() + iscsit_destroy_transport() calls
  to module init/exit

Signed-off-by: Nicholas Bellinger n...@linux-iscsi.org
---
 drivers/target/iscsi/iscsi_target.c|   35 ++-
 drivers/target/iscsi/iscsi_target_core.h   |   15 +-
 drivers/target/iscsi/iscsi_target_login.c  |  411 
 drivers/target/iscsi/iscsi_target_login.h  |6 +
 drivers/target/iscsi/iscsi_target_nego.c   |  185 ++--
 drivers/target/iscsi/iscsi_target_nego.h   |   11 +-
 drivers/target/iscsi/iscsi_target_parameters.c |   12 +-
 drivers/target/iscsi/iscsi_target_tpg.c|6 +-
 drivers/target/iscsi/iscsi_target_util.c   |   27 +--
 9 files changed, 376 insertions(+), 332 deletions(-)

diff --git a/drivers/target/iscsi/iscsi_target.c 
b/drivers/target/iscsi/iscsi_target.c
index 23a98e6..4dc1c9b 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -49,6 +49,8 @@
 #include iscsi_target_device.h
 #include iscsi_target_stat.h
 
+#include target/iscsi/iscsi_transport.h
+
 static LIST_HEAD(g_tiqn_list);
 static LIST_HEAD(g_np_list);
 static DEFINE_SPINLOCK(tiqn_lock);
@@ -400,8 +402,7 @@ struct iscsi_np *iscsit_add_np(
spin_unlock_bh(np_lock);
 
pr_debug(CORE[0] - Added Network Portal: %s:%hu on %s\n,
-   np-np_ip, np-np_port, (np-np_network_transport == ISCSI_TCP) 
?
-   TCP : SCTP);
+   np-np_ip, np-np_port, np-np_transport-name);
 
return np;
 }
@@ -440,11 +441,10 @@ int iscsit_reset_np_thread(
return 0;
 }
 
-static int iscsit_del_np_comm(struct iscsi_np *np)
+static void iscsit_free_np(struct iscsi_np *np)
 {
if (np-np_socket)
sock_release(np-np_socket);
-   return 0;
 }
 
 int iscsit_del_np(struct iscsi_np *np)
@@ -466,20 +466,32 @@ int iscsit_del_np(struct iscsi_np *np)
send_sig(SIGINT, np-np_thread, 1);
kthread_stop(np-np_thread);
}
-   iscsit_del_np_comm(np);
+
+   np-np_transport-iscsit_free_np(np);
 
spin_lock_bh(np_lock);
list_del(np-np_list);
spin_unlock_bh(np_lock);
 
pr_debug(CORE[0] - Removed Network Portal: %s:%hu on %s\n,
-   np-np_ip, np-np_port, (np-np_network_transport == ISCSI_TCP) 
?
-   TCP : SCTP);
+   np-np_ip, np-np_port, np-np_transport-name);
 
+   iscsit_put_transport(np-np_transport);
kfree(np);
return 0;
 }
 
+static struct iscsit_transport iscsi_target_transport = {
+   .name   = iSCSI/TCP,
+   .transport_type = ISCSI_TCP,
+   .owner  = NULL,
+   .iscsit_setup_np= iscsit_setup_np,
+   .iscsit_accept_np   = iscsit_accept_np,
+   .iscsit_free_np = iscsit_free_np,
+   .iscsit_get_login_rx= iscsit_get_login_rx,
+   .iscsit_put_login_tx= iscsit_put_login_tx,
+};
+
 static int __init iscsi_target_init_module(void)
 {
int ret = 0;
@@ -556,6 +568,8 @@ static int __init iscsi_target_init_module(void)
goto ooo_out;
}
 
+   iscsit_create_transport(iscsi_target_transport);
+
if (iscsit_load_discovery_tpg()  0)
goto r2t_out;
 
@@ -586,6 +600,7 @@ static void __exit iscsi_target_cleanup_module(void)
iscsi_deallocate_thread_sets();
iscsi_thread_set_free();
iscsit_release_discovery_tpg();
+   iscsit_destroy_transport(iscsi_target_transport);
kmem_cache_destroy(lio_cmd_cache);
kmem_cache_destroy(lio_qr_cache);
kmem_cache_destroy(lio_dr_cache);
@@ -4045,6 +4060,12 @@ int iscsit_close_connection(
 
if (conn-sock)
sock_release(conn-sock);
+
+   if (conn-conn_transport-iscsit_free_conn)
+   conn-conn_transport-iscsit_free_conn(conn);
+
+   iscsit_put_transport(conn-conn_transport);
+
conn-thread_set = NULL;
 
pr_debug(Moving to TARG_CONN_STATE_FREE.\n);
diff --git a/drivers/target/iscsi/iscsi_target_core.h 
b/drivers/target/iscsi/iscsi_target_core.h
index 7a333d2..2587677 100644
--- 

[RFC 03/11] iscsi-target: Add iser-target parameter keys + setup during login

2013-03-07 Thread Nicholas A. Bellinger
From: Nicholas Bellinger n...@linux-iscsi.org

This patch adds RDMAExtensions, InitiatorRecvDataSegmentLength and
TargetRecvDataSegmentLength parameters keys necessary for iser-target
login to occur.

This includes setting the necessary parameters during login path
code within iscsi_login_zero_tsih_s2(), and currently PAGE_SIZE
aligning the target's advertised MRDSL for immediate data and
unsolicited data-out incoming payloads.

Signed-off-by: Nicholas Bellinger n...@linux-iscsi.org
---
 drivers/target/iscsi/iscsi_target_core.h   |   10 +++
 drivers/target/iscsi/iscsi_target_login.c  |   69 +++---
 drivers/target/iscsi/iscsi_target_parameters.c |   75 ++--
 drivers/target/iscsi/iscsi_target_parameters.h |   16 +-
 4 files changed, 156 insertions(+), 14 deletions(-)

diff --git a/drivers/target/iscsi/iscsi_target_core.h 
b/drivers/target/iscsi/iscsi_target_core.h
index 2587677..553cc1a 100644
--- a/drivers/target/iscsi/iscsi_target_core.h
+++ b/drivers/target/iscsi/iscsi_target_core.h
@@ -244,6 +244,11 @@ struct iscsi_conn_ops {
u8  IFMarker;   /* [0,1] == [No,Yes] */
u32 OFMarkInt;  /* [1..65535] */
u32 IFMarkInt;  /* [1..65535] */
+   /*
+* iSER specific connection parameters
+*/
+   u32 InitiatorRecvDataSegmentLength; /* [512..2**24-1] */
+   u32 TargetRecvDataSegmentLength;/* [512..2**24-1] */
 };
 
 struct iscsi_sess_ops {
@@ -265,6 +270,10 @@ struct iscsi_sess_ops {
u8  DataSequenceInOrder;/* [0,1] == [No,Yes] */
u8  ErrorRecoveryLevel; /* [0..2] */
u8  SessionType;/* [0,1] == [Normal,Discovery]*/
+   /*
+* iSER specific session parameters
+*/
+   u8  RDMAExtentions; /* [0,1] == [No,Yes] */
 };
 
 struct iscsi_queue_req {
@@ -284,6 +293,7 @@ struct iscsi_data_count {
 };
 
 struct iscsi_param_list {
+   booliser;
struct list_headparam_list;
struct list_headextra_response_list;
 };
diff --git a/drivers/target/iscsi/iscsi_target_login.c 
b/drivers/target/iscsi/iscsi_target_login.c
index 9354a5f..bc4e0f8 100644
--- a/drivers/target/iscsi/iscsi_target_login.c
+++ b/drivers/target/iscsi/iscsi_target_login.c
@@ -343,6 +343,7 @@ static int iscsi_login_zero_tsih_s2(
struct iscsi_node_attrib *na;
struct iscsi_session *sess = conn-sess;
unsigned char buf[32];
+   bool iser = false;
 
sess-tpg = conn-tpg;
 
@@ -364,7 +365,10 @@ static int iscsi_login_zero_tsih_s2(
return -1;
}
 
-   iscsi_set_keys_to_negotiate(0, conn-param_list);
+   if (conn-conn_transport-transport_type == ISCSI_INFINIBAND)
+   iser = true;
+
+   iscsi_set_keys_to_negotiate(conn-param_list, iser);
 
if (sess-sess_ops-SessionType)
return iscsi_set_keys_irrelevant_for_discovery(
@@ -402,6 +406,56 @@ static int iscsi_login_zero_tsih_s2(
 
if (iscsi_login_disable_FIM_keys(conn-param_list, conn)  0)
return -1;
+   /*
+* Set RDMAExtensions=Yes by default for iSER enabled network portals
+*/
+   if (iser == true) {
+   struct iscsi_param *param;
+   unsigned long mrdsl, off;
+   int rc;
+
+   sprintf(buf, RDMAExtensions=Yes);
+   if (iscsi_change_param_value(buf, conn-param_list, 0)  0) {
+   iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
+   ISCSI_LOGIN_STATUS_NO_RESOURCES);
+   return -1;
+   }
+   /*
+* Make MaxRecvDataSegmentLength PAGE_SIZE aligned for
+* Immediate Data + Unsolicitied Data-OUT if necessary..
+*/
+   param = iscsi_find_param_from_key(MaxRecvDataSegmentLength,
+ conn-param_list);
+   if (!param) {
+   iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
+   ISCSI_LOGIN_STATUS_NO_RESOURCES);
+   return -1;
+   }
+   rc = strict_strtoul(param-value, 0, mrdsl);
+   if (rc  0) {
+   iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
+   ISCSI_LOGIN_STATUS_NO_RESOURCES);
+   return -1;
+   }
+   off = mrdsl % PAGE_SIZE;
+   if (!off)
+   return 0;
+
+   if (mrdsl  PAGE_SIZE)
+   mrdsl = PAGE_SIZE;
+   else
+   mrdsl -= off;
+
+   pr_warn(Aligning ISER MaxRecvDataSegmentLength: %lu down
+to PAGE_SIZE\n, mrdsl);
+
+ 

[RFC 04/11] iscsi-target: Add per transport iscsi_cmd alloc/free

2013-03-07 Thread Nicholas A. Bellinger
From: Nicholas Bellinger n...@linux-iscsi.org

This patch converts struct iscsi_cmd memory allocation + free to use
-iscsit_alloc_cmd() + -iscsit_free_cmd() iscsit_transport API caller,
and export iscsit_allocate_cmd() + iscsit_free_cmd() symbols

Also update iscsit_free_cmd() to include a final -iscsit_unmap_cmd()
API call.

Signed-off-by: Nicholas Bellinger n...@linux-iscsi.org
---
 drivers/target/iscsi/iscsi_target.c  |2 +
 drivers/target/iscsi/iscsi_target_util.c |   34 ++---
 drivers/target/iscsi/iscsi_target_util.h |2 +
 3 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/drivers/target/iscsi/iscsi_target.c 
b/drivers/target/iscsi/iscsi_target.c
index 4dc1c9b..9cd7b7b 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -488,6 +488,8 @@ static struct iscsit_transport iscsi_target_transport = {
.iscsit_setup_np= iscsit_setup_np,
.iscsit_accept_np   = iscsit_accept_np,
.iscsit_free_np = iscsit_free_np,
+   .iscsit_alloc_cmd   = iscsit_alloc_cmd,
+   .iscsit_free_cmd= iscsit_cache_free_cmd,
.iscsit_get_login_rx= iscsit_get_login_rx,
.iscsit_put_login_tx= iscsit_put_login_tx,
 };
diff --git a/drivers/target/iscsi/iscsi_target_util.c 
b/drivers/target/iscsi/iscsi_target_util.c
index 4cf1e7f..4a86034 100644
--- a/drivers/target/iscsi/iscsi_target_util.c
+++ b/drivers/target/iscsi/iscsi_target_util.c
@@ -149,6 +149,17 @@ void iscsit_free_r2ts_from_list(struct iscsi_cmd *cmd)
spin_unlock_bh(cmd-r2t_lock);
 }
 
+struct iscsi_cmd *iscsit_alloc_cmd(struct iscsi_conn *conn, gfp_t gfp_mask)
+{
+   struct iscsi_cmd *cmd;
+
+   cmd = kmem_cache_zalloc(lio_cmd_cache, gfp_mask);
+   if (!cmd)
+   return NULL;
+
+   return cmd;
+}
+
 /*
  * May be called from software interrupt (timer) context for allocating
  * iSCSI NopINs.
@@ -157,13 +168,12 @@ struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn 
*conn, gfp_t gfp_mask)
 {
struct iscsi_cmd *cmd;
 
-   cmd = kmem_cache_zalloc(lio_cmd_cache, gfp_mask);
+   cmd = conn-conn_transport-iscsit_alloc_cmd(conn, gfp_mask);
if (!cmd) {
pr_err(Unable to allocate memory for struct iscsi_cmd.\n);
return NULL;
}
-
-   cmd-conn   = conn;
+   cmd-conn = conn;
INIT_LIST_HEAD(cmd-i_conn_node);
INIT_LIST_HEAD(cmd-datain_list);
INIT_LIST_HEAD(cmd-cmd_r2t_list);
@@ -176,6 +186,7 @@ struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn 
*conn, gfp_t gfp_mask)
 
return cmd;
 }
+EXPORT_SYMBOL(iscsit_allocate_cmd);
 
 struct iscsi_seq *iscsit_get_seq_holder_for_datain(
struct iscsi_cmd *cmd,
@@ -661,6 +672,11 @@ void iscsit_free_queue_reqs_for_conn(struct iscsi_conn 
*conn)
spin_unlock_bh(conn-response_queue_lock);
 }
 
+void iscsit_cache_free_cmd(struct iscsi_cmd *cmd)
+{
+   kmem_cache_free(lio_cmd_cache, cmd);
+}
+
 void iscsit_release_cmd(struct iscsi_cmd *cmd)
 {
struct iscsi_conn *conn = cmd-conn;
@@ -679,17 +695,26 @@ void iscsit_release_cmd(struct iscsi_cmd *cmd)
iscsit_remove_cmd_from_response_queue(cmd, conn);
}
 
-   kmem_cache_free(lio_cmd_cache, cmd);
+   conn-conn_transport-iscsit_free_cmd(cmd);
 }
 
 void iscsit_free_cmd(struct iscsi_cmd *cmd)
 {
+   struct iscsi_conn *conn = cmd-conn;
/*
 * Determine if a struct se_cmd is associated with
 * this struct iscsi_cmd.
 */
switch (cmd-iscsi_opcode) {
case ISCSI_OP_SCSI_CMD:
+   if (cmd-data_direction == DMA_TO_DEVICE)
+   iscsit_stop_dataout_timer(cmd);
+
+   if (conn-conn_transport-iscsit_unmap_cmd)
+   conn-conn_transport-iscsit_unmap_cmd(cmd, conn);
+   /*
+* Fallthrough
+*/
case ISCSI_OP_SCSI_TMFUNC:
transport_generic_free_cmd(cmd-se_cmd, 1);
break;
@@ -709,6 +734,7 @@ void iscsit_free_cmd(struct iscsi_cmd *cmd)
break;
}
 }
+EXPORT_SYMBOL(iscsit_free_cmd);
 
 int iscsit_check_session_usage_count(struct iscsi_session *sess)
 {
diff --git a/drivers/target/iscsi/iscsi_target_util.h 
b/drivers/target/iscsi/iscsi_target_util.h
index 894d0f8..854ce89 100644
--- a/drivers/target/iscsi/iscsi_target_util.h
+++ b/drivers/target/iscsi/iscsi_target_util.h
@@ -8,6 +8,7 @@ extern struct iscsi_r2t *iscsit_get_r2t_for_eos(struct 
iscsi_cmd *, u32, u32);
 extern struct iscsi_r2t *iscsit_get_r2t_from_list(struct iscsi_cmd *);
 extern void iscsit_free_r2t(struct iscsi_r2t *, struct iscsi_cmd *);
 extern void iscsit_free_r2ts_from_list(struct iscsi_cmd *);
+extern struct iscsi_cmd *iscsit_alloc_cmd(struct iscsi_conn *, gfp_t);
 extern struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn *, gfp_t);
 extern struct iscsi_seq 

[RFC 05/11] iscsi-target: Refactor RX PDU logic + export request PDU handling

2013-03-07 Thread Nicholas A. Bellinger
From: Nicholas Bellinger n...@linux-iscsi.org

This patch refactors existing traditional iscsi RX side PDU handling
to use iscsit_transport, and exports the necessary logic for external
transport modules.

This includes:

- Refactor iscsit_handle_scsi_cmd() into PDU setup / processing
- Add updated iscsit_handle_scsi_cmd() for tradtional iscsi code
- Add iscsit_set_unsoliticed_dataout() wrapper
- Refactor iscsit_handle_data_out() into PDU check / processing
- Add updated iscsit_handle_data_out() for tradtional iscsi code
- Add iscsit_handle_nop_out() + iscsit_handle_task_mgt_cmd() to
  accept pre-allocated struct iscsi_cmd
- Add iscsit_build_r2ts_for_cmd() RDMAExtentions check to
  post ISTATE_SEND_R2T to TX immediate queue to start RDMA READ
- Refactor main traditional iscsi iscsi_target_rx_thread() PDU switch
  into iscsi_target_rx_opcode() using iscsit_allocate_cmd()
- Turn iscsi_target_rx_thread() process context into NOP for
  ib_isert side work-queue.

Signed-off-by: Nicholas Bellinger n...@linux-iscsi.org
---
 drivers/target/iscsi/iscsi_target.c  |  463 +++---
 drivers/target/iscsi/iscsi_target.h  |1 +
 drivers/target/iscsi/iscsi_target_erl1.c |8 +-
 drivers/target/iscsi/iscsi_target_util.c |1 +
 4 files changed, 295 insertions(+), 178 deletions(-)

diff --git a/drivers/target/iscsi/iscsi_target.c 
b/drivers/target/iscsi/iscsi_target.c
index 9cd7b7b..fbdc75a 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -703,6 +703,7 @@ int iscsit_add_reject_from_cmd(
 
return (!fail_conn) ? 0 : -1;
 }
+EXPORT_SYMBOL(iscsit_add_reject_from_cmd);
 
 /*
  * Map some portion of the allocated scatterlist to an iovec, suitable for
@@ -793,12 +794,10 @@ static int iscsit_allocate_iovecs(struct iscsi_cmd *cmd)
return 0;
 }
 
-static int iscsit_handle_scsi_cmd(
-   struct iscsi_conn *conn,
-   unsigned char *buf)
+int iscsit_setup_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
+ unsigned char *buf)
 {
-   int data_direction, payload_length, cmdsn_ret = 0, immed_ret;
-   struct iscsi_cmd *cmd = NULL;
+   int data_direction, payload_length;
struct iscsi_scsi_req *hdr;
int iscsi_task_attr;
int sam_task_attr;
@@ -821,8 +820,8 @@ static int iscsit_handle_scsi_cmd(
!(hdr-flags  ISCSI_FLAG_CMD_FINAL)) {
pr_err(ISCSI_FLAG_CMD_WRITE  ISCSI_FLAG_CMD_FINAL
 not set. Bad iSCSI Initiator.\n);
-   return iscsit_add_reject(ISCSI_REASON_BOOKMARK_INVALID, 1,
-   buf, conn);
+   return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID,
+   1, 1, buf, cmd);
}
 
if (((hdr-flags  ISCSI_FLAG_CMD_READ) ||
@@ -842,8 +841,8 @@ static int iscsit_handle_scsi_cmd(
pr_err(ISCSI_FLAG_CMD_READ or ISCSI_FLAG_CMD_WRITE
 set when Expected Data Transfer Length is 0 for
 CDB: 0x%02x. Bad iSCSI Initiator.\n, hdr-cdb[0]);
-   return iscsit_add_reject(ISCSI_REASON_BOOKMARK_INVALID, 1,
-   buf, conn);
+   return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID,
+   1, 1, buf, cmd);
}
 done:
 
@@ -852,29 +851,29 @@ done:
pr_err(ISCSI_FLAG_CMD_READ and/or ISCSI_FLAG_CMD_WRITE
 MUST be set if Expected Data Transfer Length is not 
0.
 Bad iSCSI Initiator\n);
-   return iscsit_add_reject(ISCSI_REASON_BOOKMARK_INVALID, 1,
-   buf, conn);
+   return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID,
+   1, 1, buf, cmd);
}
 
if ((hdr-flags  ISCSI_FLAG_CMD_READ) 
(hdr-flags  ISCSI_FLAG_CMD_WRITE)) {
pr_err(Bidirectional operations not supported!\n);
-   return iscsit_add_reject(ISCSI_REASON_BOOKMARK_INVALID, 1,
-   buf, conn);
+   return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID,
+   1, 1, buf, cmd);
}
 
if (hdr-opcode  ISCSI_OP_IMMEDIATE) {
pr_err(Illegally set Immediate Bit in iSCSI Initiator
 Scsi Command PDU.\n);
-   return iscsit_add_reject(ISCSI_REASON_BOOKMARK_INVALID, 1,
-   buf, conn);
+   return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID,
+   1, 1, buf, cmd);
}
 
if (payload_length  !conn-sess-sess_ops-ImmediateData) {
pr_err(ImmediateData=No but DataSegmentLength=%u,
 protocol error.\n, payload_length);
-   return 

[RFC 07/11] iscsi-target: Add iser network portal attribute

2013-03-07 Thread Nicholas A. Bellinger
From: Nicholas Bellinger n...@linux-iscsi.org

This patch adds a new network portal attribute for iser, that lives
under existing iscsi-target configfs layout at:

   /sys/kernel/config/target/iscsi/$TARGETNAME/$TPGT/np/$PORTAL/iser

When lio_target_np_store_iser() is enabled, iscsit_tpg_add_network_portal()
will attempt to start an rdma_cma network portal for iser-target, only if
the external ib_isert module transport has been loaded.

When disabled, iscsit_tpg_del_network_portal() will cease iser login service
on the network portal, and release any external ib_isert module reference.

Signed-off-by: Nicholas Bellinger n...@linux-iscsi.org
---
 drivers/target/iscsi/iscsi_target_configfs.c |   75 ++
 1 files changed, 75 insertions(+), 0 deletions(-)

diff --git a/drivers/target/iscsi/iscsi_target_configfs.c 
b/drivers/target/iscsi/iscsi_target_configfs.c
index 78d75c8..c4625dd 100644
--- a/drivers/target/iscsi/iscsi_target_configfs.c
+++ b/drivers/target/iscsi/iscsi_target_configfs.c
@@ -124,8 +124,83 @@ out:
 
 TF_NP_BASE_ATTR(lio_target, sctp, S_IRUGO | S_IWUSR);
 
+static ssize_t lio_target_np_show_iser(
+   struct se_tpg_np *se_tpg_np,
+   char *page)
+{
+   struct iscsi_tpg_np *tpg_np = container_of(se_tpg_np,
+   struct iscsi_tpg_np, se_tpg_np);
+   struct iscsi_tpg_np *tpg_np_iser;
+   ssize_t rb;
+
+   tpg_np_iser = iscsit_tpg_locate_child_np(tpg_np, ISCSI_INFINIBAND);
+   if (tpg_np_iser)
+   rb = sprintf(page, 1\n);
+   else
+   rb = sprintf(page, 0\n);
+
+   return rb;
+}
+
+static ssize_t lio_target_np_store_iser(
+   struct se_tpg_np *se_tpg_np,
+   const char *page,
+   size_t count)
+{
+   struct iscsi_np *np;
+   struct iscsi_portal_group *tpg;
+   struct iscsi_tpg_np *tpg_np = container_of(se_tpg_np,
+   struct iscsi_tpg_np, se_tpg_np);
+   struct iscsi_tpg_np *tpg_np_iser = NULL;
+   char *endptr;
+   u32 op;
+   int rc;
+
+   op = simple_strtoul(page, endptr, 0);
+   if ((op != 1)  (op != 0)) {
+   pr_err(Illegal value for tpg_enable: %u\n, op);
+   return -EINVAL;
+   }
+   np = tpg_np-tpg_np;
+   if (!np) {
+   pr_err(Unable to locate struct iscsi_np from
+struct iscsi_tpg_np\n);
+   return -EINVAL;
+   }
+
+   tpg = tpg_np-tpg;
+   if (iscsit_get_tpg(tpg)  0)
+   return -EINVAL;
+
+   if (op) {
+   tpg_np_iser = iscsit_tpg_add_network_portal(tpg, 
np-np_sockaddr,
+   np-np_ip, tpg_np, ISCSI_INFINIBAND);
+   if (!tpg_np_iser || IS_ERR(tpg_np_iser))
+   goto out;
+   } else {
+   tpg_np_iser = iscsit_tpg_locate_child_np(tpg_np, 
ISCSI_INFINIBAND);
+   if (!tpg_np_iser)
+   goto out;
+
+   rc = iscsit_tpg_del_network_portal(tpg, tpg_np_iser);
+   if (rc  0)
+   goto out;
+   }
+
+   printk(lio_target_np_store_iser() done, op: %d\n, op);
+
+   iscsit_put_tpg(tpg);
+   return count;
+out:
+   iscsit_put_tpg(tpg);
+   return -EINVAL;
+}
+
+TF_NP_BASE_ATTR(lio_target, iser, S_IRUGO | S_IWUSR);
+
 static struct configfs_attribute *lio_target_portal_attrs[] = {
lio_target_np_sctp.attr,
+   lio_target_np_iser.attr,
NULL,
 };
 
-- 
1.7.2.5

--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC 06/11] iscsi-target: Refactor TX queue logic + export response PDU creation

2013-03-07 Thread Nicholas A. Bellinger
From: Nicholas Bellinger n...@linux-iscsi.org

This patch refactors TX immediate + response queue handling to use
the new iscsit_transport API callers, and exports the necessary
traditional iscsi PDU response creation functions for iser-target
to utilize.

This includes:

- Add iscsit_build_datain_pdu() for DATAIN PDU init + convert
  iscsit_build_datain_pdu()
- Add iscsit_build_logout_rsp() for LOGOUT_RSP PDU init + convert
  iscsit_send_logout()
- Add iscsit_build_nopin_rsp() for NOPIN_RSP PDU init + convert
  iscsit_send_nopin()
- Add iscsit_build_rsp_pdu() for SCSI_RSP PDU init + convert
  iscsit_send_response()
- Add iscsit_build_task_mgt_rsp for TM_RSP PDU init + convert
  iscsit_send_task_mgt_rsp()
- Refactor immediate queue state switch into iscsit_immediate_queue()
- Convert handle_immediate_queue() to use iscsit_transport caller
- Refactor response queue state switch into iscsit_response_queue()
- Convert handle_response_queue to use iscsit_transport caller
- Export iscsit_logout_post_handler(), iscsit_increment_maxcmdsn()
  and iscsit_tmr_post_handler() for external transport module usage

Signed-off-by: Nicholas Bellinger n...@linux-iscsi.org
---
 drivers/target/iscsi/iscsi_target.c|  619 +++-
 drivers/target/iscsi/iscsi_target_device.c |1 +
 drivers/target/iscsi/iscsi_target_tmr.c|1 +
 3 files changed, 342 insertions(+), 279 deletions(-)

diff --git a/drivers/target/iscsi/iscsi_target.c 
b/drivers/target/iscsi/iscsi_target.c
index fbdc75a..a72b695 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -70,8 +70,7 @@ struct kmem_cache *lio_ooo_cache;
 struct kmem_cache *lio_r2t_cache;
 
 static int iscsit_handle_immediate_data(struct iscsi_cmd *,
-   unsigned char *buf, u32);
-static int iscsit_logout_post_handler(struct iscsi_cmd *, struct iscsi_conn *);
+   struct iscsi_scsi_req *, u32);
 
 struct iscsi_tiqn *iscsit_get_tiqn_for_login(unsigned char *buf)
 {
@@ -481,6 +480,9 @@ int iscsit_del_np(struct iscsi_np *np)
return 0;
 }
 
+static int iscsit_immediate_queue(struct iscsi_conn *, struct iscsi_cmd *, 
int);
+static int iscsit_response_queue(struct iscsi_conn *, struct iscsi_cmd *, int);
+
 static struct iscsit_transport iscsi_target_transport = {
.name   = iSCSI/TCP,
.transport_type = ISCSI_TCP,
@@ -492,6 +494,8 @@ static struct iscsit_transport iscsi_target_transport = {
.iscsit_free_cmd= iscsit_cache_free_cmd,
.iscsit_get_login_rx= iscsit_get_login_rx,
.iscsit_put_login_tx= iscsit_put_login_tx,
+   .iscsit_immediate_queue = iscsit_immediate_queue,
+   .iscsit_response_queue  = iscsit_response_queue,
 };
 
 static int __init iscsi_target_init_module(void)
@@ -2513,18 +2517,60 @@ static void iscsit_tx_thread_wait_for_tcp(struct 
iscsi_conn *conn)
}
 }
 
-static int iscsit_send_data_in(
-   struct iscsi_cmd *cmd,
-   struct iscsi_conn *conn)
+static void
+iscsit_build_datain_pdu(struct iscsi_cmd *cmd, struct iscsi_conn *conn,
+   struct iscsi_datain *datain, struct iscsi_data_rsp *hdr,
+   bool set_statsn)
 {
-   int iov_ret = 0, set_statsn = 0;
-   u32 iov_count = 0, tx_size = 0;
+   hdr-opcode = ISCSI_OP_SCSI_DATA_IN;
+   hdr-flags  = datain-flags;
+   if (hdr-flags  ISCSI_FLAG_DATA_STATUS) {
+   if (cmd-se_cmd.se_cmd_flags  SCF_OVERFLOW_BIT) {
+   hdr-flags |= ISCSI_FLAG_DATA_OVERFLOW;
+   hdr-residual_count = 
cpu_to_be32(cmd-se_cmd.residual_count);
+   } else if (cmd-se_cmd.se_cmd_flags  SCF_UNDERFLOW_BIT) {
+   hdr-flags |= ISCSI_FLAG_DATA_UNDERFLOW;
+   hdr-residual_count = 
cpu_to_be32(cmd-se_cmd.residual_count);
+   }
+   }
+   hton24(hdr-dlength, datain-length);
+   if (hdr-flags  ISCSI_FLAG_DATA_ACK)
+   int_to_scsilun(cmd-se_cmd.orig_fe_lun,
+   (struct scsi_lun *)hdr-lun);
+   else
+   put_unaligned_le64(0xULL, hdr-lun);
+
+   hdr-itt= cmd-init_task_tag;
+
+   if (hdr-flags  ISCSI_FLAG_DATA_ACK)
+   hdr-ttt= cpu_to_be32(cmd-targ_xfer_tag);
+   else
+   hdr-ttt= cpu_to_be32(0x);
+   if (set_statsn)
+   hdr-statsn = cpu_to_be32(cmd-stat_sn);
+   else
+   hdr-statsn = cpu_to_be32(0x);
+
+   hdr-exp_cmdsn  = cpu_to_be32(conn-sess-exp_cmd_sn);
+   hdr-max_cmdsn  = cpu_to_be32(conn-sess-max_cmd_sn);
+   hdr-datasn = cpu_to_be32(datain-data_sn);
+   hdr-offset = cpu_to_be32(datain-offset);
+
+   pr_debug(Built DataIN ITT: 0x%08x, StatSN: 0x%08x,
+

[RFC 09/11] iser-target: Add logic for verbs

2013-03-07 Thread Nicholas A. Bellinger
From: Nicholas Bellinger n...@linux-iscsi.org

Signed-off-by: Nicholas Bellinger n...@linux-iscsi.org
---
 drivers/infiniband/ulp/isert/isert_verbs.c |  476 
 drivers/infiniband/ulp/isert/isert_verbs.h |5 +
 2 files changed, 481 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/ulp/isert/isert_verbs.c
 create mode 100644 drivers/infiniband/ulp/isert/isert_verbs.h

diff --git a/drivers/infiniband/ulp/isert/isert_verbs.c 
b/drivers/infiniband/ulp/isert/isert_verbs.c
new file mode 100644
index 000..2b44eb8
--- /dev/null
+++ b/drivers/infiniband/ulp/isert/isert_verbs.c
@@ -0,0 +1,476 @@
+/***
+ * This file contains iSCSI extentions for RDMA (iSER) Verbs
+ *
+ * (c) Copyright 2013 RisingTide Systems LLC.
+ *
+ * Nicholas A. Bellinger n...@linux-iscsi.org
+ *
+ * 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.
+ /
+#include linux/socket.h
+#include linux/in.h
+#include linux/in6.h
+
+#include rdma/ib_verbs.h
+#include rdma/ib_fmr_pool.h
+#include rdma/rdma_cm.h
+#include target/iscsi/iscsi_transport.h
+
+#include isert_proto.h
+#include isert_base.h
+#include isert_core.h
+
+#define ISERT_ADDR_ROUTE_TIMEOUT 1000
+
+#defineISERT_MAX_CONN  8
+#define ISER_MAX_RX_CQ_LEN (ISERT_QP_MAX_RECV_DTOS * ISERT_MAX_CONN)
+#define ISER_MAX_TX_CQ_LEN (ISERT_QP_MAX_REQ_DTOS  * ISERT_MAX_CONN)
+
+static void
+isert_qp_event_callback(struct ib_event *e, void *context)
+{
+   pr_err(isert_qp_event_callback event: %d\n, e-event);
+}
+
+static int
+isert_query_device(struct ib_device *ib_dev, struct ib_device_attr *devattr)
+{
+   int ret;
+
+   ret = ib_query_device(ib_dev, devattr);
+   if (ret) {
+   pr_err(ib_query_device() failed: %d\n, ret);
+   return ret;
+   }
+   pr_debug(devattr-max_mr_size: 0x%016Lx\n, devattr-max_mr_size);
+   pr_debug(devattr-page_size_cap: 0x%016Lx\n, devattr-page_size_cap);
+   pr_debug(devattr-max_qp: %d\n, devattr-max_qp);
+   pr_debug(devattr-max_qp_wr: %d\n, devattr-max_qp_wr);
+   pr_debug(devattr-device_cap_flags: 0x%08x\n, 
devattr-device_cap_flags);
+   pr_debug(devattr-max_sge: %d\n, devattr-max_sge);
+   pr_debug(devattr-max_sge_rd: %d\n, devattr-max_sge_rd);
+   pr_debug(devattr-max_cq: %d\n, devattr-max_cq);
+   pr_debug(devattr-max_cqe: %d\n, devattr-max_cqe);
+   pr_debug(devattr-max_mr: %d\n, devattr-max_mr);
+   pr_debug(devattr-max_pd: %d\n, devattr-max_pd);
+   pr_debug(devattr-max_rdd: %d\n, devattr-max_rdd);
+   pr_debug(devattr-max_mw: %d\n, devattr-max_mw);
+   pr_debug(devattr-max_srq: %d\n, devattr-max_srq);
+   pr_debug(devattr-max_srq_wr: %d\n, devattr-max_srq_wr);
+   pr_debug(devattr-max_srq_sge: %d\n, devattr-max_srq_sge);
+
+   return 0;
+}
+
+static int
+isert_conn_setup_qp(struct isert_conn *isert_conn, struct rdma_cm_id *cma_id)
+{
+   struct ib_qp_init_attr attr;
+   struct ib_device_attr devattr;
+   int ret;
+
+   memset(devattr, 0, sizeof(struct ib_device_attr));
+   ret = isert_query_device(cma_id-device, devattr);
+
+   memset(attr, 0, sizeof(struct ib_qp_init_attr));
+   attr.event_handler = isert_qp_event_callback;
+   attr.qp_context = isert_conn;
+   attr.send_cq = isert_conn-conn_tx_cq;
+   attr.recv_cq = isert_conn-conn_rx_cq;
+   attr.cap.max_send_wr = ISERT_QP_MAX_REQ_DTOS;
+   attr.cap.max_recv_wr = ISERT_QP_MAX_RECV_DTOS;
+#warning FIXME: max_sge hardcoded to 16
+#if 0
+   attr.cap.max_send_sge = devattr.max_sge;
+   isert_conn-max_sge = devattr.max_sge;
+#else
+   attr.cap.max_send_sge = 16;
+   isert_conn-max_sge = 16;
+#endif
+   attr.cap.max_recv_sge = 1;
+   attr.sq_sig_type = IB_SIGNAL_REQ_WR;
+   attr.qp_type = IB_QPT_RC;
+
+   pr_debug(isert_conn_setup_qp cma_id-device: %p\n, cma_id-device);
+   pr_debug(isert_conn_setup_qp conn_pd-device: %p\n, 
isert_conn-conn_pd-device);
+
+   ret = rdma_create_qp(cma_id, isert_conn-conn_pd, attr);
+   if (ret) {
+   pr_err(rdma_create_qp failed for cma_id %d\n, ret);
+   return ret;
+   }
+   isert_conn-conn_qp = cma_id-qp;
+   pr_debug(rdma_create_qp() returned success 
.\n);
+
+   return 0;
+}
+
+static void
+isert_cq_event_callback(struct ib_event *e, void *context)
+{
+   

[RFC 08/11] iser-target: Add base + proto includes

2013-03-07 Thread Nicholas A. Bellinger
From: Nicholas Bellinger n...@linux-iscsi.org

Signed-off-by: Nicholas Bellinger n...@linux-iscsi.org
---
 drivers/infiniband/ulp/isert/isert_base.h  |  123 
 drivers/infiniband/ulp/isert/isert_proto.h |   47 +++
 2 files changed, 170 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/ulp/isert/isert_base.h
 create mode 100644 drivers/infiniband/ulp/isert/isert_proto.h

diff --git a/drivers/infiniband/ulp/isert/isert_base.h 
b/drivers/infiniband/ulp/isert/isert_base.h
new file mode 100644
index 000..a7c8bc9
--- /dev/null
+++ b/drivers/infiniband/ulp/isert/isert_base.h
@@ -0,0 +1,123 @@
+#include linux/socket.h
+#include linux/in.h
+#include linux/in6.h
+#include rdma/ib_verbs.h
+#include rdma/ib_fmr_pool.h
+#include rdma/rdma_cm.h
+
+#define ISERT_RDMA_LISTEN_BACKLOG  10
+
+enum isert_desc_type {
+   ISCSI_TX_CONTROL,
+   ISCSI_TX_DATAIN
+};
+
+enum iser_ib_op_code {
+   ISER_IB_RECV,
+   ISER_IB_SEND,
+   ISER_IB_RDMA_WRITE,
+   ISER_IB_RDMA_READ,
+};
+
+enum iser_conn_state {
+   ISER_CONN_INIT,
+   ISER_CONN_UP,
+   ISER_CONN_TERMINATING,
+   ISER_CONN_DOWN,
+};
+
+struct iser_rx_desc {
+   struct iser_hdr iser_header;
+   struct iscsi_hdr iscsi_header;
+   chardata[ISER_RECV_DATA_SEG_LEN];
+   u64 dma_addr;
+   struct ib_sge   rx_sg;
+   charpad[ISER_RX_PAD_SIZE];
+} __attribute__((packed));
+
+struct isert_rx_desc {
+   struct isert_conn   *desc_conn;
+   struct work_struct  desc_work;
+   struct iser_rx_desc desc;
+}  __attribute__((packed));
+
+struct iser_tx_desc {
+struct iser_hdr iser_header;
+struct iscsi_hdr iscsi_header;
+enum isert_desc_type type;
+u64 dma_addr;
+struct ib_sge   tx_sg[2];
+int num_sge;
+   struct isert_cmd *isert_cmd;
+   struct ib_send_wr send_wr;
+} __attribute__((packed));
+
+struct isert_rdma_wr {
+   struct list_headwr_list;
+   struct isert_cmd*isert_cmd;
+   enum iser_ib_op_codeiser_ib_op;
+   struct ib_sge   *ib_sge;
+   int num_sge;
+   struct scatterlist  *sge;
+   int send_wr_num;
+   struct ib_send_wr   *send_wr;
+};
+
+struct isert_cmd {
+   uint32_tread_stag;
+   uint32_twrite_stag;
+   uint64_tread_va;
+   uint64_twrite_va;
+   u64 sense_buf_dma;
+   u32 sense_buf_len;
+   u32 read_va_off;
+   u32 write_va_off;
+   u32 rdma_wr_num;
+   struct isert_conn   *conn;
+   struct iscsi_cmdiscsi_cmd;
+   struct ib_sge   *ib_sge;
+   struct iser_tx_desc tx_desc;
+   struct isert_rdma_wrrdma_wr;
+   struct work_struct  comp_work;
+   struct kref cmd_kref;
+};
+
+struct isert_conn {
+   enum iser_conn_statestate;
+   int post_recv_buf_count;
+   atomic_tpost_send_buf_count;
+   u32 responder_resources;
+   u32 initiator_depth;
+   u32 max_sge;
+   char*login_buf;
+   char*login_req_buf;
+   char*login_rsp_buf;
+   u64 login_req_dma;
+   u64 login_rsp_dma;
+   unsigned intconn_rx_desc_head;
+   struct isert_rx_desc*conn_rx_descs;
+   struct ib_recv_wr   conn_rx_wr[ISERT_MIN_POSTED_RX];
+   struct iscsi_conn   *conn;
+   struct list_headconn_accept_node;
+   struct completion   conn_login_comp;
+   struct iser_tx_desc conn_login_tx_desc;
+   struct rdma_cm_id   *conn_cm_id;
+   struct ib_pd*conn_pd;
+   struct ib_cq*conn_rx_cq;
+   struct ib_cq*conn_tx_cq;
+   struct ib_mr*conn_mr;
+   struct ib_qp*conn_qp;
+   struct tasklet_struct   conn_rx_tasklet;
+   struct tasklet_struct   conn_tx_tasklet;
+   struct work_struct  conn_logout_work;
+   wait_queue_head_t   conn_wait;
+   struct kref conn_kref;
+};
+
+struct isert_np {
+   wait_queue_head_t   np_accept_wq;
+   struct rdma_cm_id   *np_cm_id;
+   struct mutexnp_accept_mutex;
+   struct list_headnp_accept_list;
+   struct completion   np_login_comp;
+};
diff --git a/drivers/infiniband/ulp/isert/isert_proto.h 
b/drivers/infiniband/ulp/isert/isert_proto.h
new file mode 100644
index 000..ae38b92
--- /dev/null
+++ b/drivers/infiniband/ulp/isert/isert_proto.h
@@ -0,0 +1,47 @@
+/* From iscsi_iser.h */
+

[RFC 10/11] iser-target: Add logic for core

2013-03-07 Thread Nicholas A. Bellinger
From: Nicholas Bellinger n...@linux-iscsi.org

Signed-off-by: Nicholas Bellinger n...@linux-iscsi.org
---
 drivers/infiniband/ulp/isert/isert_core.c | 1720 +
 drivers/infiniband/ulp/isert/isert_core.h |   12 +
 2 files changed, 1732 insertions(+), 0 deletions(-)
 create mode 100644 drivers/infiniband/ulp/isert/isert_core.c
 create mode 100644 drivers/infiniband/ulp/isert/isert_core.h

diff --git a/drivers/infiniband/ulp/isert/isert_core.c 
b/drivers/infiniband/ulp/isert/isert_core.c
new file mode 100644
index 000..846911f
--- /dev/null
+++ b/drivers/infiniband/ulp/isert/isert_core.c
@@ -0,0 +1,1720 @@
+/***
+ * This file contains iSCSI extentions for RDMA (iSER) for iscsi_target_mod
+ *
+ * (c) Copyright 2013 RisingTide Systems LLC.
+ *
+ * Nicholas A. Bellinger n...@linux-iscsi.org
+ *
+ * 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.
+ /
+
+#include linux/string.h
+#include linux/module.h
+#include linux/scatterlist.h
+#include linux/socket.h
+#include linux/in.h
+#include linux/in6.h
+#include rdma/ib_verbs.h
+#include rdma/ib_fmr_pool.h
+#include rdma/rdma_cm.h
+#include target/target_core_base.h
+#include target/target_core_fabric.h
+#include target/iscsi/iscsi_transport.h
+
+#include isert_proto.h
+#include isert_base.h
+#include isert_core.h
+#include isert_verbs.h
+
+static struct workqueue_struct *isert_rx_wq;
+static struct workqueue_struct *isert_comp_wq;
+
+static void
+isert_create_send_desc(struct isert_conn *isert_conn,
+  struct isert_cmd *isert_cmd,
+  struct iser_tx_desc *tx_desc)
+{
+   struct ib_device *ib_dev = isert_conn-conn_cm_id-device;
+
+   ib_dma_sync_single_for_cpu(ib_dev, tx_desc-dma_addr,
+   ISER_HEADERS_LEN, DMA_TO_DEVICE);
+
+   memset(tx_desc-iser_header, 0, sizeof(struct iser_hdr));
+   tx_desc-iser_header.flags = ISER_VER;
+
+   tx_desc-num_sge = 1;
+   tx_desc-isert_cmd = isert_cmd;
+
+   if (tx_desc-tx_sg[0].lkey != isert_conn-conn_mr-lkey) {
+   tx_desc-tx_sg[0].lkey = isert_conn-conn_mr-lkey;
+   pr_debug(tx_desc %p lkey mismatch, fixing\n, tx_desc);
+   }
+}
+
+static int
+isert_init_tx_hdrs(struct isert_conn *isert_conn,
+  struct iser_tx_desc *tx_desc)
+{
+   struct ib_device *ib_dev = isert_conn-conn_cm_id-device;
+   u64 dma_addr;
+
+   dma_addr = ib_dma_map_single(ib_dev, (void *)tx_desc,
+   ISER_HEADERS_LEN, DMA_TO_DEVICE);
+   if (ib_dma_mapping_error(ib_dev, dma_addr)) {
+   pr_err(ib_dma_mapping_error() failed\n);
+   return -ENOMEM;
+   }
+
+   tx_desc-dma_addr = dma_addr;
+   tx_desc-tx_sg[0].addr  = tx_desc-dma_addr;
+   tx_desc-tx_sg[0].length = ISER_HEADERS_LEN;
+   tx_desc-tx_sg[0].lkey = isert_conn-conn_mr-lkey;
+
+   pr_debug(isert_init_tx_hdrs: Setup tx_sg[0].addr: 0x%llx length: %u,
+lkey: 0x%08x\n, tx_desc-tx_sg[0].addr,
+   tx_desc-tx_sg[0].length, tx_desc-tx_sg[0].lkey);
+
+   return 0;
+}
+
+static int
+isert_alloc_rx_descriptors(struct isert_conn *isert_conn)
+{
+   struct ib_device *ib_dev = isert_conn-conn_cm_id-device;
+   struct isert_rx_desc *rx_desc;
+   struct iser_rx_desc *desc;
+   struct ib_sge *rx_sg;
+   u64 dma_addr;
+   int i, j;
+
+   isert_conn-conn_rx_descs = kzalloc(ISERT_QP_MAX_RECV_DTOS *
+   sizeof(struct isert_rx_desc), 
GFP_KERNEL);
+   if (!isert_conn-conn_rx_descs)
+   goto fail;
+
+   rx_desc = isert_conn-conn_rx_descs;
+
+   for (i = 0; i  ISERT_QP_MAX_RECV_DTOS; i++, rx_desc++)  {
+   desc = rx_desc-desc;
+
+   dma_addr = ib_dma_map_single(ib_dev, (void *)desc,
+   ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE);
+   if (ib_dma_mapping_error(ib_dev, dma_addr))
+   goto dma_map_fail;
+
+   desc-dma_addr = dma_addr;
+
+   rx_sg = desc-rx_sg;
+   rx_sg-addr = desc-dma_addr;
+   rx_sg-length = ISER_RX_PAYLOAD_SIZE;
+   rx_sg-lkey = isert_conn-conn_mr-lkey;
+   }
+
+   isert_conn-conn_rx_desc_head = 0;
+   return 0;
+
+dma_map_fail:
+   rx_desc = isert_conn-conn_rx_descs;
+   for (j = 0; 

Re: [RFC 01/11] iscsi-target: Add iscsit_transport API template

2013-03-07 Thread Roland Dreier
On Thu, Mar 7, 2013 at 5:45 PM, Nicholas A. Bellinger
n...@linux-iscsi.org wrote:
 +EXPORT_SYMBOL(iscsit_get_transport);

It's not clear to me why this needs to be exported.  Who would use it
outside the core iscsi target module?
--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC 01/11] iscsi-target: Add iscsit_transport API template

2013-03-07 Thread Nicholas A. Bellinger
On Thu, 2013-03-07 at 20:14 -0800, Roland Dreier wrote:
 On Thu, Mar 7, 2013 at 5:45 PM, Nicholas A. Bellinger
 n...@linux-iscsi.org wrote:
  +EXPORT_SYMBOL(iscsit_get_transport);
 
 It's not clear to me why this needs to be exported.  Who would use it
 outside the core iscsi target module?

Oversight on my part.  Dropping the unnecessary export of
iscsit_get_transport() and iscsit_put_transport() from iscsi-target code
now..

Also, realistically, I don't expect module code beyond ib_isert.ko to
ever use the definitions in include/target/iscsi/ either.

Or and I discussed this point in the last status call, and given what
the initiator did originally (eg: export iscsi_transport) he asked to
keep it under drivers/infiniband/ulp/isert/ with the extra include bits.

I'd have a slight preference to move iser-target code under
drivers/target/iscsi/, and not put anything into include/target/iscsi/
if there won't be another module that uses it..

Do you have a preference here..?

--nab






--
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html