scsi: aacraid: use timespec64 instead of timeval
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>
This commit is contained in:
parent
335f83b911
commit
820f188659
|
@ -2383,19 +2383,19 @@ fib_free_out:
|
|||
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);
|
||||
|
@ -2412,7 +2412,7 @@ out:
|
|||
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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue