RE: [PATCH 4/7] aacraid: use aac_tmf_callback for reset fib

2017-07-05 Thread Raghava Aditya Renukunta


> -Original Message-
> From: Hannes Reinecke [mailto:h...@suse.de]
> Sent: Friday, June 30, 2017 10:18 AM
> To: Martin K. Petersen <martin.peter...@oracle.com>
> Cc: Christoph Hellwig <h...@lst.de>; James Bottomley
> <james.bottom...@hansenpartnership.com>; linux-scsi@vger.kernel.org;
> Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com>;
> Hannes Reinecke <h...@suse.de>; Hannes Reinecke <h...@suse.com>
> Subject: [PATCH 4/7] aacraid: use aac_tmf_callback for reset fib
> 
> EXTERNAL EMAIL
> 
> 
> When sending a reset fib we shouldn't rely on the scsi command,
> but rather set the TMF status in the map_info->reset_state variable.
> That allows us to send a TMF independent on a scsi command.
> 
> Signed-off-by: Hannes Reinecke <h...@suse.com>
> ---
>  drivers/scsi/aacraid/linit.c | 99 +---
> 
>  1 file changed, 74 insertions(+), 25 deletions(-)
> 
> diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
> index 57b2077..e5d2d91 100644
> --- a/drivers/scsi/aacraid/linit.c
> +++ b/drivers/scsi/aacraid/linit.c
> @@ -814,8 +814,8 @@ static int aac_eh_abort(struct scsi_cmnd* cmd)
> return ret;
>  }
> 
> -static u8 aac_eh_tmf_lun_reset_fib(struct aac_dev *aac, struct fib *fib,
> -  int bus, int cid, u64 tmf_lun)
> +static u8 aac_eh_tmf_lun_reset_fib(struct aac_hba_map_info *info,
> +  struct fib *fib, u64 tmf_lun)
>  {
> struct aac_hba_tm_req *tmf;
> u64 address;
> @@ -824,7 +824,7 @@ static u8 aac_eh_tmf_lun_reset_fib(struct aac_dev
> *aac, struct fib *fib,
> tmf = (struct aac_hba_tm_req *)fib->hw_fib_va;
> memset(tmf, 0, sizeof(*tmf));
> tmf->tmf = HBA_TMF_LUN_RESET;
> -   tmf->it_nexus = aac->hba_map[bus][cid].rmw_nexus;
> +   tmf->it_nexus = info->rmw_nexus;
> int_to_scsilun(tmf_lun, (struct scsi_lun *)tmf->lun);
> 
> address = (u64)fib->hw_error_pa;
> @@ -838,8 +838,8 @@ static u8 aac_eh_tmf_lun_reset_fib(struct aac_dev
> *aac, struct fib *fib,
> return HBA_IU_TYPE_SCSI_TM_REQ;
>  }
> 
> -static u8 aac_eh_tmf_hard_reset_fib(struct aac_dev *aac, struct fib *fib,
> -   int bus, int cid)
> +static u8 aac_eh_tmf_hard_reset_fib(struct aac_hba_map_info *info,
> +   struct fib *fib)
>  {
> struct aac_hba_reset_req *rst;
> u64 address;
> @@ -847,8 +847,7 @@ static u8 aac_eh_tmf_hard_reset_fib(struct aac_dev
> *aac, struct fib *fib,
> /* already tried, start a hard reset now */
> rst = (struct aac_hba_reset_req *)fib->hw_fib_va;
> memset(rst, 0, sizeof(*rst));
> -   /* reset_type is already zero... */
> -   rst->it_nexus = aac->hba_map[bus][cid].rmw_nexus;
> +   rst->it_nexus = info->rmw_nexus;
> 
> address = (u64)fib->hw_error_pa;
> rst->error_ptr_hi = cpu_to_le32((u32)(address >> 32));
> @@ -860,6 +859,33 @@ static u8 aac_eh_tmf_hard_reset_fib(struct aac_dev
> *aac, struct fib *fib,
> return HBA_IU_TYPE_SATA_REQ;
>  }
> 
> +void aac_tmf_callback(void *context, struct fib *fibptr)
> +{
> +   struct aac_hba_resp *err =
> +   &((struct aac_native_hba *)fibptr->hw_fib_va)->resp.err;
> +   struct aac_hba_map_info *info = context;
> +   int res;
> +
> +   switch (err->service_response) {
> +   case HBA_RESP_SVCRES_TMF_REJECTED:
> +   res = -1;
> +   break;
> +   case HBA_RESP_SVCRES_TMF_LUN_INVALID:
> +   res = 0;
> +   break;
> +   case HBA_RESP_SVCRES_TMF_COMPLETE:
> +   case HBA_RESP_SVCRES_TMF_SUCCEEDED:
> +   res = 0;
> +   break;
> +   default:
> +   res = -2;
> +   break;
> +   }
> +   aac_fib_complete(fibptr);
> +
> +   info->reset_state = res;
> +}
> +
>  /*
>   * aac_eh_dev_reset- Device reset command handling
>   * @scsi_cmd:  SCSI command block causing the reset
> @@ -870,6 +896,7 @@ static int aac_eh_dev_reset(struct scsi_cmnd *cmd)
> struct scsi_device * dev = cmd->device;
> struct Scsi_Host * host = dev->host;
> struct aac_dev * aac = (struct aac_dev *)host->hostdata;
> +   struct aac_hba_map_info *info;
> int count;
> u32 bus, cid;
> struct fib *fib;
> @@ -879,8 +906,12 @@ static int aac_eh_dev_reset(struct scsi_cmnd *cmd)
> 
> bus = aac_logical_to

[PATCH 4/7] aacraid: use aac_tmf_callback for reset fib

2017-06-30 Thread Hannes Reinecke
When sending a reset fib we shouldn't rely on the scsi command,
but rather set the TMF status in the map_info->reset_state variable.
That allows us to send a TMF independent on a scsi command.

Signed-off-by: Hannes Reinecke 
---
 drivers/scsi/aacraid/linit.c | 99 +---
 1 file changed, 74 insertions(+), 25 deletions(-)

diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 57b2077..e5d2d91 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -814,8 +814,8 @@ static int aac_eh_abort(struct scsi_cmnd* cmd)
return ret;
 }
 
-static u8 aac_eh_tmf_lun_reset_fib(struct aac_dev *aac, struct fib *fib,
-  int bus, int cid, u64 tmf_lun)
+static u8 aac_eh_tmf_lun_reset_fib(struct aac_hba_map_info *info,
+  struct fib *fib, u64 tmf_lun)
 {
struct aac_hba_tm_req *tmf;
u64 address;
@@ -824,7 +824,7 @@ static u8 aac_eh_tmf_lun_reset_fib(struct aac_dev *aac, 
struct fib *fib,
tmf = (struct aac_hba_tm_req *)fib->hw_fib_va;
memset(tmf, 0, sizeof(*tmf));
tmf->tmf = HBA_TMF_LUN_RESET;
-   tmf->it_nexus = aac->hba_map[bus][cid].rmw_nexus;
+   tmf->it_nexus = info->rmw_nexus;
int_to_scsilun(tmf_lun, (struct scsi_lun *)tmf->lun);
 
address = (u64)fib->hw_error_pa;
@@ -838,8 +838,8 @@ static u8 aac_eh_tmf_lun_reset_fib(struct aac_dev *aac, 
struct fib *fib,
return HBA_IU_TYPE_SCSI_TM_REQ;
 }
 
-static u8 aac_eh_tmf_hard_reset_fib(struct aac_dev *aac, struct fib *fib,
-   int bus, int cid)
+static u8 aac_eh_tmf_hard_reset_fib(struct aac_hba_map_info *info,
+   struct fib *fib)
 {
struct aac_hba_reset_req *rst;
u64 address;
@@ -847,8 +847,7 @@ static u8 aac_eh_tmf_hard_reset_fib(struct aac_dev *aac, 
struct fib *fib,
/* already tried, start a hard reset now */
rst = (struct aac_hba_reset_req *)fib->hw_fib_va;
memset(rst, 0, sizeof(*rst));
-   /* reset_type is already zero... */
-   rst->it_nexus = aac->hba_map[bus][cid].rmw_nexus;
+   rst->it_nexus = info->rmw_nexus;
 
address = (u64)fib->hw_error_pa;
rst->error_ptr_hi = cpu_to_le32((u32)(address >> 32));
@@ -860,6 +859,33 @@ static u8 aac_eh_tmf_hard_reset_fib(struct aac_dev *aac, 
struct fib *fib,
return HBA_IU_TYPE_SATA_REQ;
 }
 
+void aac_tmf_callback(void *context, struct fib *fibptr)
+{
+   struct aac_hba_resp *err =
+   &((struct aac_native_hba *)fibptr->hw_fib_va)->resp.err;
+   struct aac_hba_map_info *info = context;
+   int res;
+
+   switch (err->service_response) {
+   case HBA_RESP_SVCRES_TMF_REJECTED:
+   res = -1;
+   break;
+   case HBA_RESP_SVCRES_TMF_LUN_INVALID:
+   res = 0;
+   break;
+   case HBA_RESP_SVCRES_TMF_COMPLETE:
+   case HBA_RESP_SVCRES_TMF_SUCCEEDED:
+   res = 0;
+   break;
+   default:
+   res = -2;
+   break;
+   }
+   aac_fib_complete(fibptr);
+
+   info->reset_state = res;
+}
+
 /*
  * aac_eh_dev_reset- Device reset command handling
  * @scsi_cmd:  SCSI command block causing the reset
@@ -870,6 +896,7 @@ static int aac_eh_dev_reset(struct scsi_cmnd *cmd)
struct scsi_device * dev = cmd->device;
struct Scsi_Host * host = dev->host;
struct aac_dev * aac = (struct aac_dev *)host->hostdata;
+   struct aac_hba_map_info *info;
int count;
u32 bus, cid;
struct fib *fib;
@@ -879,8 +906,12 @@ static int aac_eh_dev_reset(struct scsi_cmnd *cmd)
 
bus = aac_logical_to_phys(scmd_channel(cmd));
cid = scmd_id(cmd);
+   info = >hba_map[bus][cid];
if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS ||
-   aac->hba_map[bus][cid].devtype != AAC_DEVTYPE_NATIVE_RAW)
+   info->devtype != AAC_DEVTYPE_NATIVE_RAW)
+   return FAILED;
+
+   if (info->reset_state > 0)
return FAILED;
 
pr_err("%s: Host adapter reset request. SCSI hang ?\n",
@@ -890,21 +921,19 @@ static int aac_eh_dev_reset(struct scsi_cmnd *cmd)
if (!fib)
return ret;
 
-
/* start a HBA_TMF_LUN_RESET TMF request */
-   command = aac_eh_tmf_lun_reset_fib(aac, fib, bus, cid,
-  cmd->device->lun);
+   command = aac_eh_tmf_lun_reset_fib(info, fib, dev->lun);
 
-   cmd->SCp.sent_command = 0;
+   info->reset_state = 1;
 
status = aac_hba_send(command, fib,
- (fib_callback) aac_hba_callback,
- (void *) cmd);
+ (fib_callback) aac_tmf_callback,
+ (void *) info);
 
/* Wait up to 15 seconds for completion */
for