On Fri, Jan 27, 2017 at 11:28:40AM -0800, Raghava Aditya Renukunta wrote:
> This patch adds a new functions that periodically sync the time of host
> to the adapter. In addition also informs the adapter that the driver is
> alive and kicking. Only applicable to the HBA1000 and SMARTIOC2000.
> 
> Signed-off-by: Raghava Aditya Renukunta 
> <raghavaaditya.renuku...@microsemi.com>
> Signed-off-by: Dave Carroll <david.carr...@microsemi.com>
> 
> ---
> Changes in  V2:
> None
> 
> Changes in  V3:
> None
> 
>  drivers/scsi/aacraid/aacraid.h |   3 +
>  drivers/scsi/aacraid/commsup.c | 176 
> +++++++++++++++++++++++++++++++++--------
>  2 files changed, 148 insertions(+), 31 deletions(-)
> 
> diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
> index b54c1bf..05884e6 100644
> --- a/drivers/scsi/aacraid/aacraid.h
> +++ b/drivers/scsi/aacraid/aacraid.h
> @@ -88,6 +88,9 @@ enum {
>  #define AAC_MAX_NATIVE_SIZE          2048
>  
>  #define CISS_REPORT_PHYSICAL_LUNS    0xc3
> +#define WRITE_HOST_WELLNESS          0xa5
> +#define BMIC_IN                      0x26
> +#define BMIC_OUT                     0x27
>  
>  struct aac_ciss_phys_luns_resp {
>       u8      list_length[4];         /* LUN list length (N-7, big endian) */
> diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
> index 346c1c0..0c009f1 100644
> --- a/drivers/scsi/aacraid/commsup.c
> +++ b/drivers/scsi/aacraid/commsup.c
> @@ -43,6 +43,7 @@
>  #include <linux/kthread.h>
>  #include <linux/interrupt.h>
>  #include <linux/semaphore.h>
> +#include <linux/bcd.h>
>  #include <scsi/scsi.h>
>  #include <scsi/scsi_host.h>
>  #include <scsi/scsi_device.h>
> @@ -1946,6 +1947,143 @@ static void aac_process_events(struct aac_dev *dev)
>                       flags);
>  }
>  
> +static int aac_send_wellness_command(struct aac_dev *dev, char *wellness_str,
> +                                                     u32 datasize)
> +{
> +     struct aac_srb *srbcmd;
> +     struct sgmap64 *sg64;
> +     dma_addr_t addr;
> +     char *dma_buf;
> +     struct fib *fibptr;
> +     int ret = -ENOMEM;
> +
> +     fibptr = aac_fib_alloc(dev);
> +     if (fibptr) {
> +             aac_fib_init(fibptr);
> +
> +             dma_buf = pci_alloc_consistent(dev->pdev, datasize, &addr);
> +             if (dma_buf != NULL) {

if (!dma_buf)
        return -ENOMEM;

It makes the code flow more obvious and saves you a level of indent.

> +                     u32 vbus, vid;
> +
> +                     vbus = (u32)le16_to_cpu(
> +                             dev->supplement_adapter_info.VirtDeviceBus);
> +                     vid = (u32)le16_to_cpu(
> +                             dev->supplement_adapter_info.VirtDeviceTarget);
> +
> +                     srbcmd = (struct aac_srb *)fib_data(fibptr);
> +
> +                     srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi);
> +                     srbcmd->channel = cpu_to_le32(vbus);
> +                     srbcmd->id = cpu_to_le32(vid);
> +                     srbcmd->lun = 0;
> +                     srbcmd->flags = cpu_to_le32(SRB_DataOut);
> +                     srbcmd->timeout = cpu_to_le32(10);
> +                     srbcmd->retry_limit = 0;
> +                     srbcmd->cdb_size = cpu_to_le32(12);
> +                     srbcmd->count = cpu_to_le32(datasize);
> +
> +                     memset(srbcmd->cdb, 0, sizeof(srbcmd->cdb));
> +                     srbcmd->cdb[0] = BMIC_OUT;
> +                     srbcmd->cdb[6] = WRITE_HOST_WELLNESS;
> +                     memcpy(dma_buf, (char *)wellness_str, datasize);
> +
> +                     sg64 = (struct sgmap64 *)&srbcmd->sg;
> +                     sg64->count = cpu_to_le32(1);
> +                     sg64->sg[0].addr[1] =
> +                             cpu_to_le32((u32)(((addr) >> 16) >> 16));
> +                     sg64->sg[0].addr[0] =
> +                             cpu_to_le32((u32)(addr & 0xffffffff));
> +                     sg64->sg[0].count = cpu_to_le32(datasize);
> +
> +                     ret = aac_fib_send(ScsiPortCommand64, fibptr,
> +                             sizeof(struct aac_srb), FsaNormal,
> +                             1, 1, NULL, NULL);
> +
> +                     pci_free_consistent(dev->pdev, datasize,
> +                                             (void *)dma_buf, addr);
> +     }
> +
> +             /*
> +              * Do not set XferState to zero unless
> +              * receives a response from F/W
> +              */
> +             if (ret >= 0)
> +                     aac_fib_complete(fibptr);
> +
> +             /*
> +              * FIB should be freed only after
> +              * getting the response from the F/W
> +              */
> +             if (ret != -ERESTARTSYS)
> +                     aac_fib_free(fibptr);
> +     }

