diff options
author | Arnd Bergmann <arnd@arndb.de> | 2017-11-07 05:46:05 -0500 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2017-11-08 18:08:01 -0500 |
commit | 820f188659122602ab217dd80cfa32b3ac0c55c0 (patch) | |
tree | fa0c4b29d91aa23c785fc1a18784d28e7cddb59e | |
parent | 335f83b9113421a65bfb19e0fa6a2b262ca86c26 (diff) |
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>
-rw-r--r-- | drivers/scsi/aacraid/commsup.c | 26 |
1 files changed, 13 insertions, 13 deletions
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index dfe8e70f8d99..525a652dab48 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c | |||
@@ -2383,19 +2383,19 @@ fib_free_out: | |||
2383 | goto out; | 2383 | goto out; |
2384 | } | 2384 | } |
2385 | 2385 | ||
2386 | int aac_send_safw_hostttime(struct aac_dev *dev, struct timeval *now) | 2386 | int aac_send_safw_hostttime(struct aac_dev *dev, struct timespec64 *now) |
2387 | { | 2387 | { |
2388 | struct tm cur_tm; | 2388 | struct tm cur_tm; |
2389 | char wellness_str[] = "<HW>TD\010\0\0\0\0\0\0\0\0\0DW\0\0ZZ"; | 2389 | char wellness_str[] = "<HW>TD\010\0\0\0\0\0\0\0\0\0DW\0\0ZZ"; |
2390 | u32 datasize = sizeof(wellness_str); | 2390 | u32 datasize = sizeof(wellness_str); |
2391 | unsigned long local_time; | 2391 | time64_t local_time; |
2392 | int ret = -ENODEV; | 2392 | int ret = -ENODEV; |
2393 | 2393 | ||
2394 | if (!dev->sa_firmware) | 2394 | if (!dev->sa_firmware) |
2395 | goto out; | 2395 | goto out; |
2396 | 2396 | ||
2397 | local_time = (u32)(now->tv_sec - (sys_tz.tz_minuteswest * 60)); | 2397 | local_time = (now->tv_sec - (sys_tz.tz_minuteswest * 60)); |
2398 | time_to_tm(local_time, 0, &cur_tm); | 2398 | time64_to_tm(local_time, 0, &cur_tm); |
2399 | cur_tm.tm_mon += 1; | 2399 | cur_tm.tm_mon += 1; |
2400 | cur_tm.tm_year += 1900; | 2400 | cur_tm.tm_year += 1900; |
2401 | wellness_str[8] = bin2bcd(cur_tm.tm_hour); | 2401 | wellness_str[8] = bin2bcd(cur_tm.tm_hour); |
@@ -2412,7 +2412,7 @@ out: | |||
2412 | return ret; | 2412 | return ret; |
2413 | } | 2413 | } |
2414 | 2414 | ||
2415 | int aac_send_hosttime(struct aac_dev *dev, struct timeval *now) | 2415 | int aac_send_hosttime(struct aac_dev *dev, struct timespec64 *now) |
2416 | { | 2416 | { |
2417 | int ret = -ENOMEM; | 2417 | int ret = -ENOMEM; |
2418 | struct fib *fibptr; | 2418 | struct fib *fibptr; |
@@ -2424,7 +2424,7 @@ int aac_send_hosttime(struct aac_dev *dev, struct timeval *now) | |||
2424 | 2424 | ||
2425 | aac_fib_init(fibptr); | 2425 | aac_fib_init(fibptr); |
2426 | info = (__le32 *)fib_data(fibptr); | 2426 | info = (__le32 *)fib_data(fibptr); |
2427 | *info = cpu_to_le32(now->tv_sec); | 2427 | *info = cpu_to_le32(now->tv_sec); /* overflow in y2106 */ |
2428 | ret = aac_fib_send(SendHostTime, fibptr, sizeof(*info), FsaNormal, | 2428 | ret = aac_fib_send(SendHostTime, fibptr, sizeof(*info), FsaNormal, |
2429 | 1, 1, NULL, NULL); | 2429 | 1, 1, NULL, NULL); |
2430 | 2430 | ||
@@ -2496,7 +2496,7 @@ int aac_command_thread(void *data) | |||
2496 | } | 2496 | } |
2497 | if (!time_before(next_check_jiffies,next_jiffies) | 2497 | if (!time_before(next_check_jiffies,next_jiffies) |
2498 | && ((difference = next_jiffies - jiffies) <= 0)) { | 2498 | && ((difference = next_jiffies - jiffies) <= 0)) { |
2499 | struct timeval now; | 2499 | struct timespec64 now; |
2500 | int ret; | 2500 | int ret; |
2501 | 2501 | ||
2502 | /* Don't even try to talk to adapter if its sick */ | 2502 | /* Don't even try to talk to adapter if its sick */ |
@@ -2506,15 +2506,15 @@ int aac_command_thread(void *data) | |||
2506 | next_check_jiffies = jiffies | 2506 | next_check_jiffies = jiffies |
2507 | + ((long)(unsigned)check_interval) | 2507 | + ((long)(unsigned)check_interval) |
2508 | * HZ; | 2508 | * HZ; |
2509 | do_gettimeofday(&now); | 2509 | ktime_get_real_ts64(&now); |
2510 | 2510 | ||
2511 | /* Synchronize our watches */ | 2511 | /* Synchronize our watches */ |
2512 | if (((1000000 - (1000000 / HZ)) > now.tv_usec) | 2512 | if (((NSEC_PER_SEC - (NSEC_PER_SEC / HZ)) > now.tv_nsec) |
2513 | && (now.tv_usec > (1000000 / HZ))) | 2513 | && (now.tv_nsec > (NSEC_PER_SEC / HZ))) |
2514 | difference = (((1000000 - now.tv_usec) * HZ) | 2514 | difference = (((NSEC_PER_SEC - now.tv_nsec) * HZ) |
2515 | + 500000) / 1000000; | 2515 | + NSEC_PER_SEC / 2) / NSEC_PER_SEC; |
2516 | else { | 2516 | else { |
2517 | if (now.tv_usec > 500000) | 2517 | if (now.tv_nsec > NSEC_PER_SEC / 2) |
2518 | ++now.tv_sec; | 2518 | ++now.tv_sec; |
2519 | 2519 | ||
2520 | if (dev->sa_firmware) | 2520 | if (dev->sa_firmware) |