From: Sumit Saxena <sumit.saxena@avagotech.com>
To: Tomas Henzl <thenzl@redhat.com>,
jbottomley@parallels.com, hch@infradead.org,
martin.petersen@oracle.com
Cc: linux-scsi@vger.kernel.org, Kashyap Desai <kashyap.desai@avagotech.com>
Subject: RE: [PATCH 04/15] megaraid_sas: Task management support
Date: Thu, 14 Jan 2016 17:34:19 +0530 [thread overview]
Message-ID: <b31b24124b2bb7c5b391c138fa771330@mail.gmail.com> (raw)
In-Reply-To: <5693E07E.3070308@redhat.com>
> -----Original Message-----
> From: Tomas Henzl [mailto:thenzl@redhat.com]
> Sent: Monday, January 11, 2016 10:34 PM
> To: Sumit Saxena; jbottomley@parallels.com; hch@infradead.org;
> martin.petersen@oracle.com
> Cc: linux-scsi@vger.kernel.org; kashyap.desai@avagotech.com
> Subject: Re: [PATCH 04/15] megaraid_sas: Task management support
>
> On 18.12.2015 14:26, Sumit Saxena wrote:
> > This patch will add task management(TM) support for SCSI commands in
> megaraid_sas driver.
> > Added TM functions are below-
> > 1)Task abort
> > 2)Target reset
> >
> > Below are few key points-
> >
> > 1. Currently, megaraid_sas driver performs Controller reset when any
IO times
> out.
> > With these TM support added in driver, in case of IO timeout task
> > abort and target reset will be tried to recover timed out IO. If both
> > fails to recover IO, then Controller reset will be called. If the TM
> > request times out, fail the TM and escalate to the next
level(Controller reset).
> >
> > 2. mr_device_priv_data will be allocated for all generation of
> > controller, but is_tm_capable flag will never be set for older
> > controllers (prior to Invader series) as firmware support is not
available for
> T.M functionality.
> >
> > 3. whichever firmware is capable for TM will set is_tm_capable flag in
> > firmware API, which will be used by Driver to pass TM frame to
firmware or
> return back to OS as Failure to escalate next level of Error handling.
> >
> > Signed-off-by: Sumit Saxena <sumit.saxena@avagotech.com>
> > Signed-off-by: Kashyap Desai <kashyap.desai@avagotech.com>
> > ---
> > drivers/scsi/megaraid/megaraid_sas.h | 13 +
> > drivers/scsi/megaraid/megaraid_sas_base.c | 63 +++-
> > drivers/scsi/megaraid/megaraid_sas_fusion.c | 479
> > ++++++++++++++++++++++++++-
> > drivers/scsi/megaraid/megaraid_sas_fusion.h | 117 +++++++-
> > 4 files changed, 653 insertions(+), 19 deletions(-)
> >
> > diff --git a/drivers/scsi/megaraid/megaraid_sas.h
> > b/drivers/scsi/megaraid/megaraid_sas.h
> > index dcc6ff8..0fcb156 100644
> > --- a/drivers/scsi/megaraid/megaraid_sas.h
> > +++ b/drivers/scsi/megaraid/megaraid_sas.h
> > @@ -1520,6 +1520,15 @@ union megasas_frame {
> > u8 raw_bytes[64];
> > };
> >
> > +/**
> > + * struct MR_PRIV_DEVICE - sdev private hostdata
> > + * @is_tm_capable: firmware managed tm_capable flag
> > + * @tm_busy: TM request is in progress */ struct MR_PRIV_DEVICE {
> > + bool is_tm_capable;
> > + bool tm_busy;
> > +};
> > struct megasas_cmd;
> >
> > union megasas_evt_class_locale {
> > @@ -2073,4 +2082,8 @@ void megasas_return_mfi_mpt_pthr(struct
> > megasas_instance *instance, int megasas_cmd_type(struct scsi_cmnd
> > *cmd); void megasas_setup_jbod_map(struct megasas_instance
> > *instance);
> >
> > +void megasas_update_sdev_properties(struct scsi_device *sdev); int
> > +megasas_reset_fusion(struct Scsi_Host *shost, int reason); int
> > +megasas_task_abort_fusion(struct scsi_cmnd *scmd); int
> > +megasas_reset_target_fusion(struct scsi_cmnd *scmd);
> > #endif /*LSI_MEGARAID_SAS_H */
> > diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c
> > b/drivers/scsi/megaraid/megaraid_sas_base.c
> > index 380c627..c1dc23c 100644
> > --- a/drivers/scsi/megaraid/megaraid_sas_base.c
> > +++ b/drivers/scsi/megaraid/megaraid_sas_base.c
> > @@ -189,7 +189,6 @@ int
> > wait_and_poll(struct megasas_instance *instance, struct megasas_cmd
*cmd,
> > int seconds);
> > void megasas_reset_reply_desc(struct megasas_instance *instance);
> > -int megasas_reset_fusion(struct Scsi_Host *shost, int iotimeout);
> > void megasas_fusion_ocr_wq(struct work_struct *work); static int
> > megasas_get_ld_vf_affiliation(struct megasas_instance *instance,
> > int initial);
> > @@ -1645,6 +1644,7 @@ megasas_queue_command(struct Scsi_Host *shost,
> > struct scsi_cmnd *scmd) {
> > struct megasas_instance *instance;
> > unsigned long flags;
> > + struct MR_PRIV_DEVICE *mr_device_priv_data;
> >
> > instance = (struct megasas_instance *)
> > scmd->device->host->hostdata;
> > @@ -1681,11 +1681,24 @@ megasas_queue_command(struct Scsi_Host
> *shost, struct scsi_cmnd *scmd)
> > return 0;
> > }
> >
> > + mr_device_priv_data = scmd->device->hostdata;
> > + if (!mr_device_priv_data) {
> > + spin_unlock_irqrestore(&instance->hba_lock, flags);
> > + scmd->result = DID_NO_CONNECT << 16;
> > + scmd->scsi_done(scmd);
> > + return 0;
> > + }
> > +
> > if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) {
> > spin_unlock_irqrestore(&instance->hba_lock, flags);
> > return SCSI_MLQUEUE_HOST_BUSY;
> > }
> >
> > + if (mr_device_priv_data->tm_busy) {
> > + spin_unlock_irqrestore(&instance->hba_lock, flags);
> > + return SCSI_MLQUEUE_DEVICE_BUSY;
> > + }
> > +
> > spin_unlock_irqrestore(&instance->hba_lock, flags);
> >
> > scmd->result = 0;
> > @@ -1736,27 +1749,39 @@ static struct megasas_instance
> > *megasas_lookup_instance(u16 host_no) }
> >
> > /*
> > -* megasas_set_dma_alignment - Set DMA alignment for PI enabled VD
> > +* megasas_update_sdev_properties - Update sdev structure based on
> > +controller's FW capabilities
> > *
> > * @sdev: OS provided scsi device
> > *
> > * Returns void
> > */
> > -static void megasas_set_dma_alignment(struct scsi_device *sdev)
> > +void megasas_update_sdev_properties(struct scsi_device *sdev)
> > {
> > + u16 pd_index = 0;
> > u32 device_id, ld;
> > struct megasas_instance *instance;
> > struct fusion_context *fusion;
> > + struct MR_PRIV_DEVICE *mr_device_priv_data;
> > + struct MR_PD_CFG_SEQ_NUM_SYNC *pd_sync;
> > struct MR_LD_RAID *raid;
> > struct MR_DRV_RAID_MAP_ALL *local_map_ptr;
> >
> > instance = megasas_lookup_instance(sdev->host->host_no);
> > fusion = instance->ctrl_context;
> > + mr_device_priv_data = sdev->hostdata;
> >
> > - if (!fusion)
> > + if (!fusion || !mr_device_priv_data)
> > return;
>
> How can this happen that mr_device_priv_data is NULL, and if isn't it a
problem
> that you do not set the dma alignment and other megasas_instance values?
>
Yes, "mr_device_priv_data" cannot be NULL. If allocation of
"mr_device_priv_data" is failed inside slave_alloc then slave_config will
not be called at all for that particular "sdev".
I will send modified patch.
> >
> > - if (sdev->channel >= MEGASAS_MAX_PD_CHANNELS) {
> > + if (sdev->channel < MEGASAS_MAX_PD_CHANNELS &&
> > + instance->use_seqnum_jbod_fp) {
> > + pd_index = (sdev->channel *
> MEGASAS_MAX_DEV_PER_CHANNEL) +
> > + sdev->id;
> > + pd_sync = (void *)fusion->pd_seq_sync
> > + [(instance->pd_seq_map_id - 1) & 1];
> > + mr_device_priv_data->is_tm_capable =
> > + pd_sync->seq[pd_index].capability.tmCapable;
> > + } else {
> > device_id = ((sdev->channel % 2) *
> MEGASAS_MAX_DEV_PER_CHANNEL)
> > + sdev->id;
> > local_map_ptr = fusion->ld_drv_map[(instance->map_id &
1)];
> @@
> > -1764,10 +1789,14 @@ static void megasas_set_dma_alignment(struct
> scsi_device *sdev)
> > raid = MR_LdRaidGet(ld, local_map_ptr);
> >
> > if (raid->capability.ldPiMode ==
> MR_PROT_INFO_TYPE_CONTROLLER)
> > - blk_queue_update_dma_alignment(sdev-
> >request_queue, 0x7);
> > + blk_queue_update_dma_alignment(sdev->request_queue, 0x7);
>
> Please keep the whitespace above.
Ok..
>
> > +
> > + mr_device_priv_data->is_tm_capable =
> > + raid->capability.tmCapable;
> > }
> > }
> >
> > +
> > static int megasas_slave_configure(struct scsi_device *sdev) {
> > u16 pd_index = 0;
> > @@ -1784,7 +1813,8 @@ static int megasas_slave_configure(struct
> scsi_device *sdev)
> > return -ENXIO;
> > }
> > }
> > - megasas_set_dma_alignment(sdev);
> > + megasas_update_sdev_properties(sdev);
> > +
> > /*
> > * The RAID firmware may require extended timeouts.
> > */
> > @@ -1798,6 +1828,7 @@ static int megasas_slave_alloc(struct
> > scsi_device *sdev) {
> > u16 pd_index = 0;
> > struct megasas_instance *instance ;
> > + struct MR_PRIV_DEVICE *mr_device_priv_data;
> >
> > instance = megasas_lookup_instance(sdev->host->host_no);
> > if (sdev->channel < MEGASAS_MAX_PD_CHANNELS) { @@ -1809,13
> +1840,26
> > @@ static int megasas_slave_alloc(struct scsi_device *sdev)
> > sdev->id;
> > if ((instance->allow_fw_scan || instance-
> >pd_list[pd_index].driveState ==
> > MR_PD_STATE_SYSTEM)) {
> > - return 0;
> > + goto scan_target;
> > }
> > return -ENXIO;
> > }
> > +
> > +scan_target:
> > + mr_device_priv_data = kzalloc(sizeof(*mr_device_priv_data),
> > + GFP_KERNEL);
> > + if (!mr_device_priv_data)
> > + return -ENOMEM;
> > + sdev->hostdata = mr_device_priv_data;
> > return 0;
> > }
> >
> > +static void megasas_slave_destroy(struct scsi_device *sdev) {
> > + kfree(sdev->hostdata);
> > + sdev->hostdata = NULL;
> > +}
> > +
> > /*
> > * megasas_complete_outstanding_ioctls - Complete outstanding ioctls
after a
> > * kill adapter
> > @@ -2885,6 +2929,7 @@ static struct scsi_host_template
megasas_template
> = {
> > .proc_name = "megaraid_sas",
> > .slave_configure = megasas_slave_configure,
> > .slave_alloc = megasas_slave_alloc,
> > + .slave_destroy = megasas_slave_destroy,
> > .queuecommand = megasas_queue_command,
> > .eh_device_reset_handler = megasas_reset_device,
> > .eh_bus_reset_handler = megasas_reset_bus_host, @@ -5434,6
> +5479,8
> > @@ static int megasas_io_attach(struct megasas_instance *instance)
> > if (instance->ctrl_context) {
> > host->hostt->eh_device_reset_handler = NULL;
> > host->hostt->eh_bus_reset_handler = NULL;
> > + host->hostt->eh_target_reset_handler =
> megasas_reset_target_fusion;
> > + host->hostt->eh_abort_handler = megasas_task_abort_fusion;
> > }
> >
> > /*
> > diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c
> > b/drivers/scsi/megaraid/megaraid_sas_fusion.c
> > index 1dc4537..0b31f5a 100644
> > --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
> > +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
> > @@ -2100,6 +2100,8 @@ complete_cmd_fusion(struct megasas_instance
> *instance, u32 MSIxIndex)
> > struct LD_LOAD_BALANCE_INFO *lbinfo;
> > int threshold_reply_count = 0;
> > struct scsi_cmnd *scmd_local = NULL;
> > + struct MR_TASK_MANAGE_REQUEST *mr_tm_req;
> > + struct MPI2_SCSI_TASK_MANAGE_REQUEST *mpi_tm_req;
> >
> > fusion = instance->ctrl_context;
> >
> > @@ -2141,6 +2143,16 @@ complete_cmd_fusion(struct megasas_instance
> *instance, u32 MSIxIndex)
> > extStatus = scsi_io_req->RaidContext.exStatus;
> >
> > switch (scsi_io_req->Function) {
> > + case MPI2_FUNCTION_SCSI_TASK_MGMT:
> > + mr_tm_req = (struct MR_TASK_MANAGE_REQUEST *)
> > + cmd_fusion->io_request;
> > + mpi_tm_req = (struct
> MPI2_SCSI_TASK_MANAGE_REQUEST *)
> > + &mr_tm_req->TmRequest;
> > + dev_dbg(&instance->pdev->dev, "TM completion:"
> > + "type: 0x%x TaskMID: 0x%x\n",
> > + mpi_tm_req->TaskType, mpi_tm_req-
> >TaskMID);
> > + complete(&cmd_fusion->done);
> > + break;
> > case MPI2_FUNCTION_SCSI_IO_REQUEST: /*Fast Path IO.*/
> > /* Update load balancing info */
> > device_id = MEGASAS_DEV_INDEX(scmd_local); @@ -
> 2727,6 +2739,457 @@
> > void megasas_refire_mgmt_cmd(struct megasas_instance *instance)
> > }
> > }
> >
> > +/*
> > + * megasas_track_scsiio : Track SCSI IOs outstanding to a SCSI device
> > + * @instance: per adapter struct
> > + * @channel: the channel assigned by the OS
> > + * @id: the id assigned by the OS
> > + *
> > + * Returns SUCCESS if no IOs pending to SCSI device, else return
> > +FAILED */
> > +
> > +static int megasas_track_scsiio(struct megasas_instance *instance,
> > + int id, int channel)
> > +{
> > + int i, found = 0;
> > + struct megasas_cmd_fusion *cmd_fusion;
> > + struct fusion_context *fusion;
> > + fusion = instance->ctrl_context;
> > +
> > + for (i = 0 ; i < instance->max_scsi_cmds; i++) {
> > + cmd_fusion = fusion->cmd_list[i];
> > + if (cmd_fusion->scmd &&
> > + (cmd_fusion->scmd->device->id == id &&
> > + cmd_fusion->scmd->device->channel == channel)) {
> > + dev_info(&instance->pdev->dev,
> > + "SCSI commands pending to target"
> > + "channel %d id %d \tSMID: 0x%x\n",
> > + channel, id, cmd_fusion->index);
> > + scsi_print_command(cmd_fusion->scmd);
> > + found = 1;
> > + break;
> > + }
> > + }
> > +
> > + return found ? FAILED : SUCCESS;
> > +}
> > +
> > +/**
> > + * megasas_tm_response_code - translation of device response code
> > + * @ioc: per adapter object
> > + * @mpi_reply: MPI reply returned by firmware
> > + *
> > + * Return nothing.
> > + */
> > +static void
> > +megasas_tm_response_code(struct megasas_instance *instance,
> > + struct MPI2_SCSI_TASK_MANAGE_REPLY *mpi_reply) {
> > + char *desc;
> > +
> > + switch (mpi_reply->ResponseCode) {
> > + case MPI2_SCSITASKMGMT_RSP_TM_COMPLETE:
> > + desc = "task management request completed";
> > + break;
> > + case MPI2_SCSITASKMGMT_RSP_INVALID_FRAME:
> > + desc = "invalid frame";
> > + break;
> > + case MPI2_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED:
> > + desc = "task management request not supported";
> > + break;
> > + case MPI2_SCSITASKMGMT_RSP_TM_FAILED:
> > + desc = "task management request failed";
> > + break;
> > + case MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED:
> > + desc = "task management request succeeded";
> > + break;
> > + case MPI2_SCSITASKMGMT_RSP_TM_INVALID_LUN:
> > + desc = "invalid lun";
> > + break;
> > + case 0xA:
> > + desc = "overlapped tag attempted";
> > + break;
> > + case MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC:
> > + desc = "task queued, however not sent to target";
> > + break;
> > + default:
> > + desc = "unknown";
> > + break;
> > + }
> > + dev_dbg(&instance->pdev->dev, "response_code(%01x): %s\n",
> > + mpi_reply->ResponseCode, desc);
> > + dev_dbg(&instance->pdev->dev,
> > +
> "TerminationCount/DevHandle/Function/TaskType/IOCStat/IOCLoginfo
> "
> > + " 0x%x/0x%x/0x%x/0x%x/0x%x/0x%x\n",
> > + mpi_reply->TerminationCount, mpi_reply->DevHandle,
> > + mpi_reply->Function, mpi_reply->TaskType,
> > + mpi_reply->IOCStatus, mpi_reply->IOCLogInfo); }
> > +
> > +/**
> > + * megasas_issue_tm - main routine for sending tm requests
> > + * @instance: per adapter struct
> > + * @device_handle: device handle
> > + * @channel: the channel assigned by the OS
> > + * @id: the id assigned by the OS
> > + * @type: MPI2_SCSITASKMGMT_TASKTYPE__XXX (defined in
> > +megaraid_sas_fusion.c)
> > + * @smid_task: smid assigned to the task
> > + * @m_type: TM_MUTEX_ON or TM_MUTEX_OFF
> > + * Context: user
> > + *
> > + * MegaRaid use MPT interface for Task Magement request.
> > + * A generic API for sending task management requests to firmware.
> > + *
> > + * Return SUCCESS or FAILED.
> > + */
> > +static int
> > +megasas_issue_tm(struct megasas_instance *instance, u16
device_handle,
> > + uint channel, uint id, u16 smid_task, u8 type) {
> > + struct MR_TASK_MANAGE_REQUEST *mr_request;
> > + struct MPI2_SCSI_TASK_MANAGE_REQUEST *mpi_request;
> > + unsigned long timeleft;
> > + struct megasas_cmd_fusion *cmd_fusion;
> > + struct megasas_cmd *cmd_mfi;
> > + union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc;
> > + struct fusion_context *fusion;
> > + struct megasas_cmd_fusion *scsi_lookup;
> > + int rc;
> > + struct MPI2_SCSI_TASK_MANAGE_REPLY *mpi_reply;
> > +
> > + fusion = instance->ctrl_context;
> > +
> > + cmd_mfi = megasas_get_cmd(instance);
> > +
> > + if (!cmd_mfi) {
> > + dev_err(&instance->pdev->dev, "Failed from %s %d\n",
> > + __func__, __LINE__);
> > + return -ENOMEM;
> > + }
> > +
> > + cmd_fusion = megasas_get_cmd_fusion(instance,
> > + instance->max_scsi_cmds + cmd_mfi->index);
> > +
> > + /* Save the smid. To be used for returning the cmd */
> > + cmd_mfi->context.smid = cmd_fusion->index;
> > +
> > + req_desc = megasas_get_request_descriptor(instance,
> > + (cmd_fusion->index - 1));
> > + if (!req_desc) {
> > + dev_err(&instance->pdev->dev, "Failed from %s %d\n",
> > + __func__, __LINE__);
>
> megasas_return_cmd should be called here?
I will handle this and send updated patch.
>
> > + return -ENOMEM;
> > + }
> > +
> > + cmd_fusion->request_desc = req_desc;
> > + req_desc->Words = 0;
> > +
> > + scsi_lookup = fusion->cmd_list[smid_task - 1];
> > +
> > + mr_request = (struct MR_TASK_MANAGE_REQUEST *) cmd_fusion-
> >io_request;
> > + memset(mr_request, 0, sizeof(struct MR_TASK_MANAGE_REQUEST));
> > + mpi_request = (struct MPI2_SCSI_TASK_MANAGE_REQUEST *)
> &mr_request->TmRequest;
> > + mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
> > + mpi_request->DevHandle = cpu_to_le16(device_handle);
> > + mpi_request->TaskType = type;
> > + mpi_request->TaskMID = cpu_to_le16(smid_task);
> > + mpi_request->LUN[1] = 0;
> > +
> > +
> > + req_desc = cmd_fusion->request_desc;
> > + req_desc->HighPriority.SMID = cpu_to_le16(cmd_fusion->index);
> > + req_desc->HighPriority.RequestFlags =
> > + (MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY <<
> > + MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
> > + req_desc->HighPriority.MSIxIndex = 0;
> > + req_desc->HighPriority.LMID = 0;
> > + req_desc->HighPriority.Reserved1 = 0;
> > +
> > + if (channel < MEGASAS_MAX_PD_CHANNELS)
> > + mr_request->tmReqFlags.isTMForPD = 1;
> > + else
> > + mr_request->tmReqFlags.isTMForLD = 1;
> > +
> > + init_completion(&cmd_fusion->done);
> > + megasas_fire_cmd_fusion(instance, req_desc);
> > +
> > + timeleft = wait_for_completion_timeout(&cmd_fusion->done, 50 *
HZ);
> > +
> > + if (!timeleft) {
> > + dev_err(&instance->pdev->dev,
> > + "task mgmt type 0x%x timed out\n", type);
> > + mutex_unlock(&instance->reset_mutex);
> > + rc = megasas_reset_fusion(instance->host,
> MFI_IO_TIMEOUT_OCR);
> > + mutex_lock(&instance->reset_mutex);
>
> megasas_return_cmd should be called here too?
Agree, I will fix this.
>
> > + return rc;
> > + }
> > +
> > + mpi_reply = (struct MPI2_SCSI_TASK_MANAGE_REPLY *) &mr_request-
> >TMReply;
> > + megasas_tm_response_code(instance, mpi_reply);
> > +
> > + megasas_return_cmd(instance, cmd_mfi);
> > + rc = SUCCESS;
> > + switch (type) {
> > + case MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK:
> > + if (scsi_lookup->scmd == NULL)
> > + break;
> > + else {
> > + instance->instancet->disable_intr(instance);
> > + msleep(1000);
> > + megasas_complete_cmd_dpc_fusion
> > + ((unsigned long)instance);
> > + instance->instancet->enable_intr(instance);
> > + if (scsi_lookup->scmd == NULL)
> > + break;
> > + }
> > + rc = FAILED;
> > + break;
> > +
> > + case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
> > + if ((channel == 0xFFFFFFFF) && (id == 0xFFFFFFFF))
> > + break;
> > + instance->instancet->disable_intr(instance);
> > + msleep(1000);
> > + megasas_complete_cmd_dpc_fusion
> > + ((unsigned long)instance);
> > + rc = megasas_track_scsiio(instance, id, channel);
> > + instance->instancet->enable_intr(instance);
> > +
> > + break;
> > + case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET:
> > + case MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK:
> > + break;
> > + default:
> > + rc = FAILED;
> > + break;
> > + }
> > +
> > + return rc;
> > +
> > +}
> > +
> > +/*
> > + * megasas_fusion_smid_lookup : Look for fusion command
> > +correpspodning to SCSI
> > + * @instance: per adapter struct
> > + *
> > + * Return Non Zero index, if SMID found in outstanding commands */
> > +static u16 megasas_fusion_smid_lookup(struct scsi_cmnd *scmd) {
> > + int i, ret = 0;
> > + struct megasas_instance *instance;
> > + struct megasas_cmd_fusion *cmd_fusion;
> > + struct fusion_context *fusion;
> > +
> > + instance = (struct megasas_instance
*)scmd->device->host->hostdata;
> > +
> > + fusion = instance->ctrl_context;
> > +
> > + for (i = 0; i < instance->max_scsi_cmds; i++) {
> > + cmd_fusion = fusion->cmd_list[i];
> > + if (cmd_fusion->scmd && (cmd_fusion->scmd == scmd)) {
> > + scmd_printk(KERN_NOTICE, scmd, "Abort request is
> for"
> > + " SMID: %d\n", cmd_fusion->index);
> > + ret = cmd_fusion->index;
> > + break;
> > + }
> > + }
> > +
> > + return ret;
> > +}
> > +
> > +/*
> > +* megasas_get_tm_devhandle - Get devhandle for TM request
> > +* @sdev- OS provided scsi device
> > +*
> > +* Returns- devhandle/targetID of SCSI device
> > +*/
> > +static u16 megasas_get_tm_devhandle(struct scsi_device *sdev) {
> > + u16 pd_index = 0;
> > + u32 device_id;
> > + struct megasas_instance *instance;
> > + struct fusion_context *fusion;
> > + struct MR_PD_CFG_SEQ_NUM_SYNC *pd_sync;
> > + u16 devhandle = (u16)ULONG_MAX;
> > +
> > + instance = (struct megasas_instance *)sdev->host->hostdata;
> > + fusion = instance->ctrl_context;
> > +
> > + if (sdev->channel < MEGASAS_MAX_PD_CHANNELS) {
> > + if (instance->use_seqnum_jbod_fp) {
> > + pd_index = (sdev->channel *
> MEGASAS_MAX_DEV_PER_CHANNEL) +
> > + sdev->id;
> > + pd_sync = (void *)fusion->pd_seq_sync
> > + [(instance->pd_seq_map_id
-
> 1) & 1];
> > + devhandle = pd_sync-
> >seq[pd_index].devHandle;
> > + } else
> > + sdev_printk(KERN_ERR, sdev, "Firmware expose
> tmCapable"
> > + " without JBOD MAP support from %s %d\n",
> __func__, __LINE__);
> > + } else {
> > + device_id = ((sdev->channel % 2) *
> MEGASAS_MAX_DEV_PER_CHANNEL)
> > + + sdev->id;
> > + devhandle = device_id;
> > + }
> > +
> > + return devhandle;
> > +}
> > +
> > +/*
> > + * megasas_task_abort_fusion : SCSI task abort function for fusion
> > +adapters
> > + * @scmd : pointer to scsi command object
> > + *
> > + * Return SUCCESS, if command aborted else FAILED */
> > +
> > +int megasas_task_abort_fusion(struct scsi_cmnd *scmd) {
> > + struct megasas_instance *instance;
> > + u16 smid, devhandle;
> > + struct fusion_context *fusion;
> > + int ret;
> > + struct MR_PRIV_DEVICE *mr_device_priv_data;
> > + mr_device_priv_data = scmd->device->hostdata;
> > +
> > +
> > + instance = (struct megasas_instance
*)scmd->device->host->hostdata;
> > + fusion = instance->ctrl_context;
> > +
> > + if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) {
> > + dev_err(&instance->pdev->dev, "Controller is not
> OPERATIONAL,"
> > + "SCSI host:%d\n", instance->host->host_no);
> > + ret = FAILED;
> > + return ret;
> > + }
> > +
> > + if (!mr_device_priv_data) {
> > + sdev_printk(KERN_INFO, scmd->device, "device been deleted!
"
> > + "scmd(%p)\n", scmd);
> > + scmd->result = DID_NO_CONNECT << 16;
> > + scmd->scsi_done(scmd);
>
> Device has been deleted doesn't that imply that all commands had to be
before
> finished - so you should not call scsi_done ?
Agree, I will modify this.
>
> > + ret = SUCCESS;
> > + goto out;
> > + }
> > +
> > +
> > + if (!mr_device_priv_data->is_tm_capable) {
> > + scmd->result = DID_RESET << 16;
>
> I think that setting scmd->result makes no sense here (too) a FAILED
return
> should be enough.
Agree..
>
> > + ret = FAILED;
> > + goto out;
> > + }
> > +
> > + mutex_lock(&instance->reset_mutex);
> > +
> > + smid = megasas_fusion_smid_lookup(scmd);
> > +
> > + if (!smid) {
> > + scmd->result = DID_RESET << 16;
>
> I think that setting scmd->result makes no sense here (too) a SUCCESS
return
> should be enough.
Agree..
>
> > + ret = SUCCESS;
> > + scmd_printk(KERN_NOTICE, scmd, "Command for which abort
> is"
> > + " issued is not found in oustanding commands\n");
> > + mutex_unlock(&instance->reset_mutex);
> > + goto out;
> > + }
> > +
> > + devhandle = megasas_get_tm_devhandle(scmd->device);
> > +
> > + if (devhandle == (u16)ULONG_MAX) {
> > + scmd->result = DID_RESET << 16;
>
> same here and on other places
Hmm..I agree.
>
> > + ret = SUCCESS;
> > + sdev_printk(KERN_INFO, scmd->device,
> > + "task abort issued for invalid devhandle\n");
> > + mutex_unlock(&instance->reset_mutex);
> > + goto out;
> > + }
> > + sdev_printk(KERN_INFO, scmd->device,
> > + "attempting task abort! scmd(%p) tm_dev_handle 0x%x\n",
> > + scmd, devhandle);
> > +
> > + mr_device_priv_data->tm_busy = 1;
> > + ret = megasas_issue_tm(instance, devhandle,
> > + scmd->device->channel, scmd->device->id, smid,
> > + MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK);
> > + mr_device_priv_data->tm_busy = 0;
> > +
> > + mutex_unlock(&instance->reset_mutex);
> > +out:
> > + sdev_printk(KERN_INFO, scmd->device, "task abort: %s scmd(%p)\n",
> > + ((ret == SUCCESS) ? "SUCCESS" : "FAILED"), scmd);
> > +
> > + return ret;
> > +}
> > +
> > +/*
> > + * megasas_reset_target_fusion : target reset function for fusion
> > +adapters
> > + * scmd: SCSI command pointer
> > + *
> > + * Returns SUCCESS if all commands associated with target aborted
> > +else FAILED */
> > +
> > +int megasas_reset_target_fusion(struct scsi_cmnd *scmd) {
> > +
> > + struct megasas_instance *instance;
> > + int ret = FAILED;
> > + u16 devhandle;
> > + struct fusion_context *fusion;
> > + struct MR_PRIV_DEVICE *mr_device_priv_data;
> > + mr_device_priv_data = scmd->device->hostdata;
> > +
> > + instance = (struct megasas_instance
*)scmd->device->host->hostdata;
> > + fusion = instance->ctrl_context;
> > +
> > + if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) {
> > + dev_err(&instance->pdev->dev, "Controller is not
> OPERATIONAL,"
> > + "SCSI host:%d\n", instance->host->host_no);
> > + ret = FAILED;
> > + return ret;
> > + }
> > +
> > + if (!mr_device_priv_data) {
> > + sdev_printk(KERN_INFO, scmd->device, "device been deleted!
"
> > + "scmd(%p)\n", scmd);
> > + scmd->result = DID_NO_CONNECT << 16;
> > + scmd->scsi_done(scmd);
> > + ret = SUCCESS;
> > + goto out;
> > + }
> > +
> > +
> > + if (!mr_device_priv_data->is_tm_capable) {
> > + scmd->result = DID_RESET << 16;
> > + ret = FAILED;
> > + goto out;
> > + }
> > +
> > + mutex_lock(&instance->reset_mutex);
> > + devhandle = megasas_get_tm_devhandle(scmd->device);
> > +
> > + if (devhandle == (u16)ULONG_MAX) {
> > + scmd->result = DID_RESET << 16;
> > + ret = SUCCESS;
> > + sdev_printk(KERN_INFO, scmd->device,
> > + "target reset issued for invalid devhandle\n");
> > + mutex_unlock(&instance->reset_mutex);
> > + goto out;
> > + }
> > +
> > + sdev_printk(KERN_INFO, scmd->device,
> > + "attempting target reset! scmd(%p) tm_dev_handle 0x%x\n",
> > + scmd, devhandle);
> > + mr_device_priv_data->tm_busy = 1;
> > + ret = megasas_issue_tm(instance, devhandle,
> > + scmd->device->channel, scmd->device->id, 0,
> > + MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET);
> > + mr_device_priv_data->tm_busy = 0;
> > + mutex_unlock(&instance->reset_mutex);
> > +out:
> > + scmd_printk(KERN_NOTICE, scmd, "megasas: target reset %s!!\n",
> > + (ret == SUCCESS) ? "SUCCESS" : "FAILED");
> > +
> > + return ret;
> > +}
> > +
> > /* Check for a second path that is currently UP */ int
> > megasas_check_mpio_paths(struct megasas_instance *instance,
> > struct scsi_cmnd *scmd)
> > @@ -2752,7 +3215,7 @@ out:
> > }
> >
> > /* Core fusion reset function */
> > -int megasas_reset_fusion(struct Scsi_Host *shost, int iotimeout)
> > +int megasas_reset_fusion(struct Scsi_Host *shost, int reason)
> > {
> > int retval = SUCCESS, i, convert = 0;
> > struct megasas_instance *instance;
> > @@ -2761,6 +3224,7 @@ int megasas_reset_fusion(struct Scsi_Host
*shost,
> int iotimeout)
> > u32 abs_state, status_reg, reset_adapter;
> > u32 io_timeout_in_crash_mode = 0;
> > struct scsi_cmnd *scmd_local = NULL;
> > + struct scsi_device *sdev;
> >
> > instance = (struct megasas_instance *)shost->hostdata;
> > fusion = instance->ctrl_context;
> > @@ -2779,8 +3243,8 @@ int megasas_reset_fusion(struct Scsi_Host
> > *shost, int iotimeout)
> >
> > /* IO timeout detected, forcibly put FW in FAULT state */
> > if (abs_state != MFI_STATE_FAULT && instance->crash_dump_buf &&
> > - instance->crash_dump_app_support && iotimeout) {
> > - dev_info(&instance->pdev->dev, "IO timeout is detected, "
> > + instance->crash_dump_app_support && reason) {
> > + dev_info(&instance->pdev->dev, "IO/DCMD timeout is
> detected, "
> > "forcibly FAULT Firmware\n");
> > instance->adprecovery = MEGASAS_ADPRESET_SM_INFAULT;
> > status_reg = readl(&instance->reg_set->doorbell);
> > @@ -2819,13 +3283,13 @@ int megasas_reset_fusion(struct Scsi_Host
> *shost, int iotimeout)
> > msleep(1000);
> >
> > /* First try waiting for commands to complete */
> > - if (megasas_wait_for_outstanding_fusion(instance, iotimeout,
> > + if (megasas_wait_for_outstanding_fusion(instance, reason,
> > &convert)) {
> > instance->adprecovery = MEGASAS_ADPRESET_SM_INFAULT;
> > dev_warn(&instance->pdev->dev, "resetting fusion "
> > "adapter scsi%d.\n", instance->host->host_no);
> > if (convert)
> > - iotimeout = 0;
> > + reason = 0;
> >
> > /* Now return commands back to the OS */
> > for (i = 0 ; i < instance->max_scsi_cmds; i++) { @@
-2859,7
> +3323,7
> > @@ int megasas_reset_fusion(struct Scsi_Host *shost, int iotimeout)
> > }
> >
> > /* Let SR-IOV VF & PF sync up if there was a HB failure */
> > - if (instance->requestorId && !iotimeout) {
> > + if (instance->requestorId && !reason) {
> > msleep(MEGASAS_OCR_SETTLE_TIME_VF);
> > /* Look for a late HB update after VF settle time
*/
> > if (abs_state == MFI_STATE_OPERATIONAL && @@ -
> 2954,6 +3418,9 @@
> > int megasas_reset_fusion(struct Scsi_Host *shost, int iotimeout)
> >
> > megasas_setup_jbod_map(instance);
> >
> > + shost_for_each_device(sdev, shost)
> > + megasas_update_sdev_properties(sdev);
> > +
> > clear_bit(MEGASAS_FUSION_IN_RESET,
> > &instance->reset_flags);
> > instance->instancet->enable_intr(instance);
> > diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h
> > b/drivers/scsi/megaraid/megaraid_sas_fusion.h
> > index a9e10c4..a1f1c0b 100644
> > --- a/drivers/scsi/megaraid/megaraid_sas_fusion.h
> > +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h
> > @@ -176,6 +176,7 @@ enum REGION_TYPE {
> > #define MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD (0x0100)
> > #define MPI2_SCSIIO_EEDPFLAGS_INSERT_OP (0x0004)
> > #define MPI2_FUNCTION_SCSI_IO_REQUEST (0x00) /* SCSI IO
*/
> > +#define MPI2_FUNCTION_SCSI_TASK_MGMT (0x01)
> > #define MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY (0x03)
> > #define MPI2_REQ_DESCRIPT_FLAGS_FP_IO (0x06)
> > #define MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO (0x00)
> > @@ -278,6 +279,100 @@ union MPI2_SCSI_IO_CDB_UNION {
> > struct MPI2_SGE_SIMPLE_UNION SGE;
> > };
> >
> >
> +/***************************************************************
> *****
> > +********
> > +* SCSI Task Management messages
> >
> +****************************************************************
> *****
> > +*******/
> > +
> > +/*SCSI Task Management Request Message */ struct
> > +MPI2_SCSI_TASK_MANAGE_REQUEST {
> > + u16 DevHandle; /*0x00 */
> > + u8 ChainOffset; /*0x02 */
> > + u8 Function; /*0x03 */
> > + u8 Reserved1; /*0x04 */
> > + u8 TaskType; /*0x05 */
> > + u8 Reserved2; /*0x06 */
> > + u8 MsgFlags; /*0x07 */
> > + u8 VP_ID; /*0x08 */
> > + u8 VF_ID; /*0x09 */
> > + u16 Reserved3; /*0x0A */
> > + u8 LUN[8]; /*0x0C */
> > + u32 Reserved4[7]; /*0x14 */
> > + u16 TaskMID; /*0x30 */
> > + u16 Reserved5; /*0x32 */
> > +};
> > +
> > +
> > +/*SCSI Task Management Reply Message */ struct
> > +MPI2_SCSI_TASK_MANAGE_REPLY {
> > + u16 DevHandle; /*0x00 */
> > + u8 MsgLength; /*0x02 */
> > + u8 Function; /*0x03 */
> > + u8 ResponseCode; /*0x04 */
> > + u8 TaskType; /*0x05 */
> > + u8 Reserved1; /*0x06 */
> > + u8 MsgFlags; /*0x07 */
> > + u8 VP_ID; /*0x08 */
> > + u8 VF_ID; /*0x09 */
> > + u16 Reserved2; /*0x0A */
> > + u16 Reserved3; /*0x0C */
> > + u16 IOCStatus; /*0x0E */
> > + u32 IOCLogInfo; /*0x10 */
> > + u32 TerminationCount; /*0x14 */
> > + u32 ResponseInfo; /*0x18 */
> > +};
> > +
> > +struct MR_TM_REQUEST {
> > + char request[128];
> > +};
> > +
> > +struct MR_TM_REPLY {
> > + char reply[128];
> > +};
> > +
> > +/* SCSI Task Management Request Message */ struct
> > +MR_TASK_MANAGE_REQUEST {
> > + /*To be type casted to struct MPI2_SCSI_TASK_MANAGE_REQUEST */
> > + struct MR_TM_REQUEST TmRequest;
> > + union {
> > + struct {
> > +#if defined(__BIG_ENDIAN_BITFIELD)
> > + u32 reserved1:30;
> > + u32 isTMForPD:1;
> > + u32 isTMForLD:1;
> > +#else
> > + u32 isTMForLD:1;
> > + u32 isTMForPD:1;
> > + u32 reserved1:30;
> > +#endif
> > + u32 reserved2;
> > + } tmReqFlags;
> > + struct MR_TM_REPLY TMReply;
> > + };
> > +};
> > +
> > +/* TaskType values */
> > +
> > +#define MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK (0x01)
> > +#define MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET (0x02)
> > +#define MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET (0x03)
> > +#define MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET (0x05)
> > +#define MPI2_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET (0x06)
> > +#define MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK (0x07)
> > +#define MPI2_SCSITASKMGMT_TASKTYPE_CLR_ACA (0x08)
> > +#define MPI2_SCSITASKMGMT_TASKTYPE_QRY_TASK_SET (0x09)
> > +#define MPI2_SCSITASKMGMT_TASKTYPE_QRY_ASYNC_EVENT (0x0A)
> > +
> > +/* ResponseCode values */
> > +
> > +#define MPI2_SCSITASKMGMT_RSP_TM_COMPLETE (0x00)
> > +#define MPI2_SCSITASKMGMT_RSP_INVALID_FRAME (0x02)
> > +#define MPI2_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED (0x04)
> > +#define MPI2_SCSITASKMGMT_RSP_TM_FAILED (0x05)
> > +#define MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED (0x08)
> > +#define MPI2_SCSITASKMGMT_RSP_TM_INVALID_LUN (0x09)
> > +#define MPI2_SCSITASKMGMT_RSP_TM_OVERLAPPED_TAG (0x0A)
> > +#define MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC (0x80)
> > +
> > /*
> > * RAID SCSI IO Request Message
> > * Total SGE count will be one less than _MPI2_SCSI_IO_REQUEST @@
> > -548,7 +643,8 @@ struct MR_SPAN_BLOCK_INFO { struct MR_LD_RAID {
> > struct {
> > #if defined(__BIG_ENDIAN_BITFIELD)
> > - u32 reserved4:7;
> > + u32 reserved4:6;
> > + u32 tmCapable:1;
> > u32 fpNonRWCapable:1;
> > u32 fpReadAcrossStripe:1;
> > u32 fpWriteAcrossStripe:1;
> > @@ -570,7 +666,8 @@ struct MR_LD_RAID {
> > u32 fpWriteAcrossStripe:1;
> > u32 fpReadAcrossStripe:1;
> > u32 fpNonRWCapable:1;
> > - u32 reserved4:7;
> > + u32 tmCapable:1;
> > + u32 reserved4:6;
> > #endif
> > } capability;
> > __le32 reserved6;
> > @@ -695,6 +792,7 @@ struct megasas_cmd_fusion {
> > u32 sync_cmd_idx;
> > u32 index;
> > u8 pd_r1_lb;
> > + struct completion done;
> > };
> >
> > struct LD_LOAD_BALANCE_INFO {
> > @@ -808,9 +906,18 @@ struct MR_FW_RAID_MAP_EXT {
> > * * define MR_PD_CFG_SEQ structure for system PDs
> > * */
> > struct MR_PD_CFG_SEQ {
> > - __le16 seqNum;
> > - __le16 devHandle;
> > - u8 reserved[4];
> > + u16 seqNum;
> > + u16 devHandle;
> > + struct {
> > +#if defined(__BIG_ENDIAN_BITFIELD)
> > + u8 reserved:7;
> > + u8 tmCapable:1;
> > +#else
> > + u8 tmCapable:1;
> > + u8 reserved:7;
> > +#endif
> > + } capability;
> > + u8 reserved[3];
> > } __packed;
> >
> > struct MR_PD_CFG_SEQ_NUM_SYNC {
next prev parent reply other threads:[~2016-01-14 12:04 UTC|newest]
Thread overview: 50+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-12-18 13:26 [PATCH 00/15] megaraid_sas: Updates for scsi-next Sumit Saxena
2015-12-18 13:26 ` [PATCH 01/15] megaraid_sas: Do not allow PCI access during OCR Sumit Saxena
2016-01-11 17:02 ` Tomas Henzl
2015-12-18 13:26 ` [PATCH 02/15] megaraid_sas: MFI IO timeout handling Sumit Saxena
2016-01-11 17:02 ` Tomas Henzl
2015-12-18 13:26 ` [PATCH 03/15] megaraid_sas: Syncing request flags macro names with firmware Sumit Saxena
2016-01-11 17:03 ` Tomas Henzl
2015-12-18 13:26 ` [PATCH 04/15] megaraid_sas: Task management support Sumit Saxena
2016-01-11 17:03 ` Tomas Henzl
2016-01-14 12:04 ` Sumit Saxena [this message]
2015-12-18 13:26 ` [PATCH 05/15] megaraid_sas: Update device Queue depth based on interface type Sumit Saxena
2016-01-12 14:16 ` Tomas Henzl
2016-01-14 11:48 ` Sumit Saxena
2015-12-18 13:26 ` [PATCH 06/15] megaraid_sas: Fastpath region lock bypass Sumit Saxena
2016-01-12 14:44 ` Tomas Henzl
2015-12-18 13:27 ` [PATCH 07/15] megaraid_sas: Reply Descriptor Post Queue(RDPQ) support Sumit Saxena
2015-12-18 14:49 ` [PATCH] megaraid_sas: fix kzalloc-simple.cocci warnings kbuild test robot
2015-12-18 14:49 ` [PATCH 07/15] megaraid_sas: Reply Descriptor Post Queue(RDPQ) support kbuild test robot
2016-01-14 17:38 ` Tomas Henzl
2016-01-27 18:15 ` Sumit Saxena
2015-12-18 13:27 ` [PATCH 08/15] megaraid_sas: Code optimization build_and_issue_cmd return-type Sumit Saxena
2016-01-14 18:05 ` Tomas Henzl
2015-12-18 13:27 ` [PATCH 09/15] megaraid_sas: Dual Queue depth support Sumit Saxena
2016-01-19 13:34 ` Tomas Henzl
2016-01-19 13:44 ` Sumit Saxena
2016-01-20 13:55 ` Tomas Henzl
2016-01-20 14:09 ` Sumit Saxena
2016-01-20 14:16 ` Tomas Henzl
2016-01-20 15:08 ` Sumit Saxena
2016-01-20 16:00 ` Tomas Henzl
2016-01-27 2:02 ` Martin K. Petersen
2016-01-27 7:09 ` Sumit Saxena
2015-12-18 13:27 ` [PATCH 10/15] megaraid_sas: IO throttling support Sumit Saxena
2016-01-19 13:38 ` Tomas Henzl
2016-01-28 7:18 ` Sumit Saxena
2015-12-18 13:27 ` [PATCH 11/15] megaraid_sas: Make adprecovery variable atomic Sumit Saxena
2016-01-19 13:52 ` Tomas Henzl
2016-01-28 8:30 ` Sumit Saxena
2015-12-18 13:27 ` [PATCH 12/15] megaraid_sas: MFI adapter's OCR changes Sumit Saxena
2016-01-19 14:22 ` Tomas Henzl
2016-01-28 11:12 ` Sumit Saxena
2015-12-18 13:27 ` [PATCH 13/15] megaraid_sas: Introduce module parameter for SCSI command-timeout Sumit Saxena
2016-01-19 14:57 ` Tomas Henzl
2016-01-28 11:17 ` Sumit Saxena
2015-12-18 13:27 ` [PATCH 14/15] megaraid_sas: SPERC OCR changes Sumit Saxena
2016-01-19 15:14 ` Tomas Henzl
2015-12-18 13:27 ` [PATCH 15/15] megaraid_sas: SPERC boot driver reorder Sumit Saxena
2015-12-18 14:05 ` Christoph Hellwig
2016-01-08 7:07 ` Sumit Saxena
2016-01-12 5:26 ` Sumit Saxena
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=b31b24124b2bb7c5b391c138fa771330@mail.gmail.com \
--to=sumit.saxena@avagotech.com \
--cc=hch@infradead.org \
--cc=jbottomley@parallels.com \
--cc=kashyap.desai@avagotech.com \
--cc=linux-scsi@vger.kernel.org \
--cc=martin.petersen@oracle.com \
--cc=thenzl@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).