summaryrefslogtreecommitdiff
path: root/drivers/char
diff options
context:
space:
mode:
authorSjur Brændeland <sjur.brandeland@stericsson.com>2012-12-14 13:46:42 +1030
committerRusty Russell <rusty@rustcorp.com.au>2012-12-18 15:20:44 +1030
commit276a3e954cfe4da7c492c9063741f99290d2973e (patch)
treeb2f697bcb414219a157f837c7183fedfd0eb7daa /drivers/char
parent9a2bdcc85d28506d4e5d4a9618fb133a3f40945d (diff)
downloadlinux-276a3e954cfe4da7c492c9063741f99290d2973e.tar.gz
linux-276a3e954cfe4da7c492c9063741f99290d2973e.tar.bz2
linux-276a3e954cfe4da7c492c9063741f99290d2973e.zip
virtio_console: Merge struct buffer_token into struct port_buffer
Refactoring the splice functionality by unifying the approach for sending scatter-lists and regular buffers. This simplifies buffer handling and reduces code size. Splice will now allocate a port_buffer and send_buf() and free_buf() can always be used for any buffer. Signed-off-by: Sjur Brændeland <sjur.brandeland@stericsson.com> Acked-by: Amit Shah <amit.shah@redhat.com> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/virtio_console.c129
1 files changed, 53 insertions, 76 deletions
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index db244b5b6c8a..548224686963 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -111,6 +111,12 @@ struct port_buffer {
size_t len;
/* offset in the buf from which to consume data */
size_t offset;
+
+ /* If sgpages == 0 then buf is used */
+ unsigned int sgpages;
+
+ /* sg is used if spages > 0. sg must be the last in is struct */
+ struct scatterlist sg[0];
};
/*
@@ -338,17 +344,39 @@ static inline bool use_multiport(struct ports_device *portdev)
static void free_buf(struct port_buffer *buf)
{
+ unsigned int i;
+
kfree(buf->buf);
+ for (i = 0; i < buf->sgpages; i++) {
+ struct page *page = sg_page(&buf->sg[i]);
+ if (!page)
+ break;
+ put_page(page);
+ }
+
kfree(buf);
}
-static struct port_buffer *alloc_buf(size_t buf_size)
+static struct port_buffer *alloc_buf(struct virtqueue *vq, size_t buf_size,
+ int pages)
{
struct port_buffer *buf;
- buf = kmalloc(sizeof(*buf), GFP_KERNEL);
+ /*
+ * Allocate buffer and the sg list. The sg list array is allocated
+ * directly after the port_buffer struct.
+ */
+ buf = kmalloc(sizeof(*buf) + sizeof(struct scatterlist) * pages,
+ GFP_KERNEL);
if (!buf)
goto fail;
+
+ buf->sgpages = pages;
+ if (pages > 0) {
+ buf->buf = NULL;
+ return buf;
+ }
+
buf->buf = kmalloc(buf_size, GFP_KERNEL);
if (!buf->buf)
goto free_buf;
@@ -478,52 +506,26 @@ static ssize_t send_control_msg(struct port *port, unsigned int event,
return 0;
}
-struct buffer_token {
- union {
- void *buf;
- struct scatterlist *sg;
- } u;
- /* If sgpages == 0 then buf is used, else sg is used */
- unsigned int sgpages;
-};
-
-static void reclaim_sg_pages(struct scatterlist *sg, unsigned int nrpages)
-{
- int i;
- struct page *page;
-
- for (i = 0; i < nrpages; i++) {
- page = sg_page(&sg[i]);
- if (!page)
- break;
- put_page(page);
- }
- kfree(sg);
-}
/* Callers must take the port->outvq_lock */
static void reclaim_consumed_buffers(struct port *port)
{
- struct buffer_token *tok;
+ struct port_buffer *buf;
unsigned int len;
if (!port->portdev) {
/* Device has been unplugged. vqs are already gone. */
return;
}
- while ((tok = virtqueue_get_buf(port->out_vq, &len))) {
- if (tok->sgpages)
- reclaim_sg_pages(tok->u.sg, tok->sgpages);
- else
- kfree(tok->u.buf);
- kfree(tok);
+ while ((buf = virtqueue_get_buf(port->out_vq, &len))) {
+ free_buf(buf);
port->outvq_full = false;
}
}
static ssize_t __send_to_port(struct port *port, struct scatterlist *sg,
int nents, size_t in_count,
- struct buffer_token *tok, bool nonblock)
+ void *data, bool nonblock)
{
struct virtqueue *out_vq;
int err;
@@ -536,7 +538,7 @@ static ssize_t __send_to_port(struct port *port, struct scatterlist *sg,
reclaim_consumed_buffers(port);
- err = virtqueue_add_buf(out_vq, sg, nents, 0, tok, GFP_ATOMIC);
+ err = virtqueue_add_buf(out_vq, sg, nents, 0, data, GFP_ATOMIC);
/* Tell Host to go! */
virtqueue_kick(out_vq);
@@ -574,37 +576,6 @@ done:
return in_count;
}
-static ssize_t send_buf(struct port *port, void *in_buf, size_t in_count,
- bool nonblock)
-{
- struct scatterlist sg[1];
- struct buffer_token *tok;
-
- tok = kmalloc(sizeof(*tok), GFP_ATOMIC);
- if (!tok)
- return -ENOMEM;
- tok->sgpages = 0;
- tok->u.buf = in_buf;
-
- sg_init_one(sg, in_buf, in_count);
-
- return __send_to_port(port, sg, 1, in_count, tok, nonblock);
-}
-
-static ssize_t send_pages(struct port *port, struct scatterlist *sg, int nents,
- size_t in_count, bool nonblock)
-{
- struct buffer_token *tok;
-
- tok = kmalloc(sizeof(*tok), GFP_ATOMIC);
- if (!tok)
- return -ENOMEM;
- tok->sgpages = nents;
- tok->u.sg = sg;
-
- return __send_to_port(port, sg, nents, in_count, tok, nonblock);
-}
-
/*
* Give out the data that's requested from the buffer that we have
* queued up.
@@ -750,9 +721,10 @@ static ssize_t port_fops_write(struct file *filp, const char __user *ubuf,
size_t count, loff_t *offp)
{
struct port *port;
- char *buf;
+ struct port_buffer *buf;
ssize_t ret;
bool nonblock;
+ struct scatterlist sg[1];
/* Userspace could be out to fool us */
if (!count)
@@ -768,11 +740,11 @@ static ssize_t port_fops_write(struct file *filp, const char __user *ubuf,
count = min((size_t)(32 * 1024), count);
- buf = kmalloc(count, GFP_KERNEL);
+ buf = alloc_buf(port->out_vq, count, 0);
if (!buf)
return -ENOMEM;
- ret = copy_from_user(buf, ubuf, count);
+ ret = copy_from_user(buf->buf, ubuf, count);
if (ret) {
ret = -EFAULT;
goto free_buf;
@@ -786,13 +758,14 @@ static ssize_t port_fops_write(struct file *filp, const char __user *ubuf,
* through to the host.
*/
nonblock = true;
- ret = send_buf(port, buf, count, nonblock);
+ sg_init_one(sg, buf->buf, count);
+ ret = __send_to_port(port, sg, 1, count, buf, nonblock);
if (nonblock && ret > 0)
goto out;
free_buf:
- kfree(buf);
+ free_buf(buf);
out:
return ret;
}
@@ -858,6 +831,7 @@ static ssize_t port_fops_splice_write(struct pipe_inode_info *pipe,
struct port *port = filp->private_data;
struct sg_list sgl;
ssize_t ret;
+ struct port_buffer *buf;
struct splice_desc sd = {
.total_len = len,
.flags = flags,
@@ -869,17 +843,18 @@ static ssize_t port_fops_splice_write(struct pipe_inode_info *pipe,
if (ret < 0)
return ret;
+ buf = alloc_buf(port->out_vq, 0, pipe->nrbufs);
+ if (!buf)
+ return -ENOMEM;
+
sgl.n = 0;
sgl.len = 0;
sgl.size = pipe->nrbufs;
- sgl.sg = kmalloc(sizeof(struct scatterlist) * sgl.size, GFP_KERNEL);
- if (unlikely(!sgl.sg))
- return -ENOMEM;
-
+ sgl.sg = buf->sg;
sg_init_table(sgl.sg, sgl.size);
ret = __splice_from_pipe(pipe, &sd, pipe_to_sg);
if (likely(ret > 0))
- ret = send_pages(port, sgl.sg, sgl.n, sgl.len, true);
+ ret = __send_to_port(port, buf->sg, sgl.n, sgl.len, buf, true);
if (unlikely(ret <= 0))
kfree(sgl.sg);
@@ -1035,6 +1010,7 @@ static const struct file_operations port_fops = {
static int put_chars(u32 vtermno, const char *buf, int count)
{
struct port *port;
+ struct scatterlist sg[1];
if (unlikely(early_put_chars))
return early_put_chars(vtermno, buf, count);
@@ -1043,7 +1019,8 @@ static int put_chars(u32 vtermno, const char *buf, int count)
if (!port)
return -EPIPE;
- return send_buf(port, (void *)buf, count, false);
+ sg_init_one(sg, buf, count);
+ return __send_to_port(port, sg, 1, count, (void *)buf, false);
}
/*
@@ -1264,7 +1241,7 @@ static unsigned int fill_queue(struct virtqueue *vq, spinlock_t *lock)
nr_added_bufs = 0;
do {
- buf = alloc_buf(PAGE_SIZE);
+ buf = alloc_buf(vq, PAGE_SIZE, 0);
if (!buf)
break;
? o$0j8c2쪚bH9æIeeHkZaݥһmh!~y`xnp?KzF.sdN^64:,m_4ݏ&ӧyjz1!7qTemfC$LX :2-†&!9a۞}yJh8ȝKgϚPPZDV'Xi砨WZ}|m+IWϔm%Ёm(0iLy2&0"%G{+aT.˖U0hrGk-G3JK%x-$@C94 nxo;] * vK$#t@BWB&20YI*Cjޭ6uJdHE<{20Ҽ}~??MO~/޼,D14hpȉ |B y/K@r!G*Z5HTi]J=w H+d,c\[ޗ3kŦ?~EEGo{=Gj@_vIpUWVgv3P +L4B_uم~wn?%@^TmW{Gpd%gf !w E @sYC)(0*0dcN>Tq9-ÌPA†"vros 1]9 X8}F7% /w '_a`; p2Q'oHZCyxCO4lk}J/<pIY֦6 Lh.\CMTIqz0I7HD)8$E Ȃ|? UuSٚR?Tco:QiAʣ}ݕhKQ>~;^FT ng%9.߈x?__χ­2ME~%@Ƽ%{A`vt;1>6 vut(H:G D zy[7WN?ͺ?gö*3뿯:=+NJ(ÝU+u(c4s_f>7#Z0j,GC 6MG E[!1 *jdOPIlZk~ . ݺ:]}#8µH0QY0;k ٰ"ߣh{Oo{>=Qp|~/g4(S=~)@x41^z!m[NGY%4ZsM;3MX 5_vbrN0;H:5C^9^4<ǸO|y~P^%9p,#Ҋ/_&0"ӿǺy.C؜؀zuܦ*AC;RDJ0n4GÊ( 'hp{ Н4oaj6g֥ j17Al9I$B#FrdSe)4TƱ"ft4ѪPӢyu)dP0nkmVVLGC8ZAǙx}Qg=v)/츍L$*g\ְڍ!>YBOj<̛UykzκcG (T7L=5-kv&hu1Rɛ֝(-|ߍ$7=4 {~z}VoP18JaNRotKT h"fRo)~_u\FN]HaTu%om| -S҆<8=CGbPRo -{rw٦7Gj.Ϻރ)[kG܎TP)yfGZL.C||?ӈݞ~!-m&5 hn_񬖵k/1 *9-=oWxj_V sUa_?F{"w R*̢LF"-Rg 1IL'8wS[t?GKRMgP'O~-hqsoJq /1mp.?x#t'yV~c[7kmkɵ}]ݏ5BW+8fHJT':buЄIM"]"P^W, 1 kx+3 GCi?~:7*M㷏6.@3U(<"A@nAتJ D7ٲwf)/gy; +۵^sERv58Pot:L>S?o.I9jt(B;9Ү(j\z\C$CWOa=.݅^'o'Oǎ&pQvytTjopihJF6G.CX m|~9׺r;adil_>ޞI!;v_ oTQ֎ißzI&gǘ; E#kǘ?(ï-ͺ|y^-71׻ϟNPsս\m,hRPxʰf 'JSGO\Ip*qʝCtnJ }+=3d3nu=NHB*Q>t:IE $@9áo:#ix+Fy4ZK[xu|oٯE7`0~m{;W a ̡Byd0x%L0bDhuSem@;q;yzh﷣_U$J)sC>[O-zofxmcSG5kCrC*/0Ȣ1sMdDXQAIJJ^ڤ(Uf< *%%5aͬwD ED枋(*"? =#QtpC^8Kx=7eL'a}XGfsiW.PAQSRBĊ"%:z!0!|e``Y9~'67$m 4ZK2B /8(a҄LAK5NE|_|bY8k#%CE:@)B/(kQ=+O~ՠ})tX oo4n?/`z:zr'fgnsp|}#|r9SS_ {qg)b{Cz6 O]9<OsL{m<~}m:tͥr""ܬfI,NF Hr1ӟt?҇&\T{̡QJaȃ B8m5sze8e-ɕ&H>AafSA*/#Ϸ _p;AfA8N5pEBՂ_3#,t;*QRӿEg&|w+Gz%YoG\~U`KuC~nCV}-KSiZHsU4 t,n9LxHRoEwHFŇO+|?ꗜ:5P)FCMZ}+ȀU'0AS_%7&}>^2R"M_z/Y}šT0d!~%"jԌD*u\~ ALB Bo5FՏРxh.@ 7FE@ Mҽxw_\h+À;=ǯVJ{h_^iE+\Q3 uJ|~~[t=h`ljEE|oX]=G_sRRl.DNurD!w%‰h=0F 9]NG9? w/{pe` w*uDޞs~  cLNqol=-n &`wB,0bhqzu v>VxDN:_pzw믎=rGHknѯ(?x=Yt|=9BC-u=J=~,: xȠFv e:o;&x&0] $;7jO1lY  L9-Uu3#9&_- [k3 H~~I 'nj%G4 d?CSQ"R[H-b4 X@ .T ^OكbW:\X[%[(Ȭ9@_HJ ٸӶ 8)M/`9,2Pd*HxdQfGLs{ήɗo8HWd5vv֟kBE)-7Y4QNLHĪ)@$t'Q@6ᴾ*dQ |/]'ar1'dˠl B0y53u>Nbմ>wO4AsCUETh (q2qt jK\:6/擰Cl{\+aHjv)KJ8P'Z *P.t7E'Vi,^ʗU":) \YKqAfg¯ M|{6ۦ:*-7:yz8.]3)(nK>wFwYWn$ڐ7< "W>`M I@ 2=St'of~5Q3Sr=(%z{-WdPQGƮ{GL2@T8t=Bհ&'ql;;!}d(*`ׄ ԟ8m-3QםT݆2-XaɔES,S1sXy7 UuFN4yq5&:5E!?F?r R%'iK568G^lsgeT~M”i4)g4 Zu -]Ɣ(J@J}ꃬ;'BWhtr=s{p@[ҽ|o:2zvq8H I ԱMT}}g} x?N0z=*t4W-a}?W?BR:{A2{_wa/=| *srmh~Цw+$/_A_hQA5R*6~Q?z+o{g?Vy:۫)+neKXX!X,*Dl& fv}{7s}OhD ~]vȈҜ<߷ NF4ϕUMHmʫ+4ТATtUV tDTb! XaB@jI31@`ڐX\jVq"Q4UVJb}ecO~ATYpR(sAG9ytw|[X*4c4xxAޜwH㢓[լ{ǝPb`Y $:iAA7#^ xz#dZf2e}cNն&u/ʨ)J4l$_H%6 "I4 r} "nl-4f($>}2p<`}2lQB|b  u3`8"Rl (#AmjׯLb/b_F'M T^ǡ%szm ~ |X1M)JDKG|:UY6JA" FeqegXciW.,tHZe-igr/PأWkRqf jF)k0KNձх&bЋP|(mEbl&$3uj6s&$|Vkc-[&a ^Yp˗qK.m@|W(Q^(_H3"t)[fE7!9ՙQP%&{W6 V.׌ғ޸y 7V&YFPx-zchEj opΎ#6t[I߁'%*)ye>9%b?-lꯈ\lva,}+!x B]Ku Ez0x xv~)*^iEPD0H[IeWA0o*E]Ⱥ+,z ήC]433eF*孰UJqTz-6(.~/8xz@e}7W'fHLk7ž{ZOv3 nȥlR, #yZu*ĕ{q=\wg+v tva [0D/6ƴWkTRݍz'gyjǥȆ*յKQ(aiaCҘmyȂ ;[i4B OW}~5Q9wȣ=nVF؊-:ӺͫYëPN};PH{-q񅅟Vql1H׫ҳ4-X^hHuȸ_CձFB#Z+SVs-`(Up*Z-q@ǎ"yG2cVQuߦ+o܅<3 ">*Ss0"9|aL// Тҗ҄=(e;BWv `z9D>,6X!<,P/4 aZiINW>1~_$izó5)5KokS @J_OU?5}šm?Ո%0$wQ+!((j知<=m&>dSN2yj6Q֫#l8=S翹Lg~X`Ò(#-k>^dЀHܱYV(; M3KVzh*7[ ^4yNYx!H6_h,ռ1ɠ~#j˖U*(C{%DSKwvVSxmzQj嘉f6~<%='ܙ;#> j#C'5~3kp,e̼<Fo/ ctcPfy9!susm&GplYz2Ep:w&9V9oF,4RS.fXiɧNo.ub\}\2(nl̴5ޥަ`_ؼ7uHrVN\u» 1d{eCr7RjFjD\7nVe 0G"Ǥ'iHBac{U\55-"bgn0CXȶu_ڥ[=<-!bϚv@{Ҵ,Cu( 0_BX-ߥۧھ-oyfDTy2֪>y-b5eݴvhZW:ڿg6f8f|yM ߮?`loOmL~9vQ0jtݟonU?AEV܂="6zt8OzD S@֪lw4ZMqXNu\]Ӑ?p-zq~wW~ʁzTivNwr XSuʿk@ᙇt4EB$IuS_~P;8No9(N2#g@2͹"aҌ`~$ƝYLeD+̺O;x~ϼ/Vn/<Оg[xɵ-vhAƸ3"+OPTiPs&.3VPO wJ)I)b ׆{aYgߗ ۸8 Ԃy <f$Re 'cg|Ń7 #؊gc^)Oj읱*NBie>©VǤ+qꍦ95+,!wosSK(ndBeencXkX 7R Z ra JNtVpOyo4h[/sR UX/։>Xess}s!8?Dթy>T KZ *P*%G @{0?vmUI]²9?'^[HZ]mͯ8ʊM(OǠ$5EџF?.Q"qY4^+ky`+QeI'CÓIڨz2~ A^ "S}C m˯1O~z\M\-m`unz5Z)e 6ѥHPZ(5P[ ҙ}eƟBм{R<FQJtćSP.J[v|_^]%aMo/^Ҧ3o?v)`_8nڋv|CȪu1y'JPsdNPMp=|^/"T{|-e򞕌fj-Y~栄ywxr̮Tx߯x()C] Iy寛yd%<k˗S 8yQӱ~e3nfYXMPg$t~֩a:׆j _X_ yUt 4Pc7"RVVy8`a} zcDھ 6\}NIV~Ĕ68l$z_ӷ~VR+ΝrN^߅Eb,ߔ119Zmey:x>u틷o\w]UsYf;h%/LfCSuR |J?w3cjdn!qOe؊]ߗeBUPQ-H# /Of]_>2.kx@Ol$7CmkV'WO4p{2hJ[}&ܮGf Cc}#lEw[K1hTPe4SH$.F'[jʚgn/*.>z/ip v aGǛ׈<Ǘ0{c:QMŤPBd*~h,kt)YB~Pl"!!| yN~vD^*uڤAR~y=V&5ϝ 3 Gf9q)UIENU._w} zSDߐB6z39dߘ.OTd!H#>vyt):l _Z+  h趭Aer/)ɅvXb=2ʀ>6ly(pC;M?}dMKB9TyD) 7c1D-b&חf1t;jU\=><ţ@f0)pۧPnTٹjMHڛ@(DZTuYYlsBchYOi! )APũ5&w%!n1~:o>=rXCU@OzOz-W6@ 8rGUØ|Iwi-g̝!y;ʍcCBa>DN+n<9lcp4sN3,t;G;0A GWǛ=-|`w5uֵJB(jbhrB|d^ٴcfwp}SI#1(|Ia1Y|T: !/hѮ ܱ_צ\yl.iMFWvhk\mDCEAnz=4y]_L vW 8Z*f@SOD7r/-w,.Us&[Psg_>3Ҷ>m>06#"{:z[yWU@4̵s?dD 쿛yPnAAJ:Gayv/f0Σ\mӻ6?q>KZגQBLj)O2_8-;iG4~ n]C聤 Yoab-da(P?LUOR*9onNqӦ[~c (ũ$N>%A䋬YZ8I$};W":iљDˎidP~PX(U'>oyɺ.Y U O ʭ (B4ek Zx H%v?wYϭ:MҍqNj8TQ!CT_B%)$_Gn?z}A(B qθ6wN4$,~1@g@lU;xCC+bGC}8kkglo:z3;* /zk*zO!6>)JBhIf @i r@$aT7.`g?>gHE*㇞oͭzpz7~i]>qn.F^cW)9i֊C Yi:||M{_ }'_âo<q١p&w(C*߼i4+5S Jl]?'QY@}45ܷW-Ά]L4#R<-D)CmJxT %Sb0q2T  ._w1.]<.<t["_8iD\`[6j>h y Wڼ,jӎķp*h ={ly7u4mTjsmzj P95X:ku F4oks5av0USO-gXwyʭ/BȦڙ{jkaK:_ cv.Hd cNS68r 6 rvrߑ.rUVpDut0l AeqbEy"(u jØfƝG K8F`Pʂ7j""";(O99pQ;7OσR=fBcɗO$' ;ev2^lȈ?/fӭi})ZV ^/O POT7#5GE ¢?rpk"]__1m(8ہӭ|ym| DAھ8~®%bǾ)5IXjPPzR{P=tK{;Ԏ~)FWԸuw6mQQC IFTvh%X4Fɲ}ߎu<$9as{,0͜ oc 9 -Hq1l.ں(pתY| er;Ns(,@g`.mM(^Al -&lVYdCr;|Ƒ`GFcaCi 5y[[E]rO4($>ll!gժRRSPF)2 2N!;Q1!au$*ʊEkڜ[b"<ڽ=PY#Ƣ{%;Oc[?.~󠚂}~Llfݧլ;,?y-Wc]}#db,#d%uޣݻ.,2\6J$ GU#U@+ Ya)~_9C&ʿ78c,آ\* L3QCM+):ƚqҙY{aQQ=ʛV4dwjn_]WZ(͓}7kiƥ^v~Q?ϜY,W|*KjXOʉ5-SC1)wϚδ-k.0/EZJq8axdӑAUt>FOj9uЁod_]*D݅SG{ԨXTԦHAu>f{O.V:!5%,/w r˲yÅ/XOdW(|ZS| <n=?89|޴~$%#WCO^8Qnۨ\ab/-DL2 }W,a}Ex= W'0V f6\I$MV Q{mq~͒7hϤ1NҨiu=q?E )͛C KՕnv3xtOgZ]!a4UNt偏 S1Dv(gҡ ,ʡʧw+UqNGBZn,~GY*[>I^K'aC pAjD"}8 ;9xa;*ZGn?'?a>-ĘqxWEm[upT>Wun w|b֣WENK{?m (Sy}ju j⌄9}uݾvτ<0@'Gק :}tz8nzӼ#*ӞKzBd:ð`C_oB<<,/@W]77iP=S4GEl{Z g ;b.GA}-W_2Y{TzQf٫yDVhTڑ ҒZ=֣m3[:oIh9@tz;+iEMvD,ȼ?g]|s]eY5 HV*Msx -0U`ny@J&!h MqxZ.] \>T_ :z8o @י$QQ̵VMQ edxlv=!:E=>kRc ӷˏ[0ݲOaat9ʌ8Qؾ8T )` Oob#E**$vٻ{ Fs|7DdhIG,ӹ [?7z|jqL/yu!@@ނ^zhy͋/QQ<[E5ZǦׯPۋ7(fE"}xosLWTbTB:Juq) JmP\_ڗ*-a>=7D񤻝DMU[#m>qn @> |͞zV[j[C(y_=$"X(*o~C)V%G78p1e)bZ:|yl!a+S([ @$r* ̰tvsW[!e1[/Cް QG5\>**j8a*oӼa2,HLұG մ~k򊤞_lOE\ʧGn -՞bTSВA#el~t,?7Ps{~"8"tyz3JZShERR$&x]߆YQ@HIζ1QG[2wko9(%jC3\j,NK=;btG{ţFM/W&Ȓڢ.V.<~p(#'x3s'y^KȾue¹:*$im6zB}TjIm0VBt+wpv1_2qeF֣O-5{S٦ាBW\?3Seخl TN6& ޫ {q$E's-24rCnnœo:jQǡ9QN!ɮvl"yp9%4-TQU5Aw`yo͖׵C3m's7햦_$@5<붫Bـxnq/+` GY6잆Vźr\ ueG3vL^vn[)w_]T`BCp7?o Gא޸x͊ X?A>mR] FvR!]BTC;zџuDP֠!+,<%H6Ү5=~RkʘF.wjlAQY(rs_%UaI]UWvj(yl, KAvrXv j\Q!# <ӲRw"tn).>MDh}TznKe9,;vi=-<|,l+bZAYpڃI ۰[jH(@$(^ZW5?S8& ?=VR gȡ[~Ǯ>:lBvzqlP膢uW(*1t#RQoUnG_}[W_B]+HTߔ^Z[}|v>fGL1 /*;>]FW~3>EO/;?*sNƴ.>^+ag}# PF]y?裔h > d0 qJ0'48wbu!طFT #W5>srj`= =~3U!WμCeuxQPSȭidM9@vO/ˬW~[x" y ~ H1F-eF^ѵ\|_=y' E )ކmYjSEtNuS4ѱ (@YNF`J6#%pk2wmEY6 !Qeg8u>fJ*J)گ楄TJwr4!wy {=t=k[0v`{v~@l`aBSAMmc]V -6({)i9~3*}ߞ^]GTbxXB`3!G{q.EYu(|d$ Ն!joB# :wړAxc/>hd_QQM $>xRvrIE!Py'6G  e;> ?ER@ɠ+ `ƛ7Z׭4!J/o`O+F8mOqvJrdPB~^*캚ѸEZ|ҪATA5KRFE3$:UԫƜM+N=,; hYXmfA@HV(qKj4{RV"Zp#]|o[ȵFR6VEHEa/ n̺^F8}Jt͏F]Y׽i3Xح%eu{*jV?5( 4c#3MVWr-S:<n]CWɂ"V{UP١qy욵uK#?cbT0zxZ\b౷ n˗l.#'棋ttGg?2}_k >F\ߍCP~@,{KCs`<8 GCcB(@,.& f |?+B}ay5k-(AxN9;?,2kK2g״A' CL7H+jI+K7/OethFֵHGqiXòχrSutRHoVT+r!$O.l2FI\6 Ϊh@R{ۚ^Z^peCO|]Z]z2t?/YmFN^e!r7V:)j`UW^l^6q[^QTfaOϑn:i?п*z09FiQ8QwpBB>3(*r|Tmbk$*X|=KiOGUu{* 5ku/һO>M.0\g&phk}3 L7Vfrxfo4v,ދU|.F—܅ص+]~Rnʃ >JW~L2h~eT2Pmלh:s)"Lt9N<\*C! =R碟pg 76T =9J`>5~Z]0 3dF 5ek-XмQVE|hoZsYʋnxmw[lUƞ`۳s"0F+^s_.?ooyםp];P<~g4(!ţ宻4<ڊrÑ+R@S&fx OAb+#! ݋VR.7_]-~*7`7 7ZX@ ifE],d=S=u~} ĂX"7̿#˳yOo6qHW[?WÕN|[GNѢ{{.;yzK+DWkPx\D6l;q}~+Os9ӉD9ڦ<(Jdwx-%FԶ&4dR2H\ Qȱ;Av*J VL^eǃbԺC1X~E-;C.|_TO͖ 1Sr"oA"Zo< ĪihF0\|eGkG\>k}O5qpi:dS@jQR y*N{➧ٷȻ_ [u?JvllbJkf cZ֚biea)S*cm*uj錄;LTR[_.,]3ŏ*HERF pEH6uF@ײ5 Ac |p>_]֡k n!}5X贔uB w :hTq)eMyY3ϊ5 d/JBzuQ@kFٽ38X/F3 P+qӳT9to8pUHrhܬ7Κ -eeErZ(Ih2ٸn]IE]GehԡPo7q P Qȕ1/z'()2 *.wu\(m\ Ǟ"5fLwW Gh[׭ |{3uvэ"أk<Ǚvf` ?3cꞦ] Qeb*@׆T 9U׸[V _,hAskqhM}LqG8];[# T0lg.({~| ڰh Y8$܅b(t(*b}i dx}[Lo"Sqp66:B s.jipNQ}/,f=iO.qJ?w"P LfBeL,HvO=XkÄͪmly>@'zZ7ʊBĊɚX4e+^$ɵ2NcJ07Q̥3ZBHC|kp'K&{6&qʬ |_r⡢gf܇o-! JP,^BY0݃1K2J@f^6h ѫ]!*C e5P.Bm*I hѕ@KE0w!s@ rNפ uU9PB(p|! 44I#*"fu$l5xzJ=X|KVhe˼C1̦/Ҹ5T$O[3^*~=RPQR{l<l֎ ŚӬ|,K5(rU"ީonrR qu=:a 5.feH֜RAwĤb;9:q+(' ;L[~~* ) ؠ>(J( EW+mZ nV!jxz"YiV;45ު edƙiMmOiYu/zJ.-Gww-Ѣ1*u~xyVf, jŅ YZZї8ʞ>8:g2eԃW"UTB !N<>$a!@Aa=/c9xt 䞭NA}_?ÔКqa:MU.1q/p#ݮ)oe9/*j˱QY^]c,z!}l [=û0㈐ >up\!>09QdItC\~/˟߄V.~ܠ{?,q,mTް-ؠK -(m(t*,& kYy#C% 5+tYF6"8xc~\Ud!XJe=' tGp~OGzenU'֣n҄Pto }Uk. Pt!Cܡ4%d$L)ό*@PX )rK}3V@fa ZBVh4Yvu`@ژE,Qv"hmYiQ U՘ }t:ZޤGهCߦq-l3K=e?v,#ߞϠხ{kyT*`{xrwnʬjT1b~k`HMJ fQtne݀CGb)@@569iu˵ʜUkrF?mn) ]NkT2Б_CB"O*x\NݞH= =Ak7>;v{ F~$2"'`t߁w,N]= 6<[~j(:(؄_F{|#3 Sj=p@i=k<r)Hs[`,,v v)H`#c8GtxWFHNud(n^;@-p5]@o)!4 3z%~_]ï ~E-NoO{_靈~_M>YΧ,u>N7e!'ڠ)w zyoFԇ%alv>W`z޶/{oGYS;w7u6I61Htb@Tv>{?u p.jcړ]i*Rص@׫%{Jsmg[~VJ@-џy 5m|a0KO#@:Z. ސI#&'LVSU@QlMV0Z+\;ڥ*ݸdҡ%ig-T:e,@U_:6Pcn0HrX=KdkobmW|_.&GǴA(^$I/*Gy-@S-3ye Q* /akgkGpoBٕ,oLAOkHsVM)wP*(tHͅ,0CAt֪8 ~MX5T:X[FECXPDsִ_.žd Y 8Tc㪲smnT)'{03h qW,sgFvW _s׹|Y8e[m˧ T'W)$ ]X*UI(ᡷ#Ɩ\U>bӦJ3A#SZ > I`k~ UX(GVvn@WE҉ԋ`QRؘrH , Ar]{CA ^s_ 5<^KS]}]i.~.ܦHU0E>g01<:w*J{`zn<4m.;aԧf%nNCGjq]4PF *~#=Y3i=z4վN|5qTx-O42_K/´vfp ƱV'WU]-6;kO#S泥߻˖̽}5Yǩs ӡ@8{yfqNߍ l|HwvԐ| ~ՁR+~Ƌi; Ƞ Eu|G tQ<8|fTh:Akl;h)&E0Oơk0*˥*6oTPgЩ`mj^>bq?.1Hhz2L-nTI4W{h":з'αw[Ӄ@Gh#?AR'`)p3V}}fiO':k9@K ǘq*"E5f?g׺~"-nk^><~ZU;uXcv!:4G8Ӑ!E8gh0p}|m(ޔQD{GXRH 8xJG2l mj7JO빰 vr 2"sL#ηҋ]_Ob$w,*};%'na͗S/)L746F^PhF4[Vf2&.J)aV'/ﯴUY<ޭ6̮e -w?K{1KMV 4$n-ᖴӝq,2,[ zP (\}-b(HԎX]3(;f=:I̒셯ItX,]BHU8]﯇#:vQ󿂤u8;Dr;6a~MlrwT}{]߽t`wmLMi+iznbvUA vŨ"R|ld:v|"H*V?d *%jG:OmvB.T j枅3Jo疞@ڹ  rHtTqx NƹKUkw¬j-<0ijH37F(mwmL#}5t w۠4IESLAQ\ [i猸m=^-|k;Doj㸕Y#h^ ! Śu@0ۏL]S}n? N%X초֚͌dɢ{p`UG#Pr; (Eo `FW>Wg|N#$*zQa t*o7u[7_v1l8ע`uyܰ+0,"Z~tK\]x+A3jI6eA'i57slo$\W_頧nLݞ@xdx}wV% Cw6@QԒٟ"v4DX0ߣa;"|+#7 3ּ.3zv xh]P`"7flOmMf(Y9鈶i 0 t [7\n y[_`[-t!0thCt`=k"⪽5 wUAcZB"9cj6iB*6]ޯN3+vfy }sXSUF(<*m͜n}X4W|uƆ{qm)O?뀲E;|ӭH)vufM+/83M3_-[,[de= 0G{Ǖ u.RZIb|":Z^(<|ߓV %*lq@fX:@I-Ἶ?_G-gaXżwUI#U''>״c 6Nj&?գ9_c>Mkk|O>|w~o)Aj _q q Q춇<ۏT 4?W&2]|\DM$evHP OeEgE~z7mJoO>,ou~G,l|oI+MTّ2RJ] 42PڠLv2.c")m1OWEe'nhVߝs؟Ow;qd SĿ Dby|<({ARH 3!9(TGґH6/Ҋ{ }זo*ێ ƏY thp<,9owg܍Z{y4>< f94+&HO{mn0 QN;o{ٶ>Ma]Y×Vwl!BQ+V}bsWQê4I:+3H ñunϜY((+ (#r#eP名I@^"Dy ҢTqGgDCgbu:(Y`*ܯ{$ap0W[C 2HPzdpR@b\Z)pMPD[ +E!g\?473WR@S>B+0ɔP򶹜 zUh1w@tJTf K̭ H_= rܙPQ e!iM4o[ R&<ݖlPD3C.j)%PafJ:(tL䅲/jFX6mh2vI6[QfHi+a/~6~m{8$d&#G1E15l.KT,֦ܩ$b!5YU*/,uF v k =CMǩ9 w|>{å]gKfpĜiHMOjT61^-W%Z *n ȫ.B `5yl_HlChʃqZUoL i=jqbYogV2ݰoHVqJ/:[Vem@q՘5GI4 V94񊢳:)MOq%@ J|C4ƪ^nj^A;aE155k;0n J <5'RCUwc}b)4#D\W&`Hһۗ˕8,c"E7hkQ07!mI|Qk^ Z3 R~aTSq9Ӓ0 ލ t*JT*۶weD yRܩe`TH-iU²;4׌&Rrn"A: ེ~5|[Ap@l;3y_} +XkeH AiWIZv[R4ԅ#~%chl{6=QkҊ(Y :8hu\ `4t, Ԋ0V#6%f&,][XWS?gRвS>sҊOEqhh(¥(fUq0`(Eu//ͤ." pЍa+/+3jZz+ԫʡxu*_yseu:YE'+G WbFVYteLYYbyTcʘ\13 JP-bX!5ʂh$(M6mF-J,64ͮ{G-J˹͚=zoV]+_ͥ* Ѫ)kδR#=R!օA$AEsZĻKQL, 2Z-5$ Pd(YuN vԃ(tqɳpӏD]3EeY=S*{Uԭ/͜*J32 ㆴ1~6EQBQE% Ҝޅ{'Z\V(:pF]~;jJXaLG}Wb AkSZBْB; (Cr"YM_w3+;!}wNS'ƾp{ya3f CܙQڵ{wX)VeWdrȠF҅zWz+9ԁބBssT/eG‹5dB/uf\Z-xjMWLڊdEd=#SiIr x^t[tUUzL#_@=N͒WtD{]nҦf,8ZPj^d"tp맄\MhK憑Z+(ll])x:Vb|rEwu#&5ߺv 1,ӌI<^Vǁŭx&aHE G>tTT(cBvQYG@4{ a#;mCٛrX.XovN[/Вv\7Yٮ+6H%lΪTAE$swx!NM,H(|{Eձ[_?gulS?WYc"jqԛ߃D?A=Þ Zpyyߚ:ǀ<8UÍETz {]"rBP\>oƄ9әr+541_ˉN4"Aު:P kX i:ϳ庩iY z*-YxV86&ȻGC>%@<9-^BNRy_B6iO70r .Mq~*z ynܣ=g+&^@;,g̪/6=oh,;:q$Ǘ@G^SZ>^%oDzX{̕mߊQ;#i7rm .DJ4 3*JUZ}i0 Qª1G%}sN 9WߍuaEJ&=ԞvU]{ݕ|U_Ⱝ藅5ivqJ2՟šUtAm"d E0$d7ɐ)?;dȟS)qq׊9Wi?E>6Sľws[ ,)R7pHT,Uneɮְ~vBteEJf$UIQ>y)\% R  +w&ΫTgaCI'|YnDim;RտR%wQХGi|oOh -U|N8ž:)h4TW鮭( }$W?7Axv@ J>i8}+A_ο3i?so^ƚ ؋6oF>NݘvN2b|\; 714yjFyg̺>2֒zmog}u9s-+38Fs83h@=b4L>%ЦV׽& BFWVpQ$9w4jdv3Boo=h)Fuwm Ȳrִ1 -4}O7Xf3%aº%$;pHLEA,aE-bec9 kSt_U_-j;qw=鑣2ЭyRܔaN[#S2%t5Z4QMAo̫j\H.Aul(Zz:KUƆP_Xr ݮ/|Ej Ifc~X#lFI|ʊK+wqmcjXb0 8eo/| čkvRw# ܖD U+d nb3]SZ.F`4:uN>(&6 V~:V>D6Qwwl<#sQB -% H݆#@[;l%E2*s"Pg۽齾L9_"2hsU*W<\ 7뼚Ygıs4Xz 8K|{?Ώ+qcOH}ߐ?y DhwY1- HOo~zz| %RhГ ;AP=\mB (yn苿(lrBVfFӊ8\P1`R# b6x" tD %@ v~ha3H I[mCv r"Tp"˜{aNWl,Jn#A=m grYc+ d ڈV#ܤՃII ak[z~볟Mӣ]s4Rpi D*)PyUorkO}~ 례JnѶk.R D4nY6 @Q 2""g$ \4F83ίgԨH}o&= ƙi9Sܩ-Z6X* - %-]P4(aAo/#]ڂ O4rو7p-oͅ5V-Ugw08jI\W~qR-!C+Fq-aWo<~Un?XX-;tT`dHL酪U_4`D$P!$@ yG=p1V߭qNuwB3C#M'Oγ`d^?O|~5~H]Uc"lh`zAnFTuH9 c? QR M;l"kA$dVHCiRx%/3O< 8)ᘓQE4vR2zV9*Ybo?)= ȠHHp]!d`d>=hOOShX &7ܳJٳɛ5A 0]6GKDI0,ɧβ[>kĂȈj0P{UVhZML֗kdY%:hl d`f )~gqf>XC{m"@-1]2Z9Az]e;-~PaW;[*?E5PbT ?J3.P@G|m}qAfõ$8Jm ׆u! dDyu#]~߿YAVd-ߑfrL*Jlf "0DiF҆xT 0a!FWY 17 }]bR`22fE8a<)`݇zeSwD}"*'hI)-;^N̓d0odfć/8w0xAO?xr #y?ݵ{8nڥSTᰒ Iv?U3Ũo6khK@Yz_r{ pOs!D! TAHeRC=a_L k}/OO=ڒ{ZQ1b;0{W7N|6=Q15D仉\_h@=*49:I'(-ɤ;8=Dg,HHف Pp # yt!N'S7*zϯ\Ofۼ*M4 673$ޢqޤsp.95 pac@\0)O$)&Assl R,ukaZY0ue /,[O2k꽏+k`WfFD?n/uTM p?2m46lV"4/\«L(M=Wh;@~yUDB.> r﹓g&e}>L|ZؑS ҡ~"tK8_ff>-*A_欗Oq,4쒊#W2XX0xSj>5] [j%lTj,iX!Rdf%e!vqKEAUgp~"H3ƵI.ӋM0.ǖ´HBtޔ7|@B@ 8/AHE2$Ӛޙ T-?v㥇{ݮ]p6`{kak /JCuhЊ=β`n]uqXߛ h6Pqa,QRmScmf+-Iv|ƕfT^5@}cwi o;ppңM p̎Oy{g3haA1iE6ȤETL.?.>=Sk0x{\={ '}qDה8~  6C:]d> 0]df gTxtP:}lh!N `T>=.Y>²Ѱ-x(-GePA@$D(T*5 ,87 H@tZ;oTl˻w,7''rG3@)4g>_ ADc``PkHM5383V+I<TF3\TBK>lRXR!.V;e,:O%P1S! J)NԐXttYtU7&36oNPj VhjPuYu.pqJE;qғG?'=s=?d+$xs#ǏH( ւ3ϸmKxآV Ҏ Y&5QHnQx(C͜ 0,P2rtlvɈ\ *0aAaz0Ojۧ^|G ƎFS!*0E4$O} #U"VW!U<%Lw.#FaAEޟv}fo5,W7&}g$˺'qlmW ?TI68GPaU/O^Z(Tl[G3cףf)M,߻]_Ϥc==TbZqΟhRᩬqȬfNrf|R%0 e @ MA ^ibQ 祾!z@"TUr?_8(v*ޣAcn~x]_鷍 >[kpך~=]`( H!RAE_5PmOK`qWh\)@A%T.eFahj$S،xa>c{^[{«oN࣏DL޹Jƭaj٨{E-~@N}v>kG\:!>fb&6EY<7Epڨ#tLOb ME7 G0BYx]iu8$,ȌȀc8$ϭq PgB(e>Ot+h1=KpU߇wO債BV6SZd` hw" \SHI廣l4(ջh^0-AWf kxFU\RR֎B6j 3B3A CM aR<ڰ ۻQoZ3]woz ~*H3($/W# 3܇jf{:B j;7 &C:.e 2,M w_0~3O>D/p@а eA:Kr) 5a׊a!KpWv[ QQ QEfƅ*]JhM!TABC:hTdgzdp *ep`A~>u'4ڟ]}XOCtύKOp*TxES_xgAoTNkb!D=RNJ[e8 +ޮȶ~>ѴwG?T.# ӑϟw_edF$vvSfq~z7OY_f)Swu{3C/ձ4'Tu~Zܳ\vt熧[vev 5߮|?[yϔם}otLG ڑ0g+9!K`~\Ba|{iɽO+>^ƈ?#aa R~E{~0;W\Pn61cCWU\ `4\i0߂Fk{ޤy;-o(ݟg޻+gY_kl65fnzM|kOFr1rFP4Gf)ǂl|i@aJyXHԛyGADqrXۤ1AS̓yC1Hw{{I)0 }-%N[5Ϙ>-?(sONu\g+`F}e]hw퀣LQdO] ת{}YuY-T]Z ֲ9=TW6X2iJdPY.5zxxQCy~N'(NRuVl;Gf[ 鷈fAdyssn(P٢+gMz{\Xb,sW (UbE1NJS"aaٿ5}lݏb>˽۰z$ @uMgGN j ҧS;GN\C][es^ C+iOݭрl QO@m<û7_niq4h+ ViE gNh˗@Zk3B0g+=X?b~'i ?HϷ!s-肨Ҫ5u;7{]{+k.'F6 UH~Ŧ*-[=Aq>m=clmKlUߧ=M@c2,%cU<9?FTEX%G]FEFƆ=lƝ@I*Q~~JjhďV9h]i$7*XoRS? zO5w+(Swi jő+ʔMmkx-Us=Zj:|[gA{A<AQ O^it?.?d IUގ }/vmwɘf@-E5 

D5z]t-cEq3\#bSɀ<B{X̦M*zCy-j&K2N k˄b82(dPkldC>H9Y+}F<"nd焱Hlp E1fKB3@h;˾YeWOAm4bzD`UPzVAORp Y[n6o\aZ|l:/bR "j" Rp~?|#'}*GdNڨ( v4iǟiNp! 3fO=y )u(-Ooq`y|8Itwr7 sk[z; > 6ΞH˥=t~V !Z˝#O8t)Z|`]u:Z÷m[2TouM'+oD߈Xu?G}9l6( Ň]^^@e'?