All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] NVMe: Fix START_STOP_UNIT Scsi->NVMe translation.
@ 2014-06-06 14:27 Dan McLeran
  2014-06-13 17:32 ` Verma, Vishal L
  0 siblings, 1 reply; 2+ messages in thread
From: Dan McLeran @ 2014-06-06 14:27 UTC (permalink / raw)


This patch contains several fixes for Scsi START_STOP_UNIT. The previous code did not account for
signed vs. unsigned arithmetic which resulted in an invalid lowest power state caculation when
the device only supports 1 power state.

The code for Power Condition == 2 (Idle) was not following the spec. The spec calls out
setting the device to specific power states, depending upon Power Condition Modifier, without
accounting for the number of power states supported by the device.

The code for Power Condition == 3 (Standby) was using a hard-coded '0' which I replaced with the
macro POWER_STATE_0.

Signed-off-by: Dan McLeran <daniel.mcleran at intel.com>
---
 drivers/block/nvme-scsi.c |   12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/block/nvme-scsi.c b/drivers/block/nvme-scsi.c
index 4fc25b9..61215ca 100644
--- a/drivers/block/nvme-scsi.c
+++ b/drivers/block/nvme-scsi.c
@@ -1477,7 +1477,7 @@ static int nvme_trans_power_state(struct nvme_ns *ns, struct sg_io_hdr *hdr,
 		goto out_dma;
 	}
 	id_ctrl = mem;
-	lowest_pow_st = id_ctrl->npss - 1;
+	lowest_pow_st = max(POWER_STATE_0, (int)(id_ctrl->npss - 1));
 
 	switch (pc) {
 	case NVME_POWER_STATE_START_VALID:
@@ -1496,18 +1496,18 @@ static int nvme_trans_power_state(struct nvme_ns *ns, struct sg_io_hdr *hdr,
 		/* Action unspecified if POWER CONDITION MODIFIER != [0,1,2] */
 		/* min of desired state and (lps-1) because lps is STOP */
 		if (pcmod == 0x0)
-			ps_desired = min(POWER_STATE_1, (lowest_pow_st - 1));
+			ps_desired = POWER_STATE_1;
 		else if (pcmod == 0x1)
-			ps_desired = min(POWER_STATE_2, (lowest_pow_st - 1));
+			ps_desired = POWER_STATE_2;
 		else if (pcmod == 0x2)
-			ps_desired = min(POWER_STATE_3, (lowest_pow_st - 1));
+			ps_desired = POWER_STATE_3;
 		break;
 	case NVME_POWER_STATE_STANDBY:
 		/* Action unspecified if POWER CONDITION MODIFIER != [0,1] */
 		if (pcmod == 0x0)
-			ps_desired = max(0, (lowest_pow_st - 2));
+			ps_desired = max(POWER_STATE_0, (lowest_pow_st - 2));
 		else if (pcmod == 0x1)
-			ps_desired = max(0, (lowest_pow_st - 1));
+			ps_desired = max(POWER_STATE_0, (lowest_pow_st - 1));
 		break;
 	case NVME_POWER_STATE_LU_CONTROL:
 	default:
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* [PATCH] NVMe: Fix START_STOP_UNIT Scsi->NVMe translation.
  2014-06-06 14:27 [PATCH] NVMe: Fix START_STOP_UNIT Scsi->NVMe translation Dan McLeran
@ 2014-06-13 17:32 ` Verma, Vishal L
  0 siblings, 0 replies; 2+ messages in thread
From: Verma, Vishal L @ 2014-06-13 17:32 UTC (permalink / raw)


On Fri, 2014-06-06@08:27 -0600, Dan McLeran wrote:
> This patch contains several fixes for Scsi START_STOP_UNIT. The previous code did not account for
> signed vs. unsigned arithmetic which resulted in an invalid lowest power state caculation when
> the device only supports 1 power state.
> 
> The code for Power Condition == 2 (Idle) was not following the spec. The spec calls out
> setting the device to specific power states, depending upon Power Condition Modifier, without
> accounting for the number of power states supported by the device.
> 
> The code for Power Condition == 3 (Standby) was using a hard-coded '0' which I replaced with the
> macro POWER_STATE_0.
> 
> Signed-off-by: Dan McLeran <daniel.mcleran at intel.com>
> ---
>  drivers/block/nvme-scsi.c |   12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)
> 

Looks good.
Reviewed-by: Vishal Verma <vishal.l.verma at linux.intel.com>


> diff --git a/drivers/block/nvme-scsi.c b/drivers/block/nvme-scsi.c
> index 4fc25b9..61215ca 100644
> --- a/drivers/block/nvme-scsi.c
> +++ b/drivers/block/nvme-scsi.c
> @@ -1477,7 +1477,7 @@ static int nvme_trans_power_state(struct nvme_ns *ns, struct sg_io_hdr *hdr,
>  		goto out_dma;
>  	}
>  	id_ctrl = mem;
> -	lowest_pow_st = id_ctrl->npss - 1;
> +	lowest_pow_st = max(POWER_STATE_0, (int)(id_ctrl->npss - 1));
>  
>  	switch (pc) {
>  	case NVME_POWER_STATE_START_VALID:
> @@ -1496,18 +1496,18 @@ static int nvme_trans_power_state(struct nvme_ns *ns, struct sg_io_hdr *hdr,
>  		/* Action unspecified if POWER CONDITION MODIFIER != [0,1,2] */
>  		/* min of desired state and (lps-1) because lps is STOP */
>  		if (pcmod == 0x0)
> -			ps_desired = min(POWER_STATE_1, (lowest_pow_st - 1));
> +			ps_desired = POWER_STATE_1;
>  		else if (pcmod == 0x1)
> -			ps_desired = min(POWER_STATE_2, (lowest_pow_st - 1));
> +			ps_desired = POWER_STATE_2;
>  		else if (pcmod == 0x2)
> -			ps_desired = min(POWER_STATE_3, (lowest_pow_st - 1));
> +			ps_desired = POWER_STATE_3;
>  		break;
>  	case NVME_POWER_STATE_STANDBY:
>  		/* Action unspecified if POWER CONDITION MODIFIER != [0,1] */
>  		if (pcmod == 0x0)
> -			ps_desired = max(0, (lowest_pow_st - 2));
> +			ps_desired = max(POWER_STATE_0, (lowest_pow_st - 2));
>  		else if (pcmod == 0x1)
> -			ps_desired = max(0, (lowest_pow_st - 1));
> +			ps_desired = max(POWER_STATE_0, (lowest_pow_st - 1));
>  		break;
>  	case NVME_POWER_STATE_LU_CONTROL:
>  	default:

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2014-06-13 17:32 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-06-06 14:27 [PATCH] NVMe: Fix START_STOP_UNIT Scsi->NVMe translation Dan McLeran
2014-06-13 17:32 ` Verma, Vishal L

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.