aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2017-11-07 05:46:05 -0500
committerMartin K. Petersen <martin.petersen@oracle.com>2017-11-08 18:08:01 -0500
commit820f188659122602ab217dd80cfa32b3ac0c55c0 (patch)
treefa0c4b29d91aa23c785fc1a18784d28e7cddb59e
parent335f83b9113421a65bfb19e0fa6a2b262ca86c26 (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.c26
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
2386int aac_send_safw_hostttime(struct aac_dev *dev, struct timeval *now) 2386int 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
2415int aac_send_hosttime(struct aac_dev *dev, struct timeval *now) 2415int 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)