diff mbox

[1,09/25] hpsa: fix physical target reset

Message ID 20151028220524.5323.29044.stgit@brunhilda (mailing list archive)
State Superseded, archived
Headers show

Commit Message

Don Brace Oct. 28, 2015, 10:05 p.m. UTC
From: Scott Teel <scott.teel@pmcs.com>

Set reset type in device_reset_handler to do either
logical unit reset for logical devices, or physical
target reset, for physical devices.

Reviewed-by: Scott Teel <scott.teel@pmcs.com>
Reviewed-by: Justin Lindley <justin.lindley@pmcs.com>
Reviewed-by: Kevin Barnett <kevin.barnett@pmcs.com>
Signed-off-by: Don Brace <don.brace@pmcs.com>
---
 drivers/scsi/hpsa.c |   34 ++++++++++++++++++++++++++++------
 drivers/scsi/hpsa.h |    1 +
 2 files changed, 29 insertions(+), 6 deletions(-)


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

Comments

Tomas Henzl Oct. 29, 2015, 2:30 p.m. UTC | #1
On 28.10.2015 23:05, Don Brace wrote:
> From: Scott Teel <scott.teel@pmcs.com>
>
> Set reset type in device_reset_handler to do either
> logical unit reset for logical devices, or physical
> target reset, for physical devices.
>
> Reviewed-by: Scott Teel <scott.teel@pmcs.com>
> Reviewed-by: Justin Lindley <justin.lindley@pmcs.com>
> Reviewed-by: Kevin Barnett <kevin.barnett@pmcs.com>
> Signed-off-by: Don Brace <don.brace@pmcs.com>
> ---
>  drivers/scsi/hpsa.c |   34 ++++++++++++++++++++++++++++------
>  drivers/scsi/hpsa.h |    1 +
>  2 files changed, 29 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
> index 08a761c..67136fb 100644
> --- a/drivers/scsi/hpsa.c
> +++ b/drivers/scsi/hpsa.c
> @@ -2746,9 +2746,8 @@ static int hpsa_send_reset(struct ctlr_info *h, unsigned char *scsi3addr,
>  
>  
>  	/* fill_cmd can't fail here, no data buffer to map. */
> -	(void) fill_cmd(c, HPSA_DEVICE_RESET_MSG, h, NULL, 0, 0,
> +	(void) fill_cmd(c, reset_type, h, NULL, 0, 0,
>  			scsi3addr, TYPE_MSG);
> -	c->Request.CDB[1] = reset_type; /* fill_cmd defaults to LUN reset */
>  	rc = hpsa_scsi_do_simple_cmd(h, c, reply_queue, NO_TIMEOUT);
>  	if (rc) {
>  		dev_warn(&h->pdev->dev, "Failed to send reset command\n");
> @@ -5216,6 +5215,7 @@ static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
>  	int rc;
>  	struct ctlr_info *h;
>  	struct hpsa_scsi_dev_t *dev;
> +	u8 reset_type;
>  	char msg[48];
>  
>  	/* find the controller to which the command to be aborted was sent */
> @@ -5254,15 +5254,23 @@ static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
>  	if (is_hba_lunid(dev->scsi3addr))
>  		return SUCCESS;
>  
> -	hpsa_show_dev_msg(KERN_WARNING, h, dev, "resetting");
> +	if (is_logical_dev_addr_mode(dev->scsi3addr))
> +		reset_type = HPSA_DEVICE_RESET_MSG;
> +	else
> +		reset_type = HPSA_PHYS_TARGET_RESET;
> +
> +	sprintf(msg, "resetting %s",
> +		reset_type == HPSA_DEVICE_RESET_MSG ? "logical " : "physical ");
> +	hpsa_show_dev_msg(KERN_WARNING, h, dev, msg);
>  
>  	h->reset_in_progress = 1;
>  
>  	/* send a reset to the SCSI LUN which the command was sent to */
> -	rc = hpsa_do_reset(h, dev, dev->scsi3addr, HPSA_RESET_TYPE_LUN,
> +	rc = hpsa_do_reset(h, dev, dev->scsi3addr, reset_type,
>  			   DEFAULT_REPLY_QUEUE);
> -	snprintf(msg, sizeof(msg), "reset %s",
> -		 rc == 0 ? "completed successfully" : "failed");
> +	sprintf(msg, "reset %s %s",
> +		reset_type == HPSA_DEVICE_RESET_MSG ? "logical " : "physical ",
> +		rc == 0 ? "completed successfully" : "failed");
>  	hpsa_show_dev_msg(KERN_WARNING, h, dev, msg);
>  	h->reset_in_progress = 0;
>  	return rc == 0 ? SUCCESS : FAILED;
> @@ -6379,6 +6387,20 @@ static int fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h,
>  	} else if (cmd_type == TYPE_MSG) {
>  		switch (cmd) {
>  
> +		case  HPSA_PHYS_TARGET_RESET:
> +			c->Request.CDBLen = 16;
> +			c->Request.type_attr_dir =
> +				TYPE_ATTR_DIR(cmd_type, ATTR_SIMPLE, XFER_NONE);
> +			c->Request.Timeout = 0; /* Don't time out */
> +			memset(&c->Request.CDB[0], 0, sizeof(c->Request.CDB));
> +			c->Request.CDB[0] = HPSA_RESET;
> +			c->Request.CDB[1] = HPSA_TARGET_RESET_TYPE;
> +			/* Physical target reset needs no control bytes 4-7*/
> +			c->Request.CDB[4] = 0x00;
> +			c->Request.CDB[5] = 0x00;
> +			c->Request.CDB[6] = 0x00;
> +			c->Request.CDB[7] = 0x00;
> +			break;
>  		case  HPSA_DEVICE_RESET_MSG:
>  			c->Request.CDBLen = 16;
>  			c->Request.type_attr_dir =
> diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
> index dc113c1a..04f98eb 100644
> --- a/drivers/scsi/hpsa.h
> +++ b/drivers/scsi/hpsa.h
> @@ -285,6 +285,7 @@ struct offline_device_entry {
>  #define HPSA_RESET_TYPE_BUS 0x01
>  #define HPSA_RESET_TYPE_TARGET 0x03
>  #define HPSA_RESET_TYPE_LUN 0x04
> +#define HPSA_PHYS_TARGET_RESET 0x99 /* not defined by cciss spec */

Will this new reset command work for the whole range of hpsa devices?
(and for the older cciss hw - hpsa_allow_any) ?

>  #define HPSA_MSG_SEND_RETRY_LIMIT 10
>  #define HPSA_MSG_SEND_RETRY_INTERVAL_MSECS (10000)
>  
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Don Brace Oct. 29, 2015, 3:29 p.m. UTC | #2
On 10/29/2015 09:30 AM, Tomas Henzl wrote:
> On 28.10.2015 23:05, Don Brace wrote:
>> From: Scott Teel <scott.teel@pmcs.com>
>>
>> Set reset type in device_reset_handler to do either
>> logical unit reset for logical devices, or physical
>> target reset, for physical devices.
>>
>> Reviewed-by: Scott Teel <scott.teel@pmcs.com>
>> Reviewed-by: Justin Lindley <justin.lindley@pmcs.com>
>> Reviewed-by: Kevin Barnett <kevin.barnett@pmcs.com>
>> Signed-off-by: Don Brace <don.brace@pmcs.com>
>> ---
>>   drivers/scsi/hpsa.c |   34 ++++++++++++++++++++++++++++------
>>   drivers/scsi/hpsa.h |    1 +
>>   2 files changed, 29 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
>> index 08a761c..67136fb 100644
>> --- a/drivers/scsi/hpsa.c
>> +++ b/drivers/scsi/hpsa.c
>> @@ -2746,9 +2746,8 @@ static int hpsa_send_reset(struct ctlr_info *h, unsigned char *scsi3addr,
>>   
>>   
>>   	/* fill_cmd can't fail here, no data buffer to map. */
>> -	(void) fill_cmd(c, HPSA_DEVICE_RESET_MSG, h, NULL, 0, 0,
>> +	(void) fill_cmd(c, reset_type, h, NULL, 0, 0,
>>   			scsi3addr, TYPE_MSG);
>> -	c->Request.CDB[1] = reset_type; /* fill_cmd defaults to LUN reset */
>>   	rc = hpsa_scsi_do_simple_cmd(h, c, reply_queue, NO_TIMEOUT);
>>   	if (rc) {
>>   		dev_warn(&h->pdev->dev, "Failed to send reset command\n");
>> @@ -5216,6 +5215,7 @@ static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
>>   	int rc;
>>   	struct ctlr_info *h;
>>   	struct hpsa_scsi_dev_t *dev;
>> +	u8 reset_type;
>>   	char msg[48];
>>   
>>   	/* find the controller to which the command to be aborted was sent */
>> @@ -5254,15 +5254,23 @@ static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
>>   	if (is_hba_lunid(dev->scsi3addr))
>>   		return SUCCESS;
>>   
>> -	hpsa_show_dev_msg(KERN_WARNING, h, dev, "resetting");
>> +	if (is_logical_dev_addr_mode(dev->scsi3addr))
>> +		reset_type = HPSA_DEVICE_RESET_MSG;
>> +	else
>> +		reset_type = HPSA_PHYS_TARGET_RESET;
>> +
>> +	sprintf(msg, "resetting %s",
>> +		reset_type == HPSA_DEVICE_RESET_MSG ? "logical " : "physical ");
>> +	hpsa_show_dev_msg(KERN_WARNING, h, dev, msg);
>>   
>> */
> Will this new reset command work for the whole range of hpsa devices?
> (and for the older cciss hw - hpsa_allow_any) ?
The new reset works for newer controller that support HBA mode or IO
bypass mode that allow the driver to send commands directly to a
physical device. This new reset is for those situations.

We still do the existing reset for RAID volumes.
>
>>   #define HPSA_MSG_SEND_RETRY_LIMIT 10
>>   #define HPSA_MSG_SEND_RETRY_INTERVAL_MSECS (10000)
>>   
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> --
> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Tomas Henzl Oct. 29, 2015, 3:52 p.m. UTC | #3
On 29.10.2015 16:29, Don Brace wrote:
> On 10/29/2015 09:30 AM, Tomas Henzl wrote:
>> On 28.10.2015 23:05, Don Brace wrote:
>>> From: Scott Teel <scott.teel@pmcs.com>
>>>
>>> Set reset type in device_reset_handler to do either
>>> logical unit reset for logical devices, or physical
>>> target reset, for physical devices.
>>>
>>> Reviewed-by: Scott Teel <scott.teel@pmcs.com>
>>> Reviewed-by: Justin Lindley <justin.lindley@pmcs.com>
>>> Reviewed-by: Kevin Barnett <kevin.barnett@pmcs.com>
>>> Signed-off-by: Don Brace <don.brace@pmcs.com>
>>> ---
>>>   drivers/scsi/hpsa.c |   34 ++++++++++++++++++++++++++++------
>>>   drivers/scsi/hpsa.h |    1 +
>>>   2 files changed, 29 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
>>> index 08a761c..67136fb 100644
>>> --- a/drivers/scsi/hpsa.c
>>> +++ b/drivers/scsi/hpsa.c
>>> @@ -2746,9 +2746,8 @@ static int hpsa_send_reset(struct ctlr_info *h, unsigned char *scsi3addr,
>>>   
>>>   
>>>   	/* fill_cmd can't fail here, no data buffer to map. */
>>> -	(void) fill_cmd(c, HPSA_DEVICE_RESET_MSG, h, NULL, 0, 0,
>>> +	(void) fill_cmd(c, reset_type, h, NULL, 0, 0,
>>>   			scsi3addr, TYPE_MSG);
>>> -	c->Request.CDB[1] = reset_type; /* fill_cmd defaults to LUN reset */
>>>   	rc = hpsa_scsi_do_simple_cmd(h, c, reply_queue, NO_TIMEOUT);
>>>   	if (rc) {
>>>   		dev_warn(&h->pdev->dev, "Failed to send reset command\n");
>>> @@ -5216,6 +5215,7 @@ static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
>>>   	int rc;
>>>   	struct ctlr_info *h;
>>>   	struct hpsa_scsi_dev_t *dev;
>>> +	u8 reset_type;
>>>   	char msg[48];
>>>   
>>>   	/* find the controller to which the command to be aborted was sent */
>>> @@ -5254,15 +5254,23 @@ static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
>>>   	if (is_hba_lunid(dev->scsi3addr))
>>>   		return SUCCESS;
>>>   
>>> -	hpsa_show_dev_msg(KERN_WARNING, h, dev, "resetting");
>>> +	if (is_logical_dev_addr_mode(dev->scsi3addr))
>>> +		reset_type = HPSA_DEVICE_RESET_MSG;
>>> +	else
>>> +		reset_type = HPSA_PHYS_TARGET_RESET;
>>> +
>>> +	sprintf(msg, "resetting %s",
>>> +		reset_type == HPSA_DEVICE_RESET_MSG ? "logical " : "physical ");
>>> +	hpsa_show_dev_msg(KERN_WARNING, h, dev, msg);
>>>   
>>> */
>> Will this new reset command work for the whole range of hpsa devices?
>> (and for the older cciss hw - hpsa_allow_any) ?
> The new reset works for newer controller that support HBA mode or IO
> bypass mode that allow the driver to send commands directly to a
> physical device. This new reset is for those situations.
>
> We still do the existing reset for RAID volumes.

ok, so -
Reviewed-by: Tomas Henzl <thenzl@redhat.com>

Tomas


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Hannes Reinecke Oct. 30, 2015, 7:59 a.m. UTC | #4
On 10/28/2015 11:05 PM, Don Brace wrote:
> From: Scott Teel <scott.teel@pmcs.com>
> 
> Set reset type in device_reset_handler to do either
> logical unit reset for logical devices, or physical
> target reset, for physical devices.
> 
> Reviewed-by: Scott Teel <scott.teel@pmcs.com>
> Reviewed-by: Justin Lindley <justin.lindley@pmcs.com>
> Reviewed-by: Kevin Barnett <kevin.barnett@pmcs.com>
> Signed-off-by: Don Brace <don.brace@pmcs.com>
> ---
Hmm. I would have done this in firmware by making 'physical target
reset' equivalent to a logical unit reset, but that's firmware for you.

Reviewed-by: Hannes Reinecke <hare@suse.de>


Cheers,

Hannes
diff mbox

Patch

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 08a761c..67136fb 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -2746,9 +2746,8 @@  static int hpsa_send_reset(struct ctlr_info *h, unsigned char *scsi3addr,
 
 
 	/* fill_cmd can't fail here, no data buffer to map. */
-	(void) fill_cmd(c, HPSA_DEVICE_RESET_MSG, h, NULL, 0, 0,
+	(void) fill_cmd(c, reset_type, h, NULL, 0, 0,
 			scsi3addr, TYPE_MSG);
-	c->Request.CDB[1] = reset_type; /* fill_cmd defaults to LUN reset */
 	rc = hpsa_scsi_do_simple_cmd(h, c, reply_queue, NO_TIMEOUT);
 	if (rc) {
 		dev_warn(&h->pdev->dev, "Failed to send reset command\n");
@@ -5216,6 +5215,7 @@  static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
 	int rc;
 	struct ctlr_info *h;
 	struct hpsa_scsi_dev_t *dev;
+	u8 reset_type;
 	char msg[48];
 
 	/* find the controller to which the command to be aborted was sent */
@@ -5254,15 +5254,23 @@  static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
 	if (is_hba_lunid(dev->scsi3addr))
 		return SUCCESS;
 
-	hpsa_show_dev_msg(KERN_WARNING, h, dev, "resetting");
+	if (is_logical_dev_addr_mode(dev->scsi3addr))
+		reset_type = HPSA_DEVICE_RESET_MSG;
+	else
+		reset_type = HPSA_PHYS_TARGET_RESET;
+
+	sprintf(msg, "resetting %s",
+		reset_type == HPSA_DEVICE_RESET_MSG ? "logical " : "physical ");
+	hpsa_show_dev_msg(KERN_WARNING, h, dev, msg);
 
 	h->reset_in_progress = 1;
 
 	/* send a reset to the SCSI LUN which the command was sent to */
-	rc = hpsa_do_reset(h, dev, dev->scsi3addr, HPSA_RESET_TYPE_LUN,
+	rc = hpsa_do_reset(h, dev, dev->scsi3addr, reset_type,
 			   DEFAULT_REPLY_QUEUE);
-	snprintf(msg, sizeof(msg), "reset %s",
-		 rc == 0 ? "completed successfully" : "failed");
+	sprintf(msg, "reset %s %s",
+		reset_type == HPSA_DEVICE_RESET_MSG ? "logical " : "physical ",
+		rc == 0 ? "completed successfully" : "failed");
 	hpsa_show_dev_msg(KERN_WARNING, h, dev, msg);
 	h->reset_in_progress = 0;
 	return rc == 0 ? SUCCESS : FAILED;
@@ -6379,6 +6387,20 @@  static int fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h,
 	} else if (cmd_type == TYPE_MSG) {
 		switch (cmd) {
 
+		case  HPSA_PHYS_TARGET_RESET:
+			c->Request.CDBLen = 16;
+			c->Request.type_attr_dir =
+				TYPE_ATTR_DIR(cmd_type, ATTR_SIMPLE, XFER_NONE);
+			c->Request.Timeout = 0; /* Don't time out */
+			memset(&c->Request.CDB[0], 0, sizeof(c->Request.CDB));
+			c->Request.CDB[0] = HPSA_RESET;
+			c->Request.CDB[1] = HPSA_TARGET_RESET_TYPE;
+			/* Physical target reset needs no control bytes 4-7*/
+			c->Request.CDB[4] = 0x00;
+			c->Request.CDB[5] = 0x00;
+			c->Request.CDB[6] = 0x00;
+			c->Request.CDB[7] = 0x00;
+			break;
 		case  HPSA_DEVICE_RESET_MSG:
 			c->Request.CDBLen = 16;
 			c->Request.type_attr_dir =
diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
index dc113c1a..04f98eb 100644
--- a/drivers/scsi/hpsa.h
+++ b/drivers/scsi/hpsa.h
@@ -285,6 +285,7 @@  struct offline_device_entry {
 #define HPSA_RESET_TYPE_BUS 0x01
 #define HPSA_RESET_TYPE_TARGET 0x03
 #define HPSA_RESET_TYPE_LUN 0x04
+#define HPSA_PHYS_TARGET_RESET 0x99 /* not defined by cciss spec */
 #define HPSA_MSG_SEND_RETRY_LIMIT 10
 #define HPSA_MSG_SEND_RETRY_INTERVAL_MSECS (10000)