Skip to content

Commit

Permalink
scsi: aacraid: use timespec64 instead of timeval
Browse files Browse the repository at this point in the history
aacraid passes the current time to the firmware in one of two ways,
either as year/month/day/... or as 32-bit unsigned seconds.

The first one is broken on 32-bit architectures as it cannot go past
year 2038. Using timespec64 here makes it behave properly on both 32-bit
and 64-bit architectures, and avoids relying on signed integer overflow
to pass times into the second interface.

The interface used in aac_send_hosttime() however is still problematic
in year 2106 when 32-bit seconds overflow. Hopefully we don't have to
worry about aacraid by that time.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Reviewed-by: Dave Carroll <david.carroll@microsemi.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
  • Loading branch information
Arnd Bergmann authored and Martin K. Petersen committed Nov 8, 2017
1 parent 335f83b commit 820f188
Showing 1 changed file with 13 additions and 13 deletions.
26 changes: 13 additions & 13 deletions drivers/scsi/aacraid/commsup.c
Original file line number Diff line number Diff line change
Expand Up @@ -2383,19 +2383,19 @@ static int aac_send_wellness_command(struct aac_dev *dev, char *wellness_str,
goto out;
}

int aac_send_safw_hostttime(struct aac_dev *dev, struct timeval *now)
int aac_send_safw_hostttime(struct aac_dev *dev, struct timespec64 *now)
{
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;
time64_t local_time;
int ret = -ENODEV;

if (!dev->sa_firmware)
goto out;

local_time = (u32)(now->tv_sec - (sys_tz.tz_minuteswest * 60));
time_to_tm(local_time, 0, &cur_tm);
local_time = (now->tv_sec - (sys_tz.tz_minuteswest * 60));
time64_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);
Expand All @@ -2412,7 +2412,7 @@ int aac_send_safw_hostttime(struct aac_dev *dev, struct timeval *now)
return ret;
}

int aac_send_hosttime(struct aac_dev *dev, struct timeval *now)
int aac_send_hosttime(struct aac_dev *dev, struct timespec64 *now)
{
int ret = -ENOMEM;
struct fib *fibptr;
Expand All @@ -2424,7 +2424,7 @@ int aac_send_hosttime(struct aac_dev *dev, struct timeval *now)

aac_fib_init(fibptr);
info = (__le32 *)fib_data(fibptr);
*info = cpu_to_le32(now->tv_sec);
*info = cpu_to_le32(now->tv_sec); /* overflow in y2106 */
ret = aac_fib_send(SendHostTime, fibptr, sizeof(*info), FsaNormal,
1, 1, NULL, NULL);

Expand Down Expand Up @@ -2496,7 +2496,7 @@ int aac_command_thread(void *data)
}
if (!time_before(next_check_jiffies,next_jiffies)
&& ((difference = next_jiffies - jiffies) <= 0)) {
struct timeval now;
struct timespec64 now;
int ret;

/* Don't even try to talk to adapter if its sick */
Expand All @@ -2506,15 +2506,15 @@ int aac_command_thread(void *data)
next_check_jiffies = jiffies
+ ((long)(unsigned)check_interval)
* HZ;
do_gettimeofday(&now);
ktime_get_real_ts64(&now);

/* Synchronize our watches */
if (((1000000 - (1000000 / HZ)) > now.tv_usec)
&& (now.tv_usec > (1000000 / HZ)))
difference = (((1000000 - now.tv_usec) * HZ)
+ 500000) / 1000000;
if (((NSEC_PER_SEC - (NSEC_PER_SEC / HZ)) > now.tv_nsec)
&& (now.tv_nsec > (NSEC_PER_SEC / HZ)))
difference = (((NSEC_PER_SEC - now.tv_nsec) * HZ)
+ NSEC_PER_SEC / 2) / NSEC_PER_SEC;
else {
if (now.tv_usec > 500000)
if (now.tv_nsec > NSEC_PER_SEC / 2)
++now.tv_sec;

if (dev->sa_firmware)
Expand Down

0 comments on commit 820f188

Please sign in to comment.