2019-05-31 01:09:57 -07:00
// SPDX-License-Identifier: GPL-2.0-only
2015-02-01 22:26:15 +01:00
/*
2015-06-09 22:26:05 +02:00
* Secure Element driver for STMicroelectronics NFC NCI chip
2015-02-01 22:26:15 +01:00
*
2015-06-09 22:26:05 +02:00
* Copyright ( C ) 2014 - 2015 STMicroelectronics SAS . All rights reserved .
2015-02-01 22:26:15 +01:00
*/
# include <linux/module.h>
# include <linux/nfc.h>
# include <linux/delay.h>
# include <net/nfc/nci.h>
# include <net/nfc/nci_core.h>
2015-06-09 22:26:05 +02:00
# include "st-nci.h"
2015-02-01 22:26:15 +01:00
2015-06-09 22:26:05 +02:00
struct st_nci_pipe_info {
2015-02-01 22:26:15 +01:00
u8 pipe_state ;
u8 src_host_id ;
u8 src_gate_id ;
u8 dst_host_id ;
u8 dst_gate_id ;
} __packed ;
/* Hosts */
2015-06-09 22:26:05 +02:00
# define ST_NCI_HOST_CONTROLLER_ID 0x00
# define ST_NCI_TERMINAL_HOST_ID 0x01
# define ST_NCI_UICC_HOST_ID 0x02
# define ST_NCI_ESE_HOST_ID 0xc0
2015-02-01 22:26:15 +01:00
/* Gates */
2015-06-09 22:26:05 +02:00
# define ST_NCI_APDU_READER_GATE 0xf0
# define ST_NCI_CONNECTIVITY_GATE 0x41
2015-02-01 22:26:15 +01:00
/* Pipes */
2015-06-09 22:26:05 +02:00
# define ST_NCI_DEVICE_MGNT_PIPE 0x02
2015-02-01 22:26:15 +01:00
/* Connectivity pipe only */
2015-06-09 22:26:05 +02:00
# define ST_NCI_SE_COUNT_PIPE_UICC 0x01
2015-02-01 22:26:15 +01:00
/* Connectivity + APDU Reader pipe */
2015-06-09 22:26:05 +02:00
# define ST_NCI_SE_COUNT_PIPE_EMBEDDED 0x02
2015-02-01 22:26:15 +01:00
2015-06-09 22:26:05 +02:00
# define ST_NCI_SE_TO_HOT_PLUG 1000 /* msecs */
# define ST_NCI_SE_TO_PIPES 2000
2015-02-01 22:26:15 +01:00
2015-06-09 22:26:05 +02:00
# define ST_NCI_EVT_HOT_PLUG_IS_INHIBITED(x) (x->data[0] & 0x80)
2015-02-01 22:26:15 +01:00
# define NCI_HCI_APDU_PARAM_ATR 0x01
# define NCI_HCI_ADMIN_PARAM_SESSION_IDENTITY 0x01
# define NCI_HCI_ADMIN_PARAM_WHITELIST 0x03
# define NCI_HCI_ADMIN_PARAM_HOST_LIST 0x04
2015-06-09 22:26:05 +02:00
# define ST_NCI_EVT_SE_HARD_RESET 0x20
# define ST_NCI_EVT_TRANSMIT_DATA 0x10
2015-10-25 22:54:44 +01:00
# define ST_NCI_EVT_WTX_REQUEST 0x11
2015-06-09 22:26:05 +02:00
# define ST_NCI_EVT_SE_SOFT_RESET 0x11
# define ST_NCI_EVT_SE_END_OF_APDU_TRANSFER 0x21
# define ST_NCI_EVT_HOT_PLUG 0x03
2015-02-01 22:26:15 +01:00
2015-06-09 22:26:05 +02:00
# define ST_NCI_SE_MODE_OFF 0x00
# define ST_NCI_SE_MODE_ON 0x01
2015-02-01 22:26:15 +01:00
2015-06-09 22:26:05 +02:00
# define ST_NCI_EVT_CONNECTIVITY 0x10
# define ST_NCI_EVT_TRANSACTION 0x12
2015-02-01 22:26:15 +01:00
2015-06-09 22:26:05 +02:00
# define ST_NCI_DM_GETINFO 0x13
# define ST_NCI_DM_GETINFO_PIPE_LIST 0x02
# define ST_NCI_DM_GETINFO_PIPE_INFO 0x01
# define ST_NCI_DM_PIPE_CREATED 0x02
# define ST_NCI_DM_PIPE_OPEN 0x04
# define ST_NCI_DM_RF_ACTIVE 0x80
# define ST_NCI_DM_DISCONNECT 0x30
2015-02-01 22:26:15 +01:00
2015-06-09 22:26:05 +02:00
# define ST_NCI_DM_IS_PIPE_OPEN(p) \
( ( p & 0x0f ) = = ( ST_NCI_DM_PIPE_CREATED | ST_NCI_DM_PIPE_OPEN ) )
2015-02-01 22:26:15 +01:00
2015-06-09 22:26:05 +02:00
# define ST_NCI_ATR_DEFAULT_BWI 0x04
2015-02-01 22:26:15 +01:00
/*
* WT = 2 ^ BWI / 10 [ s ] , convert into msecs and add a secure
* room by increasing by 2 this timeout
*/
2015-06-09 22:26:05 +02:00
# define ST_NCI_BWI_TO_TIMEOUT(x) ((1 << x) * 200)
# define ST_NCI_ATR_GET_Y_FROM_TD(x) (x >> 4)
2015-02-01 22:26:15 +01:00
/* If TA is present bit 0 is set */
2015-06-09 22:26:05 +02:00
# define ST_NCI_ATR_TA_PRESENT(x) (x & 0x01)
2015-02-01 22:26:15 +01:00
/* If TB is present bit 1 is set */
2015-06-09 22:26:05 +02:00
# define ST_NCI_ATR_TB_PRESENT(x) (x & 0x02)
2015-02-01 22:26:15 +01:00
2015-06-09 22:26:05 +02:00
# define ST_NCI_NUM_DEVICES 256
2015-02-01 22:26:15 +01:00
2015-06-09 22:26:05 +02:00
static DECLARE_BITMAP ( dev_mask , ST_NCI_NUM_DEVICES ) ;
2015-02-01 22:26:15 +01:00
2015-06-09 22:26:05 +02:00
/* Here are the mandatory pipe for st_nci */
static struct nci_hci_gate st_nci_gates [ ] = {
2015-02-01 22:26:15 +01:00
{ NCI_HCI_ADMIN_GATE , NCI_HCI_ADMIN_PIPE ,
2015-06-09 22:26:05 +02:00
ST_NCI_HOST_CONTROLLER_ID } ,
2015-02-01 22:26:15 +01:00
{ NCI_HCI_LINK_MGMT_GATE , NCI_HCI_LINK_MGMT_PIPE ,
2015-06-09 22:26:05 +02:00
ST_NCI_HOST_CONTROLLER_ID } ,
{ ST_NCI_DEVICE_MGNT_GATE , ST_NCI_DEVICE_MGNT_PIPE ,
ST_NCI_HOST_CONTROLLER_ID } ,
2015-02-01 22:26:15 +01:00
2015-10-25 22:54:33 +01:00
{ NCI_HCI_IDENTITY_MGMT_GATE , NCI_HCI_INVALID_PIPE ,
ST_NCI_HOST_CONTROLLER_ID } ,
2015-02-01 22:26:15 +01:00
/* Secure element pipes are created by secure element host */
2015-06-09 22:26:05 +02:00
{ ST_NCI_CONNECTIVITY_GATE , NCI_HCI_DO_NOT_OPEN_PIPE ,
ST_NCI_HOST_CONTROLLER_ID } ,
{ ST_NCI_APDU_READER_GATE , NCI_HCI_DO_NOT_OPEN_PIPE ,
ST_NCI_HOST_CONTROLLER_ID } ,
2015-02-01 22:26:15 +01:00
} ;
2015-06-09 22:26:05 +02:00
static u8 st_nci_se_get_bwi ( struct nci_dev * ndev )
2015-02-01 22:26:15 +01:00
{
int i ;
u8 td ;
2015-06-09 22:26:05 +02:00
struct st_nci_info * info = nci_get_drvdata ( ndev ) ;
2015-02-01 22:26:15 +01:00
/* Bits 8 to 5 of the first TB for T=1 encode BWI from zero to nine */
2015-06-09 22:26:05 +02:00
for ( i = 1 ; i < ST_NCI_ESE_MAX_LENGTH ; i + + ) {
td = ST_NCI_ATR_GET_Y_FROM_TD ( info - > se_info . atr [ i ] ) ;
if ( ST_NCI_ATR_TA_PRESENT ( td ) )
2015-02-01 22:26:15 +01:00
i + + ;
2015-06-09 22:26:05 +02:00
if ( ST_NCI_ATR_TB_PRESENT ( td ) ) {
2015-02-01 22:26:15 +01:00
i + + ;
return info - > se_info . atr [ i ] > > 4 ;
}
}
2015-06-09 22:26:05 +02:00
return ST_NCI_ATR_DEFAULT_BWI ;
2015-02-01 22:26:15 +01:00
}
2015-06-09 22:26:05 +02:00
static void st_nci_se_get_atr ( struct nci_dev * ndev )
2015-02-01 22:26:15 +01:00
{
2015-06-09 22:26:05 +02:00
struct st_nci_info * info = nci_get_drvdata ( ndev ) ;
2015-02-01 22:26:15 +01:00
int r ;
struct sk_buff * skb ;
2015-06-09 22:26:05 +02:00
r = nci_hci_get_param ( ndev , ST_NCI_APDU_READER_GATE ,
2015-02-01 22:26:15 +01:00
NCI_HCI_APDU_PARAM_ATR , & skb ) ;
if ( r < 0 )
return ;
2015-06-09 22:26:05 +02:00
if ( skb - > len < = ST_NCI_ESE_MAX_LENGTH ) {
2015-02-01 22:26:15 +01:00
memcpy ( info - > se_info . atr , skb - > data , skb - > len ) ;
info - > se_info . wt_timeout =
2015-06-09 22:26:05 +02:00
ST_NCI_BWI_TO_TIMEOUT ( st_nci_se_get_bwi ( ndev ) ) ;
2015-02-01 22:26:15 +01:00
}
kfree_skb ( skb ) ;
}
2015-06-09 22:26:05 +02:00
int st_nci_hci_load_session ( struct nci_dev * ndev )
2015-02-01 22:26:15 +01:00
{
int i , j , r ;
struct sk_buff * skb_pipe_list , * skb_pipe_info ;
2015-06-09 22:26:05 +02:00
struct st_nci_pipe_info * dm_pipe_info ;
u8 pipe_list [ ] = { ST_NCI_DM_GETINFO_PIPE_LIST ,
ST_NCI_TERMINAL_HOST_ID } ;
u8 pipe_info [ ] = { ST_NCI_DM_GETINFO_PIPE_INFO ,
ST_NCI_TERMINAL_HOST_ID , 0 } ;
2015-02-01 22:26:15 +01:00
2015-06-09 22:26:05 +02:00
/* On ST_NCI device pipes number are dynamics
2015-02-01 22:26:15 +01:00
* If pipes are already created , hci_dev_up will fail .
* Doing a clear all pipe is a bad idea because :
* - It does useless EEPROM cycling
* - It might cause issue for secure elements support
* ( such as removing connectivity or APDU reader pipe )
2015-06-09 22:26:05 +02:00
* A better approach on ST_NCI is to :
2015-02-01 22:26:15 +01:00
* - get a pipe list for each host .
2015-06-09 22:26:05 +02:00
* ( eg : ST_NCI_HOST_CONTROLLER_ID for now ) .
2015-02-01 22:26:15 +01:00
* ( TODO Later on UICC HOST and eSE HOST )
* - get pipe information
2015-06-09 22:26:05 +02:00
* - match retrieved pipe list in st_nci_gates
* ST_NCI_DEVICE_MGNT_GATE is a proprietary gate
* with ST_NCI_DEVICE_MGNT_PIPE .
2015-02-01 22:26:15 +01:00
* Pipe can be closed and need to be open .
*/
2015-06-09 22:26:05 +02:00
r = nci_hci_connect_gate ( ndev , ST_NCI_HOST_CONTROLLER_ID ,
ST_NCI_DEVICE_MGNT_GATE ,
ST_NCI_DEVICE_MGNT_PIPE ) ;
2015-02-01 22:26:15 +01:00
if ( r < 0 )
2015-08-14 22:33:34 +02:00
return r ;
2015-02-01 22:26:15 +01:00
/* Get pipe list */
2015-06-09 22:26:05 +02:00
r = nci_hci_send_cmd ( ndev , ST_NCI_DEVICE_MGNT_GATE ,
ST_NCI_DM_GETINFO , pipe_list , sizeof ( pipe_list ) ,
2015-02-01 22:26:15 +01:00
& skb_pipe_list ) ;
if ( r < 0 )
2015-08-14 22:33:34 +02:00
return r ;
2015-02-01 22:26:15 +01:00
/* Complete the existing gate_pipe table */
for ( i = 0 ; i < skb_pipe_list - > len ; i + + ) {
pipe_info [ 2 ] = skb_pipe_list - > data [ i ] ;
2015-06-09 22:26:05 +02:00
r = nci_hci_send_cmd ( ndev , ST_NCI_DEVICE_MGNT_GATE ,
ST_NCI_DM_GETINFO , pipe_info ,
2015-02-01 22:26:15 +01:00
sizeof ( pipe_info ) , & skb_pipe_info ) ;
if ( r )
continue ;
/*
* Match pipe ID and gate ID
* Output format from ST21NFC_DM_GETINFO is :
* - pipe state ( 1 byte )
* - source hid ( 1 byte )
* - source gid ( 1 byte )
* - destination hid ( 1 byte )
* - destination gid ( 1 byte )
*/
2015-06-09 22:26:05 +02:00
dm_pipe_info = ( struct st_nci_pipe_info * ) skb_pipe_info - > data ;
if ( dm_pipe_info - > dst_gate_id = = ST_NCI_APDU_READER_GATE & &
2016-04-30 09:12:42 +02:00
dm_pipe_info - > src_host_id = = ST_NCI_UICC_HOST_ID ) {
2015-02-01 22:26:15 +01:00
pr_err ( " Unexpected apdu_reader pipe on host %x \n " ,
dm_pipe_info - > src_host_id ) ;
2015-08-14 22:33:34 +02:00
kfree_skb ( skb_pipe_info ) ;
2015-02-01 22:26:15 +01:00
continue ;
}
2015-10-25 22:54:34 +01:00
for ( j = 3 ; ( j < ARRAY_SIZE ( st_nci_gates ) ) & &
2015-06-09 22:26:05 +02:00
( st_nci_gates [ j ] . gate ! = dm_pipe_info - > dst_gate_id ) ; j + + )
2015-02-01 22:26:15 +01:00
;
2015-06-09 22:26:05 +02:00
if ( j < ARRAY_SIZE ( st_nci_gates ) & &
st_nci_gates [ j ] . gate = = dm_pipe_info - > dst_gate_id & &
ST_NCI_DM_IS_PIPE_OPEN ( dm_pipe_info - > pipe_state ) ) {
2015-10-25 22:54:30 +01:00
ndev - > hci_dev - > init_data . gates [ j ] . pipe = pipe_info [ 2 ] ;
2015-02-01 22:26:15 +01:00
2015-06-09 22:26:05 +02:00
ndev - > hci_dev - > gate2pipe [ st_nci_gates [ j ] . gate ] =
2015-10-25 22:54:30 +01:00
pipe_info [ 2 ] ;
ndev - > hci_dev - > pipes [ pipe_info [ 2 ] ] . gate =
2015-06-09 22:26:05 +02:00
st_nci_gates [ j ] . gate ;
2015-10-25 22:54:30 +01:00
ndev - > hci_dev - > pipes [ pipe_info [ 2 ] ] . host =
2015-02-01 22:26:15 +01:00
dm_pipe_info - > src_host_id ;
}
2015-08-14 22:33:34 +02:00
kfree_skb ( skb_pipe_info ) ;
2015-02-01 22:26:15 +01:00
}
2015-10-25 22:54:28 +01:00
/*
* 3 gates have a well known pipe ID . Only NCI_HCI_LINK_MGMT_GATE
* is not yet open at this stage .
*/
r = nci_hci_connect_gate ( ndev , ST_NCI_HOST_CONTROLLER_ID ,
NCI_HCI_LINK_MGMT_GATE ,
NCI_HCI_LINK_MGMT_PIPE ) ;
2015-02-01 22:26:15 +01:00
kfree_skb ( skb_pipe_list ) ;
return r ;
}
2015-06-09 22:26:05 +02:00
EXPORT_SYMBOL_GPL ( st_nci_hci_load_session ) ;
2015-02-01 22:26:15 +01:00
2015-06-09 22:26:05 +02:00
static void st_nci_hci_admin_event_received ( struct nci_dev * ndev ,
2015-02-01 22:26:15 +01:00
u8 event , struct sk_buff * skb )
{
2015-06-09 22:26:05 +02:00
struct st_nci_info * info = nci_get_drvdata ( ndev ) ;
2015-02-01 22:26:15 +01:00
switch ( event ) {
2015-06-09 22:26:05 +02:00
case ST_NCI_EVT_HOT_PLUG :
2015-02-01 22:26:15 +01:00
if ( info - > se_info . se_active ) {
2015-06-09 22:26:05 +02:00
if ( ! ST_NCI_EVT_HOT_PLUG_IS_INHIBITED ( skb ) ) {
2015-02-01 22:26:15 +01:00
del_timer_sync ( & info - > se_info . se_active_timer ) ;
info - > se_info . se_active = false ;
complete ( & info - > se_info . req_completion ) ;
} else {
mod_timer ( & info - > se_info . se_active_timer ,
jiffies +
2015-06-09 22:26:05 +02:00
msecs_to_jiffies ( ST_NCI_SE_TO_PIPES ) ) ;
2015-02-01 22:26:15 +01:00
}
}
break ;
2015-10-25 22:54:37 +01:00
default :
nfc_err ( & ndev - > nfc_dev - > dev , " Unexpected event on admin gate \n " ) ;
2015-02-01 22:26:15 +01:00
}
}
2015-06-09 22:26:05 +02:00
static int st_nci_hci_apdu_reader_event_received ( struct nci_dev * ndev ,
2015-02-01 22:26:15 +01:00
u8 event ,
struct sk_buff * skb )
{
int r = 0 ;
2015-06-09 22:26:05 +02:00
struct st_nci_info * info = nci_get_drvdata ( ndev ) ;
2015-02-01 22:26:15 +01:00
pr_debug ( " apdu reader gate event: %x \n " , event ) ;
switch ( event ) {
2015-06-09 22:26:05 +02:00
case ST_NCI_EVT_TRANSMIT_DATA :
2015-02-01 22:26:15 +01:00
del_timer_sync ( & info - > se_info . bwi_timer ) ;
info - > se_info . bwi_active = false ;
info - > se_info . cb ( info - > se_info . cb_context ,
skb - > data , skb - > len , 0 ) ;
break ;
2015-06-09 22:26:05 +02:00
case ST_NCI_EVT_WTX_REQUEST :
2015-02-01 22:26:15 +01:00
mod_timer ( & info - > se_info . bwi_timer , jiffies +
msecs_to_jiffies ( info - > se_info . wt_timeout ) ) ;
break ;
2015-10-25 22:54:37 +01:00
default :
nfc_err ( & ndev - > nfc_dev - > dev , " Unexpected event on apdu reader gate \n " ) ;
return 1 ;
2015-02-01 22:26:15 +01:00
}
kfree_skb ( skb ) ;
return r ;
}
/*
* Returns :
* < = 0 : driver handled the event , skb consumed
* 1 : driver does not handle the event , please do standard processing
*/
2015-06-09 22:26:05 +02:00
static int st_nci_hci_connectivity_event_received ( struct nci_dev * ndev ,
2015-02-01 22:26:15 +01:00
u8 host , u8 event ,
struct sk_buff * skb )
{
int r = 0 ;
2015-02-01 22:26:19 +01:00
struct device * dev = & ndev - > nfc_dev - > dev ;
struct nfc_evt_transaction * transaction ;
2015-02-01 22:26:15 +01:00
pr_debug ( " connectivity gate event: %x \n " , event ) ;
switch ( event ) {
2015-06-09 22:26:05 +02:00
case ST_NCI_EVT_CONNECTIVITY :
2015-12-23 23:45:19 +01:00
r = nfc_se_connectivity ( ndev - > nfc_dev , host ) ;
2015-02-01 22:26:15 +01:00
break ;
2015-06-09 22:26:05 +02:00
case ST_NCI_EVT_TRANSACTION :
2015-03-31 08:02:22 +02:00
/* According to specification etsi 102 622
* 11.2 .2 .4 EVT_TRANSACTION Table 52
* Description Tag Length
* AID 81 5 to 16
* PARAMETERS 82 0 to 255
*/
2015-02-01 22:26:19 +01:00
if ( skb - > len < NFC_MIN_AID_LENGTH + 2 & &
skb - > data [ 0 ] ! = NFC_EVT_TRANSACTION_AID_TAG )
return - EPROTO ;
transaction = ( struct nfc_evt_transaction * ) devm_kzalloc ( dev ,
skb - > len - 2 , GFP_KERNEL ) ;
2019-07-23 17:11:51 -05:00
if ( ! transaction )
return - ENOMEM ;
2015-02-01 22:26:19 +01:00
transaction - > aid_len = skb - > data [ 1 ] ;
2015-03-31 08:02:22 +02:00
memcpy ( transaction - > aid , & skb - > data [ 2 ] , transaction - > aid_len ) ;
2015-02-01 22:26:19 +01:00
2015-03-31 08:02:22 +02:00
/* Check next byte is PARAMETERS tag (82) */
2015-02-01 22:26:19 +01:00
if ( skb - > data [ transaction - > aid_len + 2 ] ! =
NFC_EVT_TRANSACTION_PARAMS_TAG )
return - EPROTO ;
transaction - > params_len = skb - > data [ transaction - > aid_len + 3 ] ;
memcpy ( transaction - > params , skb - > data +
transaction - > aid_len + 4 , transaction - > params_len ) ;
r = nfc_se_transaction ( ndev - > nfc_dev , host , transaction ) ;
2015-03-31 08:02:20 +02:00
break ;
2015-02-01 22:26:15 +01:00
default :
2015-10-25 22:54:37 +01:00
nfc_err ( & ndev - > nfc_dev - > dev , " Unexpected event on connectivity gate \n " ) ;
2015-02-01 22:26:15 +01:00
return 1 ;
}
kfree_skb ( skb ) ;
return r ;
}
2015-06-09 22:26:05 +02:00
void st_nci_hci_event_received ( struct nci_dev * ndev , u8 pipe ,
2015-02-01 22:26:15 +01:00
u8 event , struct sk_buff * skb )
{
u8 gate = ndev - > hci_dev - > pipes [ pipe ] . gate ;
u8 host = ndev - > hci_dev - > pipes [ pipe ] . host ;
switch ( gate ) {
case NCI_HCI_ADMIN_GATE :
2015-06-09 22:26:05 +02:00
st_nci_hci_admin_event_received ( ndev , event , skb ) ;
2015-02-01 22:26:15 +01:00
break ;
2015-06-09 22:26:05 +02:00
case ST_NCI_APDU_READER_GATE :
st_nci_hci_apdu_reader_event_received ( ndev , event , skb ) ;
2015-02-01 22:26:15 +01:00
break ;
2015-06-09 22:26:05 +02:00
case ST_NCI_CONNECTIVITY_GATE :
2015-10-25 22:54:36 +01:00
st_nci_hci_connectivity_event_received ( ndev , host , event , skb ) ;
break ;
2015-02-01 22:26:15 +01:00
}
}
2015-06-09 22:26:05 +02:00
EXPORT_SYMBOL_GPL ( st_nci_hci_event_received ) ;
2015-02-01 22:26:15 +01:00
2015-06-09 22:26:05 +02:00
void st_nci_hci_cmd_received ( struct nci_dev * ndev , u8 pipe , u8 cmd ,
2015-02-01 22:26:15 +01:00
struct sk_buff * skb )
{
2015-06-09 22:26:05 +02:00
struct st_nci_info * info = nci_get_drvdata ( ndev ) ;
2015-02-01 22:26:15 +01:00
u8 gate = ndev - > hci_dev - > pipes [ pipe ] . gate ;
pr_debug ( " cmd: %x \n " , cmd ) ;
switch ( cmd ) {
case NCI_HCI_ANY_OPEN_PIPE :
2015-06-09 22:26:05 +02:00
if ( gate ! = ST_NCI_APDU_READER_GATE & &
ndev - > hci_dev - > pipes [ pipe ] . host ! = ST_NCI_UICC_HOST_ID )
2015-02-01 22:26:15 +01:00
ndev - > hci_dev - > count_pipes + + ;
if ( ndev - > hci_dev - > count_pipes = =
ndev - > hci_dev - > expected_pipes ) {
del_timer_sync ( & info - > se_info . se_active_timer ) ;
info - > se_info . se_active = false ;
ndev - > hci_dev - > count_pipes = 0 ;
complete ( & info - > se_info . req_completion ) ;
}
break ;
}
}
2015-06-09 22:26:05 +02:00
EXPORT_SYMBOL_GPL ( st_nci_hci_cmd_received ) ;
2015-02-01 22:26:15 +01:00
2015-06-09 22:26:05 +02:00
static int st_nci_control_se ( struct nci_dev * ndev , u8 se_idx ,
2015-10-25 22:54:39 +01:00
u8 state )
2015-02-01 22:26:15 +01:00
{
2015-06-09 22:26:05 +02:00
struct st_nci_info * info = nci_get_drvdata ( ndev ) ;
2015-10-25 22:54:41 +01:00
int r , i ;
2015-02-01 22:26:15 +01:00
struct sk_buff * sk_host_list ;
u8 host_id ;
switch ( se_idx ) {
2015-06-09 22:26:05 +02:00
case ST_NCI_UICC_HOST_ID :
2015-02-01 22:26:15 +01:00
ndev - > hci_dev - > count_pipes = 0 ;
2015-06-09 22:26:05 +02:00
ndev - > hci_dev - > expected_pipes = ST_NCI_SE_COUNT_PIPE_UICC ;
2015-02-01 22:26:15 +01:00
break ;
2015-06-09 22:26:05 +02:00
case ST_NCI_ESE_HOST_ID :
2015-02-01 22:26:15 +01:00
ndev - > hci_dev - > count_pipes = 0 ;
2015-06-09 22:26:05 +02:00
ndev - > hci_dev - > expected_pipes = ST_NCI_SE_COUNT_PIPE_EMBEDDED ;
2015-02-01 22:26:15 +01:00
break ;
default :
return - EINVAL ;
}
/*
* Wait for an EVT_HOT_PLUG in order to
* retrieve a relevant host list .
*/
reinit_completion ( & info - > se_info . req_completion ) ;
2015-10-25 22:54:39 +01:00
r = nci_nfcee_mode_set ( ndev , se_idx , state ) ;
2015-02-01 22:26:15 +01:00
if ( r ! = NCI_STATUS_OK )
return r ;
mod_timer ( & info - > se_info . se_active_timer , jiffies +
2015-06-09 22:26:05 +02:00
msecs_to_jiffies ( ST_NCI_SE_TO_HOT_PLUG ) ) ;
2015-02-01 22:26:15 +01:00
info - > se_info . se_active = true ;
/* Ignore return value and check in any case the host_list */
wait_for_completion_interruptible ( & info - > se_info . req_completion ) ;
/* There might be some "collision" after receiving a HOT_PLUG event
* This may cause the CLF to not answer to the next hci command .
* There is no possible synchronization to prevent this .
* Adding a small delay is the only way to solve the issue .
*/
2015-10-25 22:54:39 +01:00
if ( info - > se_info . se_status - > is_ese_present & &
info - > se_info . se_status - > is_uicc_present )
2015-10-25 22:54:40 +01:00
usleep_range ( 15000 , 20000 ) ;
2015-02-01 22:26:15 +01:00
r = nci_hci_get_param ( ndev , NCI_HCI_ADMIN_GATE ,
NCI_HCI_ADMIN_PARAM_HOST_LIST , & sk_host_list ) ;
if ( r ! = NCI_HCI_ANY_OK )
return r ;
2015-10-25 22:54:41 +01:00
for ( i = 0 ; i < sk_host_list - > len & &
sk_host_list - > data [ i ] ! = se_idx ; i + + )
;
host_id = sk_host_list - > data [ i ] ;
2015-02-01 22:26:15 +01:00
kfree_skb ( sk_host_list ) ;
2015-06-09 22:26:05 +02:00
if ( state = = ST_NCI_SE_MODE_ON & & host_id = = se_idx )
2015-02-01 22:26:15 +01:00
return se_idx ;
2015-06-09 22:26:05 +02:00
else if ( state = = ST_NCI_SE_MODE_OFF & & host_id ! = se_idx )
2015-02-01 22:26:15 +01:00
return se_idx ;
return - 1 ;
}
2015-06-09 22:26:05 +02:00
int st_nci_disable_se ( struct nci_dev * ndev , u32 se_idx )
2015-02-01 22:26:15 +01:00
{
int r ;
2015-06-09 22:26:05 +02:00
pr_debug ( " st_nci_disable_se \n " ) ;
2015-02-01 22:26:15 +01:00
2015-10-25 22:54:39 +01:00
/*
* According to upper layer , se_idx = = NFC_SE_UICC when
* info - > se_info . se_status - > is_uicc_enable is true should never happen
* Same for eSE .
*/
r = st_nci_control_se ( ndev , se_idx , ST_NCI_SE_MODE_OFF ) ;
if ( r < 0 ) {
/* Do best effort to release SWP */
if ( se_idx = = NFC_SE_EMBEDDED ) {
r = nci_hci_send_event ( ndev , ST_NCI_APDU_READER_GATE ,
ST_NCI_EVT_SE_END_OF_APDU_TRANSFER ,
NULL , 0 ) ;
}
return r ;
2015-02-01 22:26:15 +01:00
}
return 0 ;
}
2015-06-09 22:26:05 +02:00
EXPORT_SYMBOL_GPL ( st_nci_disable_se ) ;
2015-02-01 22:26:15 +01:00
2015-06-09 22:26:05 +02:00
int st_nci_enable_se ( struct nci_dev * ndev , u32 se_idx )
2015-02-01 22:26:15 +01:00
{
int r ;
2015-06-09 22:26:05 +02:00
pr_debug ( " st_nci_enable_se \n " ) ;
2015-02-01 22:26:15 +01:00
2015-10-25 22:54:39 +01:00
/*
* According to upper layer , se_idx = = NFC_SE_UICC when
* info - > se_info . se_status - > is_uicc_enable is true should never happen .
* Same for eSE .
*/
r = st_nci_control_se ( ndev , se_idx , ST_NCI_SE_MODE_ON ) ;
2016-04-30 09:12:47 +02:00
if ( r = = ST_NCI_ESE_HOST_ID ) {
2015-10-25 22:54:39 +01:00
st_nci_se_get_atr ( ndev ) ;
2015-06-09 22:26:05 +02:00
r = nci_hci_send_event ( ndev , ST_NCI_APDU_READER_GATE ,
ST_NCI_EVT_SE_SOFT_RESET , NULL , 0 ) ;
2015-10-25 22:54:39 +01:00
}
if ( r < 0 ) {
/*
* The activation procedure failed , the secure element
* is not connected . Remove from the list .
*/
nfc_remove_se ( ndev - > nfc_dev , se_idx ) ;
return r ;
2015-02-01 22:26:15 +01:00
}
return 0 ;
}
2015-06-09 22:26:05 +02:00
EXPORT_SYMBOL_GPL ( st_nci_enable_se ) ;
2015-02-01 22:26:15 +01:00
2015-06-09 22:26:05 +02:00
static int st_nci_hci_network_init ( struct nci_dev * ndev )
2015-02-01 22:26:15 +01:00
{
2015-10-25 22:54:36 +01:00
struct st_nci_info * info = nci_get_drvdata ( ndev ) ;
2015-02-03 19:48:05 +01:00
struct core_conn_create_dest_spec_params * dest_params ;
struct dest_spec_params spec_params ;
2015-02-01 22:26:15 +01:00
struct nci_conn_info * conn_info ;
int r , dev_num ;
2015-02-03 19:48:05 +01:00
dest_params =
kzalloc ( sizeof ( struct core_conn_create_dest_spec_params ) +
sizeof ( struct dest_spec_params ) , GFP_KERNEL ) ;
if ( dest_params = = NULL ) {
r = - ENOMEM ;
2015-02-01 22:26:15 +01:00
goto exit ;
2015-02-03 19:48:05 +01:00
}
dest_params - > type = NCI_DESTINATION_SPECIFIC_PARAM_NFCEE_TYPE ;
dest_params - > length = sizeof ( struct dest_spec_params ) ;
2015-02-03 19:48:07 +01:00
spec_params . id = ndev - > hci_dev - > nfcee_id ;
2015-02-03 19:48:05 +01:00
spec_params . protocol = NCI_NFCEE_INTERFACE_HCI_ACCESS ;
2015-06-09 22:26:05 +02:00
memcpy ( dest_params - > value , & spec_params ,
sizeof ( struct dest_spec_params ) ) ;
2015-02-03 19:48:05 +01:00
r = nci_core_conn_create ( ndev , NCI_DESTINATION_NFCEE , 1 ,
sizeof ( struct core_conn_create_dest_spec_params ) +
sizeof ( struct dest_spec_params ) ,
dest_params ) ;
if ( r ! = NCI_STATUS_OK )
goto free_dest_params ;
2015-02-01 22:26:15 +01:00
conn_info = ndev - > hci_dev - > conn_info ;
if ( ! conn_info )
2015-02-03 19:48:05 +01:00
goto free_dest_params ;
2015-02-01 22:26:15 +01:00
2015-10-25 22:54:32 +01:00
ndev - > hci_dev - > init_data . gate_count = ARRAY_SIZE ( st_nci_gates ) ;
2015-06-09 22:26:05 +02:00
memcpy ( ndev - > hci_dev - > init_data . gates , st_nci_gates ,
sizeof ( st_nci_gates ) ) ;
2015-02-01 22:26:15 +01:00
/*
* Session id must include the driver name + i2c bus addr
* persistent info to discriminate 2 identical chips
*/
2015-06-09 22:26:05 +02:00
dev_num = find_first_zero_bit ( dev_mask , ST_NCI_NUM_DEVICES ) ;
if ( dev_num > = ST_NCI_NUM_DEVICES ) {
2015-02-03 19:48:05 +01:00
r = - ENODEV ;
goto free_dest_params ;
}
2015-02-01 22:26:15 +01:00
scnprintf ( ndev - > hci_dev - > init_data . session_id ,
sizeof ( ndev - > hci_dev - > init_data . session_id ) ,
" %s%2x " , " ST21BH " , dev_num ) ;
r = nci_hci_dev_session_init ( ndev ) ;
if ( r ! = NCI_HCI_ANY_OK )
2015-03-31 08:02:14 +02:00
goto free_dest_params ;
2015-02-01 22:26:15 +01:00
2015-10-25 22:54:36 +01:00
/*
* In factory mode , we prevent secure elements activation
* by disabling nfcee on the current HCI connection id .
* HCI will be used here only for proprietary commands .
*/
if ( test_bit ( ST_NCI_FACTORY_MODE , & info - > flags ) )
2016-04-30 09:12:51 +02:00
r = nci_nfcee_mode_set ( ndev ,
ndev - > hci_dev - > conn_info - > dest_params - > id ,
2015-10-25 22:54:36 +01:00
NCI_NFCEE_DISABLE ) ;
else
2016-04-30 09:12:51 +02:00
r = nci_nfcee_mode_set ( ndev ,
ndev - > hci_dev - > conn_info - > dest_params - > id ,
2015-10-25 22:54:36 +01:00
NCI_NFCEE_ENABLE ) ;
2015-02-01 22:26:15 +01:00
2015-02-03 19:48:05 +01:00
free_dest_params :
kfree ( dest_params ) ;
2015-02-01 22:26:15 +01:00
exit :
return r ;
}
2015-06-09 22:26:05 +02:00
int st_nci_discover_se ( struct nci_dev * ndev )
2015-02-01 22:26:15 +01:00
{
2015-10-25 22:54:39 +01:00
u8 white_list [ 2 ] ;
int r , wl_size = 0 ;
2015-02-01 22:26:15 +01:00
int se_count = 0 ;
2015-10-25 22:54:36 +01:00
struct st_nci_info * info = nci_get_drvdata ( ndev ) ;
2015-02-01 22:26:15 +01:00
2015-06-09 22:26:05 +02:00
pr_debug ( " st_nci_discover_se \n " ) ;
2015-02-01 22:26:15 +01:00
2015-06-09 22:26:05 +02:00
r = st_nci_hci_network_init ( ndev ) ;
2015-02-01 22:26:15 +01:00
if ( r ! = 0 )
return r ;
2015-10-25 22:54:36 +01:00
if ( test_bit ( ST_NCI_FACTORY_MODE , & info - > flags ) )
return 0 ;
2016-04-30 09:12:41 +02:00
if ( info - > se_info . se_status - > is_uicc_present )
2015-10-25 22:54:39 +01:00
white_list [ wl_size + + ] = ST_NCI_UICC_HOST_ID ;
2016-04-30 09:12:41 +02:00
if ( info - > se_info . se_status - > is_ese_present )
2015-10-25 22:54:39 +01:00
white_list [ wl_size + + ] = ST_NCI_ESE_HOST_ID ;
if ( wl_size ) {
r = nci_hci_set_param ( ndev , NCI_HCI_ADMIN_GATE ,
NCI_HCI_ADMIN_PARAM_WHITELIST ,
white_list , wl_size ) ;
if ( r ! = NCI_HCI_ANY_OK )
return r ;
}
2015-02-01 22:26:15 +01:00
2015-10-25 22:54:39 +01:00
if ( info - > se_info . se_status - > is_uicc_present ) {
2015-06-09 22:26:05 +02:00
nfc_add_se ( ndev - > nfc_dev , ST_NCI_UICC_HOST_ID , NFC_SE_UICC ) ;
2015-02-01 22:26:15 +01:00
se_count + + ;
}
2015-10-25 22:54:39 +01:00
if ( info - > se_info . se_status - > is_ese_present ) {
nfc_add_se ( ndev - > nfc_dev , ST_NCI_ESE_HOST_ID , NFC_SE_EMBEDDED ) ;
2015-02-01 22:26:15 +01:00
se_count + + ;
}
return ! se_count ;
}
2015-06-09 22:26:05 +02:00
EXPORT_SYMBOL_GPL ( st_nci_discover_se ) ;
2015-02-01 22:26:15 +01:00
2015-06-09 22:26:05 +02:00
int st_nci_se_io ( struct nci_dev * ndev , u32 se_idx ,
2015-02-01 22:26:15 +01:00
u8 * apdu , size_t apdu_length ,
se_io_cb_t cb , void * cb_context )
{
2015-06-09 22:26:05 +02:00
struct st_nci_info * info = nci_get_drvdata ( ndev ) ;
2015-02-01 22:26:15 +01:00
pr_debug ( " \n " ) ;
switch ( se_idx ) {
2016-04-30 09:12:47 +02:00
case ST_NCI_ESE_HOST_ID :
2015-02-01 22:26:15 +01:00
info - > se_info . cb = cb ;
info - > se_info . cb_context = cb_context ;
mod_timer ( & info - > se_info . bwi_timer , jiffies +
msecs_to_jiffies ( info - > se_info . wt_timeout ) ) ;
info - > se_info . bwi_active = true ;
2015-06-09 22:26:05 +02:00
return nci_hci_send_event ( ndev , ST_NCI_APDU_READER_GATE ,
ST_NCI_EVT_TRANSMIT_DATA , apdu ,
2015-02-01 22:26:15 +01:00
apdu_length ) ;
default :
return - ENODEV ;
}
}
2015-06-09 22:26:05 +02:00
EXPORT_SYMBOL ( st_nci_se_io ) ;
2015-02-01 22:26:15 +01:00
treewide: setup_timer() -> timer_setup() (2 field)
This converts all remaining setup_timer() calls that use a nested field
to reach a struct timer_list. Coccinelle does not have an easy way to
match multiple fields, so a new script is needed to change the matches of
"&_E->_timer" into "&_E->_field1._timer" in all the rules.
spatch --very-quiet --all-includes --include-headers \
-I ./arch/x86/include -I ./arch/x86/include/generated \
-I ./include -I ./arch/x86/include/uapi \
-I ./arch/x86/include/generated/uapi -I ./include/uapi \
-I ./include/generated/uapi --include ./include/linux/kconfig.h \
--dir . \
--cocci-file ~/src/data/timer_setup-2fields.cocci
@fix_address_of depends@
expression e;
@@
setup_timer(
-&(e)
+&e
, ...)
// Update any raw setup_timer() usages that have a NULL callback, but
// would otherwise match change_timer_function_usage, since the latter
// will update all function assignments done in the face of a NULL
// function initialization in setup_timer().
@change_timer_function_usage_NULL@
expression _E;
identifier _field1;
identifier _timer;
type _cast_data;
@@
(
-setup_timer(&_E->_field1._timer, NULL, _E);
+timer_setup(&_E->_field1._timer, NULL, 0);
|
-setup_timer(&_E->_field1._timer, NULL, (_cast_data)_E);
+timer_setup(&_E->_field1._timer, NULL, 0);
|
-setup_timer(&_E._field1._timer, NULL, &_E);
+timer_setup(&_E._field1._timer, NULL, 0);
|
-setup_timer(&_E._field1._timer, NULL, (_cast_data)&_E);
+timer_setup(&_E._field1._timer, NULL, 0);
)
@change_timer_function_usage@
expression _E;
identifier _field1;
identifier _timer;
struct timer_list _stl;
identifier _callback;
type _cast_func, _cast_data;
@@
(
-setup_timer(&_E->_field1._timer, _callback, _E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, &_callback, _E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, _callback, (_cast_data)_E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, &_callback, (_cast_data)_E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, (_cast_func)_callback, _E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, (_cast_func)&_callback, _E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, (_cast_func)_callback, (_cast_data)_E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, (_cast_func)&_callback, (_cast_data)_E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, _callback, (_cast_data)_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, _callback, (_cast_data)&_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, &_callback, (_cast_data)_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, &_callback, (_cast_data)&_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, (_cast_func)_callback, (_cast_data)_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, (_cast_func)_callback, (_cast_data)&_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, (_cast_func)&_callback, (_cast_data)_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, (_cast_func)&_callback, (_cast_data)&_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
_E->_field1._timer@_stl.function = _callback;
|
_E->_field1._timer@_stl.function = &_callback;
|
_E->_field1._timer@_stl.function = (_cast_func)_callback;
|
_E->_field1._timer@_stl.function = (_cast_func)&_callback;
|
_E._field1._timer@_stl.function = _callback;
|
_E._field1._timer@_stl.function = &_callback;
|
_E._field1._timer@_stl.function = (_cast_func)_callback;
|
_E._field1._timer@_stl.function = (_cast_func)&_callback;
)
// callback(unsigned long arg)
@change_callback_handle_cast
depends on change_timer_function_usage@
identifier change_timer_function_usage._callback;
identifier change_timer_function_usage._field1;
identifier change_timer_function_usage._timer;
type _origtype;
identifier _origarg;
type _handletype;
identifier _handle;
@@
void _callback(
-_origtype _origarg
+struct timer_list *t
)
{
(
... when != _origarg
_handletype *_handle =
-(_handletype *)_origarg;
+from_timer(_handle, t, _field1._timer);
... when != _origarg
|
... when != _origarg
_handletype *_handle =
-(void *)_origarg;
+from_timer(_handle, t, _field1._timer);
... when != _origarg
|
... when != _origarg
_handletype *_handle;
... when != _handle
_handle =
-(_handletype *)_origarg;
+from_timer(_handle, t, _field1._timer);
... when != _origarg
|
... when != _origarg
_handletype *_handle;
... when != _handle
_handle =
-(void *)_origarg;
+from_timer(_handle, t, _field1._timer);
... when != _origarg
)
}
// callback(unsigned long arg) without existing variable
@change_callback_handle_cast_no_arg
depends on change_timer_function_usage &&
!change_callback_handle_cast@
identifier change_timer_function_usage._callback;
identifier change_timer_function_usage._field1;
identifier change_timer_function_usage._timer;
type _origtype;
identifier _origarg;
type _handletype;
@@
void _callback(
-_origtype _origarg
+struct timer_list *t
)
{
+ _handletype *_origarg = from_timer(_origarg, t, _field1._timer);
+
... when != _origarg
- (_handletype *)_origarg
+ _origarg
... when != _origarg
}
// Avoid already converted callbacks.
@match_callback_converted
depends on change_timer_function_usage &&
!change_callback_handle_cast &&
!change_callback_handle_cast_no_arg@
identifier change_timer_function_usage._callback;
identifier t;
@@
void _callback(struct timer_list *t)
{ ... }
// callback(struct something *handle)
@change_callback_handle_arg
depends on change_timer_function_usage &&
!match_callback_converted &&
!change_callback_handle_cast &&
!change_callback_handle_cast_no_arg@
identifier change_timer_function_usage._callback;
identifier change_timer_function_usage._field1;
identifier change_timer_function_usage._timer;
type _handletype;
identifier _handle;
@@
void _callback(
-_handletype *_handle
+struct timer_list *t
)
{
+ _handletype *_handle = from_timer(_handle, t, _field1._timer);
...
}
// If change_callback_handle_arg ran on an empty function, remove
// the added handler.
@unchange_callback_handle_arg
depends on change_timer_function_usage &&
change_callback_handle_arg@
identifier change_timer_function_usage._callback;
identifier change_timer_function_usage._field1;
identifier change_timer_function_usage._timer;
type _handletype;
identifier _handle;
identifier t;
@@
void _callback(struct timer_list *t)
{
- _handletype *_handle = from_timer(_handle, t, _field1._timer);
}
// We only want to refactor the setup_timer() data argument if we've found
// the matching callback. This undoes changes in change_timer_function_usage.
@unchange_timer_function_usage
depends on change_timer_function_usage &&
!change_callback_handle_cast &&
!change_callback_handle_cast_no_arg &&
!change_callback_handle_arg@
expression change_timer_function_usage._E;
identifier change_timer_function_usage._field1;
identifier change_timer_function_usage._timer;
identifier change_timer_function_usage._callback;
type change_timer_function_usage._cast_data;
@@
(
-timer_setup(&_E->_field1._timer, _callback, 0);
+setup_timer(&_E->_field1._timer, _callback, (_cast_data)_E);
|
-timer_setup(&_E._field1._timer, _callback, 0);
+setup_timer(&_E._field1._timer, _callback, (_cast_data)&_E);
)
// If we fixed a callback from a .function assignment, fix the
// assignment cast now.
@change_timer_function_assignment
depends on change_timer_function_usage &&
(change_callback_handle_cast ||
change_callback_handle_cast_no_arg ||
change_callback_handle_arg)@
expression change_timer_function_usage._E;
identifier change_timer_function_usage._field1;
identifier change_timer_function_usage._timer;
identifier change_timer_function_usage._callback;
type _cast_func;
typedef TIMER_FUNC_TYPE;
@@
(
_E->_field1._timer.function =
-_callback
+(TIMER_FUNC_TYPE)_callback
;
|
_E->_field1._timer.function =
-&_callback
+(TIMER_FUNC_TYPE)_callback
;
|
_E->_field1._timer.function =
-(_cast_func)_callback;
+(TIMER_FUNC_TYPE)_callback
;
|
_E->_field1._timer.function =
-(_cast_func)&_callback
+(TIMER_FUNC_TYPE)_callback
;
|
_E._field1._timer.function =
-_callback
+(TIMER_FUNC_TYPE)_callback
;
|
_E._field1._timer.function =
-&_callback;
+(TIMER_FUNC_TYPE)_callback
;
|
_E._field1._timer.function =
-(_cast_func)_callback
+(TIMER_FUNC_TYPE)_callback
;
|
_E._field1._timer.function =
-(_cast_func)&_callback
+(TIMER_FUNC_TYPE)_callback
;
)
// Sometimes timer functions are called directly. Replace matched args.
@change_timer_function_calls
depends on change_timer_function_usage &&
(change_callback_handle_cast ||
change_callback_handle_cast_no_arg ||
change_callback_handle_arg)@
expression _E;
identifier change_timer_function_usage._field1;
identifier change_timer_function_usage._timer;
identifier change_timer_function_usage._callback;
type _cast_data;
@@
_callback(
(
-(_cast_data)_E
+&_E->_field1._timer
|
-(_cast_data)&_E
+&_E._field1._timer
|
-_E
+&_E->_field1._timer
)
)
// If a timer has been configured without a data argument, it can be
// converted without regard to the callback argument, since it is unused.
@match_timer_function_unused_data@
expression _E;
identifier _field1;
identifier _timer;
identifier _callback;
@@
(
-setup_timer(&_E->_field1._timer, _callback, 0);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, _callback, 0L);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, _callback, 0UL);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, _callback, 0);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, _callback, 0L);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, _callback, 0UL);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_field1._timer, _callback, 0);
+timer_setup(&_field1._timer, _callback, 0);
|
-setup_timer(&_field1._timer, _callback, 0L);
+timer_setup(&_field1._timer, _callback, 0);
|
-setup_timer(&_field1._timer, _callback, 0UL);
+timer_setup(&_field1._timer, _callback, 0);
|
-setup_timer(_field1._timer, _callback, 0);
+timer_setup(_field1._timer, _callback, 0);
|
-setup_timer(_field1._timer, _callback, 0L);
+timer_setup(_field1._timer, _callback, 0);
|
-setup_timer(_field1._timer, _callback, 0UL);
+timer_setup(_field1._timer, _callback, 0);
)
@change_callback_unused_data
depends on match_timer_function_unused_data@
identifier match_timer_function_unused_data._callback;
type _origtype;
identifier _origarg;
@@
void _callback(
-_origtype _origarg
+struct timer_list *unused
)
{
... when != _origarg
}
Signed-off-by: Kees Cook <keescook@chromium.org>
2017-10-17 20:21:24 -07:00
static void st_nci_se_wt_timeout ( struct timer_list * t )
2015-02-01 22:26:15 +01:00
{
/*
* No answer from the secure element
* within the defined timeout .
* Let ' s send a reset request as recovery procedure .
* According to the situation , we first try to send a software reset
* to the secure element . If the next command is still not
* answering in time , we send to the CLF a secure element hardware
* reset request .
*/
/* hardware reset managed through VCC_UICC_OUT power supply */
u8 param = 0x01 ;
treewide: setup_timer() -> timer_setup() (2 field)
This converts all remaining setup_timer() calls that use a nested field
to reach a struct timer_list. Coccinelle does not have an easy way to
match multiple fields, so a new script is needed to change the matches of
"&_E->_timer" into "&_E->_field1._timer" in all the rules.
spatch --very-quiet --all-includes --include-headers \
-I ./arch/x86/include -I ./arch/x86/include/generated \
-I ./include -I ./arch/x86/include/uapi \
-I ./arch/x86/include/generated/uapi -I ./include/uapi \
-I ./include/generated/uapi --include ./include/linux/kconfig.h \
--dir . \
--cocci-file ~/src/data/timer_setup-2fields.cocci
@fix_address_of depends@
expression e;
@@
setup_timer(
-&(e)
+&e
, ...)
// Update any raw setup_timer() usages that have a NULL callback, but
// would otherwise match change_timer_function_usage, since the latter
// will update all function assignments done in the face of a NULL
// function initialization in setup_timer().
@change_timer_function_usage_NULL@
expression _E;
identifier _field1;
identifier _timer;
type _cast_data;
@@
(
-setup_timer(&_E->_field1._timer, NULL, _E);
+timer_setup(&_E->_field1._timer, NULL, 0);
|
-setup_timer(&_E->_field1._timer, NULL, (_cast_data)_E);
+timer_setup(&_E->_field1._timer, NULL, 0);
|
-setup_timer(&_E._field1._timer, NULL, &_E);
+timer_setup(&_E._field1._timer, NULL, 0);
|
-setup_timer(&_E._field1._timer, NULL, (_cast_data)&_E);
+timer_setup(&_E._field1._timer, NULL, 0);
)
@change_timer_function_usage@
expression _E;
identifier _field1;
identifier _timer;
struct timer_list _stl;
identifier _callback;
type _cast_func, _cast_data;
@@
(
-setup_timer(&_E->_field1._timer, _callback, _E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, &_callback, _E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, _callback, (_cast_data)_E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, &_callback, (_cast_data)_E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, (_cast_func)_callback, _E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, (_cast_func)&_callback, _E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, (_cast_func)_callback, (_cast_data)_E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, (_cast_func)&_callback, (_cast_data)_E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, _callback, (_cast_data)_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, _callback, (_cast_data)&_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, &_callback, (_cast_data)_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, &_callback, (_cast_data)&_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, (_cast_func)_callback, (_cast_data)_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, (_cast_func)_callback, (_cast_data)&_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, (_cast_func)&_callback, (_cast_data)_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, (_cast_func)&_callback, (_cast_data)&_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
_E->_field1._timer@_stl.function = _callback;
|
_E->_field1._timer@_stl.function = &_callback;
|
_E->_field1._timer@_stl.function = (_cast_func)_callback;
|
_E->_field1._timer@_stl.function = (_cast_func)&_callback;
|
_E._field1._timer@_stl.function = _callback;
|
_E._field1._timer@_stl.function = &_callback;
|
_E._field1._timer@_stl.function = (_cast_func)_callback;
|
_E._field1._timer@_stl.function = (_cast_func)&_callback;
)
// callback(unsigned long arg)
@change_callback_handle_cast
depends on change_timer_function_usage@
identifier change_timer_function_usage._callback;
identifier change_timer_function_usage._field1;
identifier change_timer_function_usage._timer;
type _origtype;
identifier _origarg;
type _handletype;
identifier _handle;
@@
void _callback(
-_origtype _origarg
+struct timer_list *t
)
{
(
... when != _origarg
_handletype *_handle =
-(_handletype *)_origarg;
+from_timer(_handle, t, _field1._timer);
... when != _origarg
|
... when != _origarg
_handletype *_handle =
-(void *)_origarg;
+from_timer(_handle, t, _field1._timer);
... when != _origarg
|
... when != _origarg
_handletype *_handle;
... when != _handle
_handle =
-(_handletype *)_origarg;
+from_timer(_handle, t, _field1._timer);
... when != _origarg
|
... when != _origarg
_handletype *_handle;
... when != _handle
_handle =
-(void *)_origarg;
+from_timer(_handle, t, _field1._timer);
... when != _origarg
)
}
// callback(unsigned long arg) without existing variable
@change_callback_handle_cast_no_arg
depends on change_timer_function_usage &&
!change_callback_handle_cast@
identifier change_timer_function_usage._callback;
identifier change_timer_function_usage._field1;
identifier change_timer_function_usage._timer;
type _origtype;
identifier _origarg;
type _handletype;
@@
void _callback(
-_origtype _origarg
+struct timer_list *t
)
{
+ _handletype *_origarg = from_timer(_origarg, t, _field1._timer);
+
... when != _origarg
- (_handletype *)_origarg
+ _origarg
... when != _origarg
}
// Avoid already converted callbacks.
@match_callback_converted
depends on change_timer_function_usage &&
!change_callback_handle_cast &&
!change_callback_handle_cast_no_arg@
identifier change_timer_function_usage._callback;
identifier t;
@@
void _callback(struct timer_list *t)
{ ... }
// callback(struct something *handle)
@change_callback_handle_arg
depends on change_timer_function_usage &&
!match_callback_converted &&
!change_callback_handle_cast &&
!change_callback_handle_cast_no_arg@
identifier change_timer_function_usage._callback;
identifier change_timer_function_usage._field1;
identifier change_timer_function_usage._timer;
type _handletype;
identifier _handle;
@@
void _callback(
-_handletype *_handle
+struct timer_list *t
)
{
+ _handletype *_handle = from_timer(_handle, t, _field1._timer);
...
}
// If change_callback_handle_arg ran on an empty function, remove
// the added handler.
@unchange_callback_handle_arg
depends on change_timer_function_usage &&
change_callback_handle_arg@
identifier change_timer_function_usage._callback;
identifier change_timer_function_usage._field1;
identifier change_timer_function_usage._timer;
type _handletype;
identifier _handle;
identifier t;
@@
void _callback(struct timer_list *t)
{
- _handletype *_handle = from_timer(_handle, t, _field1._timer);
}
// We only want to refactor the setup_timer() data argument if we've found
// the matching callback. This undoes changes in change_timer_function_usage.
@unchange_timer_function_usage
depends on change_timer_function_usage &&
!change_callback_handle_cast &&
!change_callback_handle_cast_no_arg &&
!change_callback_handle_arg@
expression change_timer_function_usage._E;
identifier change_timer_function_usage._field1;
identifier change_timer_function_usage._timer;
identifier change_timer_function_usage._callback;
type change_timer_function_usage._cast_data;
@@
(
-timer_setup(&_E->_field1._timer, _callback, 0);
+setup_timer(&_E->_field1._timer, _callback, (_cast_data)_E);
|
-timer_setup(&_E._field1._timer, _callback, 0);
+setup_timer(&_E._field1._timer, _callback, (_cast_data)&_E);
)
// If we fixed a callback from a .function assignment, fix the
// assignment cast now.
@change_timer_function_assignment
depends on change_timer_function_usage &&
(change_callback_handle_cast ||
change_callback_handle_cast_no_arg ||
change_callback_handle_arg)@
expression change_timer_function_usage._E;
identifier change_timer_function_usage._field1;
identifier change_timer_function_usage._timer;
identifier change_timer_function_usage._callback;
type _cast_func;
typedef TIMER_FUNC_TYPE;
@@
(
_E->_field1._timer.function =
-_callback
+(TIMER_FUNC_TYPE)_callback
;
|
_E->_field1._timer.function =
-&_callback
+(TIMER_FUNC_TYPE)_callback
;
|
_E->_field1._timer.function =
-(_cast_func)_callback;
+(TIMER_FUNC_TYPE)_callback
;
|
_E->_field1._timer.function =
-(_cast_func)&_callback
+(TIMER_FUNC_TYPE)_callback
;
|
_E._field1._timer.function =
-_callback
+(TIMER_FUNC_TYPE)_callback
;
|
_E._field1._timer.function =
-&_callback;
+(TIMER_FUNC_TYPE)_callback
;
|
_E._field1._timer.function =
-(_cast_func)_callback
+(TIMER_FUNC_TYPE)_callback
;
|
_E._field1._timer.function =
-(_cast_func)&_callback
+(TIMER_FUNC_TYPE)_callback
;
)
// Sometimes timer functions are called directly. Replace matched args.
@change_timer_function_calls
depends on change_timer_function_usage &&
(change_callback_handle_cast ||
change_callback_handle_cast_no_arg ||
change_callback_handle_arg)@
expression _E;
identifier change_timer_function_usage._field1;
identifier change_timer_function_usage._timer;
identifier change_timer_function_usage._callback;
type _cast_data;
@@
_callback(
(
-(_cast_data)_E
+&_E->_field1._timer
|
-(_cast_data)&_E
+&_E._field1._timer
|
-_E
+&_E->_field1._timer
)
)
// If a timer has been configured without a data argument, it can be
// converted without regard to the callback argument, since it is unused.
@match_timer_function_unused_data@
expression _E;
identifier _field1;
identifier _timer;
identifier _callback;
@@
(
-setup_timer(&_E->_field1._timer, _callback, 0);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, _callback, 0L);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, _callback, 0UL);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, _callback, 0);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, _callback, 0L);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, _callback, 0UL);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_field1._timer, _callback, 0);
+timer_setup(&_field1._timer, _callback, 0);
|
-setup_timer(&_field1._timer, _callback, 0L);
+timer_setup(&_field1._timer, _callback, 0);
|
-setup_timer(&_field1._timer, _callback, 0UL);
+timer_setup(&_field1._timer, _callback, 0);
|
-setup_timer(_field1._timer, _callback, 0);
+timer_setup(_field1._timer, _callback, 0);
|
-setup_timer(_field1._timer, _callback, 0L);
+timer_setup(_field1._timer, _callback, 0);
|
-setup_timer(_field1._timer, _callback, 0UL);
+timer_setup(_field1._timer, _callback, 0);
)
@change_callback_unused_data
depends on match_timer_function_unused_data@
identifier match_timer_function_unused_data._callback;
type _origtype;
identifier _origarg;
@@
void _callback(
-_origtype _origarg
+struct timer_list *unused
)
{
... when != _origarg
}
Signed-off-by: Kees Cook <keescook@chromium.org>
2017-10-17 20:21:24 -07:00
struct st_nci_info * info = from_timer ( info , t , se_info . bwi_timer ) ;
2015-02-01 22:26:15 +01:00
pr_debug ( " \n " ) ;
info - > se_info . bwi_active = false ;
if ( ! info - > se_info . xch_error ) {
info - > se_info . xch_error = true ;
2015-06-09 22:26:05 +02:00
nci_hci_send_event ( info - > ndlc - > ndev , ST_NCI_APDU_READER_GATE ,
ST_NCI_EVT_SE_SOFT_RESET , NULL , 0 ) ;
2015-02-01 22:26:15 +01:00
} else {
info - > se_info . xch_error = false ;
2015-06-09 22:26:05 +02:00
nci_hci_send_event ( info - > ndlc - > ndev , ST_NCI_DEVICE_MGNT_GATE ,
ST_NCI_EVT_SE_HARD_RESET , & param , 1 ) ;
2015-02-01 22:26:15 +01:00
}
info - > se_info . cb ( info - > se_info . cb_context , NULL , 0 , - ETIME ) ;
}
treewide: setup_timer() -> timer_setup() (2 field)
This converts all remaining setup_timer() calls that use a nested field
to reach a struct timer_list. Coccinelle does not have an easy way to
match multiple fields, so a new script is needed to change the matches of
"&_E->_timer" into "&_E->_field1._timer" in all the rules.
spatch --very-quiet --all-includes --include-headers \
-I ./arch/x86/include -I ./arch/x86/include/generated \
-I ./include -I ./arch/x86/include/uapi \
-I ./arch/x86/include/generated/uapi -I ./include/uapi \
-I ./include/generated/uapi --include ./include/linux/kconfig.h \
--dir . \
--cocci-file ~/src/data/timer_setup-2fields.cocci
@fix_address_of depends@
expression e;
@@
setup_timer(
-&(e)
+&e
, ...)
// Update any raw setup_timer() usages that have a NULL callback, but
// would otherwise match change_timer_function_usage, since the latter
// will update all function assignments done in the face of a NULL
// function initialization in setup_timer().
@change_timer_function_usage_NULL@
expression _E;
identifier _field1;
identifier _timer;
type _cast_data;
@@
(
-setup_timer(&_E->_field1._timer, NULL, _E);
+timer_setup(&_E->_field1._timer, NULL, 0);
|
-setup_timer(&_E->_field1._timer, NULL, (_cast_data)_E);
+timer_setup(&_E->_field1._timer, NULL, 0);
|
-setup_timer(&_E._field1._timer, NULL, &_E);
+timer_setup(&_E._field1._timer, NULL, 0);
|
-setup_timer(&_E._field1._timer, NULL, (_cast_data)&_E);
+timer_setup(&_E._field1._timer, NULL, 0);
)
@change_timer_function_usage@
expression _E;
identifier _field1;
identifier _timer;
struct timer_list _stl;
identifier _callback;
type _cast_func, _cast_data;
@@
(
-setup_timer(&_E->_field1._timer, _callback, _E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, &_callback, _E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, _callback, (_cast_data)_E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, &_callback, (_cast_data)_E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, (_cast_func)_callback, _E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, (_cast_func)&_callback, _E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, (_cast_func)_callback, (_cast_data)_E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, (_cast_func)&_callback, (_cast_data)_E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, _callback, (_cast_data)_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, _callback, (_cast_data)&_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, &_callback, (_cast_data)_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, &_callback, (_cast_data)&_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, (_cast_func)_callback, (_cast_data)_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, (_cast_func)_callback, (_cast_data)&_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, (_cast_func)&_callback, (_cast_data)_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, (_cast_func)&_callback, (_cast_data)&_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
_E->_field1._timer@_stl.function = _callback;
|
_E->_field1._timer@_stl.function = &_callback;
|
_E->_field1._timer@_stl.function = (_cast_func)_callback;
|
_E->_field1._timer@_stl.function = (_cast_func)&_callback;
|
_E._field1._timer@_stl.function = _callback;
|
_E._field1._timer@_stl.function = &_callback;
|
_E._field1._timer@_stl.function = (_cast_func)_callback;
|
_E._field1._timer@_stl.function = (_cast_func)&_callback;
)
// callback(unsigned long arg)
@change_callback_handle_cast
depends on change_timer_function_usage@
identifier change_timer_function_usage._callback;
identifier change_timer_function_usage._field1;
identifier change_timer_function_usage._timer;
type _origtype;
identifier _origarg;
type _handletype;
identifier _handle;
@@
void _callback(
-_origtype _origarg
+struct timer_list *t
)
{
(
... when != _origarg
_handletype *_handle =
-(_handletype *)_origarg;
+from_timer(_handle, t, _field1._timer);
... when != _origarg
|
... when != _origarg
_handletype *_handle =
-(void *)_origarg;
+from_timer(_handle, t, _field1._timer);
... when != _origarg
|
... when != _origarg
_handletype *_handle;
... when != _handle
_handle =
-(_handletype *)_origarg;
+from_timer(_handle, t, _field1._timer);
... when != _origarg
|
... when != _origarg
_handletype *_handle;
... when != _handle
_handle =
-(void *)_origarg;
+from_timer(_handle, t, _field1._timer);
... when != _origarg
)
}
// callback(unsigned long arg) without existing variable
@change_callback_handle_cast_no_arg
depends on change_timer_function_usage &&
!change_callback_handle_cast@
identifier change_timer_function_usage._callback;
identifier change_timer_function_usage._field1;
identifier change_timer_function_usage._timer;
type _origtype;
identifier _origarg;
type _handletype;
@@
void _callback(
-_origtype _origarg
+struct timer_list *t
)
{
+ _handletype *_origarg = from_timer(_origarg, t, _field1._timer);
+
... when != _origarg
- (_handletype *)_origarg
+ _origarg
... when != _origarg
}
// Avoid already converted callbacks.
@match_callback_converted
depends on change_timer_function_usage &&
!change_callback_handle_cast &&
!change_callback_handle_cast_no_arg@
identifier change_timer_function_usage._callback;
identifier t;
@@
void _callback(struct timer_list *t)
{ ... }
// callback(struct something *handle)
@change_callback_handle_arg
depends on change_timer_function_usage &&
!match_callback_converted &&
!change_callback_handle_cast &&
!change_callback_handle_cast_no_arg@
identifier change_timer_function_usage._callback;
identifier change_timer_function_usage._field1;
identifier change_timer_function_usage._timer;
type _handletype;
identifier _handle;
@@
void _callback(
-_handletype *_handle
+struct timer_list *t
)
{
+ _handletype *_handle = from_timer(_handle, t, _field1._timer);
...
}
// If change_callback_handle_arg ran on an empty function, remove
// the added handler.
@unchange_callback_handle_arg
depends on change_timer_function_usage &&
change_callback_handle_arg@
identifier change_timer_function_usage._callback;
identifier change_timer_function_usage._field1;
identifier change_timer_function_usage._timer;
type _handletype;
identifier _handle;
identifier t;
@@
void _callback(struct timer_list *t)
{
- _handletype *_handle = from_timer(_handle, t, _field1._timer);
}
// We only want to refactor the setup_timer() data argument if we've found
// the matching callback. This undoes changes in change_timer_function_usage.
@unchange_timer_function_usage
depends on change_timer_function_usage &&
!change_callback_handle_cast &&
!change_callback_handle_cast_no_arg &&
!change_callback_handle_arg@
expression change_timer_function_usage._E;
identifier change_timer_function_usage._field1;
identifier change_timer_function_usage._timer;
identifier change_timer_function_usage._callback;
type change_timer_function_usage._cast_data;
@@
(
-timer_setup(&_E->_field1._timer, _callback, 0);
+setup_timer(&_E->_field1._timer, _callback, (_cast_data)_E);
|
-timer_setup(&_E._field1._timer, _callback, 0);
+setup_timer(&_E._field1._timer, _callback, (_cast_data)&_E);
)
// If we fixed a callback from a .function assignment, fix the
// assignment cast now.
@change_timer_function_assignment
depends on change_timer_function_usage &&
(change_callback_handle_cast ||
change_callback_handle_cast_no_arg ||
change_callback_handle_arg)@
expression change_timer_function_usage._E;
identifier change_timer_function_usage._field1;
identifier change_timer_function_usage._timer;
identifier change_timer_function_usage._callback;
type _cast_func;
typedef TIMER_FUNC_TYPE;
@@
(
_E->_field1._timer.function =
-_callback
+(TIMER_FUNC_TYPE)_callback
;
|
_E->_field1._timer.function =
-&_callback
+(TIMER_FUNC_TYPE)_callback
;
|
_E->_field1._timer.function =
-(_cast_func)_callback;
+(TIMER_FUNC_TYPE)_callback
;
|
_E->_field1._timer.function =
-(_cast_func)&_callback
+(TIMER_FUNC_TYPE)_callback
;
|
_E._field1._timer.function =
-_callback
+(TIMER_FUNC_TYPE)_callback
;
|
_E._field1._timer.function =
-&_callback;
+(TIMER_FUNC_TYPE)_callback
;
|
_E._field1._timer.function =
-(_cast_func)_callback
+(TIMER_FUNC_TYPE)_callback
;
|
_E._field1._timer.function =
-(_cast_func)&_callback
+(TIMER_FUNC_TYPE)_callback
;
)
// Sometimes timer functions are called directly. Replace matched args.
@change_timer_function_calls
depends on change_timer_function_usage &&
(change_callback_handle_cast ||
change_callback_handle_cast_no_arg ||
change_callback_handle_arg)@
expression _E;
identifier change_timer_function_usage._field1;
identifier change_timer_function_usage._timer;
identifier change_timer_function_usage._callback;
type _cast_data;
@@
_callback(
(
-(_cast_data)_E
+&_E->_field1._timer
|
-(_cast_data)&_E
+&_E._field1._timer
|
-_E
+&_E->_field1._timer
)
)
// If a timer has been configured without a data argument, it can be
// converted without regard to the callback argument, since it is unused.
@match_timer_function_unused_data@
expression _E;
identifier _field1;
identifier _timer;
identifier _callback;
@@
(
-setup_timer(&_E->_field1._timer, _callback, 0);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, _callback, 0L);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, _callback, 0UL);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, _callback, 0);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, _callback, 0L);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, _callback, 0UL);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_field1._timer, _callback, 0);
+timer_setup(&_field1._timer, _callback, 0);
|
-setup_timer(&_field1._timer, _callback, 0L);
+timer_setup(&_field1._timer, _callback, 0);
|
-setup_timer(&_field1._timer, _callback, 0UL);
+timer_setup(&_field1._timer, _callback, 0);
|
-setup_timer(_field1._timer, _callback, 0);
+timer_setup(_field1._timer, _callback, 0);
|
-setup_timer(_field1._timer, _callback, 0L);
+timer_setup(_field1._timer, _callback, 0);
|
-setup_timer(_field1._timer, _callback, 0UL);
+timer_setup(_field1._timer, _callback, 0);
)
@change_callback_unused_data
depends on match_timer_function_unused_data@
identifier match_timer_function_unused_data._callback;
type _origtype;
identifier _origarg;
@@
void _callback(
-_origtype _origarg
+struct timer_list *unused
)
{
... when != _origarg
}
Signed-off-by: Kees Cook <keescook@chromium.org>
2017-10-17 20:21:24 -07:00
static void st_nci_se_activation_timeout ( struct timer_list * t )
2015-02-01 22:26:15 +01:00
{
treewide: setup_timer() -> timer_setup() (2 field)
This converts all remaining setup_timer() calls that use a nested field
to reach a struct timer_list. Coccinelle does not have an easy way to
match multiple fields, so a new script is needed to change the matches of
"&_E->_timer" into "&_E->_field1._timer" in all the rules.
spatch --very-quiet --all-includes --include-headers \
-I ./arch/x86/include -I ./arch/x86/include/generated \
-I ./include -I ./arch/x86/include/uapi \
-I ./arch/x86/include/generated/uapi -I ./include/uapi \
-I ./include/generated/uapi --include ./include/linux/kconfig.h \
--dir . \
--cocci-file ~/src/data/timer_setup-2fields.cocci
@fix_address_of depends@
expression e;
@@
setup_timer(
-&(e)
+&e
, ...)
// Update any raw setup_timer() usages that have a NULL callback, but
// would otherwise match change_timer_function_usage, since the latter
// will update all function assignments done in the face of a NULL
// function initialization in setup_timer().
@change_timer_function_usage_NULL@
expression _E;
identifier _field1;
identifier _timer;
type _cast_data;
@@
(
-setup_timer(&_E->_field1._timer, NULL, _E);
+timer_setup(&_E->_field1._timer, NULL, 0);
|
-setup_timer(&_E->_field1._timer, NULL, (_cast_data)_E);
+timer_setup(&_E->_field1._timer, NULL, 0);
|
-setup_timer(&_E._field1._timer, NULL, &_E);
+timer_setup(&_E._field1._timer, NULL, 0);
|
-setup_timer(&_E._field1._timer, NULL, (_cast_data)&_E);
+timer_setup(&_E._field1._timer, NULL, 0);
)
@change_timer_function_usage@
expression _E;
identifier _field1;
identifier _timer;
struct timer_list _stl;
identifier _callback;
type _cast_func, _cast_data;
@@
(
-setup_timer(&_E->_field1._timer, _callback, _E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, &_callback, _E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, _callback, (_cast_data)_E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, &_callback, (_cast_data)_E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, (_cast_func)_callback, _E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, (_cast_func)&_callback, _E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, (_cast_func)_callback, (_cast_data)_E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, (_cast_func)&_callback, (_cast_data)_E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, _callback, (_cast_data)_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, _callback, (_cast_data)&_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, &_callback, (_cast_data)_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, &_callback, (_cast_data)&_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, (_cast_func)_callback, (_cast_data)_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, (_cast_func)_callback, (_cast_data)&_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, (_cast_func)&_callback, (_cast_data)_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, (_cast_func)&_callback, (_cast_data)&_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
_E->_field1._timer@_stl.function = _callback;
|
_E->_field1._timer@_stl.function = &_callback;
|
_E->_field1._timer@_stl.function = (_cast_func)_callback;
|
_E->_field1._timer@_stl.function = (_cast_func)&_callback;
|
_E._field1._timer@_stl.function = _callback;
|
_E._field1._timer@_stl.function = &_callback;
|
_E._field1._timer@_stl.function = (_cast_func)_callback;
|
_E._field1._timer@_stl.function = (_cast_func)&_callback;
)
// callback(unsigned long arg)
@change_callback_handle_cast
depends on change_timer_function_usage@
identifier change_timer_function_usage._callback;
identifier change_timer_function_usage._field1;
identifier change_timer_function_usage._timer;
type _origtype;
identifier _origarg;
type _handletype;
identifier _handle;
@@
void _callback(
-_origtype _origarg
+struct timer_list *t
)
{
(
... when != _origarg
_handletype *_handle =
-(_handletype *)_origarg;
+from_timer(_handle, t, _field1._timer);
... when != _origarg
|
... when != _origarg
_handletype *_handle =
-(void *)_origarg;
+from_timer(_handle, t, _field1._timer);
... when != _origarg
|
... when != _origarg
_handletype *_handle;
... when != _handle
_handle =
-(_handletype *)_origarg;
+from_timer(_handle, t, _field1._timer);
... when != _origarg
|
... when != _origarg
_handletype *_handle;
... when != _handle
_handle =
-(void *)_origarg;
+from_timer(_handle, t, _field1._timer);
... when != _origarg
)
}
// callback(unsigned long arg) without existing variable
@change_callback_handle_cast_no_arg
depends on change_timer_function_usage &&
!change_callback_handle_cast@
identifier change_timer_function_usage._callback;
identifier change_timer_function_usage._field1;
identifier change_timer_function_usage._timer;
type _origtype;
identifier _origarg;
type _handletype;
@@
void _callback(
-_origtype _origarg
+struct timer_list *t
)
{
+ _handletype *_origarg = from_timer(_origarg, t, _field1._timer);
+
... when != _origarg
- (_handletype *)_origarg
+ _origarg
... when != _origarg
}
// Avoid already converted callbacks.
@match_callback_converted
depends on change_timer_function_usage &&
!change_callback_handle_cast &&
!change_callback_handle_cast_no_arg@
identifier change_timer_function_usage._callback;
identifier t;
@@
void _callback(struct timer_list *t)
{ ... }
// callback(struct something *handle)
@change_callback_handle_arg
depends on change_timer_function_usage &&
!match_callback_converted &&
!change_callback_handle_cast &&
!change_callback_handle_cast_no_arg@
identifier change_timer_function_usage._callback;
identifier change_timer_function_usage._field1;
identifier change_timer_function_usage._timer;
type _handletype;
identifier _handle;
@@
void _callback(
-_handletype *_handle
+struct timer_list *t
)
{
+ _handletype *_handle = from_timer(_handle, t, _field1._timer);
...
}
// If change_callback_handle_arg ran on an empty function, remove
// the added handler.
@unchange_callback_handle_arg
depends on change_timer_function_usage &&
change_callback_handle_arg@
identifier change_timer_function_usage._callback;
identifier change_timer_function_usage._field1;
identifier change_timer_function_usage._timer;
type _handletype;
identifier _handle;
identifier t;
@@
void _callback(struct timer_list *t)
{
- _handletype *_handle = from_timer(_handle, t, _field1._timer);
}
// We only want to refactor the setup_timer() data argument if we've found
// the matching callback. This undoes changes in change_timer_function_usage.
@unchange_timer_function_usage
depends on change_timer_function_usage &&
!change_callback_handle_cast &&
!change_callback_handle_cast_no_arg &&
!change_callback_handle_arg@
expression change_timer_function_usage._E;
identifier change_timer_function_usage._field1;
identifier change_timer_function_usage._timer;
identifier change_timer_function_usage._callback;
type change_timer_function_usage._cast_data;
@@
(
-timer_setup(&_E->_field1._timer, _callback, 0);
+setup_timer(&_E->_field1._timer, _callback, (_cast_data)_E);
|
-timer_setup(&_E._field1._timer, _callback, 0);
+setup_timer(&_E._field1._timer, _callback, (_cast_data)&_E);
)
// If we fixed a callback from a .function assignment, fix the
// assignment cast now.
@change_timer_function_assignment
depends on change_timer_function_usage &&
(change_callback_handle_cast ||
change_callback_handle_cast_no_arg ||
change_callback_handle_arg)@
expression change_timer_function_usage._E;
identifier change_timer_function_usage._field1;
identifier change_timer_function_usage._timer;
identifier change_timer_function_usage._callback;
type _cast_func;
typedef TIMER_FUNC_TYPE;
@@
(
_E->_field1._timer.function =
-_callback
+(TIMER_FUNC_TYPE)_callback
;
|
_E->_field1._timer.function =
-&_callback
+(TIMER_FUNC_TYPE)_callback
;
|
_E->_field1._timer.function =
-(_cast_func)_callback;
+(TIMER_FUNC_TYPE)_callback
;
|
_E->_field1._timer.function =
-(_cast_func)&_callback
+(TIMER_FUNC_TYPE)_callback
;
|
_E._field1._timer.function =
-_callback
+(TIMER_FUNC_TYPE)_callback
;
|
_E._field1._timer.function =
-&_callback;
+(TIMER_FUNC_TYPE)_callback
;
|
_E._field1._timer.function =
-(_cast_func)_callback
+(TIMER_FUNC_TYPE)_callback
;
|
_E._field1._timer.function =
-(_cast_func)&_callback
+(TIMER_FUNC_TYPE)_callback
;
)
// Sometimes timer functions are called directly. Replace matched args.
@change_timer_function_calls
depends on change_timer_function_usage &&
(change_callback_handle_cast ||
change_callback_handle_cast_no_arg ||
change_callback_handle_arg)@
expression _E;
identifier change_timer_function_usage._field1;
identifier change_timer_function_usage._timer;
identifier change_timer_function_usage._callback;
type _cast_data;
@@
_callback(
(
-(_cast_data)_E
+&_E->_field1._timer
|
-(_cast_data)&_E
+&_E._field1._timer
|
-_E
+&_E->_field1._timer
)
)
// If a timer has been configured without a data argument, it can be
// converted without regard to the callback argument, since it is unused.
@match_timer_function_unused_data@
expression _E;
identifier _field1;
identifier _timer;
identifier _callback;
@@
(
-setup_timer(&_E->_field1._timer, _callback, 0);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, _callback, 0L);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, _callback, 0UL);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, _callback, 0);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, _callback, 0L);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, _callback, 0UL);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_field1._timer, _callback, 0);
+timer_setup(&_field1._timer, _callback, 0);
|
-setup_timer(&_field1._timer, _callback, 0L);
+timer_setup(&_field1._timer, _callback, 0);
|
-setup_timer(&_field1._timer, _callback, 0UL);
+timer_setup(&_field1._timer, _callback, 0);
|
-setup_timer(_field1._timer, _callback, 0);
+timer_setup(_field1._timer, _callback, 0);
|
-setup_timer(_field1._timer, _callback, 0L);
+timer_setup(_field1._timer, _callback, 0);
|
-setup_timer(_field1._timer, _callback, 0UL);
+timer_setup(_field1._timer, _callback, 0);
)
@change_callback_unused_data
depends on match_timer_function_unused_data@
identifier match_timer_function_unused_data._callback;
type _origtype;
identifier _origarg;
@@
void _callback(
-_origtype _origarg
+struct timer_list *unused
)
{
... when != _origarg
}
Signed-off-by: Kees Cook <keescook@chromium.org>
2017-10-17 20:21:24 -07:00
struct st_nci_info * info = from_timer ( info , t ,
se_info . se_active_timer ) ;
2015-02-01 22:26:15 +01:00
pr_debug ( " \n " ) ;
info - > se_info . se_active = false ;
complete ( & info - > se_info . req_completion ) ;
}
2015-10-25 22:54:39 +01:00
int st_nci_se_init ( struct nci_dev * ndev , struct st_nci_se_status * se_status )
2015-02-01 22:26:15 +01:00
{
2015-06-09 22:26:05 +02:00
struct st_nci_info * info = nci_get_drvdata ( ndev ) ;
2015-02-01 22:26:15 +01:00
init_completion ( & info - > se_info . req_completion ) ;
/* initialize timers */
treewide: setup_timer() -> timer_setup() (2 field)
This converts all remaining setup_timer() calls that use a nested field
to reach a struct timer_list. Coccinelle does not have an easy way to
match multiple fields, so a new script is needed to change the matches of
"&_E->_timer" into "&_E->_field1._timer" in all the rules.
spatch --very-quiet --all-includes --include-headers \
-I ./arch/x86/include -I ./arch/x86/include/generated \
-I ./include -I ./arch/x86/include/uapi \
-I ./arch/x86/include/generated/uapi -I ./include/uapi \
-I ./include/generated/uapi --include ./include/linux/kconfig.h \
--dir . \
--cocci-file ~/src/data/timer_setup-2fields.cocci
@fix_address_of depends@
expression e;
@@
setup_timer(
-&(e)
+&e
, ...)
// Update any raw setup_timer() usages that have a NULL callback, but
// would otherwise match change_timer_function_usage, since the latter
// will update all function assignments done in the face of a NULL
// function initialization in setup_timer().
@change_timer_function_usage_NULL@
expression _E;
identifier _field1;
identifier _timer;
type _cast_data;
@@
(
-setup_timer(&_E->_field1._timer, NULL, _E);
+timer_setup(&_E->_field1._timer, NULL, 0);
|
-setup_timer(&_E->_field1._timer, NULL, (_cast_data)_E);
+timer_setup(&_E->_field1._timer, NULL, 0);
|
-setup_timer(&_E._field1._timer, NULL, &_E);
+timer_setup(&_E._field1._timer, NULL, 0);
|
-setup_timer(&_E._field1._timer, NULL, (_cast_data)&_E);
+timer_setup(&_E._field1._timer, NULL, 0);
)
@change_timer_function_usage@
expression _E;
identifier _field1;
identifier _timer;
struct timer_list _stl;
identifier _callback;
type _cast_func, _cast_data;
@@
(
-setup_timer(&_E->_field1._timer, _callback, _E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, &_callback, _E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, _callback, (_cast_data)_E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, &_callback, (_cast_data)_E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, (_cast_func)_callback, _E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, (_cast_func)&_callback, _E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, (_cast_func)_callback, (_cast_data)_E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, (_cast_func)&_callback, (_cast_data)_E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, _callback, (_cast_data)_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, _callback, (_cast_data)&_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, &_callback, (_cast_data)_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, &_callback, (_cast_data)&_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, (_cast_func)_callback, (_cast_data)_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, (_cast_func)_callback, (_cast_data)&_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, (_cast_func)&_callback, (_cast_data)_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, (_cast_func)&_callback, (_cast_data)&_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
_E->_field1._timer@_stl.function = _callback;
|
_E->_field1._timer@_stl.function = &_callback;
|
_E->_field1._timer@_stl.function = (_cast_func)_callback;
|
_E->_field1._timer@_stl.function = (_cast_func)&_callback;
|
_E._field1._timer@_stl.function = _callback;
|
_E._field1._timer@_stl.function = &_callback;
|
_E._field1._timer@_stl.function = (_cast_func)_callback;
|
_E._field1._timer@_stl.function = (_cast_func)&_callback;
)
// callback(unsigned long arg)
@change_callback_handle_cast
depends on change_timer_function_usage@
identifier change_timer_function_usage._callback;
identifier change_timer_function_usage._field1;
identifier change_timer_function_usage._timer;
type _origtype;
identifier _origarg;
type _handletype;
identifier _handle;
@@
void _callback(
-_origtype _origarg
+struct timer_list *t
)
{
(
... when != _origarg
_handletype *_handle =
-(_handletype *)_origarg;
+from_timer(_handle, t, _field1._timer);
... when != _origarg
|
... when != _origarg
_handletype *_handle =
-(void *)_origarg;
+from_timer(_handle, t, _field1._timer);
... when != _origarg
|
... when != _origarg
_handletype *_handle;
... when != _handle
_handle =
-(_handletype *)_origarg;
+from_timer(_handle, t, _field1._timer);
... when != _origarg
|
... when != _origarg
_handletype *_handle;
... when != _handle
_handle =
-(void *)_origarg;
+from_timer(_handle, t, _field1._timer);
... when != _origarg
)
}
// callback(unsigned long arg) without existing variable
@change_callback_handle_cast_no_arg
depends on change_timer_function_usage &&
!change_callback_handle_cast@
identifier change_timer_function_usage._callback;
identifier change_timer_function_usage._field1;
identifier change_timer_function_usage._timer;
type _origtype;
identifier _origarg;
type _handletype;
@@
void _callback(
-_origtype _origarg
+struct timer_list *t
)
{
+ _handletype *_origarg = from_timer(_origarg, t, _field1._timer);
+
... when != _origarg
- (_handletype *)_origarg
+ _origarg
... when != _origarg
}
// Avoid already converted callbacks.
@match_callback_converted
depends on change_timer_function_usage &&
!change_callback_handle_cast &&
!change_callback_handle_cast_no_arg@
identifier change_timer_function_usage._callback;
identifier t;
@@
void _callback(struct timer_list *t)
{ ... }
// callback(struct something *handle)
@change_callback_handle_arg
depends on change_timer_function_usage &&
!match_callback_converted &&
!change_callback_handle_cast &&
!change_callback_handle_cast_no_arg@
identifier change_timer_function_usage._callback;
identifier change_timer_function_usage._field1;
identifier change_timer_function_usage._timer;
type _handletype;
identifier _handle;
@@
void _callback(
-_handletype *_handle
+struct timer_list *t
)
{
+ _handletype *_handle = from_timer(_handle, t, _field1._timer);
...
}
// If change_callback_handle_arg ran on an empty function, remove
// the added handler.
@unchange_callback_handle_arg
depends on change_timer_function_usage &&
change_callback_handle_arg@
identifier change_timer_function_usage._callback;
identifier change_timer_function_usage._field1;
identifier change_timer_function_usage._timer;
type _handletype;
identifier _handle;
identifier t;
@@
void _callback(struct timer_list *t)
{
- _handletype *_handle = from_timer(_handle, t, _field1._timer);
}
// We only want to refactor the setup_timer() data argument if we've found
// the matching callback. This undoes changes in change_timer_function_usage.
@unchange_timer_function_usage
depends on change_timer_function_usage &&
!change_callback_handle_cast &&
!change_callback_handle_cast_no_arg &&
!change_callback_handle_arg@
expression change_timer_function_usage._E;
identifier change_timer_function_usage._field1;
identifier change_timer_function_usage._timer;
identifier change_timer_function_usage._callback;
type change_timer_function_usage._cast_data;
@@
(
-timer_setup(&_E->_field1._timer, _callback, 0);
+setup_timer(&_E->_field1._timer, _callback, (_cast_data)_E);
|
-timer_setup(&_E._field1._timer, _callback, 0);
+setup_timer(&_E._field1._timer, _callback, (_cast_data)&_E);
)
// If we fixed a callback from a .function assignment, fix the
// assignment cast now.
@change_timer_function_assignment
depends on change_timer_function_usage &&
(change_callback_handle_cast ||
change_callback_handle_cast_no_arg ||
change_callback_handle_arg)@
expression change_timer_function_usage._E;
identifier change_timer_function_usage._field1;
identifier change_timer_function_usage._timer;
identifier change_timer_function_usage._callback;
type _cast_func;
typedef TIMER_FUNC_TYPE;
@@
(
_E->_field1._timer.function =
-_callback
+(TIMER_FUNC_TYPE)_callback
;
|
_E->_field1._timer.function =
-&_callback
+(TIMER_FUNC_TYPE)_callback
;
|
_E->_field1._timer.function =
-(_cast_func)_callback;
+(TIMER_FUNC_TYPE)_callback
;
|
_E->_field1._timer.function =
-(_cast_func)&_callback
+(TIMER_FUNC_TYPE)_callback
;
|
_E._field1._timer.function =
-_callback
+(TIMER_FUNC_TYPE)_callback
;
|
_E._field1._timer.function =
-&_callback;
+(TIMER_FUNC_TYPE)_callback
;
|
_E._field1._timer.function =
-(_cast_func)_callback
+(TIMER_FUNC_TYPE)_callback
;
|
_E._field1._timer.function =
-(_cast_func)&_callback
+(TIMER_FUNC_TYPE)_callback
;
)
// Sometimes timer functions are called directly. Replace matched args.
@change_timer_function_calls
depends on change_timer_function_usage &&
(change_callback_handle_cast ||
change_callback_handle_cast_no_arg ||
change_callback_handle_arg)@
expression _E;
identifier change_timer_function_usage._field1;
identifier change_timer_function_usage._timer;
identifier change_timer_function_usage._callback;
type _cast_data;
@@
_callback(
(
-(_cast_data)_E
+&_E->_field1._timer
|
-(_cast_data)&_E
+&_E._field1._timer
|
-_E
+&_E->_field1._timer
)
)
// If a timer has been configured without a data argument, it can be
// converted without regard to the callback argument, since it is unused.
@match_timer_function_unused_data@
expression _E;
identifier _field1;
identifier _timer;
identifier _callback;
@@
(
-setup_timer(&_E->_field1._timer, _callback, 0);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, _callback, 0L);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, _callback, 0UL);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, _callback, 0);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, _callback, 0L);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, _callback, 0UL);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_field1._timer, _callback, 0);
+timer_setup(&_field1._timer, _callback, 0);
|
-setup_timer(&_field1._timer, _callback, 0L);
+timer_setup(&_field1._timer, _callback, 0);
|
-setup_timer(&_field1._timer, _callback, 0UL);
+timer_setup(&_field1._timer, _callback, 0);
|
-setup_timer(_field1._timer, _callback, 0);
+timer_setup(_field1._timer, _callback, 0);
|
-setup_timer(_field1._timer, _callback, 0L);
+timer_setup(_field1._timer, _callback, 0);
|
-setup_timer(_field1._timer, _callback, 0UL);
+timer_setup(_field1._timer, _callback, 0);
)
@change_callback_unused_data
depends on match_timer_function_unused_data@
identifier match_timer_function_unused_data._callback;
type _origtype;
identifier _origarg;
@@
void _callback(
-_origtype _origarg
+struct timer_list *unused
)
{
... when != _origarg
}
Signed-off-by: Kees Cook <keescook@chromium.org>
2017-10-17 20:21:24 -07:00
timer_setup ( & info - > se_info . bwi_timer , st_nci_se_wt_timeout , 0 ) ;
2015-02-01 22:26:15 +01:00
info - > se_info . bwi_active = false ;
treewide: setup_timer() -> timer_setup() (2 field)
This converts all remaining setup_timer() calls that use a nested field
to reach a struct timer_list. Coccinelle does not have an easy way to
match multiple fields, so a new script is needed to change the matches of
"&_E->_timer" into "&_E->_field1._timer" in all the rules.
spatch --very-quiet --all-includes --include-headers \
-I ./arch/x86/include -I ./arch/x86/include/generated \
-I ./include -I ./arch/x86/include/uapi \
-I ./arch/x86/include/generated/uapi -I ./include/uapi \
-I ./include/generated/uapi --include ./include/linux/kconfig.h \
--dir . \
--cocci-file ~/src/data/timer_setup-2fields.cocci
@fix_address_of depends@
expression e;
@@
setup_timer(
-&(e)
+&e
, ...)
// Update any raw setup_timer() usages that have a NULL callback, but
// would otherwise match change_timer_function_usage, since the latter
// will update all function assignments done in the face of a NULL
// function initialization in setup_timer().
@change_timer_function_usage_NULL@
expression _E;
identifier _field1;
identifier _timer;
type _cast_data;
@@
(
-setup_timer(&_E->_field1._timer, NULL, _E);
+timer_setup(&_E->_field1._timer, NULL, 0);
|
-setup_timer(&_E->_field1._timer, NULL, (_cast_data)_E);
+timer_setup(&_E->_field1._timer, NULL, 0);
|
-setup_timer(&_E._field1._timer, NULL, &_E);
+timer_setup(&_E._field1._timer, NULL, 0);
|
-setup_timer(&_E._field1._timer, NULL, (_cast_data)&_E);
+timer_setup(&_E._field1._timer, NULL, 0);
)
@change_timer_function_usage@
expression _E;
identifier _field1;
identifier _timer;
struct timer_list _stl;
identifier _callback;
type _cast_func, _cast_data;
@@
(
-setup_timer(&_E->_field1._timer, _callback, _E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, &_callback, _E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, _callback, (_cast_data)_E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, &_callback, (_cast_data)_E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, (_cast_func)_callback, _E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, (_cast_func)&_callback, _E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, (_cast_func)_callback, (_cast_data)_E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, (_cast_func)&_callback, (_cast_data)_E);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, _callback, (_cast_data)_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, _callback, (_cast_data)&_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, &_callback, (_cast_data)_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, &_callback, (_cast_data)&_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, (_cast_func)_callback, (_cast_data)_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, (_cast_func)_callback, (_cast_data)&_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, (_cast_func)&_callback, (_cast_data)_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, (_cast_func)&_callback, (_cast_data)&_E);
+timer_setup(&_E._field1._timer, _callback, 0);
|
_E->_field1._timer@_stl.function = _callback;
|
_E->_field1._timer@_stl.function = &_callback;
|
_E->_field1._timer@_stl.function = (_cast_func)_callback;
|
_E->_field1._timer@_stl.function = (_cast_func)&_callback;
|
_E._field1._timer@_stl.function = _callback;
|
_E._field1._timer@_stl.function = &_callback;
|
_E._field1._timer@_stl.function = (_cast_func)_callback;
|
_E._field1._timer@_stl.function = (_cast_func)&_callback;
)
// callback(unsigned long arg)
@change_callback_handle_cast
depends on change_timer_function_usage@
identifier change_timer_function_usage._callback;
identifier change_timer_function_usage._field1;
identifier change_timer_function_usage._timer;
type _origtype;
identifier _origarg;
type _handletype;
identifier _handle;
@@
void _callback(
-_origtype _origarg
+struct timer_list *t
)
{
(
... when != _origarg
_handletype *_handle =
-(_handletype *)_origarg;
+from_timer(_handle, t, _field1._timer);
... when != _origarg
|
... when != _origarg
_handletype *_handle =
-(void *)_origarg;
+from_timer(_handle, t, _field1._timer);
... when != _origarg
|
... when != _origarg
_handletype *_handle;
... when != _handle
_handle =
-(_handletype *)_origarg;
+from_timer(_handle, t, _field1._timer);
... when != _origarg
|
... when != _origarg
_handletype *_handle;
... when != _handle
_handle =
-(void *)_origarg;
+from_timer(_handle, t, _field1._timer);
... when != _origarg
)
}
// callback(unsigned long arg) without existing variable
@change_callback_handle_cast_no_arg
depends on change_timer_function_usage &&
!change_callback_handle_cast@
identifier change_timer_function_usage._callback;
identifier change_timer_function_usage._field1;
identifier change_timer_function_usage._timer;
type _origtype;
identifier _origarg;
type _handletype;
@@
void _callback(
-_origtype _origarg
+struct timer_list *t
)
{
+ _handletype *_origarg = from_timer(_origarg, t, _field1._timer);
+
... when != _origarg
- (_handletype *)_origarg
+ _origarg
... when != _origarg
}
// Avoid already converted callbacks.
@match_callback_converted
depends on change_timer_function_usage &&
!change_callback_handle_cast &&
!change_callback_handle_cast_no_arg@
identifier change_timer_function_usage._callback;
identifier t;
@@
void _callback(struct timer_list *t)
{ ... }
// callback(struct something *handle)
@change_callback_handle_arg
depends on change_timer_function_usage &&
!match_callback_converted &&
!change_callback_handle_cast &&
!change_callback_handle_cast_no_arg@
identifier change_timer_function_usage._callback;
identifier change_timer_function_usage._field1;
identifier change_timer_function_usage._timer;
type _handletype;
identifier _handle;
@@
void _callback(
-_handletype *_handle
+struct timer_list *t
)
{
+ _handletype *_handle = from_timer(_handle, t, _field1._timer);
...
}
// If change_callback_handle_arg ran on an empty function, remove
// the added handler.
@unchange_callback_handle_arg
depends on change_timer_function_usage &&
change_callback_handle_arg@
identifier change_timer_function_usage._callback;
identifier change_timer_function_usage._field1;
identifier change_timer_function_usage._timer;
type _handletype;
identifier _handle;
identifier t;
@@
void _callback(struct timer_list *t)
{
- _handletype *_handle = from_timer(_handle, t, _field1._timer);
}
// We only want to refactor the setup_timer() data argument if we've found
// the matching callback. This undoes changes in change_timer_function_usage.
@unchange_timer_function_usage
depends on change_timer_function_usage &&
!change_callback_handle_cast &&
!change_callback_handle_cast_no_arg &&
!change_callback_handle_arg@
expression change_timer_function_usage._E;
identifier change_timer_function_usage._field1;
identifier change_timer_function_usage._timer;
identifier change_timer_function_usage._callback;
type change_timer_function_usage._cast_data;
@@
(
-timer_setup(&_E->_field1._timer, _callback, 0);
+setup_timer(&_E->_field1._timer, _callback, (_cast_data)_E);
|
-timer_setup(&_E._field1._timer, _callback, 0);
+setup_timer(&_E._field1._timer, _callback, (_cast_data)&_E);
)
// If we fixed a callback from a .function assignment, fix the
// assignment cast now.
@change_timer_function_assignment
depends on change_timer_function_usage &&
(change_callback_handle_cast ||
change_callback_handle_cast_no_arg ||
change_callback_handle_arg)@
expression change_timer_function_usage._E;
identifier change_timer_function_usage._field1;
identifier change_timer_function_usage._timer;
identifier change_timer_function_usage._callback;
type _cast_func;
typedef TIMER_FUNC_TYPE;
@@
(
_E->_field1._timer.function =
-_callback
+(TIMER_FUNC_TYPE)_callback
;
|
_E->_field1._timer.function =
-&_callback
+(TIMER_FUNC_TYPE)_callback
;
|
_E->_field1._timer.function =
-(_cast_func)_callback;
+(TIMER_FUNC_TYPE)_callback
;
|
_E->_field1._timer.function =
-(_cast_func)&_callback
+(TIMER_FUNC_TYPE)_callback
;
|
_E._field1._timer.function =
-_callback
+(TIMER_FUNC_TYPE)_callback
;
|
_E._field1._timer.function =
-&_callback;
+(TIMER_FUNC_TYPE)_callback
;
|
_E._field1._timer.function =
-(_cast_func)_callback
+(TIMER_FUNC_TYPE)_callback
;
|
_E._field1._timer.function =
-(_cast_func)&_callback
+(TIMER_FUNC_TYPE)_callback
;
)
// Sometimes timer functions are called directly. Replace matched args.
@change_timer_function_calls
depends on change_timer_function_usage &&
(change_callback_handle_cast ||
change_callback_handle_cast_no_arg ||
change_callback_handle_arg)@
expression _E;
identifier change_timer_function_usage._field1;
identifier change_timer_function_usage._timer;
identifier change_timer_function_usage._callback;
type _cast_data;
@@
_callback(
(
-(_cast_data)_E
+&_E->_field1._timer
|
-(_cast_data)&_E
+&_E._field1._timer
|
-_E
+&_E->_field1._timer
)
)
// If a timer has been configured without a data argument, it can be
// converted without regard to the callback argument, since it is unused.
@match_timer_function_unused_data@
expression _E;
identifier _field1;
identifier _timer;
identifier _callback;
@@
(
-setup_timer(&_E->_field1._timer, _callback, 0);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, _callback, 0L);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E->_field1._timer, _callback, 0UL);
+timer_setup(&_E->_field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, _callback, 0);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, _callback, 0L);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_E._field1._timer, _callback, 0UL);
+timer_setup(&_E._field1._timer, _callback, 0);
|
-setup_timer(&_field1._timer, _callback, 0);
+timer_setup(&_field1._timer, _callback, 0);
|
-setup_timer(&_field1._timer, _callback, 0L);
+timer_setup(&_field1._timer, _callback, 0);
|
-setup_timer(&_field1._timer, _callback, 0UL);
+timer_setup(&_field1._timer, _callback, 0);
|
-setup_timer(_field1._timer, _callback, 0);
+timer_setup(_field1._timer, _callback, 0);
|
-setup_timer(_field1._timer, _callback, 0L);
+timer_setup(_field1._timer, _callback, 0);
|
-setup_timer(_field1._timer, _callback, 0UL);
+timer_setup(_field1._timer, _callback, 0);
)
@change_callback_unused_data
depends on match_timer_function_unused_data@
identifier match_timer_function_unused_data._callback;
type _origtype;
identifier _origarg;
@@
void _callback(
-_origtype _origarg
+struct timer_list *unused
)
{
... when != _origarg
}
Signed-off-by: Kees Cook <keescook@chromium.org>
2017-10-17 20:21:24 -07:00
timer_setup ( & info - > se_info . se_active_timer ,
st_nci_se_activation_timeout , 0 ) ;
2015-02-01 22:26:15 +01:00
info - > se_info . se_active = false ;
info - > se_info . xch_error = false ;
info - > se_info . wt_timeout =
2015-06-09 22:26:05 +02:00
ST_NCI_BWI_TO_TIMEOUT ( ST_NCI_ATR_DEFAULT_BWI ) ;
2015-02-01 22:26:15 +01:00
2015-10-25 22:54:39 +01:00
info - > se_info . se_status = se_status ;
2015-02-01 22:26:15 +01:00
return 0 ;
}
2015-06-09 22:26:05 +02:00
EXPORT_SYMBOL ( st_nci_se_init ) ;
2015-02-01 22:26:15 +01:00
2015-06-09 22:26:05 +02:00
void st_nci_se_deinit ( struct nci_dev * ndev )
2015-02-01 22:26:15 +01:00
{
2015-06-09 22:26:05 +02:00
struct st_nci_info * info = nci_get_drvdata ( ndev ) ;
2015-02-01 22:26:15 +01:00
if ( info - > se_info . bwi_active )
del_timer_sync ( & info - > se_info . bwi_timer ) ;
if ( info - > se_info . se_active )
del_timer_sync ( & info - > se_info . se_active_timer ) ;
info - > se_info . se_active = false ;
info - > se_info . bwi_active = false ;
}
2015-06-09 22:26:05 +02:00
EXPORT_SYMBOL ( st_nci_se_deinit ) ;
2015-02-01 22:26:15 +01:00