summaryrefslogtreecommitdiff
path: root/net/rfkill
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2020-11-04 15:46:41 +0200
committerJohannes Berg <johannes.berg@intel.com>2020-12-11 12:47:17 +0100
commit14486c82612a177cb910980c70ba900827ca0894 (patch)
treebce8d66f6a6159acbf7b7fe45b1d609fe4d99ba8 /net/rfkill
parent91163f82143630a9629a8bf0227d49173697c69c (diff)
downloadlinux-14486c82612a177cb910980c70ba900827ca0894.tar.gz
linux-14486c82612a177cb910980c70ba900827ca0894.tar.bz2
linux-14486c82612a177cb910980c70ba900827ca0894.zip
rfkill: add a reason to the HW rfkill state
The WLAN device may exist yet not be usable. This can happen when the WLAN device is controllable by both the host and some platform internal component. We need some arbritration that is vendor specific, but when the device is not available for the host, we need to reflect this state towards the user space. Add a reason field to the rfkill object (and event) so that userspace can know why the device is in rfkill: because some other platform component currently owns the device, or because the actual hw rfkill signal is asserted. Capable userspace can now determine the reason for the rfkill and possibly do some negotiation on a side band channel using a proprietary protocol to gain ownership on the device in case the device is owned by some other component. When the host gains ownership on the device, the kernel can remove the RFKILL_HARD_BLOCK_NOT_OWNER reason and the hw rfkill state will be off. Then, the userspace can bring the device up and start normal operation. The rfkill_event structure is enlarged to include the additional byte, it is now 9 bytes long. Old user space will ask to read only 8 bytes so that the kernel can know not to feed them with more data. When the user space writes 8 bytes, new kernels will just read what is present in the file descriptor. This new byte is read only from the userspace standpoint anyway. If a new user space uses an old kernel, it'll ask to read 9 bytes but will get only 8, and it'll know that it didn't get the new state. When it'll write 9 bytes, the kernel will again ignore this new byte which is read only from the userspace standpoint. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Link: https://lore.kernel.org/r/20201104134641.28816-1-emmanuel.grumbach@intel.com Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/rfkill')
-rw-r--r--net/rfkill/core.c41
1 files changed, 34 insertions, 7 deletions
diff --git a/net/rfkill/core.c b/net/rfkill/core.c
index 97101c55763d..68d6ef9e59fc 100644
--- a/net/rfkill/core.c
+++ b/net/rfkill/core.c
@@ -40,6 +40,7 @@ struct rfkill {
enum rfkill_type type;
unsigned long state;
+ unsigned long hard_block_reasons;
u32 idx;
@@ -265,6 +266,7 @@ static void rfkill_fill_event(struct rfkill_event *ev, struct rfkill *rfkill,
ev->hard = !!(rfkill->state & RFKILL_BLOCK_HW);
ev->soft = !!(rfkill->state & (RFKILL_BLOCK_SW |
RFKILL_BLOCK_SW_PREV));
+ ev->hard_block_reasons = rfkill->hard_block_reasons;
spin_unlock_irqrestore(&rfkill->lock, flags);
}
@@ -522,19 +524,29 @@ bool rfkill_get_global_sw_state(const enum rfkill_type type)
}
#endif
-bool rfkill_set_hw_state(struct rfkill *rfkill, bool blocked)
+bool rfkill_set_hw_state_reason(struct rfkill *rfkill,
+ bool blocked, unsigned long reason)
{
unsigned long flags;
bool ret, prev;
BUG_ON(!rfkill);
+ if (WARN(reason &
+ ~(RFKILL_HARD_BLOCK_SIGNAL | RFKILL_HARD_BLOCK_NOT_OWNER),
+ "hw_state reason not supported: 0x%lx", reason))
+ return blocked;
+
spin_lock_irqsave(&rfkill->lock, flags);
- prev = !!(rfkill->state & RFKILL_BLOCK_HW);
- if (blocked)
+ prev = !!(rfkill->hard_block_reasons & reason);
+ if (blocked) {
rfkill->state |= RFKILL_BLOCK_HW;
- else
- rfkill->state &= ~RFKILL_BLOCK_HW;
+ rfkill->hard_block_reasons |= reason;
+ } else {
+ rfkill->hard_block_reasons &= ~reason;
+ if (!rfkill->hard_block_reasons)
+ rfkill->state &= ~RFKILL_BLOCK_HW;
+ }
ret = !!(rfkill->state & RFKILL_BLOCK_ANY);
spin_unlock_irqrestore(&rfkill->lock, flags);
@@ -546,7 +558,7 @@ bool rfkill_set_hw_state(struct rfkill *rfkill, bool blocked)
return ret;
}
-EXPORT_SYMBOL(rfkill_set_hw_state);
+EXPORT_SYMBOL(rfkill_set_hw_state_reason);
static void __rfkill_set_sw_state(struct rfkill *rfkill, bool blocked)
{
@@ -744,6 +756,16 @@ static ssize_t soft_store(struct device *dev, struct device_attribute *attr,
}
static DEVICE_ATTR_RW(soft);
+static ssize_t hard_block_reasons_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct rfkill *rfkill = to_rfkill(dev);
+
+ return sprintf(buf, "0x%lx\n", rfkill->hard_block_reasons);
+}
+static DEVICE_ATTR_RO(hard_block_reasons);
+
static u8 user_state_from_blocked(unsigned long state)
{
if (state & RFKILL_BLOCK_HW)
@@ -796,6 +818,7 @@ static struct attribute *rfkill_dev_attrs[] = {
&dev_attr_state.attr,
&dev_attr_soft.attr,
&dev_attr_hard.attr,
+ &dev_attr_hard_block_reasons.attr,
NULL,
};
ATTRIBUTE_GROUPS(rfkill_dev);
@@ -811,6 +834,7 @@ static int rfkill_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
{
struct rfkill *rfkill = to_rfkill(dev);
unsigned long flags;
+ unsigned long reasons;
u32 state;
int error;
@@ -823,10 +847,13 @@ static int rfkill_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
return error;
spin_lock_irqsave(&rfkill->lock, flags);
state = rfkill->state;
+ reasons = rfkill->hard_block_reasons;
spin_unlock_irqrestore(&rfkill->lock, flags);
error = add_uevent_var(env, "RFKILL_STATE=%d",
user_state_from_blocked(state));
- return error;
+ if (error)
+ return error;
+ return add_uevent_var(env, "RFKILL_HW_BLOCK_REASON=0x%lx", reasons);
}
void rfkill_pause_polling(struct rfkill *rfkill)
x%q禦뿏]`Jgb2;|<% :{B<>9HLsW5gycjQ8Uدa })p "cA( i]Cᎀ?I XvX7e.  \@&83=>d4wp6 )dFm#AT0 T8`p(jDb!b9H۱4gwV]$DU7p(6&< q9D ίw`].lpxa%G($ ќ!iA8IfK0JІ$:if8gtOa0gJ^H}:(>GxO8K O$:_Ϛm:{ $]͹`[OL}w68wT54k}[Icel<:=~no{jIC:; ֑泶u>R_5wowCuV~^.ulwGT=sl? @W:;2[e^=~KDF~}z hAw\g{gE 98Tϧ;s:#`}.i|ƫ[XM!Crڬsn;Ƹ˿߀26[tM㦥ӮxUm#Ǯ̧iNm y0Y ݚ[c:ϥ%~\6pcFNtg~B 5R3row_7l(}ORvl|P?;gKllh+In!ov 3N >R4!М#^T^N;'ow\1w88vճ(û\^u_e| c<]sudAvlgX5Dl:ͽDç43r3xwn]N׮!|Vn\:\ZaRt^Z]z?%5Ibu _qgiC<0$tr'7dIrtxHDn~Wr4%Rt^Q$r<"`xvGg^8ʒpp:6uv:ZqlSo ]*_5ѯZ7]9.Vr?˼r o-7Y`;R{? PD XAwz ]v8_iu7%9_r\]2 ؉oƯRݾ G!)O`[:^ 6U]o'@> e~B~piz+Y?|c."l#$Ax/T^">sFvX&<(MBA(dq@W]f(1YK@u'h&2Ek@P%2[W0La. S*3DUgk)*e=K`GMC0-3wA̶PI?yD@7z&;(@2I{iuunA'ЖYVNdڈHV?)c#xDNpnq`ihtG_^p o$/!]pG˸ ӳ\&5& ? à0M;@-" [8[DS1zYz|> ^9Uכoix\JE/>kܑ-VSj ^TH`>/5 @Q'(HPH@<#iǯC<_Snce*@ߩDF_7V6٠Pf=W[۶^&+LLX'P`R$pW@" 0E[`+?G>WWn'GtuZ\T 萻xSb?5?Fz-7hnau=E:Th;7} yz/Fecc`moƻZ|`kc!QeoТHGujJ۬omLҩj+Ij\AcжSĞ:%~ ^PSD iΆ"SCnORBUT>䧳1=PNaǛn~yo?VE#(A!^;Br)>~7CV23ò0bo-䱣vyA FU'3K`˪vzUD e"FK,=٪َ|{IX9ecݷ !O*UTy??r;ΛY<I~Ww]$x߰ݯ2ia{.}ʄ5#^<>GC 6R x7WI u|w}ۖ -#o`=Cojy*#e!HpͲkP$ɥzӏ/g?n7ܪktO2÷b<@++ppϐ[ng:)V*UTF }}%2OS~8ZO(7>؉rpdC0h|~znTڇS V=~O~=ވZf0[Bt6YE ZN<('ʟ')tTipbx!({/ ܠ8@ yg'_VPDte+2Į;`[[X$ 2w`+ޫ꼔ND mb_Ae0[zܶ\uQwHIh7]~p>;xaM㖏 3&9nG4AZ_<^,û; " m;XppQ\(5;1RY9s?_8= {v s7׽jWɳg dp&#y^ (Ŷ9X2K/G:Ɇtş4GAb!۞H5MF¤W\lH[t PK#YEK"Gh8oU$**hbͺv]anG~DCE_YbSi-b*tE^_=/YfڪEEm3Ͳc}MH ^!paڝ oBS2Py~vN]?睽tR4f]:Wźbª"'2J F[{}Ilvuʃ`[R9׀Ή+"SyAP0@ ]dӧ p8$aPp,>7ٯϭUK"1]qלw?>,\^'~Rmv cjb)b>Z "+ 3-ecoeE∃\UD]+ @h{1 Tҹ=E5]1۶ xAg42'Z(T@ V[.!J'DZb̟Oұ ٯ>^_VxpM\C8連z6 N7_9mH1bXkJyb4-&+ꚟwǯ=u\Py :0u~O]#qTts V}qVl%u2:bc} vU{z0aE$㽠̳yo!̨Bs.@[R.D2`Է^OLVu vI 폾ag~A:w@|ͶGeO ^_#& 0%Tvo'#Oj}еY(Cgut1`Vl`0 ZCIygL\0]ZSD)@u>Љp n=7}Lhsm`y v:zJS4"lFN!$ zvhGZ8 '$${xլ(+!P:Y*Xϓ 4a} P<|Ȉ)>M;Ճ 0n_4vlQ) xNs5 wM?]~'wc5o7OfiLh+hW#fr41N@[t ~s9JG(^ )wW_@) 0G xz٦ Q{ =sO,ISn9 bP~eػ 55-fd#LdAOtYIC9oG:3HA˳u"ẇ&b=<_X/VDyUrl t=p4_xnDlxp+iO[+6ixo޼H:eۗUa*DB>vۮTb2Q2{H(1JAw91UG9S.\dZ܄( $_>P;c鋾[q)俭s~|We}dfayrK|F H Ď~/ǰv>ϰ;يۊJV z@+qxݿ4@+~aÖ;r\7.j(n$3̣:v؅P. E+̹MQq~#`}~{HPtcL3Ӿ!3׻K 9e?4%y#S2*6kٿϮ#͇l3~a#fo%U}oX:v/q(9p ^s{A /#"0ب&%E6%a'|arÚT~\+T >{_f@|W6t" v6k'5Jk 9$f.+||-f#о,=`]tY/5gcrEdb"|(aR̖T*!jQ,ml8?IqS۸hkN $-1Y&TRE"I%4M^CzdHpX2aU7Q`RD8aCuv01CU&@@9MDl'c܋2H>+oL:e־Ahkc]=.vL]bŭ)z%1f$! v $K#u{?AJ=/F:Cܖx>;Omik;R xhE#%G^{e~.fq@0(,25z)}ճWqü*_2I :۸IQpj!*EaD ouBnQ<'.-t,BOo(qFxIS'@:~ ;~QgFAc]ԯ~xƱZy.ďAZ~aˊp[Ho#h7ς=Y&9yΚ 7(ւn8 \Y 0){S76)ۍ#5@;Tal3ԋ``~˞֜ǵ7SK(A]Ju |bGS&[\ MZ^v\ϱ`aww@%x&r_/6ޡ'QK-"$+:) !0Ety, "|nkPks#(c"uJg{3+YU;+y5Mm0r%2F evs/kG^ic㎣3-I m/Aߊr>=8z^L=/&\ϴ !'3!.lqC?DCǾuVXqHתa<۰ZP-oᖇ@ " ԭA@4B"럪lڶ0 rT\Ee(*,a! ԟ]D'f$F%Eh @B:{Ja);Թ"eEg.Z>!;Oga>y:WO>ٛXtuhQ(AhjJq,vW_ `|9,>ce }ϝEa(bwȡjcʰsd8Ʀ\҈SEYv$Jh0®@FgsĹf<.V@,FiswN 緢plteǓ˫mR}y m_o, ;p'Ⱎn, _|*7(sż8~tF#"ln}Yk?kj@+f}6Yv EC5gm70 HGԎGWЁ`P,V٥h!!l3}bC3jBC=HPz%J A?ٌ',l{i[Z ,/壮B[僬Q _WfmEM҄& rr5vFMHkvpHm|x~k 3D2ssӠk ^u8.AZ`Mp[Uutiz r}S)uAܳ[ށmd_EHnbP遅^xޏZ*ZA4a_.i,CF5#(1p8L8:Ѣ&DHy$6X󪌎젏!t'~ FIU/t،ccu1Ts$B ŁG[ NwWkC^20 soX#5NAdx煮6Bk2s%A(˄#Q` 4e} ,H 6bi ˑk_8PPGZr=G|px5xZs1g *JHWj9ehdnEh8lfEÄ;fYMZ_*XF.562x`Gԇ@Lxdgf-M/E&~rWylK @S1 mi幭aotvss"^7}p51:f];qH% q@L/SYcxPS'el[ӗ0kɒd "-u7醙Aqcs|> NU꽊EsMleλ$F 6O֋nuXѢEb.(lhxlBd Kkh/g20{Q( JzQ%T({*_L"OB8䆐M^FX+Dw6Ifo4 a(aP# oMSLdPW?K[.U%!v@(9܂$!(hݒYns;߭}? ^Bam5w.-xFkKmv5kx"csh]naǯH>h zy{:/LZ( $ bio'3٪6K)J_Q+-VTe}wTmϚ_H鏞W(5~wH5 YA–p܍QqY7;,ūl+]֞.,zZ5!` =KG .*\6MJirjۈ}̮5WnfOS7%' iZL-3sIN4qI&L=6t$2jh]Rʀ؄VL2k5Ԯ7ึNުK /ޮ*TTI?"dGngZYW.ѷ $jW1<=Yc[b{_NIUag̩ Jҵ Gh{@T)֢kPH8l nFQl2z,/Q4l 3ñwIkןE=QRy[ݧ[ ɀڅ>!4^ Q!C ol3V|Bo4!LJT-a#аPvȰ\LA R/| %\'j8 #jP/xW{u!x÷y?{F 3C s?:LwvMxQ]&ؓvQgy RaB)NbN\Ͽw6G`)*?B=z'_cFj7ZrImSR\PPyʚs8Ȭ(}c`t -k 3.Px?79"k` q?!j\%WKH6Yl1w׌lIC4UZ #k>['yh @H0$Jxb C9v:NJh `=!7qBN_qF{[+;JF`.!nml e+4zl0wl3"o R&` EmT>|;;3/ FҏlO GBsNLb\޹vXپuvֹ6U∌mabC9xEvsj%6UP d7Uuj\d_ԃP.46 Z2a%ﶚ;[d:8e'R Ȓ%6HHBwvG@w"ձnQSsZl׿v@_:u-`Bv6/#b#nŸ@he d-%]3[t'ۑe& p k>1])UeN[%i͐nlT ;yK^ȸAll2|0rl-r@Y$u $[/房|OY=_Ӣ1^] XڠN޷(1>7̴wjGuv {vDqs]- &"wl%| %XsD^)v_k _9FuiGمҴEv 3^zF{j2 >e6=̎ nP3a77?nBjZa/¸`jGrV[]hbqKl>E&Ā*~w9G8ˆݜ_4 sIq_ɚ֦aKrmcR\sړ݉8Քc'Q! *'oG!Q8^r.3)?Hbxŗ8kەq+if.|q*+H]5&"&Ⱦrܗo݄s&g_HrWhF-L3*NQ0lzi>Ml- >\@Pm| .3v8EM"#=@TC#4Z5<*F_Asp\Qޣ]7@r:D~uK˼~xc՟gû~:[찬vRSұ]]kg^pUg}ҞZR}ma8;ljm!ki/Jd 4/Yݫ9g4k F]@@uk$R7X RPVzpy_/۔Ӣ0F{0pLQ@ u-d?5r2 Ìt[ZE7.a1}o2Oɫ"<|=' l+kq256\VױJNHq$rMe&GK{N71>%[]%2ĵqɭ|^]\ȚFŪ(o#ۦ{ę~~.M:KXgO ``y+0`o mK`C9_h8U<9C8)%qhn$t> qYgH=ƂX Q$A8!)#c|{x C4||uI_+\cp6; \33Ue@Q@fe~џd>nbdFan3l݌ssZ*EZx=(KP?uĈKҺKʹ Q͈n`}uvR*<~@m `qC6b$^t S5`8Fݜz `DQl6V y@J ³vQg;J^&i,c&S8b|!'ƍTNnf :98xX+- ͌a8@򏈋B='w6UgB"c5i,vm+{݊;eszqVI)pkYx ْHHS :~՝~cHW+`#+T9<+(AfScb76N=N,C1*9~>nQdN֡tP $.sm"drsϢe’G5cU\5~Pg^hiOӏ㞱~ CrqmKd0} $qD@T Y#,z kRҁA!%2% mifFlx`Wl}ẍ])c>>eI.2Qo#뿷^ʌ Hn2.9~~ou#~k$$G}\ h:f%g2DQ> zNz?.7 DBB!zN e}oی0e&P):q@͔ ovԹLm(ঽVH4'TY[>ςSUN**P`]p}q0 }̠ 920YSxDx͆.F/Y؊5z;RؙvZɭ5z>Er<ޠg5֜뾥U6׉ש;itgo[≰K}j IѸ9Uo>ig8> !BV-ڥ-*3[{g ZkpS3 *A构R_8IpWכ+L"QaL{Z]*1獒n> o<}M a!ru=h33,&K ׆֪,F HQDVk[=>hge?ɹx6atڈBEJA~k~!Iu _c[wZNF5A p{.+v<W9zu͞s.w5*<`y7m#%co8 Ϛf4W1<(Nu$M~( eM'~GorN&B߸O(Hïzm{>g8,i@]cHdapP#UЖ + ʌG[aHxD|6[ Mm N,=3AOtuw U\@:qxxftnMasnn}iI{ߟ0 6 4Iapk urlyP$鶚ְE"$1Sh3i<ǥpn[ ^Dڡ r !g)=< !ƣlɯw:`ʼnWw9!"Aq7/,&COXR#G@9W2{{ #rg A3o@<ȣu듇LRXFH^_~?@[؃ׂ2C6]BR$hq-X^3_1r}p=W3O٘pb<F{`ǤH='v9u !ْO]BeL"o'7Nj7JXf†UTd . MVM BX :ǝ uMP̺{+|hL ea}xWh9MATrh1DcޯJe%s +vs~o 9}^]O,T՟/ CFc(Qc znmL oC%Ncat>v< D^NjBOh+ qBf4)2exDT}]x2[Bg]gIǐ&|^ EwwNSyʅCA8 @RvW|%k֮| }ep:ҎyLhC>c137\bs*DF(#Up rSGǙL¥ Ja_UJA;jҳ4ӇmR$$XI ÖG(cuB~x#p 2+P37gv{.atPgYzjYT8i\RE? ˒<+gdsy~@(le5(_}7#(ҿ^`M!u TJNGU4A./|PuF(WzTg\3qit>y1}n'$dũ-`S YEFWJAH{\ȸ˙4]IE2}NP?V:~:C\!B?~n*"1 RVu|;]>}0.$}3,H'eFr7Iw&6-X.x6 AF :這p?wP}Ek_XSBEc@f:J(ͤS _.-QI:qh[iCsՆ|]TEU3iE1NnCDX H~ӏC?aTgFCڠZ:qjYbP2:$l.c̬k4R6l:rꄏBMY@xV( T! [qz 7$sJ9abT5C$2,^L3|pzs$zYQd2/_2#p\ixog38!`{_m Yrf?41xlBp BZ#kY$<uJez:h\IuΑ__jly Qމ dh˃{~s˯FAQטQ̺f8.ӱ^b Oۀɿ'W6:.~cӒj~m_>rbW7KZ2@3"?҄`89 أ[e샤!-0]ZHLee0f<2 b]ÔhA](*C"0eߵc#lIqBeRd !dU:ѓS_5l '??/D&g?ҽ^r`ǿ~z^8aҀxHL= 4܉KU6d|C;U~D~ O10re2-Y*m[rm4efkNSOfn@)rӱj10`chR1AD,Hf ]+1B(hd8]|hQ:W3"/Rﱼn]6?l^>#qbľLfz>_{bWc"2%gT4m0S({`jƋ'xoaqkn9` ¬ h>O}RVZʣ/EQ,H\mTLJ ae9uDuNK澒?Yj0R(|}9ܰn"vEɍy|7521e'o xEt!hO=80K訓<A'ĈKuV{A `,"ﳲb4'l!r?0ʑ>ibUU ʡ;4/\`E[œF&P+aF {4ȸ 9{2^ڌ_>-'9ೖ:?y~%ɹ0Q --0hY$'b:b1%2am8A۾[sr" CNmsRӮ~9i4Da^Q׋ɠ a" !?Oޝ8 @uXpm{a?P0pWZ\>[%}, p gFhAxcڪPч<[ $A X$iTf63`DLV ɌD]kc!V DK)"}[" ʋQtjA@vl>fD=epsC4Q:LJ@RsXQ){'QBoz9|.ffÿa]˗^Ni)QK%Wc<=Xg۬ qX+>lhYtǶh$ -ږ}z(+!!*zy̅i[3'l;H;X,7gJQ_k(>?s7ٍ{Rݥw63Hl%(&QEEI}m%"BV KO0]]aK1׏5Ģxo񶏷1w1Pc ?VEY$,0Ar\T~'8WZ k]aS~DȀ;JPPl\__ìG5׸0R 5d' PphMADO}.`Jؔ6őz}=toJO;;V 7 Yi]B\K#MD*MZ,(oKWL9dyhn+CTGp|(ұ~y7 (#leQ;BTB;a",c;=>ٟzHo!q[ +R0~" WUcKl.1ViL?a> 0ߔw~&XR?3eN @"AHn0 ;䓳hxC|韪}/m]Z5UQѓc&lHٹH_of{cXU  Tہ>9|eȠt 3>\8ٸQ 4)Yi4`rQXjG0C#~fbQ\#r*J$ELK9x/wSw=]:)7apkT5ʎgN#!ÌApZM;MI뇄ٶK6X__v:H"m7zDXP,_9TWƽ38 (h/-TT2S,[*kڣ)?Afw-+x&5p{'=zѡsY8f1H;ql>F`B0q.ҟ3N|d~@[7Y^&^gBnDynȞK8&Af(y"PZNg &ApL:+Qzpje*@È򞈬eB=0boL}VcR>z01Nꇻc=iϯ!{qO=4nH>8,D(z3.{/OEXqg>UR\%HB. !/Wa#Tήh< n9Ӓ-G } [R6>qP̹v "Qg]0򾓿7wک"ۊ N'K^"x '_,<`y/_qMlfq2|Eu4!as”:A=wCv?JBE\Ymr5.&]wwYc6fFC4WX9c~/D!oTB0 gA$ٶw][tQê16>#:+YZx\~w8ػ.y5 D<"NP3`,?w=Ok@ .?+ӡ_=ǫMk9@'# @%i&QQJ'̣䃓f[~IeN_L'L&17A>] hּW1Clu:Hipp}W 9)&>BfDQw6+B<Sؖ(ni }\/Tzn\1ٲ$+D nƓ؏4?VZi pkLnaJM_mH@GDTbcO #&@ 傆@.^;=H<5Qٔ] ŘQi@oppob"13/Cu1;`Epz\u H0**YpUz5(p,#8Qx)zflN*yQe8/y 7'awi>~ hA?\f@7k)4rHMl&YUҎ q(tW ʢSK_M dAUb-C^H3s}J6d)G8'1dEŧеBvg|H\=셽S}6 AbQjuq:)t|-~-z/qR$HRQZp~'%y䍊>+c+X#u7/TG(>sgǞ~M#ܝ/K>o B9T4Bl.,!Gjc~˷tj AIhFAw BxE"! փqO!6ENJ%o_:O_ z|Ӑ#`{^;"d]xJoAka۴#Y-ȉo|EV)CQ 6*dbʻ5P6X) ~f0cC(1 A\OY1.X}0QA[ ֍}O;RI?P$ҍo<3Ҟ- s>sRN=>ʢNIUYba^?qbſ]~F&W8qB]nPю-?8},DÂ+_4ߠ&w/Q1ܢJHT1PYΞn0Vׇ=6XаOf{¿cd3Kl;4 7a>j_ 535>x-Ecza cbz,š w-z@C U %LZ3k}܁fPGgE8p7:R1y !`^rLfwOug_Ջg1d(qZ" F8,7NXvC" ? &PuPl_Pd;5 Xp8#uLnB ]<\#/16`K G ԤIN@XArpRhNiG{iU|Ɨ$ـ< RcCyA x0_ӎC/Xj9ZspMmZr5x+%67x"0j[5 <CC7㭅p&t`vިX&x3ٙ01$Id׵~y%yqæ"9{Á!:ϟGg K3#E2X$QSow-'MF4u61A׉[@ǹ#/~eI@1zC}i 2xu^cj%sxÚ\R5}3OEB䢇sQ>V8'u7axx4ä̻f\[1l6U9FP 4*fAA6kW5 E,1{Tgw*gD[C83*=DKla᷉>_^P14G&"J.Wq%֭:|>SNwfì 3n&\W,"n4:- p=jnNpvqy)Z$uSE ':%!;- 5QFc9^:eI8ŚZ  = x5PsW92cZВZ4:9n:56+d7EжREr}g'Q5Wged$,pw l^| gmv(;]= rKjA~_ F+A.6@`c0 @.ؗ)G8Qd?4|{x'4wKWʻ;zGYʹd]+mjo\՟`sI`ϗ4 0rKask'gT>}朙Dt:gb\Ea oo˷O hK=}j9ARI$jLlЍd䭏Re'T#))8w9(?<\b;As׫G`ahr/ُKԎݳ?R`s>7 /➬d_*DQL4IœorkG:&Ԫ2 Q kY6kO];%SvTDQ(fFE璍TvRe>` P=/N#=k |:ݹllƛPr;gx6> Jw){J 9T^诱ml 9[~>~{߸&Y`*( cdJ;PJ:v)C {sbpBK%\CPn8ì!uu<wӪ@c冻dJ{ä0M .${^58P%4!Pܯ-zGpb~ЃeGP[QWg,WM#2g#gZ yJʙv1-~&gH4ScnDIļrFF^6 M8 [*5Ƶ7h9Bo'sebfęڍH,0xVn08n q8/"mK_KǺe`9N)']n'# N5,͘q,'5v֪gEB`<_fpN0eܴ9\id[Zf0^anS< UX4".9UHiMkMqq D {w,hlzc ךlb[Ƕ@{Rz,"`L26J³ naFs#,ÿ'MBJQ6ž8Oy!ԻɱtH'7ÆU쥧qdVKZ%;0凜RmyRQbP[#)th&WŰ8wsfnD$~36ji T:bc+I71ELiɞht>d!ܰc}|cC4Ϧ-(X%izo)c Pe@qFưz .M >@^KKe!P4Kx\L;QzhŽ:py!G;UHuȕM0и9LÑa 6&GauS$#$<4kYq$x8gz~p;y5<ЏeE~ Nk.pi](lM,9OTt2 q S:FU6G;ZclsXA{S_iI|L̫Qlp~r߯T l8^MC*Iߔ^>'fTqCñA#?l@p!QqI7g* F#t(O+s զ<1VehzK ʘa$ΰj[,D=~S7ZI^olo;lrMMGi5}%F( )<# :񻊭`#ABې) Ɛٓ@(jC79B%=73AmD'cs A XM3{0P;{ fC^!1hsb-".q2I_d=,%Bĩ <__ٯ@]-|qV6<0rMh{;=]8n=xfo!?sRm|ؕwང(8U33A\%ܳFB!'qء}{?D[vG WXX}y*t0~u!ؠp,ؓޱ[obHW9e x,s$ *iN2kCA≮BFƀso4'm⚋`K[zLLSfXĜxOl nk-.QXx=q,!o/2{Ɵ+ʘƎ#5`ʳ7fp":r(vEaɇ@yS}3Ũ#LPQnz}As_ zZOvO~xǕYP:qh̊ {rQ`( U]kH&7Ĭel5 54Y^nWh֬ҹ+Q'ĀADH[oD17ӹ)aYiQ""<>&oI` z>Lku~sL3Щ uu)m8 Xr"dף ZPꐸE(пbr a@oSl,}a[44\u턵-'PX,l-n=JiX(d+~ja0E`{Q&#(u@ +}os 99j.GebPewc jZ ?P@RAB=v>ZXŗf',~LlZ,DMJ84NA/2Ghpz{5 u"Jf>yZтHefruC_::5tOaj_0'ݩ;9HF:R*3Q!h%V\* /?.α}\_9=m rƽ&I>8Zv6!Tj%=j '-YG}q7 Q`',tp4T3B:v@0-Z%JMh|csJLh# bi=㶈49lQ}+T? 좫/g 1U4g wEQ#;>iڳR3yGIE7pGBn1]a,+P_.\y06&[6Bg0cY.7&\kF# HxޣtZysiC(/&@hy@wm|^an)cbwbi2ש3,bo&P<xGgd{|(n">GGY^GP/<!q)//@=!$w 1Y${1 AQ5r  Ko0 =Xw(_C VA[څ!M WIo5UQde=q8"~ qIWUl2s 2_=FĬ6k6f=(`PazK oШzR d@Ń}*?_=7^d.AE@#sdq `J->ad%USl{RJ+GqEpw&w XXgI(eL5U%쩵!pY =&*CUL`W^OjEo4 i).x:IPr=:Q=ۘX ]Xjšc$R&&])&.v@rTŇu2G[Uu^vUS5CK7Mtㅼ|@-j'Yh.3fZ@a(&* I>eA-d9J.yv G`2YQsZXqki TGIŀwӂ]0$*Ԫ$) 0'ၕAI O2P?OU>܂ Qu‡uv‘X<%!0f$*ŁbdI`UpMo_uŠ5'>N j0l\" I+7c qU @C"#ái,s=kmfsk{^֚?ݮ[E"ȟ껿?_z :3$)*" y(ÙQ 7jYd$Kv2ҙ#!)SG!B$y]ZPI~K :BeDu_@F~J(B8%SHQJ?\ eH%'a !Zd(Hbk}zoG[3͟=gDWKq*0Le9}rCue?SwkQo?E/La-tk>%r+f3}}u<̵Z N|&=7a֎9Єj! R<^'q#HKk~sva!4%|m(6}k^WGC+7Na;l4oչϙ}⨧KFW`P0Z]q9]~f?_pW5|g7c[5+Nx֑ݮ#hWo~8gw6~ŋ)E7y1SlT~|Fx#x7u$ǣSdlE]RRW5nxN1vY8w?m_7]R^ʁ~(n/\;rc?q_4s[4UE"oal匌:2\麇4Jˡ.{DE{W/ |3j;e =\suC6]tSXr U F'x}~Lf2mS5cCwnI9?Epyӎl5Җ t.U@;s{=y{OvP{]Ou8\Ga9?BiP O&yp 2XCS/'yr^`Q=\!f?Iz `禷|5v]UHuM.i󻪴j܀xw \Q@Z{qo?[5|겲 |~y|v/((3wXճ^{H-d6aC@x|ܱ`Wo1U\W[*{GV}En\Zq73[Cv qa\&p<){)||4v@z2mt˛dů/ ,_rׯl{-!d,s;S`w762K}LՂ~lE Q8B*]!/#kRgB>ʇѶ}Pxdl./> JMeá_}-4m`%B)zvS.KM<|[ڜm{겈L\gQHHO2kubC, =/$h}Y":ދ9(ecD(n?B72z%`ךajFLL̸^ɐeju>/XXؖofga5kE{YRB8A'v}nx5%y}_=|qZ)ѵ1<)U쏰:]l18.x'$Guf)'X kh5ڬCLz_Fa[ osfŝrɒ}|汙YX$}lB=E:%Ii<:|f TTG2F uWHxǿܚ#擎% ~@-'+{>~݂2#NjR\R]TcקIm(Eu^ H3t}G1D6Krۛi'K`@9?:v:Va/Q%F1iY {=*tRl:%(>+ ugց_}QZh_W8 m'euZ&$U.3/Ds6qlBR;xkZ4^/2]V<wYpZٰ1ן^@<?{~u]|OyQBSc5 M%S32P]0RE /k`MPd eN̺N]I٘QrR$ H)P* fL|@"ih 9I"eξ?t<~>9 |"t o<`>Fq?ew>g u*t6~5umktѕl 74o@b ᯅ^r-8U1MhB;TaZښtNkI*dȁllo^w/Կ$8V{&b(>ik}Oy DRi;̠~@o'~عX ouן]9z>_<L؂>_2 `NnIS-_YFmw/}]6C b*%#n' Y8]h=#>`2 wiAO=BGmϷJen!8o aQdHѽ߅^uh\8^G}>[$d%<:FOo(a!lJED`"OXETAL"lSW-P~DĠCCq?7x'y%q$ >[}mO#`u6UgYV6`kg|vX9s> TvBJI$O, $̴9g2d~DRͦ;ϷqGoS N& $1kZ<+ЫP$:"5 qq_;ݽa< i S:jLBgeC )dxf?J6,!i Gx661|GjlL@P _ga᭦yiC $PHBHjHgdu!hʯ`^=ߔDPSs>0*\EBR.Qb}e-KN׍!Ea$mwm7D8va٫NhDxuE85pOJHC }K[>N6 e%{Pd3O7V/%m_XZ/%Sna猹ߙ]LKf@kf/,^-]/zl^QVQE],HgC4?: ~wa[DNalXMk]CZ>5W+i1d[]g~ R*\/gisP]S~ P6SW]{Lt筄\1xk6'7ּ4eqX(Vc̄?.PěƸ\ǖ>P*+I;K}~a9;ΥC`79 4k,NO($i57YvGafF˩j:ae/ܿdهG; #4/KQrph;r4,]e!`G} "-FPh{)o@.y*$,c/\@4'VklT+1M2XJ ru%+zdKf$Jxd)r䌐< E![ٻwfAL4C2&!c*m3 jZ0g)آ0\-GɿpQ3zzHcaū;4Aܹ0$>wH!Toq8q]wwذϖ[P[$#WD)xMkx+~ -_{_qcbgc |MkCElEx[E԰RL)!Ag-g\Mpd,sKd_W7diege~.؞|<,Ծ~N:g1qu[%W,Nd P 丈N^+t%7WE_dq0LQ'*+ɿ1ep8ED}Ns9-x_F_У/cz)c$C !{Ѭ]`x@@)xXã%#c[/Q:$XggP|CӫL3%,EvYB=91҆qQ.y*pУ ,FEbKAQ>yN5\{"FGPΟv"Nb\nPi ,@DI3"C*?rS[%'zU?P7݋:U{$G}}t\D IžJ)DdYh#kpKe4I`sDk|ヴ)0RuliؖHtx[k*:^*Tf[>AѕuH$o/ #Cey{Ul?M,}£iERtq!1'C|QuϢlϤuXR5e ێxztt]]9K;;{w+qH|p>K}^VL ~=_|u^'}w87̣-'&(u³1}ʂO(U5::MwrT pTB*XɭƦtdLtcBm&͍}\#HrD9NJ.2x3+ gZO:ڐ~Cd9Rb wq^dA5wyi?IKKε\,;t 818G8Ro u-EvNgR-dtp1NˣF6FFƥ{=Ʀ Fη 8?_%B=ѫy@ D#ȘXe?G@rPWP<3{vGnw5eZvⱞ.eNoe)Y?gߩ譌**ϮЕp<.!ѝaSk:kEYbl$t0n(Ѓ & |5ee_AS3 ^<_䶐ڱT@;< @RUnbAg.e+|{<`Ӎ9k8?r,ȵV+!}Egm&oB@aZX_O_*%=4X#c1\>&GC7%;suYd{tme"s&p_ˣ6w{uji~&Ě3\|2~ X`WЧF+.|Ohj+@{"u`<gF8e$3E/-;`3ϵrlBؽDhu8<`H\8nŪ殄h!֟^9_}<\8Yqd6p.dМ-rW' j P[ɷqAGTդ-ba3JްYJɈ2lԉJmś><2IaF'Jh)(h =Hu@]&/L@|TTW}fG).޻@dlDwdP*zaع`;v'` Ac[i(Cِt@Yz^}jtو-WW9qH[ݧ6u aY-]62$Zm)Q$J,=áXϯp pNj^0gaN}qu rf35]>ncS,~ gV@ g TZCF&TQ5Djىv;P~ck"֛WٖeW3a u9Q-Ńlƀ$pjj7p̛cHֱ1DkՆ`oo=M̱q_Dt0qvQ:SFwFfکߨJg8%-˪շ'p.}p4٥cR%T,٫fHF j87g^c`MSz1:;X;dj0Eo# ;M#B6,e¶sR3UJn|7NB! s0CD@TDH E5iPJp tص#S _8ƻ=_up$CxDD_X{6}{.o񟢶$g:Ak6v{|Q4[(U]xniQe4 Lh +u>{=)ѻG|^hFs 4ųm=`<_zN "/sת_\~8 kT:w(6v*\Ƌ,Jۼ#7ږqҖ H/mADjͧ!YwC#1;Q-m7eno'L~[ oz"byxшW R;ABb%Rv}iEDz+7Tt[<7Wa \ָ],o:tui>jmzr|nNPt7um-s1*v@YP~q8KyKɻa׭9t[}Ux9l-ҍϴ Z{6Ѥ0ˆq#}:FY_էs_]4m():jwV6ls:MpA'~T^hC*% a|ݟc5E\ "3 DJA{M珇٤gA x>彰|Ҋ"0u/D2 (y[ 8C%dl\mi(@1ݽ?_Ė!_U!MC2U"X'1A}G@"B+"h.uHdA~@O/W 5=Qs{n)(OپbO_*|1Ԟ06R [wqG{t<1pȖ;OEvgz6iLC$ha`y!#š^A8zK+ø[>25mY_-2%~{'7Se?ʓ @L kxp((7Ck)!@;~`DjxG>Ily, `"0 Ο1u:Hm àx2I!w=#'hD/p@ e |}޾-sId@6IRW6> &N$xmr nqCO~\N.T!4:!:رPƁu#BUJX" %$qg ..a-jRE-4sܾ^tNu=?,`1J1yŠ0٥ksQ6ۆD1Ќh3O͚Jnsnp"uM{&}v ʂ6"] ez#g]xMOAdڠh8u@BwMy@y\Bl2uZ0^1$(d(d(*(j(j))UUDE*ucoY!q } WvФ.a B8Tj`,5!3G) sO6hNWM~<:$D cDZ)(,Ͻ .DhB"VOssWWwa0T @UP,2ISTUUTM PS#0DB4) ˦=DHDLDA DRDJ!R#DHD!DDCDHR!HR-D4L H E@DDSuf\W;S^"csqwQfh(4u-@ ~3<ڟ=~ G2g(-_`U t!Ghw r%l1Q9{x S d]uځPS"_-BtԓxnGsNG&e\GXzQu Ś ERڣemDfNpTA[X Պ.K/}ENukAXos|1=HM?-5a-2p=^_5M1L;njErx45=e +K^wh@4ț39yS/E^g9Q Rί_͡Ϊ}k }t9 e=;9fC1!J <{C齓w >8!]s7g]`h鷝d`9- b0?5ﺠt bO5 NSv SUGv N&\@Xq<pMkg=Cq;)67qD\]L B$" g({+] Ͼ]瀆='Q0n8=PomptۃEQ*W2L.̋DX^y"+x#MfМ& R)˜9e#J]$P)ًZ "N.W 9ޮ>?GD¥BOJB j)JBRRq(0WdAU,g Z IpKH UUUUDUxQ_UUTQTU~ZV"(9$(=/wq25KEST#@>L@JdILQSQ5UUT%UUEU!( hŘdf F J)iZZ&hX6ym :}ǞIC@S11`/fףQ_VY=8󇥭WM;0HNh ?C=\32_dR HvpAgMQ=<;eHj)*鳅[˦puI-hzT_~w(I?<ӈ82'_g<=V@aϗ l3es6P&X[=wUD}샀oБ巷 }b/L4Dkc @ =B $b}hh4kkT {Dre?^".誎>| PI,b}/n_?~  Y|WRS#A.&l%XzwEW5@lI$$ olso ZP~7+#"$`(``H أXVϰ$:Kn䲪E S#tnbO9ҏ1f ,  3"A34DLȸjo-ua-[U=j艬:QjJR2:k d>Q잳X;xefd fvݗXhվf`{O O]nA}-`e90ȤG9[~붃3 ˲\ŬTrr ^QȰ6lA?NfHYLp`8 1z@{|sҦap5?q6Q9ò=FOE 3`0b m#jD %ARE3TYPly2|8? * I{h(m{b>G;"[xF+.#+H=>lN͖蛇ݻ sᾍn[ H ͼ&Dz` ` nHH $@A;P *VDs?L??柩_8&6蘙'?XRVu}.xѓݿf}v[=u&׉K]+g<ݴ'sOI˝csѝ`lũV|ލuu?va7nY=HϳR f% >RFbslPry:}sbrC1ŋuζdMt @Eg Ez~Va)ALL7'ZhXM,NIHGXf\ +c6Ien /7ZF ogB;-.DVM/vp؀ &j" ifTϛ0jsbZ!m˾qY%34IOwQW0c6UH'P"/"u]jT. 0\|?"Λ?೔^/t!ӭbcN_igd@! 369>;VG%x6r2K0|̀=s;H?auӎcGS@z㊊&5Txm~卣T1v/̐y4?06.BOXPyf^uBK4"w/Pw.4:v7C3#FAB1Ұ16N&>&.Qjb#Fją@ŊsvAM1^8|7q^o Iz,N*!2J%yOg>I?~xO޻C,(7fb8Pf\$4a*'Hȼlj%  B'5!Cgt'<)^}5OҔ*}%ٌX9@2rһ2LY~kN<`pB=~# >c@YLwhΈYIZ"FHMz/87?Q^/55ߵml?6ūxuH.X=ރ} ^W0?)6>呕uWz)9ߓv|>6gwv,rh ϛ+9>UPuU49KZl%!rL0 x@/  /)eӍ1 1 7IRD kH|3ԫa@a2nq)_{R {}͵Ьm.u> ?q\: (4Q o#[u7- jrd'9Rkl4f;W5۠kHR+8"z>HZ᥷P)%''wrp|^~D96*IdCP_ zb=˄:ڵPxw[˵nW >9 i|NokHCX> @`r67>m=?񳪢2p_Arx |o544֐DldɫpYA߻=*+Sc#O@ C(8 ɷ~XK55^$ &@ >\i[Fl^?