RE: [PATCH v3 2/3] megaraid_sas : use dev_printk when possible

2015-07-08 Thread Sumit Saxena
 -Original Message-
 From: Bjorn Helgaas [mailto:bhelg...@google.com]
 Sent: Wednesday, July 08, 2015 2:23 AM
 To: Kashyap Desai; Uday Lingala; Sumit Saxena
 Cc: megaraidlinux@avagotech.com; linux-scsi@vger.kernel.org; James
 E.J.
 Bottomley; linux-ker...@vger.kernel.org; Joe Perches; Christoph Hellwig
 Subject: [PATCH v3 2/3] megaraid_sas : use dev_printk when possible

 Use dev_printk() when possible to make messages more useful.

 Signed-off-by: Bjorn Helgaas bhelg...@google.com
 ---
  drivers/scsi/megaraid/megaraid_sas_base.c   |  304
 +--
  drivers/scsi/megaraid/megaraid_sas_fusion.c |   95 
  2 files changed, 196 insertions(+), 203 deletions(-)

 diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c
 b/drivers/scsi/megaraid/megaraid_sas_base.c
 index 71b884d..a9bd592 100644
 --- a/drivers/scsi/megaraid/megaraid_sas_base.c
 +++ b/drivers/scsi/megaraid/megaraid_sas_base.c
 @@ -216,7 +216,7 @@ struct megasas_cmd *megasas_get_cmd(struct
 megasas_instance
struct megasas_cmd, list);
   list_del_init(cmd-list);
   } else {
 - printk(KERN_ERR megasas: Command pool empty!\n);
 + dev_err(instance-pdev-dev, Command pool empty!\n);
   }

   spin_unlock_irqrestore(instance-mfi_pool_lock, flags);
 @@ -370,9 +370,9 @@ megasas_adp_reset_xscale(struct megasas_instance
 *instance,
   msleep(1000); /* sleep for 3 secs */
   pcidata  = 0;
   pci_read_config_dword(instance-pdev, MFI_1068_PCSR_OFFSET,
 pcidata);
 - printk(KERN_NOTICE pcidata = %x\n, pcidata);
 + dev_notice(instance-pdev-dev, pcidata = %x\n, pcidata);
   if (pcidata  0x2) {
 - printk(KERN_NOTICE mfi 1068 offset read=%x\n, pcidata);
 + dev_notice(instance-pdev-dev, mfi 1068 offset
 read=%x\n, pcidata);
   pcidata = ~0x2;
   pci_write_config_dword(instance-pdev,
   MFI_1068_PCSR_OFFSET, pcidata);
 @@ -383,9 +383,9 @@ megasas_adp_reset_xscale(struct megasas_instance
 *instance,
   pcidata  = 0;
   pci_read_config_dword(instance-pdev,
   MFI_1068_FW_HANDSHAKE_OFFSET,
 pcidata);
 - printk(KERN_NOTICE 1068 offset handshake read=%x\n,
 pcidata);
 + dev_notice(instance-pdev-dev, 1068 offset handshake
 read=%x\n, pcidata);
   if ((pcidata  0x) == MFI_1068_FW_READY) {
 - printk(KERN_NOTICE 1068 offset pcidt=%x\n,
 pcidata);
 + dev_notice(instance-pdev-dev, 1068 offset
 pcidt=%x\n, pcidata);
   pcidata = 0;
   pci_write_config_dword(instance-pdev,
   MFI_1068_FW_HANDSHAKE_OFFSET, pcidata);
 @@ -824,7 +824,7 @@ megasas_adp_reset_gen2(struct megasas_instance
 *instance,
   while ( !( HostDiag  DIAG_WRITE_ENABLE) ) {
   msleep(100);
   HostDiag = (u32)readl(hostdiag_offset);
 - printk(KERN_NOTICE RESETGEN2: retry=%x, hostdiag=%x\n,
 + dev_notice(instance-pdev-dev, RESETGEN2: retry=%x,
 hostdiag=%x\n,
   retry, HostDiag);

   if (retry++ = 100)
 @@ -832,7 +832,7 @@ megasas_adp_reset_gen2(struct megasas_instance
 *instance,

   }

 - printk(KERN_NOTICE ADP_RESET_GEN2: HostDiag=%x\n, HostDiag);
 + dev_notice(instance-pdev-dev, ADP_RESET_GEN2:
 HostDiag=%x\n, HostDiag);

   writel((HostDiag | DIAG_RESET_ADAPTER), hostdiag_offset);

 @@ -842,7 +842,7 @@ megasas_adp_reset_gen2(struct megasas_instance
 *instance,
   while ( ( HostDiag  DIAG_RESET_ADAPTER) ) {
   msleep(100);
   HostDiag = (u32)readl(hostdiag_offset);
 - printk(KERN_NOTICE RESET_GEN2: retry=%x, hostdiag=%x\n,
 + dev_notice(instance-pdev-dev, RESET_GEN2: retry=%x,
 hostdiag=%x\n,
   retry, HostDiag);

   if (retry++ = 1000)
 @@ -1241,7 +1241,7 @@ megasas_build_dcdb(struct megasas_instance
 *instance, struct scsi_cmnd *scp,
 pthru-sgl);

   if (pthru-sge_count  instance-max_num_sge) {
 - printk(KERN_ERR megasas: DCDB two many SGE NUM=%x\n,
 + dev_err(instance-pdev-dev, DCDB too many SGE
 NUM=%x\n,
   pthru-sge_count);
   return 0;
   }
 @@ -1382,7 +1382,7 @@ megasas_build_ldio(struct megasas_instance
 *instance, struct scsi_cmnd *scp,
   ldio-sge_count = megasas_make_sgl32(instance, scp, ldio-
 sgl);

   if (ldio-sge_count  instance-max_num_sge) {
 - printk(KERN_ERR megasas: build_ld_io: sge_count = %x\n,
 + dev_err(instance-pdev-dev, build_ld_io: sge_count =
 %x\n,
   ldio-sge_count);
   return 0;
   }
 @@ -1449,24 +1449,24 @@ megasas_dump_pending_frames(struct
 megasas_instance *instance)
 

Re: [PATCH v3 5/5] target: Fix wrong setting of sense format for PI errors

2015-07-08 Thread Sagi Grimberg

On 7/8/2015 1:19 PM, Christoph Hellwig wrote:

On Mon, Jul 06, 2015 at 04:15:08PM +0300, Sagi Grimberg wrote:

PI errors should be reported in a descriptor format sense data.
Fix that by adding a desc_format flag to struct sense_info and pass
it to scsi_build_sense_buffer() to do the right thing.


Do we really need the additional flag?  We only need the descriptor
sense format because we add the sector information.  So just checking
for that should be enough, especially when paired with a comment
explaining that logic in the source file.


We don't have any other information today, but sector is not the only
information that is requires a descriptor format, so maybe it will be a
bit awkward to condition the descriptor format on the sector info?
--
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 3/3] megaraid_sas : fix whitespace errors

2015-07-08 Thread Hannes Reinecke
On 07/07/2015 10:52 PM, Bjorn Helgaas wrote:
 Fix whitespace and indentation errors.  No code change.
 
 Signed-off-by: Bjorn Helgaas bhelg...@google.com
 ---
  drivers/scsi/megaraid/megaraid_sas_base.c |  244 
 ++---
  1 file changed, 118 insertions(+), 126 deletions(-)
 
Reviewed-by: Hannes Reinecke h...@suse.de

Cheers,

Hannes
-- 
Dr. Hannes ReineckezSeries  Storage
h...@suse.de   +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)
--
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 5/5] target: Fix wrong setting of sense format for PI errors

2015-07-08 Thread Christoph Hellwig
On Wed, Jul 08, 2015 at 01:36:04PM +0300, Sagi Grimberg wrote:
 We don't have any other information today, but sector is not the only
 information that is requires a descriptor format, so maybe it will be a
 bit awkward to condition the descriptor format on the sector info?

The only reason why you'd want to support descriptor type sense data is
because you need to add a second descriptor.  If we have another case
that needs descriptor sense data it'll also need to add that additional
descriptor.  So we'll need a conditional for it in the sense data
generation anyway.
--
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 3/5] scsi: Add 'access_state' attribute

2015-07-08 Thread Hannes Reinecke
Add an 'access_state' attribute to display the LUN access state.

Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/scsi/scsi_sysfs.c  | 53 ++
 include/scsi/scsi_device.h | 13 
 include/scsi/scsi_dh.h |  1 +
 3 files changed, 67 insertions(+)

diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index b4de776..5f1a981 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -81,6 +81,34 @@ const char *scsi_host_state_name(enum scsi_host_state state)
return name;
 }
 
+static const struct {
+   enum scsi_access_state  value;
+   char*name;
+} sdev_access_states[] = {
+   { SCSI_ACCESS_STATE_UNKNOWN, unknown },
+   { SCSI_ACCESS_STATE_OPTIMAL, optimal },
+   { SCSI_ACCESS_STATE_ACTIVE, active },
+   { SCSI_ACCESS_STATE_PASSIVE, passive },
+   { SCSI_ACCESS_STATE_UNAVAILABLE, unavailable },
+   { SCSI_ACCESS_STATE_LBA, lba-dependent },
+   { SCSI_ACCESS_STATE_OFFLINE, offline },
+   { SCSI_ACCESS_STATE_TRANSITIONING, transitioning },
+   { SCSI_ACCESS_STATE_PREFERRED, preferred },
+};
+const char *scsi_access_state_name(enum scsi_access_state state)
+{
+   int i;
+   char *name = NULL;
+
+   for (i = 0; i  ARRAY_SIZE(sdev_access_states); i++) {
+   if (sdev_access_states[i].value == state) {
+   name = sdev_access_states[i].name;
+   break;
+   }
+   }
+   return name;
+}
+
 static int check_set(unsigned long long *val, char *src)
 {
char *last;
@@ -934,6 +962,30 @@ sdev_store_dh_state(struct device *dev, struct 
device_attribute *attr,
 
 static DEVICE_ATTR(dh_state, S_IRUGO | S_IWUSR, sdev_show_dh_state,
   sdev_store_dh_state);
+
+static ssize_t
+sdev_show_access_state(struct device *dev,
+  struct device_attribute *attr,
+  char *buf)
+{
+   struct scsi_device *sdev = to_scsi_device(dev);
+   enum scsi_access_state access_state = SCSI_ACCESS_STATE_UNKNOWN;
+   bool pref = false;
+
+   if (sdev-handler  sdev-handler-state) {
+   int state = sdev-handler-state(sdev);
+
+   if (state  SCSI_ACCESS_STATE_PREFERRED)
+   pref = true;
+
+   access_state = (state  SCSI_ACCESS_STATE_MASK);
+   }
+
+   return snprintf(buf, 32, %s%s\n,
+   scsi_access_state_name(access_state),
+   pref ?  preferred :);
+}
+static DEVICE_ATTR(access_state, S_IRUGO, sdev_show_access_state, NULL);
 #endif
 
 static ssize_t
@@ -1007,6 +1059,7 @@ static struct attribute *scsi_sdev_attrs[] = {
dev_attr_queue_type.attr,
 #ifdef CONFIG_SCSI_DH
dev_attr_dh_state.attr,
+   dev_attr_access_state.attr,
 #endif
dev_attr_queue_ramp_up_period.attr,
REF_EVT(media_change),
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index d2f8b7a..4a10737 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -50,6 +50,19 @@ enum scsi_device_state {
SDEV_CREATED_BLOCK, /* same as above but for created devices */
 };
 
+enum scsi_access_state {
+   SCSI_ACCESS_STATE_UNKNOWN = 0,
+   SCSI_ACCESS_STATE_OPTIMAL,
+   SCSI_ACCESS_STATE_ACTIVE,
+   SCSI_ACCESS_STATE_PASSIVE,
+   SCSI_ACCESS_STATE_UNAVAILABLE,
+   SCSI_ACCESS_STATE_LBA,
+   SCSI_ACCESS_STATE_OFFLINE,
+   SCSI_ACCESS_STATE_TRANSITIONING,
+   SCSI_ACCESS_STATE_PREFERRED = 0x80
+};
+#define SCSI_ACCESS_STATE_MASK 0x7f
+
 enum scsi_device_event {
SDEV_EVT_MEDIA_CHANGE   = 1,/* media has changed */
SDEV_EVT_INQUIRY_CHANGE_REPORTED,   /* 3F 03  UA reported */
diff --git a/include/scsi/scsi_dh.h b/include/scsi/scsi_dh.h
index 5c73062..bc1b9f0 100644
--- a/include/scsi/scsi_dh.h
+++ b/include/scsi/scsi_dh.h
@@ -71,6 +71,7 @@ struct scsi_device_handler {
int (*prep_fn)(struct scsi_device *, struct request *);
int (*set_params)(struct scsi_device *, const char *);
void (*rescan)(struct scsi_device *);
+   int (*state)(struct scsi_device *);
 };
 
 #ifdef CONFIG_SCSI_DH
-- 
1.8.5.2

--
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 5/5] target: Fix wrong setting of sense format for PI errors

2015-07-08 Thread Christoph Hellwig
On Wed, Jul 08, 2015 at 12:59:18PM +0200, Hannes Reinecke wrote:
 Actually it's controlled by the D_SENSE bit in the Control mode page
 (that's bit[2] of byte 2 in the control mode page).
 Which is currently set to '0', ie we will be returning fixed sense
 information.
 _If_ we were to report descriptor sense we will need to change that,
 too.

Just looked over SPC, and indeed D_SENSE is a strict either fixed
or descriptor, not a may return descriptor data.

So this patch actually is wrong as we never must return different sense
data types based on the sense code.
--
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 5/5] target: Fix wrong setting of sense format for PI errors

2015-07-08 Thread Sagi Grimberg

On 7/8/2015 1:59 PM, Hannes Reinecke wrote:

On 07/08/2015 12:49 PM, Christoph Hellwig wrote:

On Wed, Jul 08, 2015 at 01:36:04PM +0300, Sagi Grimberg wrote:

We don't have any other information today, but sector is not the only
information that is requires a descriptor format, so maybe it will be a
bit awkward to condition the descriptor format on the sector info?


The only reason why you'd want to support descriptor type sense data is
because you need to add a second descriptor.  If we have another case
that needs descriptor sense data it'll also need to add that additional
descriptor.  So we'll need a conditional for it in the sense data
generation anyway.


Actually it's controlled by the D_SENSE bit in the Control mode page
(that's bit[2] of byte 2 in the control mode page).
Which is currently set to '0', ie we will be returning fixed sense
information.
_If_ we were to report descriptor sense we will need to change that,
too.


I missed that bit.



And it's actually not true that you'd need descriptor sense to
encode the sector information; it'll be stored in the 'information'
section (byte 3-6) for fixed format sense.


But when I return the sector info in a fixed size format, the initiator
is not able to decode the faulty sector:

kernel: DIFv1 Type 1 reference failed on sector: 15 tag: 0xfff0 
sector MSB: 0x000f
kernel: sd 10:0:1:0: [sdc] tag#0 FAILED Result: hostbyte=DID_OK 
driverbyte=DRIVER_SENSE

kernel: sd 10:0:1:0: [sdc] tag#0 Sense Key : Aborted Command [current]
kernel: sd 10:0:1:0: [sdc] tag#0 Add. Sense: No additional sense information
kernel: sd 10:0:1:0: [sdc] tag#0 CDB: Read(10) 28 20 00 00 00 00 00 00 10 00
kernel: blk_update_request: I/O error, dev sdc, sector 0

Is that a bug?
--
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 5/5] target: Fix wrong setting of sense format for PI errors

2015-07-08 Thread Hannes Reinecke
On 07/08/2015 12:49 PM, Christoph Hellwig wrote:
 On Wed, Jul 08, 2015 at 01:36:04PM +0300, Sagi Grimberg wrote:
 We don't have any other information today, but sector is not the only
 information that is requires a descriptor format, so maybe it will be a
 bit awkward to condition the descriptor format on the sector info?
 
 The only reason why you'd want to support descriptor type sense data is
 because you need to add a second descriptor.  If we have another case
 that needs descriptor sense data it'll also need to add that additional
 descriptor.  So we'll need a conditional for it in the sense data
 generation anyway.
 
Actually it's controlled by the D_SENSE bit in the Control mode page
(that's bit[2] of byte 2 in the control mode page).
Which is currently set to '0', ie we will be returning fixed sense
information.
_If_ we were to report descriptor sense we will need to change that,
too.

And it's actually not true that you'd need descriptor sense to
encode the sector information; it'll be stored in the 'information'
section (byte 3-6) for fixed format sense.

Cheers,

Hannes
-- 
Dr. Hannes ReineckezSeries  Storage
h...@suse.de   +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)
--
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/5] scsi_dh_rdac: Add 'state' callback

2015-07-08 Thread Hannes Reinecke
Add a 'state' callback to display the current LUN access state
to sysfs.

Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/scsi/device_handler/scsi_dh_rdac.c | 17 +
 1 file changed, 17 insertions(+)

diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c 
b/drivers/scsi/device_handler/scsi_dh_rdac.c
index 3613581..151b736 100644
--- a/drivers/scsi/device_handler/scsi_dh_rdac.c
+++ b/drivers/scsi/device_handler/scsi_dh_rdac.c
@@ -834,6 +834,22 @@ static void rdac_bus_detach( struct scsi_device *sdev )
kfree(h);
 }
 
+static int rdac_state(struct scsi_device *sdev)
+{
+   struct rdac_dh_data *h = sdev-handler_data;
+   int access_state = SCSI_ACCESS_STATE_OPTIMAL;
+
+   if (h-lun_state == RDAC_LUN_UNOWNED)
+   access_state = SCSI_ACCESS_STATE_ACTIVE;
+   if (h-state == RDAC_STATE_PASSIVE)
+   access_state = SCSI_ACCESS_STATE_PASSIVE;
+
+   if (h-preferred == RDAC_PREFERRED)
+   access_state |= SCSI_ACCESS_STATE_PREFERRED;
+
+   return access_state;
+}
+
 static struct scsi_device_handler rdac_dh = {
.name = RDAC_NAME,
.module = THIS_MODULE,
@@ -842,6 +858,7 @@ static struct scsi_device_handler rdac_dh = {
.attach = rdac_bus_attach,
.detach = rdac_bus_detach,
.activate = rdac_activate,
+   .state = rdac_state,
 };
 
 static int __init rdac_init(void)
-- 
1.8.5.2

--
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 1/5] scsi: rescan VPD attributes

2015-07-08 Thread Hannes Reinecke
This patch implements a VPD page rescan if the 'rescan' sysfs
attribute is triggered.

Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/scsi/device_handler/scsi_dh_alua.c | 11 +++
 drivers/scsi/scsi.c| 20 +---
 drivers/scsi/scsi_scan.c   |  4 
 drivers/scsi/scsi_sysfs.c  |  8 ++--
 drivers/scsi/ses.c |  6 --
 include/scsi/scsi_device.h |  1 +
 6 files changed, 39 insertions(+), 11 deletions(-)

diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
b/drivers/scsi/device_handler/scsi_dh_alua.c
index d077014..e4cabc8 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -264,8 +264,11 @@ static int alua_check_vpd(struct scsi_device *sdev, struct 
alua_dh_data *h)
int device_id_size, device_id_type = 0;
struct alua_port_group *tmp_pg, *pg = NULL;
 
-   if (!sdev-vpd_pg83)
+   rcu_read_lock();
+   if (!rcu_dereference(sdev-vpd_pg83)) {
+   rcu_read_unlock();
return SCSI_DH_DEV_UNSUPP;
+   }
 
/*
 * Look for the correct descriptor.
@@ -281,8 +284,8 @@ static int alua_check_vpd(struct scsi_device *sdev, struct 
alua_dh_data *h)
 */
memset(device_id_str, 0, 256);
device_id_size = 0;
-   d = sdev-vpd_pg83 + 4;
-   while (d  sdev-vpd_pg83 + sdev-vpd_pg83_len) {
+   d = rcu_dereference(sdev-vpd_pg83) + 4;
+   while (d  rcu_dereference(sdev-vpd_pg83) + sdev-vpd_pg83_len) {
switch (d[1]  0xf) {
case 0x2:
/* EUI-64 */
@@ -366,7 +369,7 @@ static int alua_check_vpd(struct scsi_device *sdev, struct 
alua_dh_data *h)
}
d += d[3] + 4;
}
-
+   rcu_read_unlock();
if (group_id == -1) {
/*
 * Internal error; TPGS supported but required
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 207d6a7..f1c0fb5 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -803,7 +803,7 @@ void scsi_attach_vpd(struct scsi_device *sdev)
int vpd_len = SCSI_VPD_PG_LEN;
int pg80_supported = 0;
int pg83_supported = 0;
-   unsigned char *vpd_buf;
+   unsigned char *vpd_buf, *orig_vpd_buf = NULL;
 
if (sdev-skip_vpd_pages)
return;
@@ -849,8 +849,16 @@ retry_pg80:
kfree(vpd_buf);
goto retry_pg80;
}
+   mutex_lock(sdev-inquiry_mutex);
+   orig_vpd_buf = sdev-vpd_pg80;
sdev-vpd_pg80_len = result;
-   sdev-vpd_pg80 = vpd_buf;
+   rcu_assign_pointer(sdev-vpd_pg80, vpd_buf);
+   mutex_unlock(sdev-inquiry_mutex);
+   synchronize_rcu();
+   if (orig_vpd_buf) {
+   kfree(orig_vpd_buf);
+   orig_vpd_buf = NULL;
+   }
vpd_len = SCSI_VPD_PG_LEN;
}
 
@@ -870,8 +878,14 @@ retry_pg83:
kfree(vpd_buf);
goto retry_pg83;
}
+   mutex_lock(sdev-inquiry_mutex);
+   orig_vpd_buf = sdev-vpd_pg83;
sdev-vpd_pg83_len = result;
-   sdev-vpd_pg83 = vpd_buf;
+   rcu_assign_pointer(sdev-vpd_pg83, vpd_buf);
+   mutex_unlock(sdev-inquiry_mutex);
+   synchronize_rcu();
+   if (orig_vpd_buf)
+   kfree(orig_vpd_buf);
}
 }
 
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index f9f3f82..190d743 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -235,6 +235,7 @@ static struct scsi_device *scsi_alloc_sdev(struct 
scsi_target *starget,
INIT_LIST_HEAD(sdev-starved_entry);
INIT_LIST_HEAD(sdev-event_list);
spin_lock_init(sdev-list_lock);
+   mutex_init(sdev-inquiry_mutex);
INIT_WORK(sdev-event_work, scsi_evt_thread);
INIT_WORK(sdev-requeue_work, scsi_requeue_run_queue);
 
@@ -1516,6 +1517,9 @@ EXPORT_SYMBOL(scsi_add_device);
 void scsi_rescan_device(struct device *dev)
 {
device_lock(dev);
+
+   scsi_attach_vpd(to_scsi_device(dev));
+
if (dev-driver  try_module_get(dev-driver-owner)) {
struct scsi_driver *drv = to_scsi_driver(dev-driver);
 
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index e3c3b86..b4de776 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -759,11 +759,15 @@ show_vpd_##_page(struct file *filp, struct kobject *kobj, 
\
 {  \
struct device *dev = container_of(kobj, struct device, kobj);   \
struct scsi_device *sdev = to_scsi_device(dev); \
+   int ret;  

[PATCH 0/5] device handler interface update

2015-07-08 Thread Hannes Reinecke
Hi all,

the current scsi_dh interface is very limited in functionality.
In particular it's not possible to update the internal state
without triggering a failover, and it not possible to figure
out the internal state of the device handler.

This patchset adds the functionality to rescan the device handler
if something has changed and adds a new sysfs attribute 'access_state'
to display the internal state.

To make this work the first patch implements functionality to
rescan the VPD information, as it might have changed, too.

The patchset is relative to my asynchronous ALUA update posted
earlier.

The entire tree can be found on git.kernel.org:

kernel/git/hare/scsi-devel.git branch alua.v3

As usual, reviews and comments are welcome.

Hannes Reinecke (5):
  scsi: rescan VPD attributes
  scsi_dh: add 'rescan' callback
  scsi: Add 'access_state' attribute
  scsi_dh_alua: add 'state' callback function
  scsi_dh_rdac: Add 'state' callback

 drivers/scsi/device_handler/scsi_dh_alua.c | 111 +
 drivers/scsi/device_handler/scsi_dh_rdac.c |  17 +
 drivers/scsi/scsi.c|  20 +-
 drivers/scsi/scsi_lib.c|   1 +
 drivers/scsi/scsi_scan.c   |  10 +++
 drivers/scsi/scsi_sysfs.c  |  61 +++-
 drivers/scsi/ses.c |   6 +-
 include/scsi/scsi_device.h |  14 
 include/scsi/scsi_dh.h |   2 +
 9 files changed, 220 insertions(+), 22 deletions(-)

-- 
1.8.5.2

--
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/5] scsi_dh_alua: add 'state' callback function

2015-07-08 Thread Hannes Reinecke
Add a 'state' callback function to display the current path
status in sysfs.

Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/scsi/device_handler/scsi_dh_alua.c | 47 ++
 1 file changed, 47 insertions(+)

diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
b/drivers/scsi/device_handler/scsi_dh_alua.c
index 5b52017..99c4b0f 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -1182,6 +1182,52 @@ static void alua_check(struct scsi_device *sdev, bool 
force)
 }
 
 /*
+ * alua_state - report path status
+ * @sdev: device on the path to be checked
+ *
+ * Check the device status
+ */
+static int alua_state(struct scsi_device *sdev)
+{
+   struct alua_dh_data *h = sdev-handler_data;
+   struct alua_port_group *pg = NULL;
+   int access_state = SCSI_ACCESS_STATE_UNKNOWN;
+
+   rcu_read_lock();
+   if (h)
+   pg = rcu_dereference(h-pg);
+   if (pg) {
+   switch (pg-state) {
+   case TPGS_STATE_OPTIMIZED:
+   access_state = SCSI_ACCESS_STATE_OPTIMAL;
+   break;
+   case TPGS_STATE_NONOPTIMIZED:
+   access_state = SCSI_ACCESS_STATE_ACTIVE;
+   break;
+   case TPGS_STATE_STANDBY:
+   access_state = SCSI_ACCESS_STATE_PASSIVE;
+   break;
+   case TPGS_STATE_UNAVAILABLE:
+   access_state = SCSI_ACCESS_STATE_UNAVAILABLE;
+   break;
+   case TPGS_STATE_LBA_DEPENDENT:
+   access_state = SCSI_ACCESS_STATE_LBA;
+   break;
+   case TPGS_STATE_OFFLINE:
+   access_state = SCSI_ACCESS_STATE_OFFLINE;
+   break;
+   case TPGS_STATE_TRANSITIONING:
+   access_state = SCSI_ACCESS_STATE_TRANSITIONING;
+   break;
+   }
+   if (pg-pref)
+   access_state |= SCSI_ACCESS_STATE_PREFERRED;
+   }
+   rcu_read_unlock();
+   return access_state;
+}
+
+/*
  * alua_prep_fn - request callback
  *
  * Fail I/O to all paths not in state
@@ -1288,6 +1334,7 @@ static struct scsi_device_handler alua_dh = {
.activate = alua_activate,
.rescan = alua_rescan,
.set_params = alua_set_params,
+   .state = alua_state,
 };
 
 static int __init alua_init(void)
-- 
1.8.5.2

--
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/5] scsi_dh: add 'rescan' callback

2015-07-08 Thread Hannes Reinecke
If a device needs to be rescanned the device_handler might need
to be rechecked, too.
So add a 'rescan' callback to the device handler and call it
upon scsi_rescan_device().

Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/scsi/device_handler/scsi_dh_alua.c | 53 +++---
 drivers/scsi/scsi_lib.c|  1 +
 drivers/scsi/scsi_scan.c   |  8 -
 include/scsi/scsi_dh.h |  1 +
 4 files changed, 51 insertions(+), 12 deletions(-)

diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
b/drivers/scsi/device_handler/scsi_dh_alua.c
index e4cabc8..5b52017 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -262,7 +262,8 @@ static int alua_check_vpd(struct scsi_device *sdev, struct 
alua_dh_data *h)
int group_id = -1;
char device_id_str[256], *device_id = NULL;
int device_id_size, device_id_type = 0;
-   struct alua_port_group *tmp_pg, *pg = NULL;
+   struct alua_port_group *tmp_pg, *pg = NULL, *old_pg = NULL;
+   bool pg_found = false;
 
rcu_read_lock();
if (!rcu_dereference(sdev-vpd_pg83)) {
@@ -407,17 +408,25 @@ static int alua_check_vpd(struct scsi_device *sdev, 
struct alua_dh_data *h)
if (memcmp(tmp_pg-device_id, device_id,
   device_id_size))
continue;
-   kref_get(tmp_pg-kref);
spin_lock(h-pg_lock);
-   rcu_assign_pointer(h-pg, tmp_pg);
+   pg = rcu_dereference(h-pg);
+   if (pg) {
+   /*
+* This can happen if the VPD information changed
+*/
+   if (tmp_pg != pg) {
+   old_pg = pg;
+   kref_get(tmp_pg-kref);
+   rcu_assign_pointer(h-pg, tmp_pg);
+   }
+   pg_found = true;
+   }
spin_unlock(h-pg_lock);
break;
}
spin_unlock(port_group_lock);
-   if (h-pg) {
-   synchronize_rcu();
-   return SCSI_DH_OK;
-   }
+   if (pg_found)
+   goto out;
 
pg = kzalloc(sizeof(struct alua_port_group), GFP_KERNEL);
if (!pg) {
@@ -466,12 +475,17 @@ static int alua_check_vpd(struct scsi_device *sdev, 
struct alua_dh_data *h)
if (memcmp(tmp_pg-device_id, pg-device_id,
   device_id_size))
continue;
-   kref_get(tmp_pg-kref);
spin_lock(h-pg_lock);
-   rcu_assign_pointer(h-pg, tmp_pg);
+   pg = rcu_dereference(h-pg);
+   if (pg) {
+   if (tmp_pg != pg) {
+   old_pg = pg;
+   kref_get(tmp_pg-kref);
+   rcu_assign_pointer(h-pg, tmp_pg);
+   }
+   pg = NULL;
+   }
spin_unlock(h-pg_lock);
-   kfree(pg);
-   pg = NULL;
break;
}
if (pg) {
@@ -481,6 +495,13 @@ static int alua_check_vpd(struct scsi_device *sdev, struct 
alua_dh_data *h)
spin_unlock(h-pg_lock);
}
spin_unlock(port_group_lock);
+out:
+   if (old_pg) {
+   synchronize_rcu();
+   if (old_pg-rtpg_sdev)
+   flush_workqueue(old_pg-work_q);
+   kref_put(pg-kref, release_port_group);
+   }
 
return SCSI_DH_OK;
 }
@@ -1011,6 +1032,8 @@ static int alua_initialize(struct scsi_device *sdev, 
struct alua_dh_data *h)
kref_get(pg-kref);
rcu_read_unlock();
}
+   } else {
+   WARN_ON(rcu_dereference(h-pg));
}
complete(h-init_complete);
if (pg) {
@@ -1195,6 +1218,13 @@ static int alua_prep_fn(struct scsi_device *sdev, struct 
request *req)
 
 }
 
+static void alua_rescan(struct scsi_device *sdev)
+{
+   struct alua_dh_data *h = sdev-handler_data;
+
+   alua_initialize(sdev, h);
+}
+
 /*
  * alua_bus_attach - Attach device handler
  * @sdev: device to be attached to
@@ -1256,6 +1286,7 @@ static struct scsi_device_handler alua_dh = {
.prep_fn = alua_prep_fn,
.check_sense = alua_check_sense,
.activate = alua_activate,
+   .rescan = alua_rescan,
.set_params = alua_set_params,
 };
 
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 18ab4ad..991b9e1 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -2704,6 +2704,7 @@ static void scsi_evt_emit(struct scsi_device *sdev, 
struct scsi_event *evt)
envp[idx++] = SDEV_MEDIA_CHANGE=1;
break;
case SDEV_EVT_INQUIRY_CHANGE_REPORTED:
+

Re: [PATCH v3 5/5] target: Fix wrong setting of sense format for PI errors

2015-07-08 Thread Sagi Grimberg

On 7/8/2015 2:44 PM, Christoph Hellwig wrote:

On Wed, Jul 08, 2015 at 12:59:18PM +0200, Hannes Reinecke wrote:

Actually it's controlled by the D_SENSE bit in the Control mode page
(that's bit[2] of byte 2 in the control mode page).
Which is currently set to '0', ie we will be returning fixed sense
information.
_If_ we were to report descriptor sense we will need to change that,
too.


Just looked over SPC, and indeed D_SENSE is a strict either fixed
or descriptor, not a may return descriptor data.

So this patch actually is wrong as we never must return different sense
data types based on the sense code.



I'll send out v4 without this patch altogether.
--
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 20/20] scsi_dh_alua: Update version to 2.0

2015-07-08 Thread Hannes Reinecke
Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/scsi/device_handler/scsi_dh_alua.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
b/drivers/scsi/device_handler/scsi_dh_alua.c
index 30310c8..d077014 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -31,7 +31,7 @@
 #include scsi/scsi_dh.h
 
 #define ALUA_DH_NAME alua
-#define ALUA_DH_VER 1.3
+#define ALUA_DH_VER 2.0
 
 #define TPGS_STATE_OPTIMIZED   0x0
 #define TPGS_STATE_NONOPTIMIZED0x1
-- 
1.8.5.2

--
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 09/20] scsi_dh_alua: switch to scsi_execute()

2015-07-08 Thread Hannes Reinecke
All commands are issued synchronously, so no need to open-code
scsi_execute anymore.

Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/scsi/device_handler/scsi_dh_alua.c | 108 -
 1 file changed, 27 insertions(+), 81 deletions(-)

diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
b/drivers/scsi/device_handler/scsi_dh_alua.c
index 76bc66d..61301cf 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -103,72 +103,29 @@ static int realloc_buffer(struct alua_dh_data *h, 
unsigned len)
return 0;
 }
 
-static struct request *get_alua_req(struct scsi_device *sdev,
-   void *buffer, unsigned buflen, int rw)
-{
-   struct request *rq;
-   struct request_queue *q = sdev-request_queue;
-
-   rq = blk_get_request(q, rw, GFP_NOIO);
-
-   if (IS_ERR(rq)) {
-   sdev_printk(KERN_INFO, sdev,
-   %s: blk_get_request failed\n, __func__);
-   return NULL;
-   }
-   blk_rq_set_block_pc(rq);
-
-   if (buflen  blk_rq_map_kern(q, rq, buffer, buflen, GFP_NOIO)) {
-   blk_put_request(rq);
-   sdev_printk(KERN_INFO, sdev,
-   %s: blk_rq_map_kern failed\n, __func__);
-   return NULL;
-   }
-
-   rq-cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
-REQ_FAILFAST_DRIVER;
-   rq-retries = ALUA_FAILOVER_RETRIES;
-   rq-timeout = ALUA_FAILOVER_TIMEOUT * HZ;
-
-   return rq;
-}
-
 /*
  * submit_rtpg - Issue a REPORT TARGET GROUP STATES command
  * @sdev: sdev the command should be sent to
  */
-static unsigned submit_rtpg(struct scsi_device *sdev, unsigned char *buff,
+static int submit_rtpg(struct scsi_device *sdev, unsigned char *buff,
int bufflen, unsigned char *sense, int flags)
 {
-   struct request *rq;
-   int err;
-
-   rq = get_alua_req(sdev, buff, bufflen, READ);
-   if (!rq) {
-   err = DRIVER_BUSY  24;
-   goto done;
-   }
+   u8 cdb[16];
+   int req_flags = REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
+   REQ_FAILFAST_DRIVER;
 
/* Prepare the command. */
-   rq-cmd[0] = MAINTENANCE_IN;
+   memset(cdb, 0x0, 16);
+   cdb[0] = MAINTENANCE_IN;
if (!(flags  ALUA_RTPG_EXT_HDR_UNSUPP))
-   rq-cmd[1] = MI_REPORT_TARGET_PGS | MI_EXT_HDR_PARAM_FMT;
+   cdb[1] = MI_REPORT_TARGET_PGS | MI_EXT_HDR_PARAM_FMT;
else
-   rq-cmd[1] = MI_REPORT_TARGET_PGS;
-   put_unaligned_be32(bufflen, rq-cmd[6]);
-   rq-cmd_len = COMMAND_SIZE(MAINTENANCE_IN);
+   cdb[1] = MI_REPORT_TARGET_PGS;
+   put_unaligned_be32(bufflen, cdb[6]);
 
-   rq-sense = sense;
-   memset(rq-sense, 0, SCSI_SENSE_BUFFERSIZE);
-   rq-sense_len = 0;
-
-   blk_execute_rq(rq-q, NULL, rq, 1);
-   if (rq-errors)
-   err = rq-errors;
-
-   blk_put_request(rq);
-done:
-   return err;
+   return scsi_execute(sdev, cdb, DMA_FROM_DEVICE, buff, bufflen,
+   sense, ALUA_FAILOVER_TIMEOUT * HZ,
+   ALUA_FAILOVER_RETRIES, req_flags, NULL);
 }
 
 /*
@@ -178,40 +135,29 @@ done:
  * to 'active/optimized' and let the array firmware figure out
  * the states of the remaining groups.
  */
-static unsigned submit_stpg(struct scsi_device *sdev, int group_id,
-   unsigned char *sense)
+static int submit_stpg(struct scsi_device *sdev, int group_id,
+  unsigned char *sense)
 {
-   struct request *rq;
+   u8 cdb[COMMAND_SIZE(MAINTENANCE_OUT)];
unsigned char stpg_data[8];
int stpg_len = 8;
-   int err = 0;
+   int req_flags = REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
+   REQ_FAILFAST_DRIVER;
 
/* Prepare the data buffer */
memset(stpg_data, 0, stpg_len);
stpg_data[4] = TPGS_STATE_OPTIMIZED  0x0f;
put_unaligned_be16(group_id, stpg_data[6]);
 
-   rq = get_alua_req(sdev, stpg_data, stpg_len, WRITE);
-   if (!rq)
-   return DRIVER_BUSY  24;
-
/* Prepare the command. */
-   rq-cmd[0] = MAINTENANCE_OUT;
-   rq-cmd[1] = MO_SET_TARGET_PGS;
-   put_unaligned_be32(stpg_len, rq-cmd[6]);
-   rq-cmd_len = COMMAND_SIZE(MAINTENANCE_OUT);
-
-   rq-sense = sense;
-   memset(rq-sense, 0, SCSI_SENSE_BUFFERSIZE);
-   rq-sense_len = 0;
-
-   blk_execute_rq(rq-q, NULL, rq, 1);
-   if (rq-errors)
-   err = rq-errors;
-
-   blk_put_request(rq);
-
-   return err;
+   memset(cdb, 0x0, COMMAND_SIZE(MAINTENANCE_OUT));
+   cdb[0] = MAINTENANCE_OUT;
+   cdb[1] = MO_SET_TARGET_PGS;
+   put_unaligned_be32(stpg_len, cdb[6]);
+
+   return scsi_execute(sdev, cdb, DMA_TO_DEVICE, stpg_data, stpg_len,
+   

[PATCH 11/20] scsi_dh_alua: Use separate alua_port_group structure

2015-07-08 Thread Hannes Reinecke
The port group needs to be a separate structure as several
LUNs might belong to the same group.

Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/scsi/device_handler/scsi_dh_alua.c | 210 +++--
 1 file changed, 137 insertions(+), 73 deletions(-)

diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
b/drivers/scsi/device_handler/scsi_dh_alua.c
index ea4a920..3f18f6b 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -64,9 +64,13 @@
 #define ALUA_OPTIMIZE_STPG 1
 #define ALUA_RTPG_EXT_HDR_UNSUPP   2
 
-struct alua_dh_data {
+static LIST_HEAD(port_group_list);
+static DEFINE_SPINLOCK(port_group_lock);
+
+struct alua_port_group {
+   struct kref kref;
+   struct list_headnode;
int group_id;
-   int rel_port;
int tpgs;
int state;
int pref;
@@ -75,6 +79,12 @@ struct alua_dh_data {
unsigned char   *buff;
int bufflen;
unsigned char   transition_tmo;
+};
+
+struct alua_dh_data {
+   struct alua_port_group  *pg;
+   int rel_port;
+   int tpgs;
struct scsi_device  *sdev;
activate_complete   callback_fn;
void*callback_data;
@@ -86,21 +96,35 @@ struct alua_dh_data {
 static char print_alua_state(int);
 static int alua_check_sense(struct scsi_device *, struct scsi_sense_hdr *);
 
-static int realloc_buffer(struct alua_dh_data *h, unsigned len)
+static int realloc_buffer(struct alua_port_group *pg, unsigned len)
 {
-   if (h-buff  h-buff != h-inq)
-   kfree(h-buff);
+   if (pg-buff  pg-buff != pg-inq)
+   kfree(pg-buff);
 
-   h-buff = kmalloc(len, GFP_NOIO);
-   if (!h-buff) {
-   h-buff = h-inq;
-   h-bufflen = ALUA_INQUIRY_SIZE;
+   pg-buff = kmalloc(len, GFP_NOIO);
+   if (!pg-buff) {
+   pg-buff = pg-inq;
+   pg-bufflen = ALUA_INQUIRY_SIZE;
return 1;
}
-   h-bufflen = len;
+   pg-bufflen = len;
return 0;
 }
 
+static void release_port_group(struct kref *kref)
+{
+   struct alua_port_group *pg;
+
+   pg = container_of(kref, struct alua_port_group, kref);
+   printk(KERN_WARNING alua: release port group %d\n, pg-group_id);
+   spin_lock(port_group_lock);
+   list_del(pg-node);
+   spin_unlock(port_group_lock);
+   if (pg-buff  pg-inq != pg-buff)
+   kfree(pg-buff);
+   kfree(pg);
+}
+
 /*
  * submit_rtpg - Issue a REPORT TARGET GROUP STATES command
  * @sdev: sdev the command should be sent to
@@ -223,6 +247,8 @@ static int alua_check_tpgs(struct scsi_device *sdev, struct 
alua_dh_data *h)
 static int alua_check_vpd(struct scsi_device *sdev, struct alua_dh_data *h)
 {
unsigned char *d;
+   int group_id = -1;
+   struct alua_port_group *pg = NULL;
 
if (!sdev-vpd_pg83)
return SCSI_DH_DEV_UNSUPP;
@@ -239,7 +265,7 @@ static int alua_check_vpd(struct scsi_device *sdev, struct 
alua_dh_data *h)
break;
case 0x5:
/* Target port group */
-   h-group_id = (d[6]  8) + d[7];
+   group_id = (d[6]  8) + d[7];
break;
default:
break;
@@ -247,7 +273,7 @@ static int alua_check_vpd(struct scsi_device *sdev, struct 
alua_dh_data *h)
d += d[3] + 4;
}
 
-   if (h-group_id == -1) {
+   if (group_id == -1) {
/*
 * Internal error; TPGS supported but required
 * VPD identification descriptors not present.
@@ -256,15 +282,33 @@ static int alua_check_vpd(struct scsi_device *sdev, 
struct alua_dh_data *h)
sdev_printk(KERN_INFO, sdev,
%s: No target port descriptors found\n,
ALUA_DH_NAME);
-   h-state = TPGS_STATE_OPTIMIZED;
h-tpgs = TPGS_MODE_NONE;
return SCSI_DH_DEV_UNSUPP;
}
sdev_printk(KERN_INFO, sdev,
%s: port group %02x rel port %02x\n,
-   ALUA_DH_NAME, h-group_id, h-rel_port);
+   ALUA_DH_NAME, group_id, h-rel_port);
 
-   return 0;
+   pg = kzalloc(sizeof(struct alua_port_group), GFP_KERNEL);
+   if (!pg) {
+   sdev_printk(KERN_WARNING, sdev,
+   %s: kzalloc port group failed\n,
+   ALUA_DH_NAME);
+   /* Temporary failure, bypass */
+   return SCSI_DH_DEV_TEMP_BUSY;
+   }
+   pg-group_id = group_id;
+   pg-buff = pg-inq;
+   pg-bufflen = ALUA_INQUIRY_SIZE;
+

[PATCH 10/20] scsi_dh_alua: put sense buffer on stack

2015-07-08 Thread Hannes Reinecke
We don't need to have the sense buffer available all the time,
putting it on stack is totally sufficient.

Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/scsi/device_handler/scsi_dh_alua.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
b/drivers/scsi/device_handler/scsi_dh_alua.c
index 61301cf..ea4a920 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -75,8 +75,6 @@ struct alua_dh_data {
unsigned char   *buff;
int bufflen;
unsigned char   transition_tmo;
-   unsigned char   sense[SCSI_SENSE_BUFFERSIZE];
-   int senselen;
struct scsi_device  *sdev;
activate_complete   callback_fn;
void*callback_data;
@@ -379,6 +377,7 @@ static int alua_check_sense(struct scsi_device *sdev,
  */
 static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, int 
wait_for_transition)
 {
+   unsigned char sense[SCSI_SENSE_BUFFERSIZE];
struct scsi_sense_hdr sense_hdr;
int len, k, off, valid_states = 0;
unsigned char *ucp;
@@ -393,11 +392,11 @@ static int alua_rtpg(struct scsi_device *sdev, struct 
alua_dh_data *h, int wait_
expiry = round_jiffies_up(jiffies + h-transition_tmo * HZ);
 
  retry:
-   retval = submit_rtpg(sdev, h-buff, h-bufflen, h-sense, h-flags);
+   retval = submit_rtpg(sdev, h-buff, h-bufflen, sense, h-flags);
 
if (retval) {
if (!(driver_byte(retval)  DRIVER_SENSE) ||
-   !scsi_normalize_sense(h-sense, SCSI_SENSE_BUFFERSIZE,
+   !scsi_normalize_sense(sense, SCSI_SENSE_BUFFERSIZE,
  sense_hdr)) {
sdev_printk(KERN_INFO, sdev,
%s: rtpg failed, result %d\n,
@@ -532,6 +531,7 @@ static int alua_rtpg(struct scsi_device *sdev, struct 
alua_dh_data *h, int wait_
 static unsigned alua_stpg(struct scsi_device *sdev, struct alua_dh_data *h)
 {
int retval;
+   unsigned char sense[SCSI_SENSE_BUFFERSIZE];
struct scsi_sense_hdr sense_hdr;
 
if (!(h-tpgs  TPGS_MODE_EXPLICIT)) {
@@ -564,11 +564,11 @@ static unsigned alua_stpg(struct scsi_device *sdev, 
struct alua_dh_data *h)
}
/* Set state to transitioning */
h-state = TPGS_STATE_TRANSITIONING;
-   retval = submit_stpg(sdev, h-group_id, h-sense);
+   retval = submit_stpg(sdev, h-group_id, sense);
 
if (retval) {
if (!(driver_byte(retval)  DRIVER_SENSE) ||
-   !scsi_normalize_sense(h-sense, SCSI_SENSE_BUFFERSIZE,
+   !scsi_normalize_sense(sense, SCSI_SENSE_BUFFERSIZE,
  sense_hdr)) {
sdev_printk(KERN_INFO, sdev,
%s: stpg failed, result %d,
-- 
1.8.5.2

--
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 12/20] scsi_dh_alua: allocate RTPG buffer separately

2015-07-08 Thread Hannes Reinecke
The RTPG buffer will only evaluated within alua_rtpg(),
so we can allocate it locally there and avoid having to
put it into the global structure.

Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/scsi/device_handler/scsi_dh_alua.c | 55 --
 1 file changed, 21 insertions(+), 34 deletions(-)

diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
b/drivers/scsi/device_handler/scsi_dh_alua.c
index 3f18f6b..e8bfbce 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -56,7 +56,7 @@
 #define TPGS_MODE_IMPLICIT 0x1
 #define TPGS_MODE_EXPLICIT 0x2
 
-#define ALUA_INQUIRY_SIZE  36
+#define ALUA_RTPG_SIZE 128
 #define ALUA_FAILOVER_TIMEOUT  60
 #define ALUA_FAILOVER_RETRIES  5
 
@@ -75,9 +75,6 @@ struct alua_port_group {
int state;
int pref;
unsignedflags; /* used for optimizing STPG */
-   unsigned char   inq[ALUA_INQUIRY_SIZE];
-   unsigned char   *buff;
-   int bufflen;
unsigned char   transition_tmo;
 };
 
@@ -96,21 +93,6 @@ struct alua_dh_data {
 static char print_alua_state(int);
 static int alua_check_sense(struct scsi_device *, struct scsi_sense_hdr *);
 
-static int realloc_buffer(struct alua_port_group *pg, unsigned len)
-{
-   if (pg-buff  pg-buff != pg-inq)
-   kfree(pg-buff);
-
-   pg-buff = kmalloc(len, GFP_NOIO);
-   if (!pg-buff) {
-   pg-buff = pg-inq;
-   pg-bufflen = ALUA_INQUIRY_SIZE;
-   return 1;
-   }
-   pg-bufflen = len;
-   return 0;
-}
-
 static void release_port_group(struct kref *kref)
 {
struct alua_port_group *pg;
@@ -120,8 +102,6 @@ static void release_port_group(struct kref *kref)
spin_lock(port_group_lock);
list_del(pg-node);
spin_unlock(port_group_lock);
-   if (pg-buff  pg-inq != pg-buff)
-   kfree(pg-buff);
kfree(pg);
 }
 
@@ -298,8 +278,6 @@ static int alua_check_vpd(struct scsi_device *sdev, struct 
alua_dh_data *h)
return SCSI_DH_DEV_TEMP_BUSY;
}
pg-group_id = group_id;
-   pg-buff = pg-inq;
-   pg-bufflen = ALUA_INQUIRY_SIZE;
pg-tpgs = h-tpgs;
pg-state = TPGS_STATE_OPTIMIZED;
kref_init(pg-kref);
@@ -423,8 +401,8 @@ static int alua_rtpg(struct scsi_device *sdev, struct 
alua_port_group *pg, int w
 {
unsigned char sense[SCSI_SENSE_BUFFERSIZE];
struct scsi_sense_hdr sense_hdr;
-   int len, k, off, valid_states = 0;
-   unsigned char *ucp;
+   int len, k, off, valid_states = 0, bufflen = ALUA_RTPG_SIZE;
+   unsigned char *ucp, *buff;
unsigned err, retval;
unsigned long expiry, interval = 0;
unsigned int tpg_desc_tbl_off;
@@ -435,8 +413,12 @@ static int alua_rtpg(struct scsi_device *sdev, struct 
alua_port_group *pg, int w
else
expiry = round_jiffies_up(jiffies + pg-transition_tmo * HZ);
 
+   buff = kzalloc(bufflen, GFP_KERNEL);
+   if (!buff)
+   return SCSI_DH_DEV_TEMP_BUSY;
+
  retry:
-   retval = submit_rtpg(sdev, pg-buff, pg-bufflen, sense, pg-flags);
+   retval = submit_rtpg(sdev, buff, bufflen, sense, pg-flags);
 
if (retval) {
if (!(driver_byte(retval)  DRIVER_SENSE) ||
@@ -449,6 +431,7 @@ static int alua_rtpg(struct scsi_device *sdev, struct 
alua_port_group *pg, int w
err = SCSI_DH_DEV_TEMP_BUSY;
else
err = SCSI_DH_IO;
+   kfree(buff);
return err;
}
 
@@ -477,14 +460,18 @@ static int alua_rtpg(struct scsi_device *sdev, struct 
alua_port_group *pg, int w
sdev_printk(KERN_ERR, sdev, %s: rtpg failed\n,
ALUA_DH_NAME);
scsi_print_sense_hdr(sdev, ALUA_DH_NAME, sense_hdr);
+   kfree(buff);
return SCSI_DH_IO;
}
 
-   len = get_unaligned_be32(pg-buff[0]) + 4;
+   len = get_unaligned_be32(buff[0]) + 4;
 
-   if (len  pg-bufflen) {
+   if (len  bufflen) {
/* Resubmit with the correct length */
-   if (realloc_buffer(pg, len)) {
+   kfree(buff);
+   bufflen = len;
+   buff = kmalloc(bufflen, GFP_KERNEL);
+   if (!buff) {
sdev_printk(KERN_WARNING, sdev,
%s: kmalloc buffer failed\n,__func__);
/* Temporary failure, bypass */
@@ -494,9 +481,8 @@ static int alua_rtpg(struct scsi_device *sdev, struct 
alua_port_group *pg, int w
}
 
orig_transition_tmo = pg-transition_tmo;
-   if ((pg-buff[4]  RTPG_FMT_MASK) == RTPG_FMT_EXT_HDR 
-  

[PATCH 14/20] scsi_dh_alua: parse target device id

2015-07-08 Thread Hannes Reinecke
Parse VPD descriptor to figure out the device identification.
As devices might implement several descriptors the order
of preference is:
- NAA IEE Registered Extended
- EUI-64 based 16-byte
- EUI-64 based 12-byte
- NAA IEEE Registered
- NAA IEEE Extended
A SCSI name string descriptor is preferred to all of them
if the identification is longer than 16 bytes.

Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/scsi/device_handler/scsi_dh_alua.c | 152 -
 1 file changed, 147 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
b/drivers/scsi/device_handler/scsi_dh_alua.c
index f4d851a..6991171 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -70,6 +70,9 @@ static DEFINE_SPINLOCK(port_group_lock);
 struct alua_port_group {
struct kref kref;
struct list_headnode;
+   unsigned char   device_id[256];
+   unsigned char   device_id_str[256];
+   int device_id_size;
int group_id;
int tpgs;
int state;
@@ -227,17 +230,84 @@ static int alua_check_vpd(struct scsi_device *sdev, 
struct alua_dh_data *h)
 {
unsigned char *d;
int group_id = -1;
-   struct alua_port_group *pg = NULL;
+   char device_id_str[256], *device_id = NULL;
+   int device_id_size, device_id_type = 0;
+   struct alua_port_group *tmp_pg, *pg = NULL;
 
if (!sdev-vpd_pg83)
return SCSI_DH_DEV_UNSUPP;
 
/*
 * Look for the correct descriptor.
+* Order of preference for lun descriptor:
+* - SCSI name string
+* - NAA IEEE Registered Extended
+* - EUI-64 based 16-byte
+* - EUI-64 based 12-byte
+* - NAA IEEE Registered
+* - NAA IEEE Extended
+* as longer descriptors reduce the likelyhood
+* of identification clashes.
 */
+   memset(device_id_str, 0, 256);
+   device_id_size = 0;
d = sdev-vpd_pg83 + 4;
while (d  sdev-vpd_pg83 + sdev-vpd_pg83_len) {
switch (d[1]  0xf) {
+   case 0x2:
+   /* EUI-64 */
+   if ((d[1]  0x30) == 0x00) {
+   if (device_id_size  d[3])
+   break;
+   /* Prefer NAA IEEE Registered Extended */
+   if (device_id_type == 0x3 
+   device_id_size == d[3])
+   break;
+   device_id_size = d[3];
+   device_id = d + 4;
+   device_id_type = d[1]  0xf;
+   switch (device_id_size) {
+   case 8:
+   sprintf(device_id_str,
+   eui.%8phN, d + 4);
+   break;
+   case 12:
+   sprintf(device_id_str,
+   eui.%12phN, d + 4);
+   break;
+   case 16:
+   sprintf(device_id_str,
+   eui.%16phN, d + 4);
+   break;
+   default:
+   device_id_size = 0;
+   break;
+   }
+   }
+   break;
+   case 0x3:
+   /* NAA */
+   if ((d[1]  0x30) == 0x00) {
+   if (device_id_size  d[3])
+   break;
+   device_id_size = d[3];
+   device_id = d + 4;
+   device_id_type = d[1]  0xf;
+   switch (device_id_size) {
+   case 8:
+   sprintf(device_id_str,
+   naa.%8phN, d + 4);
+   break;
+   case 16:
+   sprintf(device_id_str,
+   naa.%16phN, d + 4);
+   break;
+   default:
+   device_id_size = 0;
+   break;
+   }
+   }
+   break;
case 0x4:
/* Relative target port 

[PATCH 15/20] revert scsi_dh_alua: ALUA hander attach should succeed while TPG is transitioning

2015-07-08 Thread Hannes Reinecke
This reverts commit a8e5a2d593cbfccf530c3382c2c328d2edaa7b66

Obsoleted by the next patch.

Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/scsi/device_handler/scsi_dh_alua.c | 22 --
 1 file changed, 8 insertions(+), 14 deletions(-)

diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
b/drivers/scsi/device_handler/scsi_dh_alua.c
index 6991171..88c150a 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -498,13 +498,12 @@ static int alua_check_sense(struct scsi_device *sdev,
 /*
  * alua_rtpg - Evaluate REPORT TARGET GROUP STATES
  * @sdev: the device to be evaluated.
- * @wait_for_transition: if nonzero, wait ALUA_FAILOVER_TIMEOUT seconds for 
device to exit transitioning state
  *
  * Evaluate the Target Port Group State.
  * Returns SCSI_DH_DEV_OFFLINED if the path is
  * found to be unusable.
  */
-static int alua_rtpg(struct scsi_device *sdev, struct alua_port_group *pg, int 
wait_for_transition)
+static int alua_rtpg(struct scsi_device *sdev, struct alua_port_group *pg)
 {
unsigned char sense[SCSI_SENSE_BUFFERSIZE];
struct scsi_sense_hdr sense_hdr;
@@ -600,7 +599,7 @@ static int alua_rtpg(struct scsi_device *sdev, struct 
alua_port_group *pg, int w
else
pg-transition_tmo = ALUA_FAILOVER_TIMEOUT;
 
-   if (wait_for_transition  (orig_transition_tmo != pg-transition_tmo)) 
{
+   if (orig_transition_tmo != pg-transition_tmo) {
sdev_printk(KERN_INFO, sdev,
%s: transition timeout set to %d seconds\n,
ALUA_DH_NAME, pg-transition_tmo);
@@ -638,19 +637,14 @@ static int alua_rtpg(struct scsi_device *sdev, struct 
alua_port_group *pg, int w
 
switch (pg-state) {
case TPGS_STATE_TRANSITIONING:
-   if (wait_for_transition) {
-   if (time_before(jiffies, expiry)) {
-   /* State transition, retry */
-   interval += 2000;
-   msleep(interval);
-   goto retry;
-   }
-   err = SCSI_DH_RETRY;
-   } else {
-   err = SCSI_DH_OK;
+   if (time_before(jiffies, expiry)) {
+   /* State transition, retry */
+   interval += 2000;
+   msleep(interval);
+   goto retry;
}
-
/* Transitioning time exceeded, set port to standby */
+   err = SCSI_DH_RETRY;
pg-state = TPGS_STATE_STANDBY;
break;
case TPGS_STATE_OFFLINE:
-- 
1.8.5.2

--
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 13/20] scsi_dh_alua: simplify sense code handling

2015-07-08 Thread Hannes Reinecke
Most sense code is already handled in the generic
code, so we shouldn't be adding special cases here.
However, when doing so we need to check for
unit attention whenever we're sending an internal
command.

Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/scsi/device_handler/scsi_dh_alua.c | 50 +++---
 1 file changed, 11 insertions(+), 39 deletions(-)

diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
b/drivers/scsi/device_handler/scsi_dh_alua.c
index e8bfbce..f4d851a 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -91,7 +91,6 @@ struct alua_dh_data {
 #define ALUA_POLICY_SWITCH_ALL 1
 
 static char print_alua_state(int);
-static int alua_check_sense(struct scsi_device *, struct scsi_sense_hdr *);
 
 static void release_port_group(struct kref *kref)
 {
@@ -321,28 +320,6 @@ static int alua_check_sense(struct scsi_device *sdev,
 * LUN Not Accessible - ALUA state transition
 */
return ADD_TO_MLQUEUE;
-   if (sense_hdr-asc == 0x04  sense_hdr-ascq == 0x0b)
-   /*
-* LUN Not Accessible -- Target port in standby state
-*/
-   return SUCCESS;
-   if (sense_hdr-asc == 0x04  sense_hdr-ascq == 0x0c)
-   /*
-* LUN Not Accessible -- Target port in unavailable 
state
-*/
-   return SUCCESS;
-   if (sense_hdr-asc == 0x04  sense_hdr-ascq == 0x12)
-   /*
-* LUN Not Ready -- Offline
-*/
-   return SUCCESS;
-   if (sdev-allow_restart 
-   sense_hdr-asc == 0x04  sense_hdr-ascq == 0x02)
-   /*
-* if the device is not started, we need to wake
-* the error handler to start the motor
-*/
-   return FAILED;
break;
case UNIT_ATTENTION:
if (sense_hdr-asc == 0x29  sense_hdr-ascq == 0x00)
@@ -357,7 +334,7 @@ static int alua_check_sense(struct scsi_device *sdev,
return ADD_TO_MLQUEUE;
if (sense_hdr-asc == 0x2a  sense_hdr-ascq == 0x01)
/*
-* Mode Parameters Changed
+* Mode Parameter Changed
 */
return ADD_TO_MLQUEUE;
if (sense_hdr-asc == 0x2a  sense_hdr-ascq == 0x06)
@@ -370,18 +347,6 @@ static int alua_check_sense(struct scsi_device *sdev,
 * Implicit ALUA state transition failed
 */
return ADD_TO_MLQUEUE;
-   if (sense_hdr-asc == 0x3f  sense_hdr-ascq == 0x03)
-   /*
-* Inquiry data has changed
-*/
-   return ADD_TO_MLQUEUE;
-   if (sense_hdr-asc == 0x3f  sense_hdr-ascq == 0x0e)
-   /*
-* REPORTED_LUNS_DATA_HAS_CHANGED is reported
-* when switching controllers on targets like
-* Intel Multi-Flex. We can just retry.
-*/
-   return ADD_TO_MLQUEUE;
break;
}
 
@@ -449,9 +414,16 @@ static int alua_rtpg(struct scsi_device *sdev, struct 
alua_port_group *pg, int w
pg-flags |= ALUA_RTPG_EXT_HDR_UNSUPP;
goto retry;
}
-
-   err = alua_check_sense(sdev, sense_hdr);
-   if (err == ADD_TO_MLQUEUE  time_before(jiffies, expiry)) {
+   /*
+* Retry on ALUA state transition or if any
+* UNIT ATTENTION occurred.
+*/
+   if (sense_hdr.sense_key == NOT_READY 
+   sense_hdr.asc == 0x04  sense_hdr.ascq == 0x0a)
+   err = SCSI_DH_RETRY;
+   if (sense_hdr.sense_key == UNIT_ATTENTION)
+   err = SCSI_DH_RETRY;
+   if (err == SCSI_DH_RETRY  time_before(jiffies, expiry)) {
sdev_printk(KERN_ERR, sdev, %s: rtpg retry\n,
ALUA_DH_NAME);
scsi_print_sense_hdr(sdev, ALUA_DH_NAME, sense_hdr);
-- 
1.8.5.2

--
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 4/5] target: Use scsi helpers to build the sense data correctly

2015-07-08 Thread Sagi Grimberg

On 7/8/2015 1:17 PM, Christoph Hellwig wrote:

--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -7,6 +7,7 @@
  #include linux/blkdev.h
  #include linux/percpu_ida.h
  #include linux/t10-pi.h
+#include scsi/scsi_common.h
  #include net/sock.h
  #include net/tcp.h


Please only add the include in the files that need it.  (And many of the
existing includes should be fixed up the same way, but that's a
different story).



OK, I'll move it.
--
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 2/5] target: Split transport_send_check_condition_and_sense()

2015-07-08 Thread Sagi Grimberg

On 7/8/2015 1:15 PM, Christoph Hellwig wrote:

+   if (r == (__force int)TCM_CHECK_CONDITION_UNIT_ATTENTION) {


You probably want to compare reason here to avoid the cast.



I do want it...
--
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 3/3] sd: do not try to spin-up disks for ALUA 'transitioning' state

2015-07-08 Thread Hannes Reinecke
On 07/08/2015 10:41 AM, Sagi Grimberg wrote:
 On 7/8/2015 10:41 AM, Hannes Reinecke wrote:
 If a disk reports an ALUA 'transitioning' state we should not
 try to spin up the device.

 Signed-off-by: Hannes Reinecke h...@suse.de
 ---
   drivers/scsi/sd.c | 2 ++
   1 file changed, 2 insertions(+)

 diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
 index 7c0bdaa..180a6e8 100644
 --- a/drivers/scsi/sd.c
 +++ b/drivers/scsi/sd.c
 @@ -1801,6 +1801,8 @@ sd_spinup_disk(struct scsi_disk *sdkp)
   if (sense_valid  sshdr.sense_key == NOT_READY) {
   if (sshdr.asc == 4  sshdr.ascq == 3)
   break;/* manual intervention required */
 +if (sshdr.asc == 4  sshdr.ascq == 0xa)
 +break;  /* transitioning */
   if (sshdr.asc == 4  sshdr.ascq == 0xb)
   break;/* standby */
   if (sshdr.asc == 4  sshdr.ascq == 0xc)

 
 
 Hi Hannes,
 
 Just nit-picking, but do you think that these four if statements can be
 re-organized to condition (asc == 4) once and OR on the rest?
Sure they can, I don't mind.
Once we have a general agreement about these patches (hint, hint :-)
I can update it.

Cheers,

Hannes
-- 
Dr. Hannes Reinecke   zSeries  Storage
h...@suse.de  +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg)
--
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 16/20] scsi_dh_alua: Use workqueue for RTPG

2015-07-08 Thread Hannes Reinecke
The current ALUA device_handler has two drawbacks:
- We're sending a 'SET TARGET PORT GROUP' command to every LUN,
  disregarding the fact that several LUNs might be in a port group
  and will be automatically switched whenever _any_ LUN within
  that port group receives the command.
- Whenever a LUN is in 'transitioning' mode we cannot block I/O
  to that LUN, instead the controller has to abort the command.
  This leads to increased traffic across the wire and heavy load
  on the controller during switchover.

With this patch the RTPG handling is moved to a per-portgroup
workqueue. This reduces the number of 'REPORT TARGET PORT GROUP'
and 'SET TARGET PORT GROUPS' sent to the controller as we're sending
them now per port group, and not per device as previously.
It also allows us to block I/O to any LUN / port group found to be
in 'transitioning' ALUA mode, as the workqueue item will be requeued
until the controller moves out of transitioning.

Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/scsi/device_handler/scsi_dh_alua.c | 412 -
 1 file changed, 349 insertions(+), 63 deletions(-)

diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
b/drivers/scsi/device_handler/scsi_dh_alua.c
index 88c150a..ea47d15 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -22,6 +22,8 @@
 #include linux/slab.h
 #include linux/delay.h
 #include linux/module.h
+#include linux/workqueue.h
+#include linux/rcupdate.h
 #include asm/unaligned.h
 #include scsi/scsi.h
 #include scsi/scsi_dbg.h
@@ -59,10 +61,15 @@
 #define ALUA_RTPG_SIZE 128
 #define ALUA_FAILOVER_TIMEOUT  60
 #define ALUA_FAILOVER_RETRIES  5
+#define ALUA_RTPG_DELAY_MSECS  5
 
 /* device handler flags */
-#define ALUA_OPTIMIZE_STPG 1
-#define ALUA_RTPG_EXT_HDR_UNSUPP   2
+#define ALUA_OPTIMIZE_STPG 0x01
+#define ALUA_RTPG_EXT_HDR_UNSUPP   0x02
+/* State machine flags */
+#define ALUA_PG_RUN_RTPG   0x10
+#define ALUA_PG_RUN_STPG   0x20
+
 
 static LIST_HEAD(port_group_list);
 static DEFINE_SPINLOCK(port_group_lock);
@@ -79,13 +86,29 @@ struct alua_port_group {
int pref;
unsignedflags; /* used for optimizing STPG */
unsigned char   transition_tmo;
+   unsigned long   expiry;
+   unsigned long   interval;
+   charwork_q_name[264];
+   struct workqueue_struct *work_q;
+   struct delayed_work rtpg_work;
+   struct delayed_work stpg_work;
+   struct delayed_work qdata_work;
+   spinlock_t  rtpg_lock;
+   struct list_headrtpg_list;
+   struct scsi_device  *rtpg_sdev;
 };
 
 struct alua_dh_data {
struct alua_port_group  *pg;
+   spinlock_t  pg_lock;
int rel_port;
int tpgs;
-   struct scsi_device  *sdev;
+   int error;
+   struct completion   init_complete;
+};
+
+struct alua_queue_data {
+   struct list_headentry;
activate_complete   callback_fn;
void*callback_data;
 };
@@ -94,6 +117,10 @@ struct alua_dh_data {
 #define ALUA_POLICY_SWITCH_ALL 1
 
 static char print_alua_state(int);
+static void alua_rtpg_work(struct work_struct *work);
+static void alua_stpg_work(struct work_struct *work);
+static void alua_qdata_work(struct work_struct *work);
+static void alua_check(struct scsi_device *sdev);
 
 static void release_port_group(struct kref *kref)
 {
@@ -104,6 +131,9 @@ static void release_port_group(struct kref *kref)
spin_lock(port_group_lock);
list_del(pg-node);
spin_unlock(port_group_lock);
+   WARN_ON(pg-rtpg_sdev);
+   if (pg-work_q)
+   destroy_workqueue(pg-work_q);
kfree(pg);
 }
 
@@ -374,13 +404,17 @@ static int alua_check_vpd(struct scsi_device *sdev, 
struct alua_dh_data *h)
if (memcmp(tmp_pg-device_id, device_id,
   device_id_size))
continue;
-   h-pg = tmp_pg;
kref_get(tmp_pg-kref);
+   spin_lock(h-pg_lock);
+   rcu_assign_pointer(h-pg, tmp_pg);
+   spin_unlock(h-pg_lock);
break;
}
spin_unlock(port_group_lock);
-   if (h-pg)
+   if (h-pg) {
+   synchronize_rcu();
return SCSI_DH_OK;
+   }
 
pg = kzalloc(sizeof(struct alua_port_group), GFP_KERNEL);
if (!pg) {
@@ -402,6 +436,20 @@ static int alua_check_vpd(struct scsi_device *sdev, struct 
alua_dh_data *h)
pg-tpgs = h-tpgs;
pg-state = TPGS_STATE_OPTIMIZED;
kref_init(pg-kref);
+   INIT_DELAYED_WORK(pg-rtpg_work, alua_rtpg_work);
+   INIT_DELAYED_WORK(pg-stpg_work, 

[PATCH 18/20] scsi_dh_alua: update all port states

2015-07-08 Thread Hannes Reinecke
When we read in the target port group state we should be
updating all affected port groups, otherwise we risk
running out of sync.

Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/scsi/device_handler/scsi_dh_alua.c | 28 
 1 file changed, 24 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
b/drivers/scsi/device_handler/scsi_dh_alua.c
index aa58659..44b57bc 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -560,11 +560,13 @@ static int alua_rtpg(struct scsi_device *sdev, struct 
alua_port_group *pg)
 {
unsigned char sense[SCSI_SENSE_BUFFERSIZE];
struct scsi_sense_hdr sense_hdr;
+   struct alua_port_group *tmp_pg;
int len, k, off, valid_states = 0, bufflen = ALUA_RTPG_SIZE;
unsigned char *ucp, *buff;
unsigned err, retval;
unsigned int tpg_desc_tbl_off;
unsigned char orig_transition_tmo;
+   unsigned long flags;
 
if (!pg-expiry) {
if (!pg-transition_tmo)
@@ -669,17 +671,35 @@ static int alua_rtpg(struct scsi_device *sdev, struct 
alua_port_group *pg)
else
tpg_desc_tbl_off = 4;
 
+   spin_lock_irqsave(port_group_lock, flags);
for (k = tpg_desc_tbl_off, ucp = buff + tpg_desc_tbl_off;
 k  len;
 k += off, ucp += off) {
 
-   if (pg-group_id == (ucp[2]  8) + ucp[3]) {
-   pg-state = ucp[0]  0x0f;
-   pg-pref = ucp[0]  7;
-   valid_states = ucp[1];
+   list_for_each_entry(tmp_pg, port_group_list, node) {
+   u16 group_id = get_unaligned_be16(ucp[2]);
+   if (tmp_pg-group_id != group_id)
+   continue;
+   if (tmp_pg-device_id_size != pg-device_id_size)
+   continue;
+   if (memcmp(tmp_pg-device_id, pg-device_id,
+  tmp_pg-device_id_size))
+   continue;
+   tmp_pg-state = ucp[0]  0x0f;
+   tmp_pg-pref = ucp[0]  7;
+   sdev_printk(KERN_INFO, sdev,
+   %s: device %s port group %02x 
+   state %c %s\n, ALUA_DH_NAME,
+   tmp_pg-device_id_str, tmp_pg-group_id,
+   print_alua_state(tmp_pg-state),
+   tmp_pg-pref ?
+   preferred : non-preferred);
+   if (tmp_pg == pg)
+   valid_states = ucp[1];
}
off = 8 + (ucp[7] * 4);
}
+   spin_unlock_irqrestore(port_group_lock, flags);
 
sdev_printk(KERN_INFO, sdev,
%s: port group %02x state %c %s supports %c%c%c%c%c%c%c\n,
-- 
1.8.5.2

--
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 01/20] scsi_dh_alua: Disable ALUA handling for non-disk devices

2015-07-08 Thread Hannes Reinecke
Non-disk devices might support ALUA, but the firmware
implementation is untested and frequently broken.
As we're don't actually need it disable ALUA support
for non-disk device for now.

Signed-off-by: Hannes Reinecke h...@suse.de
Reviewed-by: Bart Van Assche bart.vanass...@sandisk.com
---
 drivers/scsi/device_handler/scsi_dh_alua.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
b/drivers/scsi/device_handler/scsi_dh_alua.c
index cc2773b..7d01ef0 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -320,6 +320,18 @@ static int alua_check_tpgs(struct scsi_device *sdev, 
struct alua_dh_data *h)
 {
int err = SCSI_DH_OK;
 
+   /*
+* ALUA support for non-disk devices is fraught with
+* difficulties, so disable it for now.
+*/
+   if (sdev-type != TYPE_DISK) {
+   h-tpgs = TPGS_MODE_NONE;
+   sdev_printk(KERN_INFO, sdev,
+   %s: disable for non-disk devices\n,
+   ALUA_DH_NAME);
+   return SCSI_DH_DEV_UNSUPP;
+   }
+
h-tpgs = scsi_device_tpgs(sdev);
switch (h-tpgs) {
case TPGS_MODE_EXPLICIT|TPGS_MODE_IMPLICIT:
-- 
1.8.5.2

--
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 03/20] scsi_dh_alua: improved logging

2015-07-08 Thread Hannes Reinecke
Issue different logging messages if ALUA is not supported
or the TPGS setting is invalid.

Reviewed-by: Christoph Hellwig h...@lst.de
Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/scsi/device_handler/scsi_dh_alua.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
b/drivers/scsi/device_handler/scsi_dh_alua.c
index f15b977..a20c8bf 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -310,12 +310,18 @@ static int alua_check_tpgs(struct scsi_device *sdev, 
struct alua_dh_data *h)
sdev_printk(KERN_INFO, sdev, %s: supports implicit TPGS\n,
ALUA_DH_NAME);
break;
-   default:
-   h-tpgs = TPGS_MODE_NONE;
+   case TPGS_MODE_NONE:
sdev_printk(KERN_INFO, sdev, %s: not supported\n,
ALUA_DH_NAME);
err = SCSI_DH_DEV_UNSUPP;
break;
+   default:
+   sdev_printk(KERN_INFO, sdev,
+   %s: unsupported TPGS setting %d\n,
+   ALUA_DH_NAME, h-tpgs);
+   h-tpgs = TPGS_MODE_NONE;
+   err = SCSI_DH_DEV_UNSUPP;
+   break;
}
 
return err;
-- 
1.8.5.2

--
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 17/20] scsi_dh_alua: Recheck state on unit attention

2015-07-08 Thread Hannes Reinecke
When we receive a unit attention code of 'ALUA state changed'
we should recheck the state, as it might be due to an implicit
ALUA state transition.
At the same time a workqueue item might already be queued, which
should be started immediately to avoid any delays.

Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/scsi/device_handler/scsi_dh_alua.c | 48 +++---
 1 file changed, 24 insertions(+), 24 deletions(-)

diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
b/drivers/scsi/device_handler/scsi_dh_alua.c
index ea47d15..aa58659 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -120,7 +120,7 @@ static char print_alua_state(int);
 static void alua_rtpg_work(struct work_struct *work);
 static void alua_stpg_work(struct work_struct *work);
 static void alua_qdata_work(struct work_struct *work);
-static void alua_check(struct scsi_device *sdev);
+static void alua_check(struct scsi_device *sdev, bool force);
 
 static void release_port_group(struct kref *kref)
 {
@@ -505,7 +505,7 @@ static char print_alua_state(int state)
 }
 
 static int alua_check_sense(struct scsi_device *sdev,
-   struct scsi_sense_hdr *sense_hdr)
+struct scsi_sense_hdr *sense_hdr)
 {
switch (sense_hdr-sense_key) {
case NOT_READY:
@@ -514,36 +514,34 @@ static int alua_check_sense(struct scsi_device *sdev,
 * LUN Not Accessible - ALUA state transition
 * Kickoff worker to update internal state.
 */
-   alua_check(sdev);
-   return ADD_TO_MLQUEUE;
+   alua_check(sdev, false);
+   return NEEDS_RETRY;
}
break;
case UNIT_ATTENTION:
-   if (sense_hdr-asc == 0x29  sense_hdr-ascq == 0x00)
-   /*
-* Power On, Reset, or Bus Device Reset, just retry.
-*/
-   return ADD_TO_MLQUEUE;
-   if (sense_hdr-asc == 0x29  sense_hdr-ascq == 0x04)
-   /*
-* Device internal reset
-*/
-   return ADD_TO_MLQUEUE;
-   if (sense_hdr-asc == 0x2a  sense_hdr-ascq == 0x01)
+   if (sense_hdr-asc == 0x29  sense_hdr-ascq == 0x00) {
/*
-* Mode Parameter Changed
+* Power On, Reset, or Bus Device Reset.
+* Might have obscured a state transition,
+* so schedule a recheck.
 */
+   alua_check(sdev, true);
return ADD_TO_MLQUEUE;
-   if (sense_hdr-asc == 0x2a  sense_hdr-ascq == 0x06)
+   }
+   if (sense_hdr-asc == 0x2a  sense_hdr-ascq == 0x06) {
/*
 * ALUA state changed
 */
+   alua_check(sdev, true);
return ADD_TO_MLQUEUE;
-   if (sense_hdr-asc == 0x2a  sense_hdr-ascq == 0x07)
+   }
+   if (sense_hdr-asc == 0x2a  sense_hdr-ascq == 0x07) {
/*
 * Implicit ALUA state transition failed
 */
+   alua_check(sdev, true);
return ADD_TO_MLQUEUE;
+   }
break;
}
 
@@ -899,7 +897,7 @@ static void alua_qdata_work(struct work_struct *work)
 
 static void alua_rtpg_queue(struct alua_port_group *pg,
struct scsi_device *sdev,
-   struct alua_queue_data *qdata)
+   struct alua_queue_data *qdata, bool force)
 {
int start_queue = 0;
unsigned long flags;
@@ -920,7 +918,9 @@ static void alua_rtpg_queue(struct alua_port_group *pg,
pg-rtpg_sdev = sdev;
scsi_device_get(sdev);
start_queue = 1;
-   }
+   } else if (!(pg-flags  ALUA_PG_RUN_RTPG)  force)
+   start_queue = 1;
+
spin_unlock_irqrestore(pg-rtpg_lock, flags);
 
if (start_queue)
@@ -959,7 +959,7 @@ static int alua_initialize(struct scsi_device *sdev, struct 
alua_dh_data *h)
complete(h-init_complete);
if (pg) {
pg-expiry = 0;
-   alua_rtpg_queue(pg, sdev, NULL);
+   alua_rtpg_queue(pg, sdev, NULL, true);
kref_put(pg-kref, release_port_group);
}
return h-error;
@@ -1072,7 +1072,7 @@ static int alua_activate(struct scsi_device *sdev,
pg-flags |= ALUA_OPTIMIZE_STPG;
spin_unlock_irqrestore(pg-rtpg_lock, flags);
}
-   alua_rtpg_queue(pg, sdev, qdata);
+   

[PATCH 08/20] scsi_dh_alua: Make stpg synchronous

2015-07-08 Thread Hannes Reinecke
We should be issuing STPG synchronously as we need to
evaluate the return code on failure.

Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/scsi/device_handler/scsi_dh_alua.c | 189 +
 1 file changed, 87 insertions(+), 102 deletions(-)

diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
b/drivers/scsi/device_handler/scsi_dh_alua.c
index 28a3b99..76bc66d 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -172,94 +172,46 @@ done:
 }
 
 /*
- * stpg_endio - Evaluate SET TARGET GROUP STATES
- * @sdev: the device to be evaluated
- * @state: the new target group state
- *
- * Evaluate a SET TARGET GROUP STATES command response.
- */
-static void stpg_endio(struct request *req, int error)
-{
-   struct alua_dh_data *h = req-end_io_data;
-   struct scsi_sense_hdr sense_hdr;
-   unsigned err = SCSI_DH_OK;
-
-   if (host_byte(req-errors) != DID_OK ||
-   msg_byte(req-errors) != COMMAND_COMPLETE) {
-   err = SCSI_DH_IO;
-   goto done;
-   }
-
-   if (scsi_normalize_sense(h-sense, SCSI_SENSE_BUFFERSIZE,
-sense_hdr)) {
-   err = alua_check_sense(h-sdev, sense_hdr);
-   if (err == ADD_TO_MLQUEUE) {
-   err = SCSI_DH_RETRY;
-   goto done;
-   }
-   sdev_printk(KERN_INFO, h-sdev, %s: stpg failed\n,
-   ALUA_DH_NAME);
-   scsi_print_sense_hdr(h-sdev, ALUA_DH_NAME, sense_hdr);
-   err = SCSI_DH_IO;
-   } else if (error)
-   err = SCSI_DH_IO;
-
-   if (err == SCSI_DH_OK) {
-   h-state = TPGS_STATE_OPTIMIZED;
-   sdev_printk(KERN_INFO, h-sdev,
-   %s: port group %02x switched to state %c\n,
-   ALUA_DH_NAME, h-group_id,
-   print_alua_state(h-state));
-   }
-done:
-   req-end_io_data = NULL;
-   __blk_put_request(req-q, req);
-   if (h-callback_fn) {
-   h-callback_fn(h-callback_data, err);
-   h-callback_fn = h-callback_data = NULL;
-   }
-   return;
-}
-
-/*
  * submit_stpg - Issue a SET TARGET GROUP STATES command
  *
  * Currently we're only setting the current target port group state
  * to 'active/optimized' and let the array firmware figure out
  * the states of the remaining groups.
  */
-static unsigned submit_stpg(struct alua_dh_data *h)
+static unsigned submit_stpg(struct scsi_device *sdev, int group_id,
+   unsigned char *sense)
 {
struct request *rq;
+   unsigned char stpg_data[8];
int stpg_len = 8;
-   struct scsi_device *sdev = h-sdev;
+   int err = 0;
 
/* Prepare the data buffer */
-   memset(h-buff, 0, stpg_len);
-   h-buff[4] = TPGS_STATE_OPTIMIZED  0x0f;
-   h-buff[6] = (h-group_id  8)  0xff;
-   h-buff[7] = h-group_id  0xff;
+   memset(stpg_data, 0, stpg_len);
+   stpg_data[4] = TPGS_STATE_OPTIMIZED  0x0f;
+   put_unaligned_be16(group_id, stpg_data[6]);
 
-   rq = get_alua_req(sdev, h-buff, stpg_len, WRITE);
+   rq = get_alua_req(sdev, stpg_data, stpg_len, WRITE);
if (!rq)
-   return SCSI_DH_RES_TEMP_UNAVAIL;
+   return DRIVER_BUSY  24;
 
/* Prepare the command. */
rq-cmd[0] = MAINTENANCE_OUT;
rq-cmd[1] = MO_SET_TARGET_PGS;
-   rq-cmd[6] = (stpg_len  24)  0xff;
-   rq-cmd[7] = (stpg_len  16)  0xff;
-   rq-cmd[8] = (stpg_len   8)  0xff;
-   rq-cmd[9] = stpg_len  0xff;
+   put_unaligned_be32(stpg_len, rq-cmd[6]);
rq-cmd_len = COMMAND_SIZE(MAINTENANCE_OUT);
 
-   rq-sense = h-sense;
+   rq-sense = sense;
memset(rq-sense, 0, SCSI_SENSE_BUFFERSIZE);
-   rq-sense_len = h-senselen = 0;
-   rq-end_io_data = h;
+   rq-sense_len = 0;
+
+   blk_execute_rq(rq-q, NULL, rq, 1);
+   if (rq-errors)
+   err = rq-errors;
+
+   blk_put_request(rq);
 
-   blk_execute_rq_nowait(rq-q, NULL, rq, 1, stpg_endio);
-   return SCSI_DH_OK;
+   return err;
 }
 
 /*
@@ -498,7 +450,8 @@ static int alua_rtpg(struct scsi_device *sdev, struct 
alua_dh_data *h, int wait_
retval = submit_rtpg(sdev, h-buff, h-bufflen, h-sense, h-flags);
 
if (retval) {
-   if (!scsi_normalize_sense(h-sense, SCSI_SENSE_BUFFERSIZE,
+   if (!(driver_byte(retval)  DRIVER_SENSE) ||
+   !scsi_normalize_sense(h-sense, SCSI_SENSE_BUFFERSIZE,
  sense_hdr)) {
sdev_printk(KERN_INFO, sdev,
%s: rtpg failed, result %d\n,
@@ -624,6 +577,69 @@ static int alua_rtpg(struct scsi_device *sdev, struct 
alua_dh_data *h, int wait_
 }
 
 /*
+ * alua_stpg - Issue a SET TARGET GROUP STATES command
+ *
+ * Issue a 

[PATCH 19/20] scsi_dh_alua: Send TEST UNIT READY to poll for transitioning

2015-07-08 Thread Hannes Reinecke
Sending a 'REPORT TARGET PORT GROUP' command is a costly operation,
as the array has to gather information about all ports.
So instead of using RTPG to poll for a status update when a port
is in transitioning we should be sending a TEST UNIT READY, and
wait for the sense code to report success.

Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/scsi/device_handler/scsi_dh_alua.c | 33 ++
 1 file changed, 33 insertions(+)

diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
b/drivers/scsi/device_handler/scsi_dh_alua.c
index 44b57bc..30310c8 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -549,6 +549,30 @@ static int alua_check_sense(struct scsi_device *sdev,
 }
 
 /*
+ * alua_tur - Send a TEST UNIT READY
+ * @sdev: device to which the TEST UNIT READY command should be send
+ *
+ * Send a TEST UNIT READY to @sdev to figure out the device state
+ * Returns SCSI_DH_RETRY if the sense code is NOT READY/ALUA TRANSITIONING,
+ * SCSI_DH_OK if no error occured, and SCSI_DH_IO otherwise.
+ */
+static int alua_tur(struct scsi_device *sdev)
+{
+   struct scsi_sense_hdr sense_hdr;
+   int retval;
+
+   retval = scsi_test_unit_ready(sdev, ALUA_FAILOVER_TIMEOUT * HZ,
+ ALUA_FAILOVER_RETRIES, sense_hdr);
+   if (sense_hdr.sense_key == NOT_READY 
+   sense_hdr.asc == 0x04  sense_hdr.ascq == 0x0a)
+   return SCSI_DH_RETRY;
+   else if (retval)
+   return SCSI_DH_IO;
+   else
+   return SCSI_DH_OK;
+}
+
+/*
  * alua_rtpg - Evaluate REPORT TARGET GROUP STATES
  * @sdev: the device to be evaluated.
  *
@@ -820,7 +844,16 @@ static void alua_rtpg_work(struct work_struct *work)
return;
}
if (pg-flags  ALUA_PG_RUN_RTPG) {
+   int state = pg-state;
spin_unlock_irqrestore(pg-rtpg_lock, flags);
+   if (state == TPGS_STATE_TRANSITIONING) {
+   if (alua_tur(sdev) == SCSI_DH_RETRY) {
+   queue_delayed_work(pg-work_q, pg-rtpg_work,
+  pg-interval * HZ);
+   return;
+   }
+   /* Send RTPG on failure or if TUR indicates SUCCESS */
+   }
err = alua_rtpg(sdev, pg);
if (err == SCSI_DH_RETRY) {
queue_delayed_work(pg-work_q, pg-rtpg_work,
-- 
1.8.5.2

--
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 00/10] Integrate scsi_dh better into the scsi core V4

2015-07-08 Thread Hannes Reinecke
This series ties scsi_dh deeper into the scsi core, and fixes all kinds
of issues in it, most importantly the race between using and detaching
device handlers.

Changes since V1:
  - updated comments / strings based on review feedback
  - moved scsi_dh.c to drivers/scsi to fix the srcdir = objdir build
  - changed the old patch 2 to have saner handling of mismatching device
handlers in dm.
  - dropped patch 1: not having a hw handler is fine if we don't plan to
change it anyway
  - dropped patch 3: not necessary anymore.
Changes since V2:
  - Fixup issues during attaching device_handler from dm-multipath
  - Add patch to clarify scsi_dh_activate() error codes
Changes since V3:
  - Fixup device handler attach.
  - Zero out device handler on detach
  - Move 'dh_state' attribute to generic code

Christoph Hellwig (8):
  dm-mpath, scsi_dh: don't let dm detach device handlers
  dm-mpath, scsi_dh: request scsi_dh modules in scsi_dh, not dm-mpath
  scsi_dh: move to drivers/scsi
  scsi_dh: integrate into the core SCSI code
  scsi_dh: move device matching to the core code
  scsi_dh: kill struct scsi_dh_data
  scsi_dh: add a common helper to get a scsi_device from a request_queue
  scsi_dh: don't allow to detach device handlers at runtime

Hannes Reinecke (2):
  scsi_dh: return individual errors in scsi_dh_activate()
  scsi_dh: move 'dh_state' sysfs attribute to generic code

 drivers/md/dm-mpath.c   |  27 +-
 drivers/scsi/Makefile   |   1 +
 drivers/scsi/device_handler/Kconfig |   2 +-
 drivers/scsi/device_handler/Makefile|   1 -
 drivers/scsi/device_handler/scsi_dh.c   | 621 
 drivers/scsi/device_handler/scsi_dh_alua.c  |  31 +-
 drivers/scsi/device_handler/scsi_dh_emc.c   |  58 +--
 drivers/scsi/device_handler/scsi_dh_hp_sw.c |  55 +--
 drivers/scsi/device_handler/scsi_dh_rdac.c  |  80 +---
 drivers/scsi/scsi_dh.c  | 371 +
 drivers/scsi/scsi_error.c   |   6 +-
 drivers/scsi/scsi_lib.c |   6 +-
 drivers/scsi/scsi_priv.h|   9 +
 drivers/scsi/scsi_sysfs.c   |  70 
 include/scsi/scsi_device.h  |  27 +-
 include/scsi/scsi_dh.h  |  29 +-
 16 files changed, 529 insertions(+), 865 deletions(-)
 delete mode 100644 drivers/scsi/device_handler/scsi_dh.c
 create mode 100644 drivers/scsi/scsi_dh.c

-- 
1.8.5.2

--
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 04/10] scsi_dh: integrate into the core SCSI code

2015-07-08 Thread Hannes Reinecke
From: Christoph Hellwig h...@lst.de

Stop building scsi_dh as a separate module and integrate it fully into the
core SCSI code with explicit callouts at bus scan time.  For now the
callouts are placed at the same point as the old bus notifiers were called,
but in the future we will be able to look at ALUA INQUIRY data earlier on.

Note that this also means that the device handler modules need to be loaded
by the time we scan the bus.  The next patches will add support for
autoloading device handlers at bus scan time to make sure they are always
loaded if they are enabled in the kernel config.

Signed-off-by: Christoph Hellwig h...@lst.de
Reviewed-by: Martin K. Petersen martin.peter...@oracle.com
Reviewed-by: Hannes Reinecke h...@suse.de
Acked-by: Mike Snitzer snit...@redhat.com
---
 drivers/scsi/Makefile   |   2 +-
 drivers/scsi/device_handler/Kconfig |   2 +-
 drivers/scsi/scsi_dh.c  | 183 +++-
 drivers/scsi/scsi_priv.h|   9 ++
 drivers/scsi/scsi_sysfs.c   |  10 ++
 include/scsi/scsi_dh.h  |   2 +-
 6 files changed, 34 insertions(+), 174 deletions(-)

diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index 22f54b0..ef260bb 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -171,7 +171,7 @@ scsi_mod-$(CONFIG_SYSCTL)   += scsi_sysctl.o
 scsi_mod-$(CONFIG_SCSI_PROC_FS)+= scsi_proc.o
 scsi_mod-y += scsi_trace.o scsi_logging.o
 scsi_mod-$(CONFIG_PM)  += scsi_pm.o
-obj-$(CONFIG_SCSI_DH)  += scsi_dh.o
+scsi_mod-$(CONFIG_SCSI_DH) += scsi_dh.o
 
 hv_storvsc-y   := storvsc_drv.o
 
diff --git a/drivers/scsi/device_handler/Kconfig 
b/drivers/scsi/device_handler/Kconfig
index 69abd0a..e5647d5 100644
--- a/drivers/scsi/device_handler/Kconfig
+++ b/drivers/scsi/device_handler/Kconfig
@@ -3,7 +3,7 @@
 #
 
 menuconfig SCSI_DH
-   tristate SCSI Device Handlers
+   bool SCSI Device Handlers
depends on SCSI
default n
help
diff --git a/drivers/scsi/scsi_dh.c b/drivers/scsi/scsi_dh.c
index 3c06c72..2d6a8bd 100644
--- a/drivers/scsi/scsi_dh.c
+++ b/drivers/scsi/scsi_dh.c
@@ -57,15 +57,8 @@ static struct scsi_device_handler *scsi_dh_lookup(const char 
*name)
return dh;
 }
 
-/*
- * device_handler_match_function - Match a device handler to a device
- * @sdev - SCSI device to be tested
- *
- * Tests @sdev against the match function of all registered device_handler.
- * Returns the found device handler or NULL if not found.
- */
 static struct scsi_device_handler *
-device_handler_match_function(struct scsi_device *sdev)
+device_handler_match(struct scsi_device *sdev)
 {
struct scsi_device_handler *tmp_dh, *found_dh = NULL;
 
@@ -81,29 +74,6 @@ device_handler_match_function(struct scsi_device *sdev)
 }
 
 /*
- * device_handler_match - Attach a device handler to a device
- * @scsi_dh - The device handler to match against or NULL
- * @sdev - SCSI device to be tested against @scsi_dh
- *
- * Tests @sdev against the device handler @scsi_dh or against
- * all registered device_handler if @scsi_dh == NULL.
- * Returns the found device handler or NULL if not found.
- */
-static struct scsi_device_handler *
-device_handler_match(struct scsi_device_handler *scsi_dh,
-struct scsi_device *sdev)
-{
-   struct scsi_device_handler *found_dh;
-
-   found_dh = device_handler_match_function(sdev);
-
-   if (scsi_dh  found_dh != scsi_dh)
-   found_dh = NULL;
-
-   return found_dh;
-}
-
-/*
  * scsi_dh_handler_attach - Attach a device handler to a device
  * @sdev - SCSI device the device handler should attach to
  * @scsi_dh - The device handler to attach
@@ -211,119 +181,26 @@ static struct device_attribute scsi_dh_state_attr =
__ATTR(dh_state, S_IRUGO | S_IWUSR, show_dh_state,
   store_dh_state);
 
-/*
- * scsi_dh_sysfs_attr_add - Callback for scsi_init_dh
- */
-static int scsi_dh_sysfs_attr_add(struct device *dev, void *data)
+int scsi_dh_add_device(struct scsi_device *sdev)
 {
-   struct scsi_device *sdev;
+   struct scsi_device_handler *devinfo;
int err;
 
-   if (!scsi_is_sdev_device(dev))
-   return 0;
-
-   sdev = to_scsi_device(dev);
-
-   err = device_create_file(sdev-sdev_gendev,
-scsi_dh_state_attr);
-
-   return 0;
-}
-
-/*
- * scsi_dh_sysfs_attr_remove - Callback for scsi_exit_dh
- */
-static int scsi_dh_sysfs_attr_remove(struct device *dev, void *data)
-{
-   struct scsi_device *sdev;
-
-   if (!scsi_is_sdev_device(dev))
-   return 0;
-
-   sdev = to_scsi_device(dev);
-
-   device_remove_file(sdev-sdev_gendev,
-  scsi_dh_state_attr);
-
-   return 0;
-}
+   err = device_create_file(sdev-sdev_gendev, scsi_dh_state_attr);
+   if (err)
+   return err;
 
-/*
- * scsi_dh_notifier - notifier chain 

[PATCH 02/10] dm-mpath, scsi_dh: request scsi_dh modules in scsi_dh, not dm-mpath

2015-07-08 Thread Hannes Reinecke
From: Christoph Hellwig h...@lst.de

This way we can reused the same code any attachment method, not just those
requested from dm-mpath.

Signed-off-by: Christoph Hellwig h...@lst.de
Reviewed-by: Martin K. Petersen martin.peter...@oracle.com
Reviewed-by: Hannes Reinecke h...@suse.de
Acked-by: Mike Snitzer snit...@redhat.com
---
 drivers/md/dm-mpath.c |  6 --
 drivers/scsi/device_handler/scsi_dh.c | 35 ++-
 include/scsi/scsi_dh.h|  5 -
 3 files changed, 18 insertions(+), 28 deletions(-)

diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index a9f58fd..5a67671 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -725,12 +725,6 @@ static int parse_hw_handler(struct dm_arg_set *as, struct 
multipath *m)
return 0;
 
m-hw_handler_name = kstrdup(dm_shift_arg(as), GFP_KERNEL);
-   if (!try_then_request_module(scsi_dh_handler_exist(m-hw_handler_name),
-scsi_dh_%s, m-hw_handler_name)) {
-   ti-error = unknown hardware handler type;
-   ret = -EINVAL;
-   goto fail;
-   }
 
if (hw_argc  1) {
char *p;
diff --git a/drivers/scsi/device_handler/scsi_dh.c 
b/drivers/scsi/device_handler/scsi_dh.c
index 869b5bd..5bd0af6 100644
--- a/drivers/scsi/device_handler/scsi_dh.c
+++ b/drivers/scsi/device_handler/scsi_dh.c
@@ -29,7 +29,7 @@
 static DEFINE_SPINLOCK(list_lock);
 static LIST_HEAD(scsi_dh_list);
 
-static struct scsi_device_handler *get_device_handler(const char *name)
+static struct scsi_device_handler *__scsi_dh_lookup(const char *name)
 {
struct scsi_device_handler *tmp, *found = NULL;
 
@@ -44,6 +44,19 @@ static struct scsi_device_handler *get_device_handler(const 
char *name)
return found;
 }
 
+static struct scsi_device_handler *scsi_dh_lookup(const char *name)
+{
+   struct scsi_device_handler *dh;
+
+   dh = __scsi_dh_lookup(name);
+   if (!dh) {
+   request_module(name);
+   dh = __scsi_dh_lookup(name);
+   }
+
+   return dh;
+}
+
 /*
  * device_handler_match_function - Match a device handler to a device
  * @sdev - SCSI device to be tested
@@ -158,7 +171,7 @@ store_dh_state(struct device *dev, struct device_attribute 
*attr,
/*
 * Attach to a device handler
 */
-   if (!(scsi_dh = get_device_handler(buf)))
+   if (!(scsi_dh = scsi_dh_lookup(buf)))
return err;
err = scsi_dh_handler_attach(sdev, scsi_dh);
} else {
@@ -322,8 +335,7 @@ static int scsi_dh_notifier_remove(struct device *dev, void 
*data)
  */
 int scsi_register_device_handler(struct scsi_device_handler *scsi_dh)
 {
-
-   if (get_device_handler(scsi_dh-name))
+   if (__scsi_dh_lookup(scsi_dh-name))
return -EBUSY;
 
if (!scsi_dh-attach || !scsi_dh-detach)
@@ -350,7 +362,7 @@ EXPORT_SYMBOL_GPL(scsi_register_device_handler);
 int scsi_unregister_device_handler(struct scsi_device_handler *scsi_dh)
 {
 
-   if (!get_device_handler(scsi_dh-name))
+   if (!__scsi_dh_lookup(scsi_dh-name))
return -ENODEV;
 
bus_for_each_dev(scsi_bus_type, NULL, scsi_dh,
@@ -455,17 +467,6 @@ int scsi_dh_set_params(struct request_queue *q, const char 
*params)
 EXPORT_SYMBOL_GPL(scsi_dh_set_params);
 
 /*
- * scsi_dh_handler_exist - Return TRUE(1) if a device handler exists for
- * the given name. FALSE(0) otherwise.
- * @name - name of the device handler.
- */
-int scsi_dh_handler_exist(const char *name)
-{
-   return (get_device_handler(name) != NULL);
-}
-EXPORT_SYMBOL_GPL(scsi_dh_handler_exist);
-
-/*
  * scsi_dh_attach - Attach device handler
  * @q - Request queue that is associated with the scsi_device
  *  the handler should be attached to
@@ -478,7 +479,7 @@ int scsi_dh_attach(struct request_queue *q, const char 
*name)
struct scsi_device_handler *scsi_dh;
int err = 0;
 
-   scsi_dh = get_device_handler(name);
+   scsi_dh = scsi_dh_lookup(name);
if (!scsi_dh)
return -EINVAL;
 
diff --git a/include/scsi/scsi_dh.h b/include/scsi/scsi_dh.h
index 99c9196..966b921 100644
--- a/include/scsi/scsi_dh.h
+++ b/include/scsi/scsi_dh.h
@@ -57,7 +57,6 @@ enum {
 };
 #if defined(CONFIG_SCSI_DH) || defined(CONFIG_SCSI_DH_MODULE)
 extern int scsi_dh_activate(struct request_queue *, activate_complete, void *);
-extern int scsi_dh_handler_exist(const char *);
 extern int scsi_dh_attach(struct request_queue *, const char *);
 extern const char *scsi_dh_attached_handler_name(struct request_queue *, 
gfp_t);
 extern int scsi_dh_set_params(struct request_queue *, const char *);
@@ -68,10 +67,6 @@ static inline int scsi_dh_activate(struct request_queue *req,
fn(data, 0);
return 0;
 }
-static inline int scsi_dh_handler_exist(const char *name)
-{
-   return 

[PATCH 08/10] scsi_dh: don't allow to detach device handlers at runtime

2015-07-08 Thread Hannes Reinecke
From: Christoph Hellwig h...@lst.de

The I/O submission and completion pathes call into the device handler
without any synchronization agains detachment.  So disallow detaching
device handlers at runtime.

Signed-off-by: Christoph Hellwig h...@lst.de
Reviewed-by: Martin K. Petersen martin.peter...@oracle.com
Reviewed-by: Hannes Reinecke h...@suse.de
---
 drivers/scsi/scsi_dh.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/scsi_dh.c b/drivers/scsi/scsi_dh.c
index 265e3dd..7723280 100644
--- a/drivers/scsi/scsi_dh.c
+++ b/drivers/scsi/scsi_dh.c
@@ -180,8 +180,10 @@ store_dh_state(struct device *dev, struct device_attribute 
*attr,
/*
 * Detach from a device handler
 */
-   scsi_dh_handler_detach(sdev);
-   err = 0;
+   sdev_printk(KERN_WARNING, sdev,
+   can't detach handler %s.\n,
+   sdev-handler-name);
+   err = -EINVAL;
} else if (!strncmp(buf, activate, 8)) {
/*
 * Activate a device handler
-- 
1.8.5.2

--
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 3/3] megaraid_sas : fix whitespace errors

2015-07-08 Thread Sumit Saxena
 -Original Message-
 From: Bjorn Helgaas [mailto:bhelg...@google.com]
 Sent: Wednesday, July 08, 2015 2:23 AM
 To: Kashyap Desai; Uday Lingala; Sumit Saxena
 Cc: megaraidlinux@avagotech.com; linux-scsi@vger.kernel.org; James
 E.J.
 Bottomley; linux-ker...@vger.kernel.org; Joe Perches; Christoph Hellwig
 Subject: [PATCH v3 3/3] megaraid_sas : fix whitespace errors

 Fix whitespace and indentation errors.  No code change.

 Signed-off-by: Bjorn Helgaas bhelg...@google.com
 ---
  drivers/scsi/megaraid/megaraid_sas_base.c |  244
 ++--
 -
  1 file changed, 118 insertions(+), 126 deletions(-)

 diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c
 b/drivers/scsi/megaraid/megaraid_sas_base.c
 index a9bd592..5156faa 100644
 --- a/drivers/scsi/megaraid/megaraid_sas_base.c
 +++ b/drivers/scsi/megaraid/megaraid_sas_base.c
 @@ -273,6 +273,7 @@ static inline void
  megasas_enable_intr_xscale(struct megasas_instance *instance)  {
   struct megasas_register_set __iomem *regs;
 +
   regs = instance-reg_set;
   writel(0, (regs)-outbound_intr_mask);

 @@ -289,6 +290,7 @@ megasas_disable_intr_xscale(struct megasas_instance
 *instance)  {
   struct megasas_register_set __iomem *regs;
   u32 mask = 0x1f;
 +
   regs = instance-reg_set;
   writel(mask, regs-outbound_intr_mask);
   /* Dummy readl to force pci flush */
 @@ -313,6 +315,7 @@ megasas_clear_intr_xscale(struct megasas_register_set
 __iomem * regs)  {
   u32 status;
   u32 mfiStatus = 0;
 +
   /*
* Check if it is our interrupt
*/
 @@ -348,6 +351,7 @@ megasas_fire_cmd_xscale(struct megasas_instance
 *instance,
   struct megasas_register_set __iomem *regs)  {
   unsigned long flags;
 +
   spin_lock_irqsave(instance-hba_lock, flags);
   writel((frame_phys_addr  3)|(frame_count),
  (regs)-inbound_queue_port);
 @@ -364,6 +368,7 @@ megasas_adp_reset_xscale(struct megasas_instance
 *instance,  {
   u32 i;
   u32 pcidata;
 +
   writel(MFI_ADP_RESET, regs-inbound_doorbell);

   for (i = 0; i  3; i++)
 @@ -402,7 +407,6 @@ static int
  megasas_check_reset_xscale(struct megasas_instance *instance,
   struct megasas_register_set __iomem *regs)  {
 -
   if ((instance-adprecovery != MEGASAS_HBA_OPERATIONAL) 
   (le32_to_cpu(*instance-consumer) ==
   MEGASAS_ADPRESET_INPROG_SIGN))
 @@ -433,7 +437,7 @@ static struct megasas_instance_template
 megasas_instance_template_xscale = {

  /**
  *The following functions are defined for ppc (deviceid : 0x60)
 -*controllers
 +*controllers
  */

  /**
 @@ -444,6 +448,7 @@ static inline void
  megasas_enable_intr_ppc(struct megasas_instance *instance)  {
   struct megasas_register_set __iomem *regs;
 +
   regs = instance-reg_set;
   writel(0x, (regs)-outbound_doorbell_clear);

 @@ -462,6 +467,7 @@ megasas_disable_intr_ppc(struct megasas_instance
 *instance)  {
   struct megasas_register_set __iomem *regs;
   u32 mask = 0x;
 +
   regs = instance-reg_set;
   writel(mask, regs-outbound_intr_mask);
   /* Dummy readl to force pci flush */
 @@ -522,6 +528,7 @@ megasas_fire_cmd_ppc(struct megasas_instance
 *instance,
   struct megasas_register_set __iomem *regs)  {
   unsigned long flags;
 +
   spin_lock_irqsave(instance-hba_lock, flags);
   writel((frame_phys_addr | (frame_count1))|1,
   (regs)-inbound_queue_port);
 @@ -566,6 +573,7 @@ static inline void
  megasas_enable_intr_skinny(struct megasas_instance *instance)  {
   struct megasas_register_set __iomem *regs;
 +
   regs = instance-reg_set;
   writel(0x, (regs)-outbound_intr_mask);

 @@ -584,6 +592,7 @@ megasas_disable_intr_skinny(struct megasas_instance
 *instance)  {
   struct megasas_register_set __iomem *regs;
   u32 mask = 0x;
 +
   regs = instance-reg_set;
   writel(mask, regs-outbound_intr_mask);
   /* Dummy readl to force pci flush */
 @@ -634,8 +643,8 @@ megasas_clear_intr_skinny(struct megasas_register_set
 __iomem *regs)
   writel(status, regs-outbound_intr_status);

   /*
 - * dummy read to flush PCI
 - */
 +  * dummy read to flush PCI
 +  */
   readl(regs-outbound_intr_status);

   return mfiStatus;
 @@ -654,6 +663,7 @@ megasas_fire_cmd_skinny(struct megasas_instance
 *instance,
   struct megasas_register_set __iomem *regs)  {
   unsigned long flags;
 +
   spin_lock_irqsave(instance-hba_lock, flags);
   writel(upper_32_bits(frame_phys_addr),
  (regs)-inbound_high_queue_port);
 @@ -706,6 +716,7 @@ static inline void
  megasas_enable_intr_gen2(struct megasas_instance *instance)  {
   struct megasas_register_set __iomem *regs;
 +
   regs = instance-reg_set;
   writel(0x, (regs)-outbound_doorbell_clear);

 @@ -725,6 +736,7 @@ megasas_disable_intr_gen2(struct 

Re: blk-mq vs kmemleak

2015-07-08 Thread Christoph Hellwig
On Tue, Jul 07, 2015 at 06:59:37AM -0700, Bart Van Assche wrote:
 Please note that my test was run with CONFIG_SLUB_DEBUG=y which causes a red
 zone to be allocated before and after each block of allocated memory. Could
 that explain the kmalloc-96 objects ?

96 is almost guaranteed to be the sense buffer allocated in
scsi_init_request and freed in scsi_exit_request.
--
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 5/5] target: Fix wrong setting of sense format for PI errors

2015-07-08 Thread Christoph Hellwig
On Mon, Jul 06, 2015 at 04:15:08PM +0300, Sagi Grimberg wrote:
 PI errors should be reported in a descriptor format sense data.
 Fix that by adding a desc_format flag to struct sense_info and pass
 it to scsi_build_sense_buffer() to do the right thing.

Do we really need the additional flag?  We only need the descriptor
sense format because we add the sector information.  So just checking
for that should be enough, especially when paired with a comment
explaining that logic in the source file.
--
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 2/3] megaraid_sas : use dev_printk when possible

2015-07-08 Thread Hannes Reinecke
On 07/07/2015 10:52 PM, Bjorn Helgaas wrote:
 Use dev_printk() when possible to make messages more useful.
 
 Signed-off-by: Bjorn Helgaas bhelg...@google.com
 ---
  drivers/scsi/megaraid/megaraid_sas_base.c   |  304 
 +--
  drivers/scsi/megaraid/megaraid_sas_fusion.c |   95 
  2 files changed, 196 insertions(+), 203 deletions(-)
 
[ .. ]
 @@ -1873,8 +1872,8 @@ static int megasas_get_ld_vf_affiliation_111(struct 
 megasas_instance *instance,
   cmd = megasas_get_cmd(instance);
  
   if (!cmd) {
 - printk(KERN_DEBUG megasas: megasas_get_ld_vf_affiliation_111:
 -Failed to get cmd for scsi%d.\n,
 + dev_printk(KERN_DEBUG, instance-pdev-dev, 
 megasas_get_ld_vf_affiliation_111:
 +Failed to get cmd for scsi%d\n,
   instance-host-host_no);
   return -ENOMEM;
   }
Makes one wonder why we don't have a 'dev_debug'; dev_notice() and
dev_warn() are there ...

Otherwise: Reviewed-by: Hannes Reinecke h...@suse.de

Cheers,

Hannes
-- 
Dr. Hannes ReineckezSeries  Storage
h...@suse.de   +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)
--
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


[Bug 101201] New: hpsa hang when creating ext4 FS

2015-07-08 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=101201

Bug ID: 101201
   Summary: hpsa hang when creating ext4 FS
   Product: SCSI Drivers
   Version: 2.5
Kernel Version: 3.16.7-ckt11-1
  Hardware: x86-64
OS: Linux
  Tree: Mainline
Status: NEW
  Severity: normal
  Priority: P1
 Component: Other
  Assignee: scsi_drivers-ot...@kernel-bugs.osdl.org
  Reporter: elac...@easter-eggs.com
Regression: No

Hardware:

HP ProLiant DL385p Gen8 with 2 SSD 100G and 2 HD SATA 3TB, configured in HBA
mode, no HW RAID set up.

I boot on the Debian 8 installer, then


- load hpsa
- create one partition on each of the SSD
- create a soft RAID 1 using mdadm on those 2 partition
- raid synchronize successfully
- create a pv, then a vg on this raid without problem
- doing mkswap on a LV without problem
- doing mkfs.ext4 on a LV - the process HANG

dmesg gives:

[ 1490.566398] hpsa :03:00.0: Abort request on C6:B2:T0:L0
[ 1490.566819] hpsa :03:00.0: ABORT REQUEST on C6:B2:T0:L0
Tag:0x:0030 Command:0x42 SN:0x1687d9  REQUEST SUCCEEDED.
[ 1540.309302] hpsa :03:00.0: ABORT REQUEST on C6:B2:T0:L0
Tag:0x:0030 Command:0x42 SN:0x1687d9  FAILED. Aborted command has
not completed after 30 seconds.
[ 1540.309319] hpsa :03:00.0: Abort request on C6:B2:T1:L0
[ 1540.345047] hpsa :03:00.0: ABORT REQUEST on C6:B2:T1:L0
Tag:0x:0010 Command:0x42 SN:0x1687d8  REQUEST SUCCEEDED.
[ 1588.796036] hpsa :03:00.0: ABORT REQUEST on C6:B2:T1:L0
Tag:0x:0010 Command:0x42 SN:0x1687d8  FAILED. Aborted command has
not completed after 30 seconds.
[ 1588.796090] hpsa :03:00.0: resetting device 6:2:0:0


the mkfs process doesn't finish and I can no longer access disks (parted,
etc..)

I can repeat this on two identical servers.

I looked at kernel changelogs and did not see anything that may fix this on
recent releases.

-- 
You are receiving this mail because:
You are watching the assignee of the bug.
--
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 1/3] sd: Fixup capacity for ALUA standby or transitioning ports

2015-07-08 Thread Hannes Reinecke
If a target port is in ALUA 'standby' or 'transitioning' state it
might not need to respond to a 'READ CAPACITY' command. So fixup
the initialization for these cases.

Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/scsi/sd.c | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 3b2fcb4..03fdfa9 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1981,6 +1981,16 @@ static int read_capacity_16(struct scsi_disk *sdkp, 
struct scsi_device *sdp,
 * give it one more chance */
if (--reset_retries  0)
continue;
+   if (sense_valid 
+   sshdr.sense_key == NOT_READY 
+   sshdr.asc == 0x04  sshdr.ascq == 0x0a)
+   /* Target port in transition */
+   return 0;
+   if (sense_valid 
+   sshdr.sense_key == NOT_READY 
+   sshdr.asc == 0x04  sshdr.ascq == 0x0b)
+   /* Target port in standy state */
+   return 0;
}
retries--;
 
@@ -2063,6 +2073,16 @@ static int read_capacity_10(struct scsi_disk *sdkp, 
struct scsi_device *sdp,
 * give it one more chance */
if (--reset_retries  0)
continue;
+   if (sense_valid 
+   sshdr.sense_key == NOT_READY 
+   sshdr.asc == 0x04  sshdr.ascq == 0x0a)
+   /* Target port in transition */
+   return 0;
+   if (sense_valid 
+   sshdr.sense_key == NOT_READY 
+   sshdr.asc == 0x04  sshdr.ascq == 0x0b)
+   /* Target port in standy state */
+   return 0;
}
retries--;
 
@@ -2177,6 +2197,8 @@ got_data:
sector_size = 512;
sd_printk(KERN_NOTICE, sdkp, Sector size 0 reported, 
  assuming 512.\n);
+   if (!sdkp-physical_block_size)
+   sdkp-physical_block_size = sector_size;
}
 
if (sector_size != 512 
-- 
1.8.5.2

--
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 07/10] scsi_dh: add a common helper to get a scsi_device from a request_queue

2015-07-08 Thread Hannes Reinecke
From: Christoph Hellwig h...@lst.de

And cleanup the various messy opencoded versions of this.  Note that this
moves the sdev_state checks outside the queue_lock coverage, but as
we don't hold the lock over the activation they are only advisory anyway.

Signed-off-by: Christoph Hellwig h...@lst.de
Reviewed-by: Martin K. Petersen martin.peter...@oracle.com
Reviewed-by: Hannes Reinecke h...@suse.de
---
 drivers/scsi/scsi_dh.c | 99 +++---
 1 file changed, 46 insertions(+), 53 deletions(-)

diff --git a/drivers/scsi/scsi_dh.c b/drivers/scsi/scsi_dh.c
index bfa6b3a..265e3dd 100644
--- a/drivers/scsi/scsi_dh.c
+++ b/drivers/scsi/scsi_dh.c
@@ -282,6 +282,20 @@ int scsi_unregister_device_handler(struct 
scsi_device_handler *scsi_dh)
 }
 EXPORT_SYMBOL_GPL(scsi_unregister_device_handler);
 
+static struct scsi_device *get_sdev_from_queue(struct request_queue *q)
+{
+   struct scsi_device *sdev;
+   unsigned long flags;
+
+   spin_lock_irqsave(q-queue_lock, flags);
+   sdev = q-queuedata;
+   if (!sdev || !get_device(sdev-sdev_gendev))
+   sdev = NULL;
+   spin_unlock_irqrestore(q-queue_lock, flags);
+
+   return sdev;
+}
+
 /*
  * scsi_dh_activate - activate the path associated with the scsi_device
  *  corresponding to the given request queue.
@@ -297,41 +311,37 @@ EXPORT_SYMBOL_GPL(scsi_unregister_device_handler);
  */
 int scsi_dh_activate(struct request_queue *q, activate_complete fn, void *data)
 {
-   int err = 0;
-   unsigned long flags;
struct scsi_device *sdev;
-   struct device *dev = NULL;
+   int err = SCSI_DH_NOSYS;
 
-   spin_lock_irqsave(q-queue_lock, flags);
-   sdev = q-queuedata;
+   sdev = get_sdev_from_queue(q);
if (!sdev) {
-   spin_unlock_irqrestore(q-queue_lock, flags);
-   err = SCSI_DH_NOSYS;
if (fn)
fn(data, err);
return err;
}
 
-   dev = get_device(sdev-sdev_gendev);
-   if (!sdev-handler || !dev ||
-   sdev-sdev_state == SDEV_CANCEL ||
+   if (!sdev-handler)
+   goto out_fn;
+   if (sdev-sdev_state == SDEV_CANCEL ||
sdev-sdev_state == SDEV_DEL)
-   err = SCSI_DH_NOSYS;
-   if (sdev-sdev_state == SDEV_OFFLINE)
-   err = SCSI_DH_DEV_OFFLINED;
-   spin_unlock_irqrestore(q-queue_lock, flags);
+   goto out_fn;
 
-   if (err) {
-   if (fn)
-   fn(data, err);
-   goto out;
-   }
+   err = SCSI_DH_DEV_OFFLINED;
+   if (sdev-sdev_state == SDEV_OFFLINE)
+   goto out_fn;
 
if (sdev-handler-activate)
err = sdev-handler-activate(sdev, fn, data);
-out:
-   put_device(dev);
+
+out_put_device:
+   put_device(sdev-sdev_gendev);
return err;
+
+out_fn:
+   if (fn)
+   fn(data, err);
+   goto out_put_device;
 }
 EXPORT_SYMBOL_GPL(scsi_dh_activate);
 
@@ -347,21 +357,15 @@ EXPORT_SYMBOL_GPL(scsi_dh_activate);
  */
 int scsi_dh_set_params(struct request_queue *q, const char *params)
 {
-   int err = -SCSI_DH_NOSYS;
-   unsigned long flags;
struct scsi_device *sdev;
+   int err = -SCSI_DH_NOSYS;
 
-   spin_lock_irqsave(q-queue_lock, flags);
-   sdev = q-queuedata;
-   if (sdev-handler 
-   sdev-handler-set_params 
-   get_device(sdev-sdev_gendev))
-   err = 0;
-   spin_unlock_irqrestore(q-queue_lock, flags);
-
-   if (err)
+   sdev = get_sdev_from_queue(q);
+   if (!sdev)
return err;
-   err = sdev-handler-set_params(sdev, params);
+
+   if (sdev-handler  sdev-handler-set_params)
+   err = sdev-handler-set_params(sdev, params);
put_device(sdev-sdev_gendev);
return err;
 }
@@ -375,23 +379,19 @@ EXPORT_SYMBOL_GPL(scsi_dh_set_params);
  */
 int scsi_dh_attach(struct request_queue *q, const char *name)
 {
-   unsigned long flags;
struct scsi_device *sdev;
struct scsi_device_handler *scsi_dh;
int err = 0;
 
-   scsi_dh = scsi_dh_lookup(name);
-   if (!scsi_dh)
-   return -EINVAL;
-
-   spin_lock_irqsave(q-queue_lock, flags);
-   sdev = q-queuedata;
-   if (!sdev || !get_device(sdev-sdev_gendev))
-   err = -ENODEV;
-   spin_unlock_irqrestore(q-queue_lock, flags);
+   sdev = get_sdev_from_queue(q);
+   if (!sdev)
+   return -ENODEV;
 
-   if (err)
-   return err;
+   scsi_dh = scsi_dh_lookup(name);
+   if (!scsi_dh) {
+   err = -EINVAL;
+   goto out_put_device;
+   }
 
if (sdev-handler) {
if (sdev-handler != scsi_dh)
@@ -418,22 +418,15 @@ EXPORT_SYMBOL_GPL(scsi_dh_attach);
  */
 const char *scsi_dh_attached_handler_name(struct request_queue *q, gfp_t gfp)
 {
-   unsigned long flags;

[PATCH 01/10] dm-mpath, scsi_dh: don't let dm detach device handlers

2015-07-08 Thread Hannes Reinecke
From: Christoph Hellwig h...@lst.de

While allowing dm-mpath to attach device handlers is a functionality we need
for backwards compatibility reason there is no reason to reference count
them and detach them if dm-mpath stops using the device for some reason.

If the device handler works for the given device it can just stay attached,
and we can take the retain_hw_handler codepath.

Signed-off-by: Christoph Hellwig h...@lst.de
Acked-by: Mike Snitzer snit...@redhat.com
Acked-by: Hannes Reinecke h...@suse.de
---
 drivers/md/dm-mpath.c | 21 +++-
 drivers/scsi/device_handler/scsi_dh.c | 96 ---
 include/scsi/scsi_device.h|  1 -
 include/scsi/scsi_dh.h|  5 --
 4 files changed, 28 insertions(+), 95 deletions(-)

diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index eff7bdd..a9f58fd 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -159,12 +159,9 @@ static struct priority_group *alloc_priority_group(void)
 static void free_pgpaths(struct list_head *pgpaths, struct dm_target *ti)
 {
struct pgpath *pgpath, *tmp;
-   struct multipath *m = ti-private;
 
list_for_each_entry_safe(pgpath, tmp, pgpaths, list) {
list_del(pgpath-list);
-   if (m-hw_handler_name)
-   scsi_dh_detach(bdev_get_queue(pgpath-path.dev-bdev));
dm_put_device(ti, pgpath-path.dev);
free_pgpath(pgpath);
}
@@ -580,6 +577,7 @@ static struct pgpath *parse_path(struct dm_arg_set *as, 
struct path_selector *ps
q = bdev_get_queue(p-path.dev-bdev);
 
if (m-retain_attached_hw_handler) {
+retain:
attached_handler_name = scsi_dh_attached_handler_name(q, 
GFP_KERNEL);
if (attached_handler_name) {
/*
@@ -599,20 +597,14 @@ static struct pgpath *parse_path(struct dm_arg_set *as, 
struct path_selector *ps
}
 
if (m-hw_handler_name) {
-   /*
-* Increments scsi_dh reference, even when using an
-* already-attached handler.
-*/
r = scsi_dh_attach(q, m-hw_handler_name);
if (r == -EBUSY) {
-   /*
-* Already attached to different hw_handler:
-* try to reattach with correct one.
-*/
-   scsi_dh_detach(q);
-   r = scsi_dh_attach(q, m-hw_handler_name);
-   }
+   char b[BDEVNAME_SIZE];
 
+   printk(KERN_INFO dm-mpath: retaining handler on device 
%s\n,
+   bdevname(p-path.dev-bdev, b));
+   goto retain;
+   }
if (r  0) {
ti-error = error attaching hardware handler;
dm_put_device(ti, p-path.dev);
@@ -624,7 +616,6 @@ static struct pgpath *parse_path(struct dm_arg_set *as, 
struct path_selector *ps
if (r  0) {
ti-error = unable to set hardware 
handler parameters;
-   scsi_dh_detach(q);
dm_put_device(ti, p-path.dev);
goto bad;
}
diff --git a/drivers/scsi/device_handler/scsi_dh.c 
b/drivers/scsi/device_handler/scsi_dh.c
index 1efebc9..869b5bd 100644
--- a/drivers/scsi/device_handler/scsi_dh.c
+++ b/drivers/scsi/device_handler/scsi_dh.c
@@ -100,14 +100,6 @@ static int scsi_dh_handler_attach(struct scsi_device *sdev,
 {
struct scsi_dh_data *d;
 
-   if (sdev-scsi_dh_data) {
-   if (sdev-scsi_dh_data-scsi_dh != scsi_dh)
-   return -EBUSY;
-
-   kref_get(sdev-scsi_dh_data-kref);
-   return 0;
-   }
-
if (!try_module_get(scsi_dh-module))
return -EINVAL;
 
@@ -120,7 +112,6 @@ static int scsi_dh_handler_attach(struct scsi_device *sdev,
}
 
d-scsi_dh = scsi_dh;
-   kref_init(d-kref);
d-sdev = sdev;
 
spin_lock_irq(sdev-request_queue-queue_lock);
@@ -129,12 +120,14 @@ static int scsi_dh_handler_attach(struct scsi_device 
*sdev,
return 0;
 }
 
-static void __detach_handler (struct kref *kref)
+/*
+ * scsi_dh_handler_detach - Detach a device handler from a device
+ * @sdev - SCSI device the device handler should be detached from
+ */
+static void scsi_dh_handler_detach(struct scsi_device *sdev)
 {
-   struct scsi_dh_data *scsi_dh_data =
-   container_of(kref, struct scsi_dh_data, kref);
+   struct scsi_dh_data *scsi_dh_data = sdev-scsi_dh_data;
struct scsi_device_handler *scsi_dh = scsi_dh_data-scsi_dh;
-   struct scsi_device *sdev = scsi_dh_data-sdev;
 
scsi_dh-detach(sdev);
 
@@ -147,30 

Re: [PATCH 3/3] sd: do not try to spin-up disks for ALUA 'transitioning' state

2015-07-08 Thread Sagi Grimberg

On 7/8/2015 10:41 AM, Hannes Reinecke wrote:

If a disk reports an ALUA 'transitioning' state we should not
try to spin up the device.

Signed-off-by: Hannes Reinecke h...@suse.de
---
  drivers/scsi/sd.c | 2 ++
  1 file changed, 2 insertions(+)

diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 7c0bdaa..180a6e8 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1801,6 +1801,8 @@ sd_spinup_disk(struct scsi_disk *sdkp)
if (sense_valid  sshdr.sense_key == NOT_READY) {
if (sshdr.asc == 4  sshdr.ascq == 3)
break;  /* manual intervention required */
+   if (sshdr.asc == 4  sshdr.ascq == 0xa)
+   break;  /* transitioning */
if (sshdr.asc == 4  sshdr.ascq == 0xb)
break;  /* standby */
if (sshdr.asc == 4  sshdr.ascq == 0xc)




Hi Hannes,

Just nit-picking, but do you think that these four if statements can be
re-organized to condition (asc == 4) once and OR on the rest?
--
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 10/10] scsi_dh: move 'dh_state' sysfs attribute to generic code

2015-07-08 Thread Hannes Reinecke
As scsi_dh.c is now always compiled in we should be moving
the 'dh_state' attribute to the generic code.

Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/scsi/scsi_dh.c| 65 ---
 drivers/scsi/scsi_sysfs.c | 60 +++
 2 files changed, 60 insertions(+), 65 deletions(-)

diff --git a/drivers/scsi/scsi_dh.c b/drivers/scsi/scsi_dh.c
index a9494f3..42f20f1 100644
--- a/drivers/scsi/scsi_dh.c
+++ b/drivers/scsi/scsi_dh.c
@@ -153,76 +153,12 @@ static void scsi_dh_handler_detach(struct scsi_device 
*sdev)
module_put(sdev-handler-module);
 }
 
-/*
- * Functions for sysfs attribute 'dh_state'
- */
-static ssize_t
-store_dh_state(struct device *dev, struct device_attribute *attr,
-  const char *buf, size_t count)
-{
-   struct scsi_device *sdev = to_scsi_device(dev);
-   struct scsi_device_handler *scsi_dh;
-   int err = -EINVAL;
-
-   if (sdev-sdev_state == SDEV_CANCEL ||
-   sdev-sdev_state == SDEV_DEL)
-   return -ENODEV;
-
-   if (!sdev-handler) {
-   /*
-* Attach to a device handler
-*/
-   if (!(scsi_dh = scsi_dh_lookup(buf)))
-   return err;
-   err = scsi_dh_handler_attach(sdev, scsi_dh);
-   } else {
-   if (!strncmp(buf, detach, 6)) {
-   /*
-* Detach from a device handler
-*/
-   sdev_printk(KERN_WARNING, sdev,
-   can't detach handler %s.\n,
-   sdev-handler-name);
-   err = -EINVAL;
-   } else if (!strncmp(buf, activate, 8)) {
-   /*
-* Activate a device handler
-*/
-   if (sdev-handler-activate)
-   err = sdev-handler-activate(sdev, NULL, NULL);
-   else
-   err = 0;
-   }
-   }
-
-   return err0?err:count;
-}
-
-static ssize_t
-show_dh_state(struct device *dev, struct device_attribute *attr, char *buf)
-{
-   struct scsi_device *sdev = to_scsi_device(dev);
-
-   if (!sdev-handler)
-   return snprintf(buf, 20, detached\n);
-
-   return snprintf(buf, 20, %s\n, sdev-handler-name);
-}
-
-static struct device_attribute scsi_dh_state_attr =
-   __ATTR(dh_state, S_IRUGO | S_IWUSR, show_dh_state,
-  store_dh_state);
-
 int scsi_dh_add_device(struct scsi_device *sdev)
 {
struct scsi_device_handler *devinfo = NULL;
const char *drv;
int err;
 
-   err = device_create_file(sdev-sdev_gendev, scsi_dh_state_attr);
-   if (err)
-   return err;
-
drv = scsi_dh_find_driver(sdev);
if (drv)
devinfo = scsi_dh_lookup(drv);
@@ -235,7 +171,6 @@ void scsi_dh_remove_device(struct scsi_device *sdev)
 {
if (sdev-handler)
scsi_dh_handler_detach(sdev);
-   device_remove_file(sdev-sdev_gendev, scsi_dh_state_attr);
 }
 
 /*
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index c8a120f..e3c3b86 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -17,6 +17,7 @@
 #include scsi/scsi_device.h
 #include scsi/scsi_host.h
 #include scsi/scsi_tcq.h
+#include scsi/scsi_dh.h
 #include scsi/scsi_transport.h
 #include scsi/scsi_driver.h
 
@@ -875,6 +876,62 @@ sdev_show_function(queue_depth, %d\n);
 static DEVICE_ATTR(queue_depth, S_IRUGO | S_IWUSR, sdev_show_queue_depth,
   sdev_store_queue_depth);
 
+#ifdef CONFIG_SCSI_DH
+static ssize_t
+sdev_show_dh_state(struct device *dev, struct device_attribute *attr,
+  char *buf)
+{
+   struct scsi_device *sdev = to_scsi_device(dev);
+
+   if (!sdev-handler)
+   return snprintf(buf, 20, detached\n);
+
+   return snprintf(buf, 20, %s\n, sdev-handler-name);
+}
+
+static ssize_t
+sdev_store_dh_state(struct device *dev, struct device_attribute *attr,
+   const char *buf, size_t count)
+{
+   struct scsi_device *sdev = to_scsi_device(dev);
+   int err = -EINVAL;
+
+   if (sdev-sdev_state == SDEV_CANCEL ||
+   sdev-sdev_state == SDEV_DEL)
+   return -ENODEV;
+
+   if (!sdev-handler) {
+   /*
+* Attach to a device handler
+*/
+   err = scsi_dh_attach(sdev-request_queue, buf);
+   } else {
+   if (!strncmp(buf, detach, 6)) {
+   /*
+* Detach from a device handler
+*/
+   sdev_printk(KERN_WARNING, sdev,
+   can't detach handler %s.\n,
+   sdev-handler-name);
+   err = 

Re: [PATCH v3 2/5] target: Split transport_send_check_condition_and_sense()

2015-07-08 Thread Christoph Hellwig
 + if (r == (__force int)TCM_CHECK_CONDITION_UNIT_ATTENTION) {

You probably want to compare reason here to avoid the cast.

Otherwise looks good,

Reviewed-by: Christoph Hellwig h...@lst.de
--
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/3] megaraid : use dev_printk when possible

2015-07-08 Thread Hannes Reinecke
On 07/07/2015 10:52 PM, Bjorn Helgaas wrote:
 Use dev_printk() when possible to make messages more useful.
 
 Signed-off-by: Bjorn Helgaas bhelg...@google.com
 ---
  drivers/scsi/megaraid.c |  140 
 ++-
  1 file changed, 66 insertions(+), 74 deletions(-)
 
Reviewed-by: Hannes Reinecke h...@suse.de

Cheers,

Hannes
-- 
Dr. Hannes ReineckezSeries  Storage
h...@suse.de   +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)
--
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/3] scsi: rescan device if an invalid capacity had been reported

2015-07-08 Thread Hannes Reinecke
Device paths in ALUA state 'standby' do not necessarily support
the READ_CAPACITY command. This patch adds a new flag 'invalid_capacity'
to the scsi device, and rescans the device if an ALUA state
change occurred.

Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/scsi/scsi_lib.c|  4 
 drivers/scsi/sd.c  | 19 ++-
 include/scsi/scsi_device.h |  1 +
 3 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index c005e42..d4245f0 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -2701,6 +2701,7 @@ static void scsi_evt_emit(struct scsi_device *sdev, 
struct scsi_event *evt)
envp[idx++] = SDEV_UA=INQUIRY_DATA_HAS_CHANGED;
break;
case SDEV_EVT_CAPACITY_CHANGE_REPORTED:
+   scsi_rescan_device(sdev-sdev_gendev);
envp[idx++] = SDEV_UA=CAPACITY_DATA_HAS_CHANGED;
break;
case SDEV_EVT_SOFT_THRESHOLD_REACHED_REPORTED:
@@ -2713,6 +2714,9 @@ static void scsi_evt_emit(struct scsi_device *sdev, 
struct scsi_event *evt)
envp[idx++] = SDEV_UA=REPORTED_LUNS_DATA_HAS_CHANGED;
break;
case SDEV_EVT_ALUA_STATE_CHANGE_REPORTED:
+   if (sdev-invalid_capacity)
+   scsi_rescan_device(sdev-sdev_gendev);
+
envp[idx++] = SDEV_UA=ASYMMETRIC_ACCESS_STATE_CHANGED;
break;
default:
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 03fdfa9..7c0bdaa 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1983,14 +1983,18 @@ static int read_capacity_16(struct scsi_disk *sdkp, 
struct scsi_device *sdp,
continue;
if (sense_valid 
sshdr.sense_key == NOT_READY 
-   sshdr.asc == 0x04  sshdr.ascq == 0x0a)
+   sshdr.asc == 0x04  sshdr.ascq == 0x0a) {
/* Target port in transition */
+   sdp-invalid_capacity = 1;
return 0;
+   }
if (sense_valid 
sshdr.sense_key == NOT_READY 
-   sshdr.asc == 0x04  sshdr.ascq == 0x0b)
+   sshdr.asc == 0x04  sshdr.ascq == 0x0b) {
/* Target port in standy state */
+   sdp-invalid_capacity = 1;
return 0;
+   }
}
retries--;
 
@@ -2075,14 +2079,18 @@ static int read_capacity_10(struct scsi_disk *sdkp, 
struct scsi_device *sdp,
continue;
if (sense_valid 
sshdr.sense_key == NOT_READY 
-   sshdr.asc == 0x04  sshdr.ascq == 0x0a)
+   sshdr.asc == 0x04  sshdr.ascq == 0x0a) {
/* Target port in transition */
+   sdp-invalid_capacity = 1;
return 0;
+   }
if (sense_valid 
sshdr.sense_key == NOT_READY 
-   sshdr.asc == 0x04  sshdr.ascq == 0x0b)
+   sshdr.asc == 0x04  sshdr.ascq == 0x0b) {
/* Target port in standy state */
+   sdp-invalid_capacity = 1;
return 0;
+   }
}
retries--;
 
@@ -2199,7 +2207,8 @@ got_data:
  assuming 512.\n);
if (!sdkp-physical_block_size)
sdkp-physical_block_size = sector_size;
-   }
+   } else
+   sdp-invalid_capacity = 0;
 
if (sector_size != 512 
sector_size != 1024 
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index 50c2a36..99bde5a 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -175,6 +175,7 @@ struct scsi_device {
unsigned no_dif:1;  /* T10 PI (DIF) should be disabled */
unsigned broken_fua:1;  /* Don't set FUA bit */
unsigned lun_in_cdb:1;  /* Store LUN bits in CDB[1] */
+   unsigned invalid_capacity:1;/* READ_CAPACITY not supported */
 
atomic_t disk_events_disable_depth; /* disable depth for disk events */
 
-- 
1.8.5.2

--
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 Resend] mpt2sas: setpci reset kernel oops fix

2015-07-08 Thread Christoph Hellwig

On Wed, Jul 08, 2015 at 11:17:47AM +0530, Nagarajkumar Narayanan wrote:
 Note: pci_access_mutex is used only if nytro warpdrive cards 
 (ioc-is_warpdrive based on device id) are used
 as we could not test this case with other SAS2 HBA cards
 We can remove this check if this behaviour confirmed from other
 cards.

I don't see any downside of taking the lock, and conditional locking
like this is a always a bad sign.
--
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 03/10] scsi_dh: move to drivers/scsi

2015-07-08 Thread Hannes Reinecke
From: Christoph Hellwig h...@lst.de

Prepare for building scsi_dh.c into the core SCSI module by moving it to
drivers/scsi.

Signed-off-by: Christoph Hellwig h...@lst.de
Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/scsi/Makefile |   1 +
 drivers/scsi/device_handler/Makefile  |   1 -
 drivers/scsi/device_handler/scsi_dh.c | 570 --
 drivers/scsi/scsi_dh.c| 570 ++
 4 files changed, 571 insertions(+), 571 deletions(-)
 delete mode 100644 drivers/scsi/device_handler/scsi_dh.c
 create mode 100644 drivers/scsi/scsi_dh.c

diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index 91209e3..22f54b0 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -171,6 +171,7 @@ scsi_mod-$(CONFIG_SYSCTL)   += scsi_sysctl.o
 scsi_mod-$(CONFIG_SCSI_PROC_FS)+= scsi_proc.o
 scsi_mod-y += scsi_trace.o scsi_logging.o
 scsi_mod-$(CONFIG_PM)  += scsi_pm.o
+obj-$(CONFIG_SCSI_DH)  += scsi_dh.o
 
 hv_storvsc-y   := storvsc_drv.o
 
diff --git a/drivers/scsi/device_handler/Makefile 
b/drivers/scsi/device_handler/Makefile
index e1d2ea0..09866c5 100644
--- a/drivers/scsi/device_handler/Makefile
+++ b/drivers/scsi/device_handler/Makefile
@@ -1,7 +1,6 @@
 #
 # SCSI Device Handler
 #
-obj-$(CONFIG_SCSI_DH)  += scsi_dh.o
 obj-$(CONFIG_SCSI_DH_RDAC) += scsi_dh_rdac.o
 obj-$(CONFIG_SCSI_DH_HP_SW)+= scsi_dh_hp_sw.o
 obj-$(CONFIG_SCSI_DH_EMC)  += scsi_dh_emc.o
diff --git a/drivers/scsi/device_handler/scsi_dh.c 
b/drivers/scsi/device_handler/scsi_dh.c
deleted file mode 100644
index 5bd0af6..000
--- a/drivers/scsi/device_handler/scsi_dh.c
+++ /dev/null
@@ -1,570 +0,0 @@
-/*
- * SCSI device handler infrastruture.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Copyright IBM Corporation, 2007
- *  Authors:
- *   Chandra Seetharaman sekha...@us.ibm.com
- *   Mike Anderson andm...@linux.vnet.ibm.com
- */
-
-#include linux/slab.h
-#include linux/module.h
-#include scsi/scsi_dh.h
-#include ../scsi_priv.h
-
-static DEFINE_SPINLOCK(list_lock);
-static LIST_HEAD(scsi_dh_list);
-
-static struct scsi_device_handler *__scsi_dh_lookup(const char *name)
-{
-   struct scsi_device_handler *tmp, *found = NULL;
-
-   spin_lock(list_lock);
-   list_for_each_entry(tmp, scsi_dh_list, list) {
-   if (!strncmp(tmp-name, name, strlen(tmp-name))) {
-   found = tmp;
-   break;
-   }
-   }
-   spin_unlock(list_lock);
-   return found;
-}
-
-static struct scsi_device_handler *scsi_dh_lookup(const char *name)
-{
-   struct scsi_device_handler *dh;
-
-   dh = __scsi_dh_lookup(name);
-   if (!dh) {
-   request_module(name);
-   dh = __scsi_dh_lookup(name);
-   }
-
-   return dh;
-}
-
-/*
- * device_handler_match_function - Match a device handler to a device
- * @sdev - SCSI device to be tested
- *
- * Tests @sdev against the match function of all registered device_handler.
- * Returns the found device handler or NULL if not found.
- */
-static struct scsi_device_handler *
-device_handler_match_function(struct scsi_device *sdev)
-{
-   struct scsi_device_handler *tmp_dh, *found_dh = NULL;
-
-   spin_lock(list_lock);
-   list_for_each_entry(tmp_dh, scsi_dh_list, list) {
-   if (tmp_dh-match  tmp_dh-match(sdev)) {
-   found_dh = tmp_dh;
-   break;
-   }
-   }
-   spin_unlock(list_lock);
-   return found_dh;
-}
-
-/*
- * device_handler_match - Attach a device handler to a device
- * @scsi_dh - The device handler to match against or NULL
- * @sdev - SCSI device to be tested against @scsi_dh
- *
- * Tests @sdev against the device handler @scsi_dh or against
- * all registered device_handler if @scsi_dh == NULL.
- * Returns the found device handler or NULL if not found.
- */
-static struct scsi_device_handler *
-device_handler_match(struct scsi_device_handler *scsi_dh,
-struct scsi_device *sdev)
-{
-   struct scsi_device_handler *found_dh;
-
-   found_dh = device_handler_match_function(sdev);
-
-   if (scsi_dh  found_dh != 

[PATCH 06/10] scsi_dh: kill struct scsi_dh_data

2015-07-08 Thread Hannes Reinecke
From: Christoph Hellwig h...@lst.de

Add a -handler and a -handler_data field to struct scsi_device and kill
this indirection.  Also move struct scsi_device_handler to scsi_dh.h so that
changes to it don't require rebuilding every SCSI LLDD.

Signed-off-by: Christoph Hellwig h...@lst.de
Reviewed-by: Martin K. Petersen martin.peter...@oracle.com
Reviewed-by: Hannes Reinecke h...@suse.de
---
 drivers/scsi/device_handler/scsi_dh_alua.c  | 25 --
 drivers/scsi/device_handler/scsi_dh_emc.c   | 29 +--
 drivers/scsi/device_handler/scsi_dh_hp_sw.c | 25 --
 drivers/scsi/device_handler/scsi_dh_rdac.c  | 30 +---
 drivers/scsi/scsi_dh.c  | 75 +++--
 drivers/scsi/scsi_error.c   |  6 +--
 drivers/scsi/scsi_lib.c |  6 +--
 include/scsi/scsi_device.h  | 25 ++
 include/scsi/scsi_dh.h  | 17 +++
 9 files changed, 98 insertions(+), 140 deletions(-)

diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
b/drivers/scsi/device_handler/scsi_dh_alua.c
index ace2457..cc2773b 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -62,7 +62,6 @@
 #define ALUA_OPTIMIZE_STPG 1
 
 struct alua_dh_data {
-   struct scsi_dh_data dh_data;
int group_id;
int rel_port;
int tpgs;
@@ -86,11 +85,6 @@ struct alua_dh_data {
 static char print_alua_state(int);
 static int alua_check_sense(struct scsi_device *, struct scsi_sense_hdr *);
 
-static inline struct alua_dh_data *get_alua_data(struct scsi_device *sdev)
-{
-   return container_of(sdev-scsi_dh_data, struct alua_dh_data, dh_data);
-}
-
 static int realloc_buffer(struct alua_dh_data *h, unsigned len)
 {
if (h-buff  h-buff != h-inq)
@@ -708,7 +702,7 @@ out:
  */
 static int alua_set_params(struct scsi_device *sdev, const char *params)
 {
-   struct alua_dh_data *h = get_alua_data(sdev);
+   struct alua_dh_data *h = sdev-handler_data;
unsigned int optimize = 0, argc;
const char *p = params;
int result = SCSI_DH_OK;
@@ -746,7 +740,7 @@ MODULE_PARM_DESC(optimize_stpg, Allow use of a 
non-optimized path, rather than
 static int alua_activate(struct scsi_device *sdev,
activate_complete fn, void *data)
 {
-   struct alua_dh_data *h = get_alua_data(sdev);
+   struct alua_dh_data *h = sdev-handler_data;
int err = SCSI_DH_OK;
int stpg = 0;
 
@@ -804,7 +798,7 @@ out:
  */
 static int alua_prep_fn(struct scsi_device *sdev, struct request *req)
 {
-   struct alua_dh_data *h = get_alua_data(sdev);
+   struct alua_dh_data *h = sdev-handler_data;
int ret = BLKPREP_OK;
 
if (h-state == TPGS_STATE_TRANSITIONING)
@@ -823,14 +817,14 @@ static int alua_prep_fn(struct scsi_device *sdev, struct 
request *req)
  * alua_bus_attach - Attach device handler
  * @sdev: device to be attached to
  */
-static struct scsi_dh_data *alua_bus_attach(struct scsi_device *sdev)
+static int alua_bus_attach(struct scsi_device *sdev)
 {
struct alua_dh_data *h;
int err;
 
h = kzalloc(sizeof(*h) , GFP_KERNEL);
if (!h)
-   return ERR_PTR(-ENOMEM);
+   return -ENOMEM;
h-tpgs = TPGS_MODE_UNINITIALIZED;
h-state = TPGS_STATE_OPTIMIZED;
h-group_id = -1;
@@ -843,11 +837,11 @@ static struct scsi_dh_data *alua_bus_attach(struct 
scsi_device *sdev)
if (err != SCSI_DH_OK  err != SCSI_DH_DEV_OFFLINED)
goto failed;
 
-   sdev_printk(KERN_NOTICE, sdev, %s: Attached\n, ALUA_DH_NAME);
-   return h-dh_data;
+   sdev-handler_data = h;
+   return 0;
 failed:
kfree(h);
-   return ERR_PTR(-EINVAL);
+   return -EINVAL;
 }
 
 /*
@@ -856,10 +850,11 @@ failed:
  */
 static void alua_bus_detach(struct scsi_device *sdev)
 {
-   struct alua_dh_data *h = get_alua_data(sdev);
+   struct alua_dh_data *h = sdev-handler_data;
 
if (h-buff  h-inq != h-buff)
kfree(h-buff);
+   sdev-handler_data = NULL;
kfree(h);
 }
 
diff --git a/drivers/scsi/device_handler/scsi_dh_emc.c 
b/drivers/scsi/device_handler/scsi_dh_emc.c
index fd31e67..e6fb97c 100644
--- a/drivers/scsi/device_handler/scsi_dh_emc.c
+++ b/drivers/scsi/device_handler/scsi_dh_emc.c
@@ -72,7 +72,6 @@ static const char * lun_state[] =
 };
 
 struct clariion_dh_data {
-   struct scsi_dh_data dh_data;
/*
 * Flags:
 *  CLARIION_SHORT_TRESPASS
@@ -114,13 +113,6 @@ struct clariion_dh_data {
int current_sp;
 };
 
-static inline struct clariion_dh_data
-   *get_clariion_data(struct scsi_device *sdev)
-{
-   return container_of(sdev-scsi_dh_data, struct clariion_dh_data,
-   dh_data);
-}
-
 /*
  * Parse MODE_SELECT cmd reply.
  */
@@ -450,7 

[PATCH 09/10] scsi_dh: return individual errors in scsi_dh_activate()

2015-07-08 Thread Hannes Reinecke
When calling scsi_dh_activate() we should be returning
individual errors and not lumping all into one.

Reviewed-by: Bart van Assche bart.vanass...@sandisk.com
Reviewed-by: Christoph Hellwig h...@lst.de
Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/scsi/scsi_dh.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/scsi/scsi_dh.c b/drivers/scsi/scsi_dh.c
index 7723280..a9494f3 100644
--- a/drivers/scsi/scsi_dh.c
+++ b/drivers/scsi/scsi_dh.c
@@ -325,6 +325,7 @@ int scsi_dh_activate(struct request_queue *q, 
activate_complete fn, void *data)
 
if (!sdev-handler)
goto out_fn;
+   err = SCSI_DH_NOTCONN;
if (sdev-sdev_state == SDEV_CANCEL ||
sdev-sdev_state == SDEV_DEL)
goto out_fn;
-- 
1.8.5.2

--
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 05/10] scsi_dh: move device matching to the core code

2015-07-08 Thread Hannes Reinecke
From: Christoph Hellwig h...@lst.de

Add a single list of devices that need non-ALUA device handlers to the core
scsi_dh code so that we can autoload the modules for them at probe time.

While this is a little ugly in terms of architecture it actually
significantly simplifies the code in addition to the new autoloading
functionality.

Signed-off-by: Christoph Hellwig h...@lst.de
Reviewed-by: Martin K. Petersen martin.peter...@oracle.com
Reviewed-by: Hannes Reinecke h...@suse.de
Acked-by: Mike Snitzer snit...@redhat.com
---
 drivers/scsi/device_handler/scsi_dh_alua.c  |  6 ---
 drivers/scsi/device_handler/scsi_dh_emc.c   | 29 --
 drivers/scsi/device_handler/scsi_dh_hp_sw.c | 30 ---
 drivers/scsi/device_handler/scsi_dh_rdac.c  | 50 -
 drivers/scsi/scsi_dh.c  | 84 ++---
 include/scsi/scsi_device.h  |  1 -
 6 files changed, 66 insertions(+), 134 deletions(-)

diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
b/drivers/scsi/device_handler/scsi_dh_alua.c
index 854b568..ace2457 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -819,11 +819,6 @@ static int alua_prep_fn(struct scsi_device *sdev, struct 
request *req)
 
 }
 
-static bool alua_match(struct scsi_device *sdev)
-{
-   return (scsi_device_tpgs(sdev) != 0);
-}
-
 /*
  * alua_bus_attach - Attach device handler
  * @sdev: device to be attached to
@@ -877,7 +872,6 @@ static struct scsi_device_handler alua_dh = {
.check_sense = alua_check_sense,
.activate = alua_activate,
.set_params = alua_set_params,
-   .match = alua_match,
 };
 
 static int __init alua_init(void)
diff --git a/drivers/scsi/device_handler/scsi_dh_emc.c 
b/drivers/scsi/device_handler/scsi_dh_emc.c
index 6ed1caa..fd31e67 100644
--- a/drivers/scsi/device_handler/scsi_dh_emc.c
+++ b/drivers/scsi/device_handler/scsi_dh_emc.c
@@ -622,34 +622,6 @@ done:
return result;
 }
 
-static const struct {
-   char *vendor;
-   char *model;
-} clariion_dev_list[] = {
-   {DGC, RAID},
-   {DGC, DISK},
-   {DGC, VRAID},
-   {NULL, NULL},
-};
-
-static bool clariion_match(struct scsi_device *sdev)
-{
-   int i;
-
-   if (scsi_device_tpgs(sdev))
-   return false;
-
-   for (i = 0; clariion_dev_list[i].vendor; i++) {
-   if (!strncmp(sdev-vendor, clariion_dev_list[i].vendor,
-   strlen(clariion_dev_list[i].vendor)) 
-   !strncmp(sdev-model, clariion_dev_list[i].model,
-   strlen(clariion_dev_list[i].model))) {
-   return true;
-   }
-   }
-   return false;
-}
-
 static struct scsi_dh_data *clariion_bus_attach(struct scsi_device *sdev)
 {
struct clariion_dh_data *h;
@@ -698,7 +670,6 @@ static struct scsi_device_handler clariion_dh = {
.activate   = clariion_activate,
.prep_fn= clariion_prep_fn,
.set_params = clariion_set_params,
-   .match  = clariion_match,
 };
 
 static int __init clariion_init(void)
diff --git a/drivers/scsi/device_handler/scsi_dh_hp_sw.c 
b/drivers/scsi/device_handler/scsi_dh_hp_sw.c
index 485d995..1bf10d3 100644
--- a/drivers/scsi/device_handler/scsi_dh_hp_sw.c
+++ b/drivers/scsi/device_handler/scsi_dh_hp_sw.c
@@ -311,35 +311,6 @@ static int hp_sw_activate(struct scsi_device *sdev,
return 0;
 }
 
-static const struct {
-   char *vendor;
-   char *model;
-} hp_sw_dh_data_list[] = {
-   {COMPAQ, MSA1000 VOLUME},
-   {COMPAQ, HSV110},
-   {HP, HSV100},
-   {DEC, HSG80},
-   {NULL, NULL},
-};
-
-static bool hp_sw_match(struct scsi_device *sdev)
-{
-   int i;
-
-   if (scsi_device_tpgs(sdev))
-   return false;
-
-   for (i = 0; hp_sw_dh_data_list[i].vendor; i++) {
-   if (!strncmp(sdev-vendor, hp_sw_dh_data_list[i].vendor,
-   strlen(hp_sw_dh_data_list[i].vendor)) 
-   !strncmp(sdev-model, hp_sw_dh_data_list[i].model,
-   strlen(hp_sw_dh_data_list[i].model))) {
-   return true;
-   }
-   }
-   return false;
-}
-
 static struct scsi_dh_data *hp_sw_bus_attach(struct scsi_device *sdev)
 {
struct hp_sw_dh_data *h;
@@ -379,7 +350,6 @@ static struct scsi_device_handler hp_sw_dh = {
.detach = hp_sw_bus_detach,
.activate   = hp_sw_activate,
.prep_fn= hp_sw_prep_fn,
-   .match  = hp_sw_match,
 };
 
 static int __init hp_sw_init(void)
diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c 
b/drivers/scsi/device_handler/scsi_dh_rdac.c
index b46ace3..d89616f 100644
--- a/drivers/scsi/device_handler/scsi_dh_rdac.c
+++ b/drivers/scsi/device_handler/scsi_dh_rdac.c
@@ -778,55 +778,6 @@ static int rdac_check_sense(struct scsi_device *sdev,
return SCSI_RETURN_NOT_HANDLED;
 

[PATCH 02/20] scsi_dh_alua: Use vpd_pg83 information

2015-07-08 Thread Hannes Reinecke
The SCSI device now has the VPD page 0x83 information attached,
so there is no need to query it again.

Reviewed-by: Christoph Hellwig h...@lst.de
Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/scsi/device_handler/scsi_dh_alua.c | 83 +-
 1 file changed, 13 insertions(+), 70 deletions(-)

diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
b/drivers/scsi/device_handler/scsi_dh_alua.c
index 7d01ef0..f15b977 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -131,43 +131,6 @@ static struct request *get_alua_req(struct scsi_device 
*sdev,
 }
 
 /*
- * submit_vpd_inquiry - Issue an INQUIRY VPD page 0x83 command
- * @sdev: sdev the command should be sent to
- */
-static int submit_vpd_inquiry(struct scsi_device *sdev, struct alua_dh_data *h)
-{
-   struct request *rq;
-   int err = SCSI_DH_RES_TEMP_UNAVAIL;
-
-   rq = get_alua_req(sdev, h-buff, h-bufflen, READ);
-   if (!rq)
-   goto done;
-
-   /* Prepare the command. */
-   rq-cmd[0] = INQUIRY;
-   rq-cmd[1] = 1;
-   rq-cmd[2] = 0x83;
-   rq-cmd[4] = h-bufflen;
-   rq-cmd_len = COMMAND_SIZE(INQUIRY);
-
-   rq-sense = h-sense;
-   memset(rq-sense, 0, SCSI_SENSE_BUFFERSIZE);
-   rq-sense_len = h-senselen = 0;
-
-   err = blk_execute_rq(rq-q, NULL, rq, 1);
-   if (err == -EIO) {
-   sdev_printk(KERN_INFO, sdev,
-   %s: evpd inquiry failed with %x\n,
-   ALUA_DH_NAME, rq-errors);
-   h-senselen = rq-sense_len;
-   err = SCSI_DH_IO;
-   }
-   blk_put_request(rq);
-done:
-   return err;
-}
-
-/*
  * submit_rtpg - Issue a REPORT TARGET GROUP STATES command
  * @sdev: sdev the command should be sent to
  */
@@ -359,43 +322,24 @@ static int alua_check_tpgs(struct scsi_device *sdev, 
struct alua_dh_data *h)
 }
 
 /*
- * alua_vpd_inquiry - Evaluate INQUIRY vpd page 0x83
+ * alua_check_vpd - Evaluate INQUIRY vpd page 0x83
  * @sdev: device to be checked
  *
  * Extract the relative target port and the target port group
  * descriptor from the list of identificators.
  */
-static int alua_vpd_inquiry(struct scsi_device *sdev, struct alua_dh_data *h)
+static int alua_check_vpd(struct scsi_device *sdev, struct alua_dh_data *h)
 {
-   int len;
-   unsigned err;
unsigned char *d;
 
- retry:
-   err = submit_vpd_inquiry(sdev, h);
-
-   if (err != SCSI_DH_OK)
-   return err;
-
-   /* Check if vpd page exceeds initial buffer */
-   len = (h-buff[2]  8) + h-buff[3] + 4;
-   if (len  h-bufflen) {
-   /* Resubmit with the correct length */
-   if (realloc_buffer(h, len)) {
-   sdev_printk(KERN_WARNING, sdev,
-   %s: kmalloc buffer failed\n,
-   ALUA_DH_NAME);
-   /* Temporary failure, bypass */
-   return SCSI_DH_DEV_TEMP_BUSY;
-   }
-   goto retry;
-   }
+   if (!sdev-vpd_pg83)
+   return SCSI_DH_DEV_UNSUPP;
 
/*
-* Now look for the correct descriptor.
+* Look for the correct descriptor.
 */
-   d = h-buff + 4;
-   while (d  h-buff + len) {
+   d = sdev-vpd_pg83 + 4;
+   while (d  sdev-vpd_pg83 + sdev-vpd_pg83_len) {
switch (d[1]  0xf) {
case 0x4:
/* Relative target port */
@@ -422,14 +366,13 @@ static int alua_vpd_inquiry(struct scsi_device *sdev, 
struct alua_dh_data *h)
ALUA_DH_NAME);
h-state = TPGS_STATE_OPTIMIZED;
h-tpgs = TPGS_MODE_NONE;
-   err = SCSI_DH_DEV_UNSUPP;
-   } else {
-   sdev_printk(KERN_INFO, sdev,
-   %s: port group %02x rel port %02x\n,
-   ALUA_DH_NAME, h-group_id, h-rel_port);
+   return SCSI_DH_DEV_UNSUPP;
}
+   sdev_printk(KERN_INFO, sdev,
+   %s: port group %02x rel port %02x\n,
+   ALUA_DH_NAME, h-group_id, h-rel_port);
 
-   return err;
+   return 0;
 }
 
 static char print_alua_state(int state)
@@ -692,7 +635,7 @@ static int alua_initialize(struct scsi_device *sdev, struct 
alua_dh_data *h)
if (err != SCSI_DH_OK)
goto out;
 
-   err = alua_vpd_inquiry(sdev, h);
+   err = alua_check_vpd(sdev, h);
if (err != SCSI_DH_OK)
goto out;
 
-- 
1.8.5.2

--
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


[PATCHv2 00/20] asynchronous ALUA device handler

2015-07-08 Thread Hannes Reinecke
Hi all,

here is an update to the ALUA device handler. The main
features are:

- Topology discovery: the device handler creates a separate
  port_group structure, which is used to update all paths to
  the same port group. With that we achieve a significant
  reduction of the number of RTPGs.
- Asynchronous state update: The ALUA state is now updated
  from a workqueue item, so all concurrent RTPG calls are
  coaleasced. The ALUA state update is also triggered by
  sense codes indicating an ALUA state change.
- Use the existing vpd page 0x83 to detect device IDs

The patchset is relative to the V3 version of the scsi_dh update.
The entire tree can be found at

kernel/hare/scsi-devel branch alua.v3

on git.kernel.org

As usual, reviews and comments are welcome.

Changes to v1:
  - Split off rtpg workqueue into separate items
  - User per-port workqueues
  - Incorporate review from Bart
  - Incorporate review from hch

Hannes Reinecke (20):
  scsi_dh_alua: Disable ALUA handling for non-disk devices
  scsi_dh_alua: Use vpd_pg83 information
  scsi_dh_alua: improved logging
  scsi_dh_alua: Improve error handling
  scsi: remove scsi_show_sense_hdr()
  scsi_dh_alua: use flag for RTPG extended header
  scsi_dh_alua: Pass buffer as function argument
  scsi_dh_alua: Make stpg synchronous
  scsi_dh_alua: switch to scsi_execute()
  scsi_dh_alua: put sense buffer on stack
  scsi_dh_alua: Use separate alua_port_group structure
  scsi_dh_alua: allocate RTPG buffer separately
  scsi_dh_alua: simplify sense code handling
  scsi_dh_alua: parse target device id
  revert scsi_dh_alua: ALUA hander attach should succeed while TPG is
transitioning
  scsi_dh_alua: Use workqueue for RTPG
  scsi_dh_alua: Recheck state on unit attention
  scsi_dh_alua: update all port states
  scsi_dh_alua: Send TEST UNIT READY to poll for transitioning
  scsi_dh_alua: Update version to 2.0

 drivers/scsi/device_handler/scsi_dh_alua.c | 1231 ++--
 include/scsi/scsi_dbg.h|2 -
 2 files changed, 809 insertions(+), 424 deletions(-)

-- 
1.8.5.2

--
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 07/20] scsi_dh_alua: Pass buffer as function argument

2015-07-08 Thread Hannes Reinecke
Pass in the buffer as a function argument for submit_vpd() and
submit_rtpg().

Reviewed-by: Bart Van Assche bart.vanass...@sandisk.com
Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/scsi/device_handler/scsi_dh_alua.c | 24 +++-
 1 file changed, 11 insertions(+), 13 deletions(-)

diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
b/drivers/scsi/device_handler/scsi_dh_alua.c
index 3f4fe0e..28a3b99 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -22,6 +22,7 @@
 #include linux/slab.h
 #include linux/delay.h
 #include linux/module.h
+#include asm/unaligned.h
 #include scsi/scsi.h
 #include scsi/scsi_dbg.h
 #include scsi/scsi_eh.h
@@ -136,12 +137,13 @@ static struct request *get_alua_req(struct scsi_device 
*sdev,
  * submit_rtpg - Issue a REPORT TARGET GROUP STATES command
  * @sdev: sdev the command should be sent to
  */
-static unsigned submit_rtpg(struct scsi_device *sdev, struct alua_dh_data *h)
+static unsigned submit_rtpg(struct scsi_device *sdev, unsigned char *buff,
+   int bufflen, unsigned char *sense, int flags)
 {
struct request *rq;
int err;
 
-   rq = get_alua_req(sdev, h-buff, h-bufflen, READ);
+   rq = get_alua_req(sdev, buff, bufflen, READ);
if (!rq) {
err = DRIVER_BUSY  24;
goto done;
@@ -149,25 +151,21 @@ static unsigned submit_rtpg(struct scsi_device *sdev, 
struct alua_dh_data *h)
 
/* Prepare the command. */
rq-cmd[0] = MAINTENANCE_IN;
-   if (!(h-flags  ALUA_RTPG_EXT_HDR_UNSUPP))
+   if (!(flags  ALUA_RTPG_EXT_HDR_UNSUPP))
rq-cmd[1] = MI_REPORT_TARGET_PGS | MI_EXT_HDR_PARAM_FMT;
else
rq-cmd[1] = MI_REPORT_TARGET_PGS;
-   rq-cmd[6] = (h-bufflen  24)  0xff;
-   rq-cmd[7] = (h-bufflen  16)  0xff;
-   rq-cmd[8] = (h-bufflen   8)  0xff;
-   rq-cmd[9] = h-bufflen  0xff;
+   put_unaligned_be32(bufflen, rq-cmd[6]);
rq-cmd_len = COMMAND_SIZE(MAINTENANCE_IN);
 
-   rq-sense = h-sense;
+   rq-sense = sense;
memset(rq-sense, 0, SCSI_SENSE_BUFFERSIZE);
-   rq-sense_len = h-senselen = 0;
+   rq-sense_len = 0;
 
blk_execute_rq(rq-q, NULL, rq, 1);
-   if (rq-errors) {
+   if (rq-errors)
err = rq-errors;
-   h-senselen = rq-sense_len;
-   }
+
blk_put_request(rq);
 done:
return err;
@@ -497,7 +495,7 @@ static int alua_rtpg(struct scsi_device *sdev, struct 
alua_dh_data *h, int wait_
expiry = round_jiffies_up(jiffies + h-transition_tmo * HZ);
 
  retry:
-   retval = submit_rtpg(sdev, h);
+   retval = submit_rtpg(sdev, h-buff, h-bufflen, h-sense, h-flags);
 
if (retval) {
if (!scsi_normalize_sense(h-sense, SCSI_SENSE_BUFFERSIZE,
-- 
1.8.5.2

--
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 05/20] scsi: remove scsi_show_sense_hdr()

2015-07-08 Thread Hannes Reinecke
Last caller is gone, so remove it.

Reviewed-by: Bart Van Assche bart.vanass...@sandisk.com
Reviewed-by: Reviewed-by: Christoph Hellwig h...@lst.de
Signed-off-by: Hannes Reinecke h...@suse.de
---
 include/scsi/scsi_dbg.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/include/scsi/scsi_dbg.h b/include/scsi/scsi_dbg.h
index f8170e9..56710e0 100644
--- a/include/scsi/scsi_dbg.h
+++ b/include/scsi/scsi_dbg.h
@@ -12,8 +12,6 @@ extern size_t __scsi_format_command(char *, size_t,
   const unsigned char *, size_t);
 extern void scsi_show_extd_sense(const struct scsi_device *, const char *,
 unsigned char, unsigned char);
-extern void scsi_show_sense_hdr(const struct scsi_device *, const char *,
-   const struct scsi_sense_hdr *);
 extern void scsi_print_sense_hdr(const struct scsi_device *, const char *,
 const struct scsi_sense_hdr *);
 extern void scsi_print_sense(const struct scsi_cmnd *);
-- 
1.8.5.2

--
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 04/20] scsi_dh_alua: Improve error handling

2015-07-08 Thread Hannes Reinecke
Improve error handling and use standard logging functions
instead of hand-crafted ones.

Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/scsi/device_handler/scsi_dh_alua.c | 78 +++---
 1 file changed, 39 insertions(+), 39 deletions(-)

diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
b/drivers/scsi/device_handler/scsi_dh_alua.c
index a20c8bf..0b92319 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -23,6 +23,7 @@
 #include linux/delay.h
 #include linux/module.h
 #include scsi/scsi.h
+#include scsi/scsi_dbg.h
 #include scsi/scsi_eh.h
 #include scsi/scsi_dh.h
 
@@ -138,11 +139,13 @@ static unsigned submit_rtpg(struct scsi_device *sdev, 
struct alua_dh_data *h,
bool rtpg_ext_hdr_req)
 {
struct request *rq;
-   int err = SCSI_DH_RES_TEMP_UNAVAIL;
+   int err;
 
rq = get_alua_req(sdev, h-buff, h-bufflen, READ);
-   if (!rq)
+   if (!rq) {
+   err = DRIVER_BUSY  24;
goto done;
+   }
 
/* Prepare the command. */
rq-cmd[0] = MAINTENANCE_IN;
@@ -160,13 +163,10 @@ static unsigned submit_rtpg(struct scsi_device *sdev, 
struct alua_dh_data *h,
memset(rq-sense, 0, SCSI_SENSE_BUFFERSIZE);
rq-sense_len = h-senselen = 0;
 
-   err = blk_execute_rq(rq-q, NULL, rq, 1);
-   if (err == -EIO) {
-   sdev_printk(KERN_INFO, sdev,
-   %s: rtpg failed with %x\n,
-   ALUA_DH_NAME, rq-errors);
+   blk_execute_rq(rq-q, NULL, rq, 1);
+   if (rq-errors) {
+   err = rq-errors;
h-senselen = rq-sense_len;
-   err = SCSI_DH_IO;
}
blk_put_request(rq);
 done:
@@ -174,13 +174,11 @@ done:
 }
 
 /*
- * alua_stpg - Evaluate SET TARGET GROUP STATES
+ * stpg_endio - Evaluate SET TARGET GROUP STATES
  * @sdev: the device to be evaluated
  * @state: the new target group state
  *
- * Send a SET TARGET GROUP STATES command to the device.
- * We only have to test here if we should resubmit the command;
- * any other error is assumed as a failure.
+ * Evaluate a SET TARGET GROUP STATES command response.
  */
 static void stpg_endio(struct request *req, int error)
 {
@@ -194,22 +192,16 @@ static void stpg_endio(struct request *req, int error)
goto done;
}
 
-   if (req-sense_len  0) {
-   err = scsi_normalize_sense(h-sense, SCSI_SENSE_BUFFERSIZE,
-  sense_hdr);
-   if (!err) {
-   err = SCSI_DH_IO;
-   goto done;
-   }
+   if (scsi_normalize_sense(h-sense, SCSI_SENSE_BUFFERSIZE,
+sense_hdr)) {
err = alua_check_sense(h-sdev, sense_hdr);
if (err == ADD_TO_MLQUEUE) {
err = SCSI_DH_RETRY;
goto done;
}
-   sdev_printk(KERN_INFO, h-sdev,
-   %s: stpg sense code: %02x/%02x/%02x\n,
-   ALUA_DH_NAME, sense_hdr.sense_key,
-   sense_hdr.asc, sense_hdr.ascq);
+   sdev_printk(KERN_INFO, h-sdev, %s: stpg failed\n,
+   ALUA_DH_NAME);
+   scsi_print_sense_hdr(h-sdev, ALUA_DH_NAME, sense_hdr);
err = SCSI_DH_IO;
} else if (error)
err = SCSI_DH_IO;
@@ -494,7 +486,7 @@ static int alua_rtpg(struct scsi_device *sdev, struct 
alua_dh_data *h, int wait_
struct scsi_sense_hdr sense_hdr;
int len, k, off, valid_states = 0;
unsigned char *ucp;
-   unsigned err;
+   unsigned err, retval;
bool rtpg_ext_hdr_req = 1;
unsigned long expiry, interval = 0;
unsigned int tpg_desc_tbl_off;
@@ -506,13 +498,20 @@ static int alua_rtpg(struct scsi_device *sdev, struct 
alua_dh_data *h, int wait_
expiry = round_jiffies_up(jiffies + h-transition_tmo * HZ);
 
  retry:
-   err = submit_rtpg(sdev, h, rtpg_ext_hdr_req);
-
-   if (err == SCSI_DH_IO  h-senselen  0) {
-   err = scsi_normalize_sense(h-sense, SCSI_SENSE_BUFFERSIZE,
-  sense_hdr);
-   if (!err)
-   return SCSI_DH_IO;
+   retval = submit_rtpg(sdev, h, rtpg_ext_hdr_req);
+
+   if (retval) {
+   if (!scsi_normalize_sense(h-sense, SCSI_SENSE_BUFFERSIZE,
+ sense_hdr)) {
+   sdev_printk(KERN_INFO, sdev,
+   %s: rtpg failed, result %d\n,
+   ALUA_DH_NAME, retval);
+   if (driver_byte(retval) == DRIVER_BUSY)
+   err = SCSI_DH_DEV_TEMP_BUSY;
+   else
+   err = 

[PATCH 06/20] scsi_dh_alua: use flag for RTPG extended header

2015-07-08 Thread Hannes Reinecke
We should be using a flag when RTPG extended header is not
supported, that saves us sending RTPG twice for older arrays.

Reviewed-by: Bart Van Assche bart.vanass...@sandisk.com
Reviewed-by: Christoph Hellwig h...@lst.de
Signed-off-by: Hannes Reinecke h...@suse.de
---
 drivers/scsi/device_handler/scsi_dh_alua.c | 15 +++
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c 
b/drivers/scsi/device_handler/scsi_dh_alua.c
index 0b92319..3f4fe0e 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -59,8 +59,9 @@
 #define ALUA_FAILOVER_TIMEOUT  60
 #define ALUA_FAILOVER_RETRIES  5
 
-/* flags passed from user level */
+/* device handler flags */
 #define ALUA_OPTIMIZE_STPG 1
+#define ALUA_RTPG_EXT_HDR_UNSUPP   2
 
 struct alua_dh_data {
int group_id;
@@ -135,8 +136,7 @@ static struct request *get_alua_req(struct scsi_device 
*sdev,
  * submit_rtpg - Issue a REPORT TARGET GROUP STATES command
  * @sdev: sdev the command should be sent to
  */
-static unsigned submit_rtpg(struct scsi_device *sdev, struct alua_dh_data *h,
-   bool rtpg_ext_hdr_req)
+static unsigned submit_rtpg(struct scsi_device *sdev, struct alua_dh_data *h)
 {
struct request *rq;
int err;
@@ -149,7 +149,7 @@ static unsigned submit_rtpg(struct scsi_device *sdev, 
struct alua_dh_data *h,
 
/* Prepare the command. */
rq-cmd[0] = MAINTENANCE_IN;
-   if (rtpg_ext_hdr_req)
+   if (!(h-flags  ALUA_RTPG_EXT_HDR_UNSUPP))
rq-cmd[1] = MI_REPORT_TARGET_PGS | MI_EXT_HDR_PARAM_FMT;
else
rq-cmd[1] = MI_REPORT_TARGET_PGS;
@@ -487,7 +487,6 @@ static int alua_rtpg(struct scsi_device *sdev, struct 
alua_dh_data *h, int wait_
int len, k, off, valid_states = 0;
unsigned char *ucp;
unsigned err, retval;
-   bool rtpg_ext_hdr_req = 1;
unsigned long expiry, interval = 0;
unsigned int tpg_desc_tbl_off;
unsigned char orig_transition_tmo;
@@ -498,7 +497,7 @@ static int alua_rtpg(struct scsi_device *sdev, struct 
alua_dh_data *h, int wait_
expiry = round_jiffies_up(jiffies + h-transition_tmo * HZ);
 
  retry:
-   retval = submit_rtpg(sdev, h, rtpg_ext_hdr_req);
+   retval = submit_rtpg(sdev, h);
 
if (retval) {
if (!scsi_normalize_sense(h-sense, SCSI_SENSE_BUFFERSIZE,
@@ -521,10 +520,10 @@ static int alua_rtpg(struct scsi_device *sdev, struct 
alua_dh_data *h, int wait_
 * The retry without rtpg_ext_hdr_req set
 * handles this.
 */
-   if (rtpg_ext_hdr_req == 1 
+   if (!(h-flags  ALUA_RTPG_EXT_HDR_UNSUPP) 
sense_hdr.sense_key == ILLEGAL_REQUEST 
sense_hdr.asc == 0x24  sense_hdr.ascq == 0) {
-   rtpg_ext_hdr_req = 0;
+   h-flags |= ALUA_RTPG_EXT_HDR_UNSUPP;
goto retry;
}
 
-- 
1.8.5.2

--
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 2/3] megaraid_sas : use dev_printk when possible

2015-07-08 Thread Bjorn Helgaas
On Wed, Jul 8, 2015 at 5:47 AM, Hannes Reinecke h...@suse.de wrote:
 On 07/07/2015 10:52 PM, Bjorn Helgaas wrote:
 Use dev_printk() when possible to make messages more useful.

 Signed-off-by: Bjorn Helgaas bhelg...@google.com
 ---
  drivers/scsi/megaraid/megaraid_sas_base.c   |  304 
 +--
  drivers/scsi/megaraid/megaraid_sas_fusion.c |   95 
  2 files changed, 196 insertions(+), 203 deletions(-)

 [ .. ]
 @@ -1873,8 +1872,8 @@ static int megasas_get_ld_vf_affiliation_111(struct 
 megasas_instance *instance,
   cmd = megasas_get_cmd(instance);

   if (!cmd) {
 - printk(KERN_DEBUG megasas: megasas_get_ld_vf_affiliation_111:
 -Failed to get cmd for scsi%d.\n,
 + dev_printk(KERN_DEBUG, instance-pdev-dev, 
 megasas_get_ld_vf_affiliation_111:
 +Failed to get cmd for scsi%d\n,
   instance-host-host_no);
   return -ENOMEM;
   }
 Makes one wonder why we don't have a 'dev_debug'; dev_notice() and
 dev_warn() are there ...

There actually is a 'dev_dbg()' but when CONFIG_DYNAMIC_DEBUG is set,
I think dev_dbg() generates no output by default.  So to preserve the
previous behavior of this message always appears in the dmesg log no
matter what the dynamic debug setting, I used dev_printk(KERN_DEBUG).

Somebody who maintains these drivers could probably go through and
convert these to either dev_info() or dev_dbg() depending on what they
need.  That would require more judgment than I wanted to get into :)

Thanks for taking a look at these!

Bjorn
--
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 5/5] target: Fix wrong setting of sense format for PI errors

2015-07-08 Thread Sagi Grimberg

On 7/8/2015 2:14 PM, Sagi Grimberg wrote:


And it's actually not true that you'd need descriptor sense to
encode the sector information; it'll be stored in the 'information'
section (byte 3-6) for fixed format sense.


But when I return the sector info in a fixed size format, the initiator
is not able to decode the faulty sector:

kernel: DIFv1 Type 1 reference failed on sector: 15 tag: 0xfff0
sector MSB: 0x000f
kernel: sd 10:0:1:0: [sdc] tag#0 FAILED Result: hostbyte=DID_OK
driverbyte=DRIVER_SENSE
kernel: sd 10:0:1:0: [sdc] tag#0 Sense Key : Aborted Command [current]
kernel: sd 10:0:1:0: [sdc] tag#0 Add. Sense: No additional sense
information
kernel: sd 10:0:1:0: [sdc] tag#0 CDB: Read(10) 28 20 00 00 00 00 00 00
10 00
kernel: blk_update_request: I/O error, dev sdc, sector 0

Is that a bug?


Bleh, found the bug... It was in scsi_set_sense_information()

For Fixed sized sense the information field is 4 bytes so this fixes it:
diff --git a/drivers/scsi/scsi_common.c b/drivers/scsi/scsi_common.c
index 41432c1..8cfb7ee 100644
--- a/drivers/scsi/scsi_common.c
+++ b/drivers/scsi/scsi_common.c
@@ -270,7 +270,7 @@ void scsi_set_sense_information(u8 *buf, u64 info)
put_unaligned_be64(info, ucp[4]);
} else if ((buf[0]  0x7f) == 0x70) {
buf[0] |= 0x80;
-   put_unaligned_be64(info, buf[3]);
+ put_unaligned_be32(info, buf[3]);
}
 }
 EXPORT_SYMBOL(scsi_set_sense_information);

I'll send out a separate patch.

Thanks Hannes and Christoph for catching this.

Sagi.
--
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 v4 4/5] target: Use scsi helpers to build the sense data correctly

2015-07-08 Thread Sagi Grimberg
Instead of open coding the sense buffer construction, use
scsi scsi_build_sense_buffer() and scsi_set_sense_information()
helpers which moved to scsi_common.

Signed-off-by: Sagi Grimberg sa...@mellanox.com
Reviewed-by: Christoph Hellwig h...@lst.de
---
 drivers/target/target_core_spc.c   | 31 +--
 drivers/target/target_core_transport.c | 21 -
 2 files changed, 9 insertions(+), 43 deletions(-)

diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c
index b074443..c43dcbf 100644
--- a/drivers/target/target_core_spc.c
+++ b/drivers/target/target_core_spc.c
@@ -1157,32 +1157,11 @@ static sense_reason_t spc_emulate_request_sense(struct 
se_cmd *cmd)
if (!rbuf)
return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
 
-   if (!core_scsi3_ua_clear_for_request_sense(cmd, ua_asc, ua_ascq)) {
-   /*
-* CURRENT ERROR, UNIT ATTENTION
-*/
-   buf[0] = 0x70;
-   buf[SPC_SENSE_KEY_OFFSET] = UNIT_ATTENTION;
-
-   /*
-* The Additional Sense Code (ASC) from the UNIT ATTENTION
-*/
-   buf[SPC_ASC_KEY_OFFSET] = ua_asc;
-   buf[SPC_ASCQ_KEY_OFFSET] = ua_ascq;
-   buf[7] = 0x0A;
-   } else {
-   /*
-* CURRENT ERROR, NO SENSE
-*/
-   buf[0] = 0x70;
-   buf[SPC_SENSE_KEY_OFFSET] = NO_SENSE;
-
-   /*
-* NO ADDITIONAL SENSE INFORMATION
-*/
-   buf[SPC_ASC_KEY_OFFSET] = 0x00;
-   buf[7] = 0x0A;
-   }
+   if (!core_scsi3_ua_clear_for_request_sense(cmd, ua_asc, ua_ascq))
+   scsi_build_sense_buffer(0, buf, UNIT_ATTENTION,
+   ua_asc, ua_ascq);
+   else
+   scsi_build_sense_buffer(0, buf, NO_SENSE, 0x0, 0x0);
 
memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd-data_length));
transport_kunmap_data_sg(cmd);
diff --git a/drivers/target/target_core_transport.c 
b/drivers/target/target_core_transport.c
index 31373f3..923e69d 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -38,6 +38,7 @@
 #include net/sock.h
 #include net/tcp.h
 #include scsi/scsi_proto.h
+#include scsi/scsi_common.h
 
 #include target/target_core_base.h
 #include target/target_core_backend.h
@@ -2620,19 +2621,6 @@ bool transport_wait_for_tasks(struct se_cmd *cmd)
 }
 EXPORT_SYMBOL(transport_wait_for_tasks);
 
-static
-void transport_err_sector_info(unsigned char *buffer, sector_t bad_sector)
-{
-   /* Place failed LBA in sense data information descriptor 0. */
-   buffer[SPC_ADD_SENSE_LEN_OFFSET] = 0xc;
-   buffer[SPC_DESC_TYPE_OFFSET] = 0; /* Information */
-   buffer[SPC_ADDITIONAL_DESC_LEN_OFFSET] = 0xa;
-   buffer[SPC_VALIDITY_OFFSET] = 0x80;
-
-   /* Descriptor Information: failing sector */
-   put_unaligned_be64(bad_sector, buffer[12]);
-}
-
 struct sense_info {
u8 key;
u8 asc;
@@ -2759,7 +2747,6 @@ static void translate_sense_reason(struct se_cmd *cmd, 
sense_reason_t reason)
si = sense_info_table[(__force int)
   TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE];
 
-   buffer[SPC_SENSE_KEY_OFFSET] = si-key;
if (reason == TCM_CHECK_CONDITION_UNIT_ATTENTION) {
core_scsi3_ua_for_check_condition(cmd, asc, ascq);
WARN_ON_ONCE(asc == 0);
@@ -2771,10 +2758,10 @@ static void translate_sense_reason(struct se_cmd *cmd, 
sense_reason_t reason)
asc = si-asc;
ascq = si-ascq;
}
-   buffer[SPC_ASC_KEY_OFFSET] = asc;
-   buffer[SPC_ASCQ_KEY_OFFSET] = ascq;
+
+   scsi_build_sense_buffer(0, buffer, si-key, asc, ascq);
if (si-add_sector_info)
-   transport_err_sector_info(cmd-sense_buffer, cmd-bad_sector);
+   scsi_set_sense_information(buffer, cmd-bad_sector);
 }
 
 int
-- 
1.8.4.3

--
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 v4 4/5] target: Use scsi helpers to build the sense data correctly

2015-07-08 Thread Hannes Reinecke
On 07/08/2015 04:58 PM, Sagi Grimberg wrote:
 Instead of open coding the sense buffer construction, use
 scsi scsi_build_sense_buffer() and scsi_set_sense_information()
 helpers which moved to scsi_common.
 
 Signed-off-by: Sagi Grimberg sa...@mellanox.com
 Reviewed-by: Christoph Hellwig h...@lst.de
 ---
  drivers/target/target_core_spc.c   | 31 +--
  drivers/target/target_core_transport.c | 21 -
  2 files changed, 9 insertions(+), 43 deletions(-)
 
Reviewed-by: Hannes Reinecke h...@suse.de

Cheers,

Hannes
-- 
Dr. Hannes ReineckezSeries  Storage
h...@suse.de   +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)
--
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 v4 5/5] target: Return ABORTED_COMMAND sense key for PI errors

2015-07-08 Thread Sagi Grimberg
PI errors were reported with ILLEGAL_REQUEST sense key but
there was actually no problem with the request. Target
detected PI errors should be reported with aborted command
sense key.

Signed-off-by: Sagi Grimberg sa...@mellanox.com
---
 drivers/target/target_core_transport.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/target/target_core_transport.c 
b/drivers/target/target_core_transport.c
index 923e69d..1847fdc 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -2705,19 +2705,19 @@ static const struct sense_info sense_info_table[] = {
.ascq = 0x00,
},
[TCM_LOGICAL_BLOCK_GUARD_CHECK_FAILED] = {
-   .key = ILLEGAL_REQUEST,
+   .key = ABORTED_COMMAND,
.asc = 0x10,
.ascq = 0x01, /* LOGICAL BLOCK GUARD CHECK FAILED */
.add_sector_info = true,
},
[TCM_LOGICAL_BLOCK_APP_TAG_CHECK_FAILED] = {
-   .key = ILLEGAL_REQUEST,
+   .key = ABORTED_COMMAND,
.asc = 0x10,
.ascq = 0x02, /* LOGICAL BLOCK APPLICATION TAG CHECK FAILED */
.add_sector_info = true,
},
[TCM_LOGICAL_BLOCK_REF_TAG_CHECK_FAILED] = {
-   .key = ILLEGAL_REQUEST,
+   .key = ABORTED_COMMAND,
.asc = 0x10,
.ascq = 0x03, /* LOGICAL BLOCK REFERENCE TAG CHECK FAILED */
.add_sector_info = true,
-- 
1.8.4.3

--
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 v4 3/5] scsi: Move sense handling routines to scsi_common

2015-07-08 Thread Sagi Grimberg
Sense data handling is also done in the target stack.
Hence, move sense handling routines to scsi_common so
the target will be able to use them as well.

Signed-off-by: Sagi Grimberg sa...@mellanox.com
Reviewed-by: Bart Van Assche bart.vanass...@sandisk.com
Reviewed-by: Christoph Hellwig h...@lst.de
---
 drivers/scsi/scsi_common.c | 98 +
 drivers/scsi/scsi_error.c  | 99 +-
 include/scsi/scsi_common.h |  5 +++
 include/scsi/scsi_eh.h |  7 +---
 4 files changed, 105 insertions(+), 104 deletions(-)

diff --git a/drivers/scsi/scsi_common.c b/drivers/scsi/scsi_common.c
index 2ff0922..41432c1 100644
--- a/drivers/scsi/scsi_common.c
+++ b/drivers/scsi/scsi_common.c
@@ -5,6 +5,7 @@
 #include linux/bug.h
 #include linux/kernel.h
 #include linux/string.h
+#include asm/unaligned.h
 #include scsi/scsi_common.h
 
 /* NB: These are exposed through /proc/scsi/scsi and form part of the ABI.
@@ -176,3 +177,100 @@ bool scsi_normalize_sense(const u8 *sense_buffer, int 
sb_len,
return true;
 }
 EXPORT_SYMBOL(scsi_normalize_sense);
+
+/**
+ * scsi_sense_desc_find - search for a given descriptor type in
descriptor sense data format.
+ * @sense_buffer:  byte array of descriptor format sense data
+ * @sb_len:number of valid bytes in sense_buffer
+ * @desc_type: value of descriptor type to find
+ * (e.g. 0 - information)
+ *
+ * Notes:
+ * only valid when sense data is in descriptor format
+ *
+ * Return value:
+ * pointer to start of (first) descriptor if found else NULL
+ */
+const u8 * scsi_sense_desc_find(const u8 * sense_buffer, int sb_len,
+   int desc_type)
+{
+   int add_sen_len, add_len, desc_len, k;
+   const u8 * descp;
+
+   if ((sb_len  8) || (0 == (add_sen_len = sense_buffer[7])))
+   return NULL;
+   if ((sense_buffer[0]  0x72) || (sense_buffer[0]  0x73))
+   return NULL;
+   add_sen_len = (add_sen_len  (sb_len - 8)) ?
+   add_sen_len : (sb_len - 8);
+   descp = sense_buffer[8];
+   for (desc_len = 0, k = 0; k  add_sen_len; k += desc_len) {
+   descp += desc_len;
+   add_len = (k  (add_sen_len - 1)) ? descp[1]: -1;
+   desc_len = add_len + 2;
+   if (descp[0] == desc_type)
+   return descp;
+   if (add_len  0) // short descriptor ??
+   break;
+   }
+   return NULL;
+}
+EXPORT_SYMBOL(scsi_sense_desc_find);
+
+/**
+ * scsi_build_sense_buffer - build sense data in a buffer
+ * @desc:  Sense format (non zero == descriptor format,
+ *  0 == fixed format)
+ * @buf:   Where to build sense data
+ * @key:   Sense key
+ * @asc:   Additional sense code
+ * @ascq:  Additional sense code qualifier
+ *
+ **/
+void scsi_build_sense_buffer(int desc, u8 *buf, u8 key, u8 asc, u8 ascq)
+{
+   if (desc) {
+   buf[0] = 0x72;  /* descriptor, current */
+   buf[1] = key;
+   buf[2] = asc;
+   buf[3] = ascq;
+   buf[7] = 0;
+   } else {
+   buf[0] = 0x70;  /* fixed, current */
+   buf[2] = key;
+   buf[7] = 0xa;
+   buf[12] = asc;
+   buf[13] = ascq;
+   }
+}
+EXPORT_SYMBOL(scsi_build_sense_buffer);
+
+/**
+ * scsi_set_sense_information - set the information field in a
+ * formatted sense data buffer
+ * @buf:   Where to build sense data
+ * @info:  64-bit information value to be set
+ *
+ **/
+void scsi_set_sense_information(u8 *buf, u64 info)
+{
+   if ((buf[0]  0x7f) == 0x72) {
+   u8 *ucp, len;
+
+   len = buf[7];
+   ucp = (char *)scsi_sense_desc_find(buf, len + 8, 0);
+   if (!ucp) {
+   buf[7] = len + 0xa;
+   ucp = buf + 8 + len;
+   }
+   ucp[0] = 0;
+   ucp[1] = 0xa;
+   ucp[2] = 0x80; /* Valid bit */
+   ucp[3] = 0;
+   put_unaligned_be64(info, ucp[4]);
+   } else if ((buf[0]  0x7f) == 0x70) {
+   buf[0] |= 0x80;
+   put_unaligned_be64(info, buf[3]);
+   }
+}
+EXPORT_SYMBOL(scsi_set_sense_information);
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 106884a..6e6b2d2 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -26,7 +26,6 @@
 #include linux/blkdev.h
 #include linux/delay.h
 #include linux/jiffies.h
-#include asm/unaligned.h
 
 #include scsi/scsi.h
 #include scsi/scsi_cmnd.h
@@ -34,6 +33,7 @@
 #include scsi/scsi_device.h
 #include scsi/scsi_driver.h
 #include scsi/scsi_eh.h
+#include scsi/scsi_common.h
 #include scsi/scsi_transport.h
 #include scsi/scsi_host.h
 #include scsi/scsi_ioctl.h
@@ -2408,45 +2408,6 @@ bool 

[PATCH] lpfc: Destroy lpfc_hba_index IDR on module exit

2015-07-08 Thread Johannes Thumshirn
Destroy lpfc_hba_index IDR on module exit, reclaiming the allocated memory.

This was detected by the following semantic patch (written by Luis Rodriguez
mcg...@suse.com)
SmPL
@ defines_module_init @
declarer name module_init, module_exit;
declarer name DEFINE_IDR;
identifier init;
@@

module_init(init);

@ defines_module_exit @
identifier exit;
@@

module_exit(exit);

@ declares_idr depends on defines_module_init  defines_module_exit @
identifier idr;
@@

DEFINE_IDR(idr);

@ on_exit_calls_destroy depends on declares_idr  defines_module_exit @
identifier declares_idr.idr, defines_module_exit.exit;
@@

exit(void)
{
 ...
 idr_destroy(idr);
 ...
}

@ missing_module_idr_destroy depends on declares_idr  defines_module_exit  
!on_exit_calls_destroy @
identifier declares_idr.idr, defines_module_exit.exit;
@@

exit(void)
{
 ...
 +idr_destroy(idr);
}
/SmPL

Signed-off-by: Johannes Thumshirn jthumsh...@suse.de
---
 drivers/scsi/lpfc/lpfc_init.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index f962118..4bedb06 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -11477,6 +11477,7 @@ lpfc_exit(void)
free_pages((unsigned long)_dump_buf_dif, _dump_buf_dif_order);
}
kfree(lpfc_used_cpu);
+   idr_destroy(lpfc_hba_index);
 }
 
 module_init(lpfc_init);
-- 
2.4.3

--
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 v4 3/5] scsi: Move sense handling routines to scsi_common

2015-07-08 Thread Sagi Grimberg

On 7/8/2015 6:06 PM, Hannes Reinecke wrote:


We're adding extra fields here, so we need to make sure to not
overflow the buffer. You probably have to pass in the buffersize
to avoid an overflow ...
Yeah, I know, it's theoretical at the moment.
But there's nothing which prevents anyone to add other fields to it,
so this field might be the one causing the overflow.


Since this patch is simply a movement of functions I don't think I
should change any functionality here. Would it be acceptable to fix
this in an incremental 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


[PATCH] st: Destroy st_index_idr on module exit

2015-07-08 Thread Johannes Thumshirn
Destroy st_index_idr on module exit, reclaiming the allocated memory.

This was detected by the following semantic patch (written by Luis Rodriguez
mcg...@suse.com)
SmPL
@ defines_module_init @
declarer name module_init, module_exit;
declarer name DEFINE_IDR;
identifier init;
@@

module_init(init);

@ defines_module_exit @
identifier exit;
@@

module_exit(exit);

@ declares_idr depends on defines_module_init  defines_module_exit @
identifier idr;
@@

DEFINE_IDR(idr);

@ on_exit_calls_destroy depends on declares_idr  defines_module_exit @
identifier declares_idr.idr, defines_module_exit.exit;
@@

exit(void)
{
 ...
 idr_destroy(idr);
 ...
}

@ missing_module_idr_destroy depends on declares_idr  defines_module_exit  
!on_exit_calls_destroy @
identifier declares_idr.idr, defines_module_exit.exit;
@@

exit(void)
{
 ...
 +idr_destroy(idr);
}
/SmPL

Signed-off-by: Johannes Thumshirn jthumsh...@suse.de
---
 drivers/scsi/st.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 3f25b8f..79ac024 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -4427,6 +4427,7 @@ static void __exit exit_st(void)
unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
 ST_MAX_TAPE_ENTRIES);
class_unregister(st_sysfs_class);
+   idr_destroy(st_index_idr);
printk(KERN_INFO st: Unloaded.\n);
 }
 
-- 
2.4.3

--
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 v4 3/5] scsi: Move sense handling routines to scsi_common

2015-07-08 Thread Hannes Reinecke
On 07/08/2015 04:58 PM, Sagi Grimberg wrote:
 Sense data handling is also done in the target stack.
 Hence, move sense handling routines to scsi_common so
 the target will be able to use them as well.
 
 Signed-off-by: Sagi Grimberg sa...@mellanox.com
 Reviewed-by: Bart Van Assche bart.vanass...@sandisk.com
 Reviewed-by: Christoph Hellwig h...@lst.de
 ---
  drivers/scsi/scsi_common.c | 98 +
  drivers/scsi/scsi_error.c  | 99 
 +-
  include/scsi/scsi_common.h |  5 +++
  include/scsi/scsi_eh.h |  7 +---
  4 files changed, 105 insertions(+), 104 deletions(-)
 
 diff --git a/drivers/scsi/scsi_common.c b/drivers/scsi/scsi_common.c
 index 2ff0922..41432c1 100644
 --- a/drivers/scsi/scsi_common.c
 +++ b/drivers/scsi/scsi_common.c
 @@ -5,6 +5,7 @@
  #include linux/bug.h
  #include linux/kernel.h
  #include linux/string.h
 +#include asm/unaligned.h
  #include scsi/scsi_common.h
  
  /* NB: These are exposed through /proc/scsi/scsi and form part of the ABI.
 @@ -176,3 +177,100 @@ bool scsi_normalize_sense(const u8 *sense_buffer, int 
 sb_len,
   return true;
  }
  EXPORT_SYMBOL(scsi_normalize_sense);
 +
 +/**
 + * scsi_sense_desc_find - search for a given descriptor type in  
 descriptor sense data format.
 + * @sense_buffer:byte array of descriptor format sense data
 + * @sb_len:  number of valid bytes in sense_buffer
 + * @desc_type:   value of descriptor type to find
 + *   (e.g. 0 - information)
 + *
 + * Notes:
 + *   only valid when sense data is in descriptor format
 + *
 + * Return value:
 + *   pointer to start of (first) descriptor if found else NULL
 + */
 +const u8 * scsi_sense_desc_find(const u8 * sense_buffer, int sb_len,
 + int desc_type)
 +{
 + int add_sen_len, add_len, desc_len, k;
 + const u8 * descp;
 +
 + if ((sb_len  8) || (0 == (add_sen_len = sense_buffer[7])))
 + return NULL;
 + if ((sense_buffer[0]  0x72) || (sense_buffer[0]  0x73))
 + return NULL;
 + add_sen_len = (add_sen_len  (sb_len - 8)) ?
 + add_sen_len : (sb_len - 8);
 + descp = sense_buffer[8];
 + for (desc_len = 0, k = 0; k  add_sen_len; k += desc_len) {
 + descp += desc_len;
 + add_len = (k  (add_sen_len - 1)) ? descp[1]: -1;
 + desc_len = add_len + 2;
 + if (descp[0] == desc_type)
 + return descp;
 + if (add_len  0) // short descriptor ??
 + break;
 + }
 + return NULL;
 +}
 +EXPORT_SYMBOL(scsi_sense_desc_find);
 +
 +/**
 + * scsi_build_sense_buffer - build sense data in a buffer
 + * @desc:Sense format (non zero == descriptor format,
 + *  0 == fixed format)
 + * @buf: Where to build sense data
 + * @key: Sense key
 + * @asc: Additional sense code
 + * @ascq:Additional sense code qualifier
 + *
 + **/
 +void scsi_build_sense_buffer(int desc, u8 *buf, u8 key, u8 asc, u8 ascq)
 +{
 + if (desc) {
 + buf[0] = 0x72;  /* descriptor, current */
 + buf[1] = key;
 + buf[2] = asc;
 + buf[3] = ascq;
 + buf[7] = 0;
 + } else {
 + buf[0] = 0x70;  /* fixed, current */
 + buf[2] = key;
 + buf[7] = 0xa;
 + buf[12] = asc;
 + buf[13] = ascq;
 + }
 +}
 +EXPORT_SYMBOL(scsi_build_sense_buffer);
 +
 +/**
 + * scsi_set_sense_information - set the information field in a
 + *   formatted sense data buffer
 + * @buf: Where to build sense data
 + * @info:64-bit information value to be set
 + *
 + **/
 +void scsi_set_sense_information(u8 *buf, u64 info)
 +{
 + if ((buf[0]  0x7f) == 0x72) {
 + u8 *ucp, len;
 +
 + len = buf[7];
 + ucp = (char *)scsi_sense_desc_find(buf, len + 8, 0);
 + if (!ucp) {
 + buf[7] = len + 0xa;
 + ucp = buf + 8 + len;
 + }
We're adding extra fields here, so we need to make sure to not
overflow the buffer. You probably have to pass in the buffersize
to avoid an overflow ...
Yeah, I know, it's theoretical at the moment.
But there's nothing which prevents anyone to add other fields to it,
so this field might be the one causing the overflow.

Cheers,

Hannes
-- 
Dr. Hannes ReineckezSeries  Storage
h...@suse.de   +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)
--
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 v4 0/5] Target sense data handling modifications

2015-07-08 Thread Sagi Grimberg
This patch set modifies the target sense data handling.
First, cleanup transport_send_check_condition_and_sense()
by splitting the sense translation to a separate function.
Second, convert sense reason the switch statement to a table
driven code. Third, Use scsi common helpers to correctly set
the sense buffer. Last, Fix sense key wrong setting of t10-pi
errors.

Changes from v2:
- Removed wrong patch 5/5 for descriptor format sense data
- Added a patch (5/5) that fixes wrong sense key for PI errors
- Incorporate hch's comments
- Added Reviewed-by tags

Changes from v2:
- Pass sense_reason_t to scsi_translate_sense()
- Split patch 3:
  1) move the helpers to scsi_common.c
  2) use helpers in the target code
  3) always use descriptor-type sense data for PI errors

Changes from v1:
- Added Reviewed-by tags for patches 1,2
- Fixed compilation error after testing patch #3 on scsi/for-next
  branch. Moved scsi_sense_desc_find() to scsi_common as well (dependency)
  and also moved asm/unaligned.h include to scsi_common.h

Changes from v0:
- Added Bart's patches and converted my patch to apply over his
- Moved scsi sense helpers to scsi_common

Bart Van Assche (2):
  target: Inline transport_get_sense_codes()
  target: Split transport_send_check_condition_and_sense()

Sagi Grimberg (3):
  scsi: Move sense handling routines to scsi_common
  target: Use scsi helpers to build the sense data correctly
  target: Return ABORTED_COMMAND sense key for PI errors

 drivers/scsi/scsi_common.c |  98 
 drivers/scsi/scsi_error.c  |  99 +
 drivers/target/target_core_spc.c   |  31 +--
 drivers/target/target_core_transport.c | 396 -
 include/scsi/scsi_common.h |   5 +
 include/scsi/scsi_eh.h |   7 +-
 6 files changed, 252 insertions(+), 384 deletions(-)

-- 
1.8.4.3

--
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 v4 1/5] target: Inline transport_get_sense_codes()

2015-07-08 Thread Sagi Grimberg
From: Bart Van Assche bart.vanass...@sandisk.com

Inline this function in its call site since it performs a trivial
task and since it is only called once.

Signed-off-by: Bart Van Assche bart.vanass...@sandisk.com
Signed-off-by: Sagi Grimberg sa...@mellanox.com
Reviewed-by: Hannes Reinecke h...@suse.de
Reviewed-by: Christoph Hellwig h...@lst.de
---
 drivers/target/target_core_transport.c | 16 ++--
 1 file changed, 2 insertions(+), 14 deletions(-)

diff --git a/drivers/target/target_core_transport.c 
b/drivers/target/target_core_transport.c
index 1bc8378..e895156 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -2620,17 +2620,6 @@ bool transport_wait_for_tasks(struct se_cmd *cmd)
 }
 EXPORT_SYMBOL(transport_wait_for_tasks);
 
-static int transport_get_sense_codes(
-   struct se_cmd *cmd,
-   u8 *asc,
-   u8 *ascq)
-{
-   *asc = cmd-scsi_asc;
-   *ascq = cmd-scsi_ascq;
-
-   return 0;
-}
-
 static
 void transport_err_sector_info(unsigned char *buffer, sector_t bad_sector)
 {
@@ -2824,9 +2813,8 @@ transport_send_check_condition_and_sense(struct se_cmd 
*cmd,
buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* Not Ready */
buffer[SPC_SENSE_KEY_OFFSET] = NOT_READY;
-   transport_get_sense_codes(cmd, asc, ascq);
-   buffer[SPC_ASC_KEY_OFFSET] = asc;
-   buffer[SPC_ASCQ_KEY_OFFSET] = ascq;
+   buffer[SPC_ASC_KEY_OFFSET] = cmd-scsi_asc;
+   buffer[SPC_ASCQ_KEY_OFFSET] = cmd-scsi_ascq;
break;
case TCM_MISCOMPARE_VERIFY:
/* CURRENT ERROR */
-- 
1.8.4.3

--
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 v4 2/5] target: Split transport_send_check_condition_and_sense()

2015-07-08 Thread Sagi Grimberg
From: Bart Van Assche bart.vanass...@sandisk.com

Move the code for translating a sense_reason_t code into a SCSI status
ASC and ASCQ codes from transport_send_check_condition_and_sense() into
the new function translate_sense_reason(). Convert the switch statement
that performs the translation into table-driven code.

Signed-off-by: Bart Van Assche bart.vanass...@sandisk.com
Signed-off-by: Sagi Grimberg sa...@mellanox.com
Reviewed-by: Hannes Reinecke h...@suse.de
Reviewed-by: Christoph Hellwig h...@lst.de
---
 drivers/target/target_core_transport.c | 383 +
 1 file changed, 148 insertions(+), 235 deletions(-)

diff --git a/drivers/target/target_core_transport.c 
b/drivers/target/target_core_transport.c
index e895156..31373f3 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -2633,13 +2633,155 @@ void transport_err_sector_info(unsigned char *buffer, 
sector_t bad_sector)
put_unaligned_be64(bad_sector, buffer[12]);
 }
 
+struct sense_info {
+   u8 key;
+   u8 asc;
+   u8 ascq;
+   bool add_sector_info;
+};
+
+static const struct sense_info sense_info_table[] = {
+   [TCM_NO_SENSE] = {
+   .key = NOT_READY
+   },
+   [TCM_NON_EXISTENT_LUN] = {
+   .key = ILLEGAL_REQUEST,
+   .asc = 0x25 /* LOGICAL UNIT NOT SUPPORTED */
+   },
+   [TCM_UNSUPPORTED_SCSI_OPCODE] = {
+   .key = ILLEGAL_REQUEST,
+   .asc = 0x20, /* INVALID COMMAND OPERATION CODE */
+   },
+   [TCM_SECTOR_COUNT_TOO_MANY] = {
+   .key = ILLEGAL_REQUEST,
+   .asc = 0x20, /* INVALID COMMAND OPERATION CODE */
+   },
+   [TCM_UNKNOWN_MODE_PAGE] = {
+   .key = ILLEGAL_REQUEST,
+   .asc = 0x24, /* INVALID FIELD IN CDB */
+   },
+   [TCM_CHECK_CONDITION_ABORT_CMD] = {
+   .key = ABORTED_COMMAND,
+   .asc = 0x29, /* BUS DEVICE RESET FUNCTION OCCURRED */
+   .ascq = 0x03,
+   },
+   [TCM_INCORRECT_AMOUNT_OF_DATA] = {
+   .key = ABORTED_COMMAND,
+   .asc = 0x0c, /* WRITE ERROR */
+   .ascq = 0x0d, /* NOT ENOUGH UNSOLICITED DATA */
+   },
+   [TCM_INVALID_CDB_FIELD] = {
+   .key = ILLEGAL_REQUEST,
+   .asc = 0x24, /* INVALID FIELD IN CDB */
+   },
+   [TCM_INVALID_PARAMETER_LIST] = {
+   .key = ILLEGAL_REQUEST,
+   .asc = 0x26, /* INVALID FIELD IN PARAMETER LIST */
+   },
+   [TCM_PARAMETER_LIST_LENGTH_ERROR] = {
+   .key = ILLEGAL_REQUEST,
+   .asc = 0x1a, /* PARAMETER LIST LENGTH ERROR */
+   },
+   [TCM_UNEXPECTED_UNSOLICITED_DATA] = {
+   .key = ILLEGAL_REQUEST,
+   .asc = 0x0c, /* WRITE ERROR */
+   .ascq = 0x0c, /* UNEXPECTED_UNSOLICITED_DATA */
+   },
+   [TCM_SERVICE_CRC_ERROR] = {
+   .key = ABORTED_COMMAND,
+   .asc = 0x47, /* PROTOCOL SERVICE CRC ERROR */
+   .ascq = 0x05, /* N/A */
+   },
+   [TCM_SNACK_REJECTED] = {
+   .key = ABORTED_COMMAND,
+   .asc = 0x11, /* READ ERROR */
+   .ascq = 0x13, /* FAILED RETRANSMISSION REQUEST */
+   },
+   [TCM_WRITE_PROTECTED] = {
+   .key = DATA_PROTECT,
+   .asc = 0x27, /* WRITE PROTECTED */
+   },
+   [TCM_ADDRESS_OUT_OF_RANGE] = {
+   .key = ILLEGAL_REQUEST,
+   .asc = 0x21, /* LOGICAL BLOCK ADDRESS OUT OF RANGE */
+   },
+   [TCM_CHECK_CONDITION_UNIT_ATTENTION] = {
+   .key = UNIT_ATTENTION,
+   },
+   [TCM_CHECK_CONDITION_NOT_READY] = {
+   .key = NOT_READY,
+   },
+   [TCM_MISCOMPARE_VERIFY] = {
+   .key = MISCOMPARE,
+   .asc = 0x1d, /* MISCOMPARE DURING VERIFY OPERATION */
+   .ascq = 0x00,
+   },
+   [TCM_LOGICAL_BLOCK_GUARD_CHECK_FAILED] = {
+   .key = ILLEGAL_REQUEST,
+   .asc = 0x10,
+   .ascq = 0x01, /* LOGICAL BLOCK GUARD CHECK FAILED */
+   .add_sector_info = true,
+   },
+   [TCM_LOGICAL_BLOCK_APP_TAG_CHECK_FAILED] = {
+   .key = ILLEGAL_REQUEST,
+   .asc = 0x10,
+   .ascq = 0x02, /* LOGICAL BLOCK APPLICATION TAG CHECK FAILED */
+   .add_sector_info = true,
+   },
+   [TCM_LOGICAL_BLOCK_REF_TAG_CHECK_FAILED] = {
+   .key = ILLEGAL_REQUEST,
+   .asc = 0x10,
+   .ascq = 0x03, /* LOGICAL BLOCK REFERENCE TAG CHECK FAILED */
+   .add_sector_info = true,
+   },
+   [TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE] = {
+   /*
+* Returning ILLEGAL REQUEST would cause immediate IO errors on
+* Solaris initiators.  Returning NOT READY instead means the
+* operations will be retried 

Re: [PATCH v4 5/5] target: Return ABORTED_COMMAND sense key for PI errors

2015-07-08 Thread Hannes Reinecke
On 07/08/2015 04:58 PM, Sagi Grimberg wrote:
 PI errors were reported with ILLEGAL_REQUEST sense key but
 there was actually no problem with the request. Target
 detected PI errors should be reported with aborted command
 sense key.
 
 Signed-off-by: Sagi Grimberg sa...@mellanox.com
 ---
  drivers/target/target_core_transport.c | 6 +++---
  1 file changed, 3 insertions(+), 3 deletions(-)
 
 diff --git a/drivers/target/target_core_transport.c 
 b/drivers/target/target_core_transport.c
 index 923e69d..1847fdc 100644
 --- a/drivers/target/target_core_transport.c
 +++ b/drivers/target/target_core_transport.c
 @@ -2705,19 +2705,19 @@ static const struct sense_info sense_info_table[] = {
   .ascq = 0x00,
   },
   [TCM_LOGICAL_BLOCK_GUARD_CHECK_FAILED] = {
 - .key = ILLEGAL_REQUEST,
 + .key = ABORTED_COMMAND,
   .asc = 0x10,
   .ascq = 0x01, /* LOGICAL BLOCK GUARD CHECK FAILED */
   .add_sector_info = true,
   },
   [TCM_LOGICAL_BLOCK_APP_TAG_CHECK_FAILED] = {
 - .key = ILLEGAL_REQUEST,
 + .key = ABORTED_COMMAND,
   .asc = 0x10,
   .ascq = 0x02, /* LOGICAL BLOCK APPLICATION TAG CHECK FAILED */
   .add_sector_info = true,
   },
   [TCM_LOGICAL_BLOCK_REF_TAG_CHECK_FAILED] = {
 - .key = ILLEGAL_REQUEST,
 + .key = ABORTED_COMMAND,
   .asc = 0x10,
   .ascq = 0x03, /* LOGICAL BLOCK REFERENCE TAG CHECK FAILED */
   .add_sector_info = true,
 
Reviewed-by: Hannes Reinecke h...@suse.de

Cheers,

Hannes
-- 
Dr. Hannes ReineckezSeries  Storage
h...@suse.de   +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)
--
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] [SCSI] FlashPoint: optimize string comparison

2015-07-08 Thread Khalid Aziz

On 07/08/2015 01:12 AM, Frans Klaver wrote:

On Wed, Jul 8, 2015 at 7:45 AM, Christophe JAILLET
christophe.jail...@wanadoo.fr wrote:

Le 07/07/2015 19:04, Khalid Aziz a écrit :


On 07/07/2015 02:45 AM, Frans Klaver wrote:


On Tue, Jul 7, 2015 at 7:39 AM, Christophe JAILLET
christophe.jail...@wanadoo.fr wrote:


Stop comparing the strings as soon as we know that they don't match.

Signed-off-by: Christophe JAILLET christophe.jail...@wanadoo.fr
---
   drivers/scsi/FlashPoint.c | 4 +++-
   1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/FlashPoint.c b/drivers/scsi/FlashPoint.c
index 5c74e4c..24a4d1a 100644
--- a/drivers/scsi/FlashPoint.c
+++ b/drivers/scsi/FlashPoint.c
@@ -6280,8 +6280,10 @@ static unsigned char FPT_scmachid(unsigned char
p_card,
  match = 1;

  for (k = 0; k  ID_STRING_LENGTH; k++) {
-   if (p_id_string[k] !=
FPT_scamInfo[i].id_string[k])
+   if (p_id_string[k] !=
FPT_scamInfo[i].id_string[k]) {
  match = 0;
+   break;
+   }
  }

  if (match) {



Why doesn't this use strncmp?

Thanks,
Frans



I suspect that is how this code came from Mylex many years ago. Using
strncmp would indeed be a better way to clean this up. Also, further down in
the same routine:

 if (FPT_scamInfo[match].state == ID_UNUSED) {
 for (k = 0; k  ID_STRING_LENGTH; k++) {
 FPT_scamInfo[match].id_string[k] =
 p_id_string[k];
 }


This should use strncpy instead. There is another similar spot further
down.

Christophe, if you can send a new patch with these clean-ups, that would
be great.

Thanks,
Khalid



Hi,

I'm sorry but I won't propose a new patch for that.

I had the same reaction at first (why not use strncmp?) but it seems to be
the way this driver is coded. Should we want to introduce strncmp here,
then, as you have noticed, strcpy should be used to. memset could be also
used in many places. Then looking elsewhere in the code, many things should,
IMHO, also be fixed. (use consistently empty lines before/after code ; use
consistently { }...)

Another concern to me is the use of carriage return. In the following
examples, things could be much more readable if not limited to 50 chars per
line, or so.


80. Parts of the code are indented way too much, resulting in these
unreadable lines. I have to say that this entire driver looks like
something that (sh|w)ould be in staging right now.


FlashPoint.c and BusLogic.c together make up the buslogic driver. I went 
through a massive clean up of BusLogic.c (addressing issues like the 
ones you guys are bringing up) when I took over maintenance of buslogic 
driver and made it 64-bit clean. I am very much in agreement with 
suggested clean ups, but this code has been in the kernel for a very 
long time and cleaning it up at this point for the sake of clean up is 
not a reason enough to destabilize a very stable driver. staging is for 
drivers under development and in experimental state. buslogic driver is 
most definitely not experimental. For now we either leave FlashPoint.c 
as it is or clean it up as part of a bigger effort to add new 
functionality or fix a major bug.


Christophe's original patch fixes an inefficiency in the code, so my 
take on it is to either accept the very specific fix without modifying 
rest of the code or combine this fix with clean up of at least the 
entire FPT_scmachid() routine.


Thanks,
Khalid



--
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 3/5] scsi: Move sense handling routines to scsi_common

2015-07-08 Thread Christoph Hellwig
Looks good,

Reviewed-by: Christoph Hellwig h...@lst.de
--
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 4/5] target: Use scsi helpers to build the sense data correctly

2015-07-08 Thread Christoph Hellwig
 --- a/include/target/target_core_base.h
 +++ b/include/target/target_core_base.h
 @@ -7,6 +7,7 @@
  #include linux/blkdev.h
  #include linux/percpu_ida.h
  #include linux/t10-pi.h
 +#include scsi/scsi_common.h
  #include net/sock.h
  #include net/tcp.h

Please only add the include in the files that need it.  (And many of the
existing includes should be fixed up the same way, but that's a
different story).

Otherwise looks good:

Reviewed-by: Christoph Hellwig h...@lst.de
--
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] libiscsi: Fix host busy blocking during connection teardown

2015-07-08 Thread Chris Leech
On Tue, Jun 23, 2015 at 6:11 PM, John Soni Jose sony.j...@avagotech.com wrote:

  Issue:
  In case of hw iscsi offload, an host can have N-number of active
  connections. There can be IO's running on some connections which
  make host-host_busy always TRUE. Now if logout from a connection
  is tried then the code gets into an infinite loop as host-host_busy
  is always TRUE.

  iscsi_conn_teardown()
  {
.
 /*
  * Block until all in-progress commands for this connection
  * time out or fail.
  */
  for (;;) {
   spin_lock_irqsave(session-host-host_lock, flags);
   if (!atomic_read(session-host-host_busy)) { /* OK for ERL == 0 */
   spin_unlock_irqrestore(session-host-host_lock, flags);
   break;
   }
  spin_unlock_irqrestore(session-host-host_lock, flags);
  msleep_interruptible(500);
  iscsi_conn_printk(KERN_INFO, conn, iscsi conn_destroy(): 
  host_busy %d host_failed %d\n,
   atomic_read(session-host-host_busy),
   session-host-host_failed);

 
 ...
  }
   }
   This is not an issue with software-iscsi/iser as each cxn is a separate
   host.

  Fix:
  Acquiring eh_mutex in iscsi_conn_teardown() before setting
  session-state = ISCSI_STATE_TERMINATE.

 Signed-off-by: John Soni Jose sony.j...@aavagotech.com
 ---
  drivers/scsi/libiscsi.c | 25 ++---
  1 file changed, 2 insertions(+), 23 deletions(-)

 diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
 index 8053f24..98d9bb6 100644
 --- a/drivers/scsi/libiscsi.c
 +++ b/drivers/scsi/libiscsi.c
 @@ -2941,10 +2941,10 @@ void iscsi_conn_teardown(struct iscsi_cls_conn 
 *cls_conn)
  {
 struct iscsi_conn *conn = cls_conn-dd_data;
 struct iscsi_session *session = conn-session;
 -   unsigned long flags;

 del_timer_sync(conn-transport_timer);

 +   mutex_lock(session-eh_mutex);
 spin_lock_bh(session-frwd_lock);
 conn-c_stage = ISCSI_CONN_CLEANUP_WAIT;
 if (session-leadconn == conn) {
 @@ -2956,28 +2956,6 @@ void iscsi_conn_teardown(struct iscsi_cls_conn 
 *cls_conn)
 }
 spin_unlock_bh(session-frwd_lock);

 -   /*
 -* Block until all in-progress commands for this connection
 -* time out or fail.
 -*/
 -   for (;;) {
 -   spin_lock_irqsave(session-host-host_lock, flags);
 -   if (!atomic_read(session-host-host_busy)) { /* OK for ERL 
 == 0 */
 -   spin_unlock_irqrestore(session-host-host_lock, 
 flags);
 -   break;
 -   }
 -   spin_unlock_irqrestore(session-host-host_lock, flags);
 -   msleep_interruptible(500);
 -   iscsi_conn_printk(KERN_INFO, conn, iscsi conn_destroy(): 
 - host_busy %d host_failed %d\n,
 - atomic_read(session-host-host_busy),
 - session-host-host_failed);
 -   /*
 -* force eh_abort() to unblock
 -*/
 -   wake_up(conn-ehwait);
 -   }
 -
 /* flush queued up work because we free the connection below */
 iscsi_suspend_tx(conn);

 @@ -2994,6 +2972,7 @@ void iscsi_conn_teardown(struct iscsi_cls_conn 
 *cls_conn)
 if (session-leadconn == conn)
 session-leadconn = NULL;
 spin_unlock_bh(session-frwd_lock);
 +   mutex_unlock(session-eh_mutex);

 iscsi_destroy_conn(cls_conn);
  }
 --


Looks good to me, solid reasoning on why host_busy is the wrong thing to check.

Reviewed-by: Chris Leech cle...@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] [SCSI] FlashPoint: optimize string comparison

2015-07-08 Thread Frans Klaver
On Wed, Jul 8, 2015 at 7:45 AM, Christophe JAILLET
christophe.jail...@wanadoo.fr wrote:
 Le 07/07/2015 19:04, Khalid Aziz a écrit :

 On 07/07/2015 02:45 AM, Frans Klaver wrote:

 On Tue, Jul 7, 2015 at 7:39 AM, Christophe JAILLET
 christophe.jail...@wanadoo.fr wrote:

 Stop comparing the strings as soon as we know that they don't match.

 Signed-off-by: Christophe JAILLET christophe.jail...@wanadoo.fr
 ---
   drivers/scsi/FlashPoint.c | 4 +++-
   1 file changed, 3 insertions(+), 1 deletion(-)

 diff --git a/drivers/scsi/FlashPoint.c b/drivers/scsi/FlashPoint.c
 index 5c74e4c..24a4d1a 100644
 --- a/drivers/scsi/FlashPoint.c
 +++ b/drivers/scsi/FlashPoint.c
 @@ -6280,8 +6280,10 @@ static unsigned char FPT_scmachid(unsigned char
 p_card,
  match = 1;

  for (k = 0; k  ID_STRING_LENGTH; k++) {
 -   if (p_id_string[k] !=
 FPT_scamInfo[i].id_string[k])
 +   if (p_id_string[k] !=
 FPT_scamInfo[i].id_string[k]) {
  match = 0;
 +   break;
 +   }
  }

  if (match) {


 Why doesn't this use strncmp?

 Thanks,
 Frans


 I suspect that is how this code came from Mylex many years ago. Using
 strncmp would indeed be a better way to clean this up. Also, further down in
 the same routine:

 if (FPT_scamInfo[match].state == ID_UNUSED) {
 for (k = 0; k  ID_STRING_LENGTH; k++) {
 FPT_scamInfo[match].id_string[k] =
 p_id_string[k];
 }


 This should use strncpy instead. There is another similar spot further
 down.

 Christophe, if you can send a new patch with these clean-ups, that would
 be great.

 Thanks,
 Khalid


 Hi,

 I'm sorry but I won't propose a new patch for that.

 I had the same reaction at first (why not use strncmp?) but it seems to be
 the way this driver is coded. Should we want to introduce strncmp here,
 then, as you have noticed, strcpy should be used to. memset could be also
 used in many places. Then looking elsewhere in the code, many things should,
 IMHO, also be fixed. (use consistently empty lines before/after code ; use
 consistently { }...)

 Another concern to me is the use of carriage return. In the following
 examples, things could be much more readable if not limited to 50 chars per
 line, or so.

80. Parts of the code are indented way too much, resulting in these
unreadable lines. I have to say that this entire driver looks like
something that (sh|w)ould be in staging right now.

Frans
--
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/3] megaraid : use dev_printk when possible

2015-07-08 Thread Sumit Saxena
 -Original Message-
 From: Bjorn Helgaas [mailto:bhelg...@google.com]
 Sent: Wednesday, July 08, 2015 2:22 AM
 To: Kashyap Desai; Uday Lingala; Sumit Saxena
 Cc: megaraidlinux@avagotech.com; linux-scsi@vger.kernel.org; James
 E.J.
 Bottomley; linux-ker...@vger.kernel.org; Joe Perches; Christoph Hellwig
 Subject: [PATCH v3 1/3] megaraid : use dev_printk when possible

 Use dev_printk() when possible to make messages more useful.

 Signed-off-by: Bjorn Helgaas bhelg...@google.com
 ---
  drivers/scsi/megaraid.c |  140
 ++-
  1 file changed, 66 insertions(+), 74 deletions(-)

 diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index
 bc7b34c..9d05302 100644
 --- a/drivers/scsi/megaraid.c
 +++ b/drivers/scsi/megaraid.c
 @@ -268,8 +268,8 @@ mega_query_adapter(adapter_t *adapter)
   raw_mbox[2] = NC_SUBOP_PRODUCT_INFO;/* i.e. 0x0E */

   if ((retval = issue_scb_block(adapter, raw_mbox)))
 - printk(KERN_WARNING
 - megaraid: Product_info cmd failed with error: %d\n,
 + dev_warn(adapter-dev-dev,
 + Product_info cmd failed with error: %d\n,
   retval);

   pci_unmap_single(adapter-dev, prod_info_dma_handle, @@ -
 334,7 +334,7 @@ mega_query_adapter(adapter_t *adapter)
   adapter-bios_version[4] = 0;
   }

 - printk(KERN_NOTICE megaraid: [%s:%s] detected %d logical drives.\n,
 + dev_notice(adapter-dev-dev, [%s:%s] detected %d logical
 drives\n,
   adapter-fw_version, adapter-bios_version, adapter-
 numldrv);

   /*
 @@ -342,7 +342,7 @@ mega_query_adapter(adapter_t *adapter)
*/
   adapter-support_ext_cdb = mega_support_ext_cdb(adapter);
   if (adapter-support_ext_cdb)
 - printk(KERN_NOTICE megaraid: supports extended CDBs.\n);
 + dev_notice(adapter-dev-dev, supports extended CDBs\n);


   return 0;
 @@ -678,11 +678,11 @@ mega_build_cmd(adapter_t *adapter, Scsi_Cmnd
 *cmd, int *busy)

   if(!(adapter-flag  (1L  cmd-device-channel))) {

 - printk(KERN_NOTICE
 - scsi%d: scanning scsi channel %d ,
 + dev_notice(adapter-dev-dev,
 + scsi%d: scanning scsi channel %d 
 + for logical drives\n,
   adapter-host-host_no,
   cmd-device-channel);
 - printk(for logical drives.\n);

   adapter-flag |= (1L  cmd-device-channel);
   }
 @@ -983,11 +983,11 @@ mega_prepare_passthru(adapter_t *adapter, scb_t
 *scb, Scsi_Cmnd *cmd,
   case READ_CAPACITY:
   if(!(adapter-flag  (1L  cmd-device-channel))) {

 - printk(KERN_NOTICE
 - scsi%d: scanning scsi channel %d [P%d] ,
 + dev_notice(adapter-dev-dev,
 + scsi%d: scanning scsi channel %d [P%d] 
 + for physical devices\n,
   adapter-host-host_no,
   cmd-device-channel, channel);
 - printk(for physical devices.\n);

   adapter-flag |= (1L  cmd-device-channel);
   }
 @@ -1045,11 +1045,11 @@ mega_prepare_extpassthru(adapter_t *adapter,
 scb_t *scb, Scsi_Cmnd *cmd,
   case READ_CAPACITY:
   if(!(adapter-flag  (1L  cmd-device-channel))) {

 - printk(KERN_NOTICE
 - scsi%d: scanning scsi channel %d [P%d] ,
 + dev_notice(adapter-dev-dev,
 + scsi%d: scanning scsi channel %d [P%d] 
 + for physical devices\n,
   adapter-host-host_no,
   cmd-device-channel, channel);
 - printk(for physical devices.\n);

   adapter-flag |= (1L  cmd-device-channel);
   }
 @@ -1241,7 +1241,7 @@ issue_scb_block(adapter_t *adapter, u_char
 *raw_mbox)
   return mbox-m_in.status;

  bug_blocked_mailbox:
 - printk(KERN_WARNING megaraid: Blocked mailbox..!!\n);
 + dev_warn(adapter-dev-dev, Blocked mailbox..!!\n);
   udelay (1000);
   return -1;
  }
 @@ -1454,9 +1454,8 @@ mega_cmd_done(adapter_t *adapter, u8
 completed[], int nstatus, int status)
* Make sure f/w has completed a valid command
*/
   if( !(scb-state  SCB_ISSUED) || scb-cmd == NULL ) {
 - printk(KERN_CRIT
 - megaraid: invalid command );
 -   

[Bug 100921] Kernel cannot read partition table automatically.But use partprobe command can.

2015-07-08 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=100921

--- Comment #2 from Wallance ha...@126.com ---
Oh,I have solved it.

-- 
You are receiving this mail because:
You are the assignee for the bug.
--
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