Not sure if it's my mailclient, but indentation looks a bit odd here.

> +
> +     return ret;
> +}
> +
> +int aac_send_hosttime(struct aac_dev *dev, struct timeval *now)
> +{
> +     int ret = -ENOMEM;
> +     struct fib *fibptr;
> +
> +     /*
> +      *  This whole block needs to be rewritten with helpers
> +      *  Changing tabs to a single space should not be allowed!!
> +      */
> +
> +     if (dev->sa_firmware) {
> +             struct tm cur_tm;
> +             char wellness_str[] = "<HW>TD\010\0\0\0\0\0\0\0\0\0DW\0\0ZZ";
> +             u32 datasize = sizeof(wellness_str);
> +             unsigned long local_time;
> +
> +             local_time = (u32)(now->tv_sec - (sys_tz.tz_minuteswest * 60));
> +             time_to_tm(local_time, 0, &cur_tm);
> +             cur_tm.tm_mon += 1;
> +             cur_tm.tm_year += 1900;
> +             wellness_str[8] = bin2bcd(cur_tm.tm_hour);
> +             wellness_str[9] = bin2bcd(cur_tm.tm_min);
> +             wellness_str[10] = bin2bcd(cur_tm.tm_sec);
> +             wellness_str[12] = bin2bcd(cur_tm.tm_mon);
> +             wellness_str[13] = bin2bcd(cur_tm.tm_mday);
> +             wellness_str[14] = bin2bcd(cur_tm.tm_year / 100);
> +             wellness_str[15] = bin2bcd(cur_tm.tm_year % 100);
> +
> +             ret = aac_send_wellness_command(dev, wellness_str, datasize);
> +
> +             return ret;
> +     }
> +
> +     fibptr = aac_fib_alloc(dev);
> +     if (fibptr) {

Same here.

> +             __le32 *info;
> +
> +             aac_fib_init(fibptr);
> +             info = (__le32 *)fib_data(fibptr);
> +             *info = cpu_to_le32(now->tv_sec);
> +             ret = aac_fib_send(
> +                     SendHostTime, fibptr,
> +                     sizeof(*info), FsaNormal,
> +                     1, 1, NULL, NULL);
> +
> +             /*
> +              * Do not set XferState to zero unless
> +              * receives a response from F/W
> +              */
> +             if (ret >= 0)
> +                     aac_fib_complete(fibptr);
> +
> +             /*
> +              * FIB should be freed only after
> +              * getting the response from the F/W
> +              */
> +             if (ret != -ERESTARTSYS)
> +                     aac_fib_free(fibptr);
> +     }
> +
> +     return ret;
> +}
> +
>  /**
>   *   aac_command_thread      -       command processing thread
>   *   @dev: Adapter to monitor
> @@ -2001,7 +2139,7 @@ int aac_command_thread(void *data)
>  
>                       /* Don't even try to talk to adapter if its sick */
>                       ret = aac_check_health(dev);
> -                     if (!ret && !dev->queues)
> +                     if (!dev->queues)
>                               break;
>                       next_check_jiffies = jiffies
>                                          + ((long)(unsigned)check_interval)
> @@ -2014,36 +2152,12 @@ int aac_command_thread(void *data)
>                               difference = (((1000000 - now.tv_usec) * HZ)
>                                 + 500000) / 1000000;
>                       else if (ret == 0) {
> -                             struct fib *fibptr;
> -
> -                             if ((fibptr = aac_fib_alloc(dev))) {
> -                                     int status;
> -                                     __le32 *info;
> -
> -                                     aac_fib_init(fibptr);
> -
> -                                     info = (__le32 *) fib_data(fibptr);
> -                                     if (now.tv_usec > 500000)
> -                                             ++now.tv_sec;
> -
> -                                     *info = cpu_to_le32(now.tv_sec);
> -
> -                                     status = aac_fib_send(SendHostTime,
> -                                             fibptr,
> -                                             sizeof(*info),
> -                                             FsaNormal,
> -                                             1, 1,
> -                                             NULL,
> -                                             NULL);
> -                                     /* Do not set XferState to zero unless
> -                                      * receives a response from F/W */
> -                                     if (status >= 0)
> -                                             aac_fib_complete(fibptr);
> -                                     /* FIB should be freed only after
> -                                      * getting the response from the F/W */
> -                                     if (status != -ERESTARTSYS)
> -                                             aac_fib_free(fibptr);
> -                             }
> +
> +                             if (now.tv_usec > 500000)
> +                                     ++now.tv_sec;
> +
> +                             ret = aac_send_hosttime(dev, &now);
> +
>                               difference = (long)(unsigned)update_interval*HZ;
>                       } else {
>                               /* retry shortly */
> -- 
> 2.7.4
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 
Johannes Thumshirn                                          Storage
jthumsh...@suse.de                                +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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to