RE: [PATCH V3 16/24] aacraid: Add task management functionality

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




> -----Original Message-----
> From: Johannes Thumshirn [mailto:jthumshirn@xxxxxxx]
> Sent: Monday, January 30, 2017 3:20 AM
> To: Raghava Aditya Renukunta
> <RaghavaAditya.Renukunta@xxxxxxxxxxxxx>
> Cc: jejb@xxxxxxxxxxxxxxxxxx; martin.petersen@xxxxxxxxxx; linux-
> scsi@xxxxxxxxxxxxxxx; Dave Carroll <david.carroll@xxxxxxxxxxxxx>; Gana
> Sridaran <gana.sridaran@xxxxxxxxxxxxx>; Scott Benesh
> <scott.benesh@xxxxxxxxxxxxx>
> Subject: Re: [PATCH V3 16/24] aacraid: Add task management functionality
> 
> EXTERNAL EMAIL
> 
> 
> On Fri, Jan 27, 2017 at 11:28:45AM -0800, Raghava Aditya Renukunta wrote:
> > Added support to send out task management commands.
> >
> > Signed-off-by: Raghava Aditya Renukunta
> <RaghavaAditya.Renukunta@xxxxxxxxxxxxx>
> > Signed-off-by: Dave Carroll <David.Carroll@xxxxxxxxxxxxx>
> >
> > ---
> 
> [...]
> 
> > @@ -3365,7 +3462,151 @@ static void aac_srb_callback(void *context,
> struct fib * fibptr)
> >
> >  /**
> >   *
> > - * aac_send_scb_fib
> > + * aac_hba_callback
> > + * @context: the context set in the fib - here it is scsi cmd
> > + * @fibptr: pointer to the fib
> > + *
> > + * Handles the completion of a native HBA scsi command
> > + *
> > + */
> > +void aac_hba_callback(void *context, struct fib *fibptr)
> > +{
> > +     struct aac_dev *dev;
> > +     struct scsi_cmnd *scsicmd;
> > +
> > +     scsicmd = (struct scsi_cmnd *) context;
> > +
> > +     if (!aac_valid_context(scsicmd, fibptr))
> > +             return;
> > +
> > +     WARN_ON(fibptr == NULL);
> > +     dev = fibptr->dev;
> > +
> > +     if (!(fibptr->flags & FIB_CONTEXT_FLAG_NATIVE_HBA_TMF))
> > +             scsi_dma_unmap(scsicmd);
> > +
> > +     if (fibptr->flags & FIB_CONTEXT_FLAG_FASTRESP) {
> > +             /* fast response */
> > +             scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
> > +     } else {
> > +             struct aac_hba_resp *err =
> > +                     &((struct aac_native_hba *)fibptr->hw_fib_va)->resp.err;
> > +
> > +             // BUG_ON(err->iu_type != HBA_IU_TYPE_RESP);
> 
> Please zap that C++ comment and see if you can tidy up the remaining code a
> bit (e.g a new function for the else block, switch statement iterating over
> err->serivce_response, etc...)

Yes Johannes,
I have some ideas to rewrite this bit of code, let me go ahead and do it then.


> > +             if (err->service_response ==
> HBA_RESP_SVCRES_TASK_COMPLETE) {
> > +                     scsicmd->result = err->status;
> > +                     /* set residual count */
> > +                     scsi_set_resid(scsicmd,
> > +                             le32_to_cpu(err->residual_count));
> > +
> > +                     switch (err->status) {
> > +                     case SAM_STAT_GOOD:
> > +                             scsicmd->result |= DID_OK << 16 |
> > +                                     COMMAND_COMPLETE << 8;
> > +                             break;
> > +                     case SAM_STAT_CHECK_CONDITION:
> > +                     {
> > +                             int len;
> > +
> > +                             len = min_t(u8, err->sense_response_data_len,
> > +                                     SCSI_SENSE_BUFFERSIZE);
> > +                             if (len)
> > +                                     memcpy(scsicmd->sense_buffer,
> > +                                             err->sense_response_buf, len);
> > +                             scsicmd->result |= DID_OK << 16 |
> > +                                     COMMAND_COMPLETE << 8;
> > +                             break;
> > +                     }
> > +                     case SAM_STAT_BUSY:
> > +                             scsicmd->result |= DID_BUS_BUSY << 16 |
> > +                                     COMMAND_COMPLETE << 8;
> > +                             break;
> > +                     case SAM_STAT_TASK_ABORTED:
> > +                             scsicmd->result |= DID_ABORT << 16 |
> > +                                     ABORT << 8;
> > +                             break;
> > +                     case SAM_STAT_RESERVATION_CONFLICT:
> > +                     case SAM_STAT_TASK_SET_FULL:
> > +                     default:
> > +                             scsicmd->result |= DID_ERROR << 16 |
> > +                                     COMMAND_COMPLETE << 8;
> > +                             break;
> > +                     }
> > +             } else if (err->service_response == HBA_RESP_SVCRES_FAILURE) {
> > +                     switch (err->status) {
> > +                     case HBA_RESP_STAT_HBAMODE_DISABLED:
> > +                     {
> > +                             u32 bus, cid;
> > +
> > +                             bus = aac_logical_to_phys(
> > +                                             scmd_channel(scsicmd));
> > +                             cid = scmd_id(scsicmd);
> > +                             if (dev->hba_map[bus][cid].devtype ==
> > +                                     AAC_DEVTYPE_NATIVE_RAW) {
> > +                                     dev->hba_map[bus][cid].devtype =
> > +                                             AAC_DEVTYPE_ARC_RAW;
> > +                                     dev->hba_map[bus][cid].rmw_nexus =
> > +                                             0xffffffff;
> > +                             }
> > +                             scsicmd->result = DID_NO_CONNECT << 16 |
> > +                                     COMMAND_COMPLETE << 8;
> > +                             break;
> > +                     }
> > +                     case HBA_RESP_STAT_IO_ERROR:
> > +                     case HBA_RESP_STAT_NO_PATH_TO_DEVICE:
> > +                             scsicmd->result = DID_OK << 16 |
> > +                                     COMMAND_COMPLETE << 8 | SAM_STAT_BUSY;
> > +                             break;
> > +                     case HBA_RESP_STAT_IO_ABORTED:
> > +                             scsicmd->result = DID_ABORT << 16 |
> > +                                     ABORT << 8;
> > +                             break;
> > +                     case HBA_RESP_STAT_INVALID_DEVICE:
> > +                             scsicmd->result = DID_NO_CONNECT << 16 |
> > +                                     COMMAND_COMPLETE << 8;
> > +                             break;
> > +                     case HBA_RESP_STAT_UNDERRUN:
> > +                             /* UNDERRUN is OK */
> > +                             scsicmd->result = DID_OK << 16 |
> > +                                     COMMAND_COMPLETE << 8;
> > +                             break;
> > +                     case HBA_RESP_STAT_OVERRUN:
> > +                     default:
> > +                             scsicmd->result = DID_ERROR << 16 |
> > +                                     COMMAND_COMPLETE << 8;
> > +                             break;
> > +                     }
> > +             } else if (err->service_response ==
> > +                     HBA_RESP_SVCRES_TMF_REJECTED) {
> > +                     scsicmd->result =
> > +                             DID_ERROR << 16 | MESSAGE_REJECT << 8;
> > +             } else if (err->service_response ==
> > +                     HBA_RESP_SVCRES_TMF_LUN_INVALID) {
> > +                     scsicmd->result =
> > +                             DID_NO_CONNECT << 16 | COMMAND_COMPLETE << 8;
> > +             } else if ((err->service_response ==
> > +                     HBA_RESP_SVCRES_TMF_COMPLETE) ||
> > +                     (err->service_response ==
> > +                     HBA_RESP_SVCRES_TMF_SUCCEEDED)) {
> > +                     scsicmd->result =
> > +                             DID_OK << 16 | COMMAND_COMPLETE << 8;
> > +             } else {
> > +                     scsicmd->result =
> > +                             DID_ERROR << 16 | COMMAND_COMPLETE << 8;
> > +             }
> > +     }
> > +
> > +     aac_fib_complete(fibptr);
> > +
> > +     if (fibptr->flags & FIB_CONTEXT_FLAG_NATIVE_HBA_TMF)
> > +             scsicmd->SCp.sent_command = 1;
> > +     else
> > +             scsicmd->scsi_done(scsicmd);
> > +}
> 
> [...]
> 
> > @@ -3408,6 +3649,54 @@ static int aac_send_srb_fib(struct scsi_cmnd*
> scsicmd)
> >       return -1;
> >  }
> >
> > +/**
> > + *
> > + * aac_send_hba_fib
> > + * @scsicmd: the scsi command block
> > + *
> > + * This routine will form a FIB and fill in the aac_hba_cmd_req from the
> > + * scsicmd passed in.
> > + */
> > +static int aac_send_hba_fib(struct scsi_cmnd *scsicmd)
> > +{
> > +     struct fib *cmd_fibcontext;
> > +     struct aac_dev *dev;
> > +     int status;
> > +
> > +     dev = (struct aac_dev *)scsicmd->device->host->hostdata;
> 
> dev = shost_priv(scsicmd->device->host);

Yes, 

> [...]
> 
> > @@ -3660,6 +3949,73 @@ static int aac_convert_sgraw2(struct
> aac_raw_io2 *rio2, int pages, int nseg, int
> >       return 0;
> >  }
> >
> > +static long aac_build_sghba(struct scsi_cmnd *scsicmd,
> > +                     struct aac_hba_cmd_req *hbacmd,
> > +                     int sg_max,
> > +                     u64 sg_address)
> > +{
> > +     unsigned long byte_count = 0;
> > +     int nseg;
> > +
> > +     nseg = scsi_dma_map(scsicmd);
> > +     if (nseg < 0)
> > +             return nseg;
> 
> if (nseg <= 0)
>         return nseg;

Yes
 
> > +     if (nseg) {
> > +             struct scatterlist *sg;
> > +             int i;
> > +             u32 cur_size;
> > +             struct aac_hba_sgl *sge;
> > +
> > +             if (nseg > HBA_MAX_SG_EMBEDDED)
> > +                     sge = &hbacmd->sge[2];
> > +             else
> > +                     sge = &hbacmd->sge[0];
> > +
> > +             scsi_for_each_sg(scsicmd, sg, nseg, i) {
> > +                     int count = sg_dma_len(sg);
> > +                     u64 addr = sg_dma_address(sg);
> > +
> > +                     WARN_ON(i >= sg_max);
> > +                     sge->addr_hi = cpu_to_le32((u32)(addr>>32));
> > +                     sge->addr_lo = cpu_to_le32((u32)(addr & 0xffffffff));
> > +                     cur_size = cpu_to_le32(count);
> > +                     sge->len = cur_size;
> > +                     sge->flags = 0;
> > +                     byte_count += count;
> > +                     sge++;
> > +             }
> > +
> > +             sge--;
> > +             /* hba wants the size to be exact */
> > +             if (byte_count > scsi_bufflen(scsicmd)) {
> > +                     u32 temp = le32_to_cpu(sge->len) -
> > +                             (byte_count - scsi_bufflen(scsicmd));
> > +                     sge->len = cpu_to_le32(temp);
> > +                     byte_count = scsi_bufflen(scsicmd);
> > +             }
> > +
> > +             if (nseg <= HBA_MAX_SG_EMBEDDED) {
> > +                     hbacmd->emb_data_desc_count = cpu_to_le32(nseg);
> > +                     sge->flags = cpu_to_le32(0x40000000);
> > +             } else {
> > +                     /* not embedded */
> > +                     hbacmd->sge[0].flags = cpu_to_le32(0x80000000);
> > +                     hbacmd->emb_data_desc_count = (u8)cpu_to_le32(1);
> > +                     hbacmd->sge[0].addr_hi =
> > +                             (u32)cpu_to_le32(sg_address >> 32);
> > +                     hbacmd->sge[0].addr_lo =
> > +                             cpu_to_le32((u32)(sg_address & 0xffffffff));
> > +             }
> > +
> > +             /* Check for command underflow */
> > +             if (scsicmd->underflow && (byte_count < scsicmd->underflow)) {
> > +                     pr_warn("aacraid: cmd len %08lX cmd underflow %08X\n",
> > +                                     byte_count, scsicmd->underflow);
> > +             }
> > +     }
> > +     return byte_count;
> > +}
> > +
> >  #ifdef AAC_DETAILED_STATUS_INFO

Regards,
Raghava Aditya

> >  struct aac_srb_status_info {
> > --
> > 2.7.4
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> > the body of a message to majordomo@xxxxxxxxxxxxxxx
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> --
> Johannes Thumshirn                                          Storage
> jthumshirn@xxxxxxx                                +49 911 74053 689
> SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
> GF: Felix Imendörffer, Jane Smithard, Graham Norton
> HRB 21284 (AG Nürnberg)
> Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]

  Powered by Linux