@@ -303,17 +303,17 @@ dpll_msg_add_pin_freq(struct sk_buff *msg, struct dpll_pin *pin,
303
303
if (nla_put_64bit (msg , DPLL_A_PIN_FREQUENCY , sizeof (freq ), & freq ,
304
304
DPLL_A_PIN_PAD ))
305
305
return - EMSGSIZE ;
306
- for (fs = 0 ; fs < pin -> prop -> freq_supported_num ; fs ++ ) {
306
+ for (fs = 0 ; fs < pin -> prop . freq_supported_num ; fs ++ ) {
307
307
nest = nla_nest_start (msg , DPLL_A_PIN_FREQUENCY_SUPPORTED );
308
308
if (!nest )
309
309
return - EMSGSIZE ;
310
- freq = pin -> prop -> freq_supported [fs ].min ;
310
+ freq = pin -> prop . freq_supported [fs ].min ;
311
311
if (nla_put_64bit (msg , DPLL_A_PIN_FREQUENCY_MIN , sizeof (freq ),
312
312
& freq , DPLL_A_PIN_PAD )) {
313
313
nla_nest_cancel (msg , nest );
314
314
return - EMSGSIZE ;
315
315
}
316
- freq = pin -> prop -> freq_supported [fs ].max ;
316
+ freq = pin -> prop . freq_supported [fs ].max ;
317
317
if (nla_put_64bit (msg , DPLL_A_PIN_FREQUENCY_MAX , sizeof (freq ),
318
318
& freq , DPLL_A_PIN_PAD )) {
319
319
nla_nest_cancel (msg , nest );
@@ -329,9 +329,9 @@ static bool dpll_pin_is_freq_supported(struct dpll_pin *pin, u32 freq)
329
329
{
330
330
int fs ;
331
331
332
- for (fs = 0 ; fs < pin -> prop -> freq_supported_num ; fs ++ )
333
- if (freq >= pin -> prop -> freq_supported [fs ].min &&
334
- freq <= pin -> prop -> freq_supported [fs ].max )
332
+ for (fs = 0 ; fs < pin -> prop . freq_supported_num ; fs ++ )
333
+ if (freq >= pin -> prop . freq_supported [fs ].min &&
334
+ freq <= pin -> prop . freq_supported [fs ].max )
335
335
return true;
336
336
return false;
337
337
}
@@ -421,7 +421,7 @@ static int
421
421
dpll_cmd_pin_get_one (struct sk_buff * msg , struct dpll_pin * pin ,
422
422
struct netlink_ext_ack * extack )
423
423
{
424
- const struct dpll_pin_properties * prop = pin -> prop ;
424
+ const struct dpll_pin_properties * prop = & pin -> prop ;
425
425
struct dpll_pin_ref * ref ;
426
426
int ret ;
427
427
@@ -553,6 +553,24 @@ __dpll_device_change_ntf(struct dpll_device *dpll)
553
553
return dpll_device_event_send (DPLL_CMD_DEVICE_CHANGE_NTF , dpll );
554
554
}
555
555
556
+ static bool dpll_pin_available (struct dpll_pin * pin )
557
+ {
558
+ struct dpll_pin_ref * par_ref ;
559
+ unsigned long i ;
560
+
561
+ if (!xa_get_mark (& dpll_pin_xa , pin -> id , DPLL_REGISTERED ))
562
+ return false;
563
+ xa_for_each (& pin -> parent_refs , i , par_ref )
564
+ if (xa_get_mark (& dpll_pin_xa , par_ref -> pin -> id ,
565
+ DPLL_REGISTERED ))
566
+ return true;
567
+ xa_for_each (& pin -> dpll_refs , i , par_ref )
568
+ if (xa_get_mark (& dpll_device_xa , par_ref -> dpll -> id ,
569
+ DPLL_REGISTERED ))
570
+ return true;
571
+ return false;
572
+ }
573
+
556
574
/**
557
575
* dpll_device_change_ntf - notify that the dpll device has been changed
558
576
* @dpll: registered dpll pointer
@@ -579,7 +597,7 @@ dpll_pin_event_send(enum dpll_cmd event, struct dpll_pin *pin)
579
597
int ret = - ENOMEM ;
580
598
void * hdr ;
581
599
582
- if (WARN_ON (! xa_get_mark ( & dpll_pin_xa , pin -> id , DPLL_REGISTERED ) ))
600
+ if (! dpll_pin_available ( pin ))
583
601
return - ENODEV ;
584
602
585
603
msg = genlmsg_new (NLMSG_GOODSIZE , GFP_KERNEL );
@@ -717,7 +735,7 @@ dpll_pin_on_pin_state_set(struct dpll_pin *pin, u32 parent_idx,
717
735
int ret ;
718
736
719
737
if (!(DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE &
720
- pin -> prop -> capabilities )) {
738
+ pin -> prop . capabilities )) {
721
739
NL_SET_ERR_MSG (extack , "state changing is not allowed" );
722
740
return - EOPNOTSUPP ;
723
741
}
@@ -753,7 +771,7 @@ dpll_pin_state_set(struct dpll_device *dpll, struct dpll_pin *pin,
753
771
int ret ;
754
772
755
773
if (!(DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE &
756
- pin -> prop -> capabilities )) {
774
+ pin -> prop . capabilities )) {
757
775
NL_SET_ERR_MSG (extack , "state changing is not allowed" );
758
776
return - EOPNOTSUPP ;
759
777
}
@@ -780,7 +798,7 @@ dpll_pin_prio_set(struct dpll_device *dpll, struct dpll_pin *pin,
780
798
int ret ;
781
799
782
800
if (!(DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE &
783
- pin -> prop -> capabilities )) {
801
+ pin -> prop . capabilities )) {
784
802
NL_SET_ERR_MSG (extack , "prio changing is not allowed" );
785
803
return - EOPNOTSUPP ;
786
804
}
@@ -808,7 +826,7 @@ dpll_pin_direction_set(struct dpll_pin *pin, struct dpll_device *dpll,
808
826
int ret ;
809
827
810
828
if (!(DPLL_PIN_CAPABILITIES_DIRECTION_CAN_CHANGE &
811
- pin -> prop -> capabilities )) {
829
+ pin -> prop . capabilities )) {
812
830
NL_SET_ERR_MSG (extack , "direction changing is not allowed" );
813
831
return - EOPNOTSUPP ;
814
832
}
@@ -838,8 +856,8 @@ dpll_pin_phase_adj_set(struct dpll_pin *pin, struct nlattr *phase_adj_attr,
838
856
int ret ;
839
857
840
858
phase_adj = nla_get_s32 (phase_adj_attr );
841
- if (phase_adj > pin -> prop -> phase_range .max ||
842
- phase_adj < pin -> prop -> phase_range .min ) {
859
+ if (phase_adj > pin -> prop . phase_range .max ||
860
+ phase_adj < pin -> prop . phase_range .min ) {
843
861
NL_SET_ERR_MSG_ATTR (extack , phase_adj_attr ,
844
862
"phase adjust value not supported" );
845
863
return - EINVAL ;
@@ -1023,7 +1041,7 @@ dpll_pin_find(u64 clock_id, struct nlattr *mod_name_attr,
1023
1041
unsigned long i ;
1024
1042
1025
1043
xa_for_each_marked (& dpll_pin_xa , i , pin , DPLL_REGISTERED ) {
1026
- prop = pin -> prop ;
1044
+ prop = & pin -> prop ;
1027
1045
cid_match = clock_id ? pin -> clock_id == clock_id : true;
1028
1046
mod_match = mod_name_attr && module_name (pin -> module ) ?
1029
1047
!nla_strcmp (mod_name_attr ,
@@ -1130,6 +1148,10 @@ int dpll_nl_pin_id_get_doit(struct sk_buff *skb, struct genl_info *info)
1130
1148
}
1131
1149
pin = dpll_pin_find_from_nlattr (info );
1132
1150
if (!IS_ERR (pin )) {
1151
+ if (!dpll_pin_available (pin )) {
1152
+ nlmsg_free (msg );
1153
+ return - ENODEV ;
1154
+ }
1133
1155
ret = dpll_msg_add_pin_handle (msg , pin );
1134
1156
if (ret ) {
1135
1157
nlmsg_free (msg );
@@ -1179,6 +1201,8 @@ int dpll_nl_pin_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
1179
1201
1180
1202
xa_for_each_marked_start (& dpll_pin_xa , i , pin , DPLL_REGISTERED ,
1181
1203
ctx -> idx ) {
1204
+ if (!dpll_pin_available (pin ))
1205
+ continue ;
1182
1206
hdr = genlmsg_put (skb , NETLINK_CB (cb -> skb ).portid ,
1183
1207
cb -> nlh -> nlmsg_seq ,
1184
1208
& dpll_nl_family , NLM_F_MULTI ,
@@ -1441,7 +1465,8 @@ int dpll_pin_pre_doit(const struct genl_split_ops *ops, struct sk_buff *skb,
1441
1465
}
1442
1466
info -> user_ptr [0 ] = xa_load (& dpll_pin_xa ,
1443
1467
nla_get_u32 (info -> attrs [DPLL_A_PIN_ID ]));
1444
- if (!info -> user_ptr [0 ]) {
1468
+ if (!info -> user_ptr [0 ] ||
1469
+ !dpll_pin_available (info -> user_ptr [0 ])) {
1445
1470
NL_SET_ERR_MSG (info -> extack , "pin not found" );
1446
1471
ret = - ENODEV ;
1447
1472
goto unlock_dev ;
0 commit comments