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
> <[email protected]>
> Signed-off-by: Dave Carroll <[email protected]>
>
> ---
> 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 [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
Johannes Thumshirn Storage
[email protected] +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 [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html