@@ -165,6 +165,9 @@ enum ssif_stat_indexes {
165
165
/* Number of watchdog pretimeouts. */
166
166
SSIF_STAT_watchdog_pretimeouts ,
167
167
168
+ /* Number of alers received. */
169
+ SSIF_STAT_alerts ,
170
+
168
171
/* Always add statistics before this value, it must be last. */
169
172
SSIF_NUM_STATS
170
173
};
@@ -213,7 +216,16 @@ struct ssif_info {
213
216
#define WDT_PRE_TIMEOUT_INT 0x08
214
217
unsigned char msg_flags ;
215
218
219
+ u8 global_enables ;
216
220
bool has_event_buffer ;
221
+ bool supports_alert ;
222
+
223
+ /*
224
+ * Used to tell what we should do with alerts. If we are
225
+ * waiting on a response, read the data immediately.
226
+ */
227
+ bool got_alert ;
228
+ bool waiting_alert ;
217
229
218
230
/*
219
231
* If set to true, this will request events the next time the
@@ -517,14 +529,10 @@ static int ssif_i2c_send(struct ssif_info *ssif_info,
517
529
static void msg_done_handler (struct ssif_info * ssif_info , int result ,
518
530
unsigned char * data , unsigned int len );
519
531
520
- static void retry_timeout ( unsigned long data )
532
+ static void start_get ( struct ssif_info * ssif_info )
521
533
{
522
- struct ssif_info * ssif_info = (void * ) data ;
523
534
int rv ;
524
535
525
- if (ssif_info -> stopping )
526
- return ;
527
-
528
536
ssif_info -> rtc_us_timer = 0 ;
529
537
530
538
rv = ssif_i2c_send (ssif_info , msg_done_handler , I2C_SMBUS_READ ,
@@ -539,6 +547,46 @@ static void retry_timeout(unsigned long data)
539
547
}
540
548
}
541
549
550
+ static void retry_timeout (unsigned long data )
551
+ {
552
+ struct ssif_info * ssif_info = (void * ) data ;
553
+ unsigned long oflags , * flags ;
554
+ bool waiting ;
555
+
556
+ if (ssif_info -> stopping )
557
+ return ;
558
+
559
+ flags = ipmi_ssif_lock_cond (ssif_info , & oflags );
560
+ waiting = ssif_info -> waiting_alert ;
561
+ ssif_info -> waiting_alert = false;
562
+ ipmi_ssif_unlock_cond (ssif_info , flags );
563
+
564
+ if (waiting )
565
+ start_get (ssif_info );
566
+ }
567
+
568
+
569
+ static void ssif_alert (struct i2c_client * client , unsigned int data )
570
+ {
571
+ struct ssif_info * ssif_info = i2c_get_clientdata (client );
572
+ unsigned long oflags , * flags ;
573
+ bool do_get = false;
574
+
575
+ ssif_inc_stat (ssif_info , alerts );
576
+
577
+ flags = ipmi_ssif_lock_cond (ssif_info , & oflags );
578
+ if (ssif_info -> waiting_alert ) {
579
+ ssif_info -> waiting_alert = false;
580
+ del_timer (& ssif_info -> retry_timer );
581
+ do_get = true;
582
+ } else if (ssif_info -> curr_msg ) {
583
+ ssif_info -> got_alert = true;
584
+ }
585
+ ipmi_ssif_unlock_cond (ssif_info , flags );
586
+ if (do_get )
587
+ start_get (ssif_info );
588
+ }
589
+
542
590
static int start_resend (struct ssif_info * ssif_info );
543
591
544
592
static void msg_done_handler (struct ssif_info * ssif_info , int result ,
@@ -558,9 +606,12 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result,
558
606
if (ssif_info -> retries_left > 0 ) {
559
607
ssif_inc_stat (ssif_info , receive_retries );
560
608
609
+ flags = ipmi_ssif_lock_cond (ssif_info , & oflags );
610
+ ssif_info -> waiting_alert = true;
611
+ ssif_info -> rtc_us_timer = SSIF_MSG_USEC ;
561
612
mod_timer (& ssif_info -> retry_timer ,
562
613
jiffies + SSIF_MSG_JIFFIES );
563
- ssif_info -> rtc_us_timer = SSIF_MSG_USEC ;
614
+ ipmi_ssif_unlock_cond ( ssif_info , flags ) ;
564
615
return ;
565
616
}
566
617
@@ -649,7 +700,7 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result,
649
700
if (rv < 0 ) {
650
701
if (ssif_info -> ssif_debug & SSIF_DEBUG_MSG )
651
702
pr_info (PFX
652
- "Error from i2c_non_blocking_op(2) \n" );
703
+ "Error from ssif_i2c_send \n" );
653
704
654
705
result = - EIO ;
655
706
} else
@@ -863,15 +914,32 @@ static void msg_written_handler(struct ssif_info *ssif_info, int result,
863
914
msg_done_handler (ssif_info , - EIO , NULL , 0 );
864
915
}
865
916
} else {
917
+ unsigned long oflags , * flags ;
918
+ bool got_alert ;
919
+
866
920
ssif_inc_stat (ssif_info , sent_messages );
867
921
ssif_inc_stat (ssif_info , sent_messages_parts );
868
922
869
- /* Wait a jiffie then request the next message */
870
- ssif_info -> retries_left = SSIF_RECV_RETRIES ;
871
- ssif_info -> rtc_us_timer = SSIF_MSG_PART_USEC ;
872
- mod_timer (& ssif_info -> retry_timer ,
873
- jiffies + SSIF_MSG_PART_JIFFIES );
874
- return ;
923
+ flags = ipmi_ssif_lock_cond (ssif_info , & oflags );
924
+ got_alert = ssif_info -> got_alert ;
925
+ if (got_alert ) {
926
+ ssif_info -> got_alert = false;
927
+ ssif_info -> waiting_alert = false;
928
+ }
929
+
930
+ if (got_alert ) {
931
+ ipmi_ssif_unlock_cond (ssif_info , flags );
932
+ /* The alert already happened, try now. */
933
+ retry_timeout ((unsigned long ) ssif_info );
934
+ } else {
935
+ /* Wait a jiffie then request the next message */
936
+ ssif_info -> waiting_alert = true;
937
+ ssif_info -> retries_left = SSIF_RECV_RETRIES ;
938
+ ssif_info -> rtc_us_timer = SSIF_MSG_PART_USEC ;
939
+ mod_timer (& ssif_info -> retry_timer ,
940
+ jiffies + SSIF_MSG_PART_JIFFIES );
941
+ ipmi_ssif_unlock_cond (ssif_info , flags );
942
+ }
875
943
}
876
944
}
877
945
@@ -880,6 +948,8 @@ static int start_resend(struct ssif_info *ssif_info)
880
948
int rv ;
881
949
int command ;
882
950
951
+ ssif_info -> got_alert = false;
952
+
883
953
if (ssif_info -> data_len > 32 ) {
884
954
command = SSIF_IPMI_MULTI_PART_REQUEST_START ;
885
955
ssif_info -> multi_data = ssif_info -> data ;
@@ -1242,6 +1312,8 @@ static int smi_stats_proc_show(struct seq_file *m, void *v)
1242
1312
ssif_get_stat (ssif_info , events ));
1243
1313
seq_printf (m , "watchdog_pretimeouts: %u\n" ,
1244
1314
ssif_get_stat (ssif_info , watchdog_pretimeouts ));
1315
+ seq_printf (m , "alerts: %u\n" ,
1316
+ ssif_get_stat (ssif_info , alerts ));
1245
1317
return 0 ;
1246
1318
}
1247
1319
@@ -1324,6 +1396,12 @@ static bool check_acpi(struct ssif_info *ssif_info, struct device *dev)
1324
1396
return false;
1325
1397
}
1326
1398
1399
+ /*
1400
+ * Global enables we care about.
1401
+ */
1402
+ #define GLOBAL_ENABLES_MASK (IPMI_BMC_EVT_MSG_BUFF | IPMI_BMC_RCV_MSG_INTR | \
1403
+ IPMI_BMC_EVT_MSG_INTR)
1404
+
1327
1405
static int ssif_probe (struct i2c_client * client , const struct i2c_device_id * id )
1328
1406
{
1329
1407
unsigned char msg [3 ];
@@ -1454,6 +1532,8 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id)
1454
1532
goto found ;
1455
1533
}
1456
1534
1535
+ ssif_info -> global_enables = resp [3 ];
1536
+
1457
1537
if (resp [3 ] & IPMI_BMC_EVT_MSG_BUFF ) {
1458
1538
ssif_info -> has_event_buffer = true;
1459
1539
/* buffer is already enabled, nothing to do. */
@@ -1462,18 +1542,37 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id)
1462
1542
1463
1543
msg [0 ] = IPMI_NETFN_APP_REQUEST << 2 ;
1464
1544
msg [1 ] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD ;
1465
- msg [2 ] = resp [ 3 ] | IPMI_BMC_EVT_MSG_BUFF ;
1545
+ msg [2 ] = ssif_info -> global_enables | IPMI_BMC_EVT_MSG_BUFF ;
1466
1546
rv = do_cmd (client , 3 , msg , & len , resp );
1467
1547
if (rv || (len < 2 )) {
1468
- pr_warn (PFX "Error getting global enables: %d %d %2.2x\n" ,
1548
+ pr_warn (PFX "Error setting global enables: %d %d %2.2x\n" ,
1469
1549
rv , len , resp [2 ]);
1470
1550
rv = 0 ; /* Not fatal */
1471
1551
goto found ;
1472
1552
}
1473
1553
1474
- if (resp [2 ] == 0 )
1554
+ if (resp [2 ] == 0 ) {
1475
1555
/* A successful return means the event buffer is supported. */
1476
1556
ssif_info -> has_event_buffer = true;
1557
+ ssif_info -> global_enables |= IPMI_BMC_EVT_MSG_BUFF ;
1558
+ }
1559
+
1560
+ msg [0 ] = IPMI_NETFN_APP_REQUEST << 2 ;
1561
+ msg [1 ] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD ;
1562
+ msg [2 ] = ssif_info -> global_enables | IPMI_BMC_RCV_MSG_INTR ;
1563
+ rv = do_cmd (client , 3 , msg , & len , resp );
1564
+ if (rv || (len < 2 )) {
1565
+ pr_warn (PFX "Error setting global enables: %d %d %2.2x\n" ,
1566
+ rv , len , resp [2 ]);
1567
+ rv = 0 ; /* Not fatal */
1568
+ goto found ;
1569
+ }
1570
+
1571
+ if (resp [2 ] == 0 ) {
1572
+ /* A successful return means the alert is supported. */
1573
+ ssif_info -> supports_alert = true;
1574
+ ssif_info -> global_enables |= IPMI_BMC_RCV_MSG_INTR ;
1575
+ }
1477
1576
1478
1577
found :
1479
1578
ssif_info -> intf_num = atomic_inc_return (& next_intf );
@@ -1831,6 +1930,7 @@ static struct i2c_driver ssif_i2c_driver = {
1831
1930
},
1832
1931
.probe = ssif_probe ,
1833
1932
.remove = ssif_remove ,
1933
+ .alert = ssif_alert ,
1834
1934
.id_table = ssif_id ,
1835
1935
.detect = ssif_detect
1836
1936
};
0 commit comments