From b14044eba1ce191794ba4ce0a891950be460ad79 Mon Sep 17 00:00:00 2001 From: Robin Mallinson Date: Sun, 18 Nov 2012 21:52:28 +0000 Subject: [PATCH] Refactor dev_write prior to allowing it to take partial strings. --- ServoBlaster/servoblaster.c | 70 ++++++++++++++++++----------------- ServoBlaster/servoblaster.ko | Bin 10421 -> 10364 bytes 2 files changed, 37 insertions(+), 33 deletions(-) diff --git a/ServoBlaster/servoblaster.c b/ServoBlaster/servoblaster.c index b222372..f08ed14 100644 --- a/ServoBlaster/servoblaster.c +++ b/ServoBlaster/servoblaster.c @@ -404,45 +404,49 @@ static ssize_t dev_read(struct file *filp,char *buf,size_t count,loff_t *f_pos) static ssize_t dev_write(struct file *filp,const char *buf,size_t count,loff_t *f_pos) { - int servo; - int cnt; - int n; char str[32]; - char dummy; - cnt = count < 32 ? count : 31; - if (copy_from_user(str, buf, cnt)) { + if (count > 31) count = 31; + if (copy_from_user(str, buf, count)) { return -EFAULT; } - str[cnt] = '\0'; - n = sscanf(str, "%d=%d\n%c", &servo, &cnt, &dummy); - if (n != 2) { - printk(KERN_WARNING "ServoBlaster: Failed to parse command (n=%d)\n", n); - return -EINVAL; - } - if (servo < 0 || servo >= NUM_SERVOS) { - printk(KERN_WARNING "ServoBlaster: Bad servo number %d\n", servo); - return -EINVAL; - } - if (cnt < 0 || cnt > cycle_ticks / 8 - 1) { - printk(KERN_WARNING "ServoBlaster: Bad value %d\n", cnt); - return -EINVAL; - } - if (wait_for_servo(servo)) - return -EINTR; + str[count] = '\0'; - // Normally, the first GPIO transfer sets the output, while the second - // clears it after a delay. For the special case of a delay of 0, we - // ensure that the first GPIO transfer also clears the output. - if (cnt == 0) { - ctl->cb[servo*4+0].dst = ((GPIO_BASE + GPCLR0*4) & 0x00ffffff) | 0x7e000000; - } else { - ctl->cb[servo*4+0].dst = ((GPIO_BASE + GPSET0*4) & 0x00ffffff) | 0x7e000000; - ctl->cb[servo*4+1].length = cnt * sizeof(uint32_t); - ctl->cb[servo*4+3].length = (cycle_ticks / 8 - cnt) * sizeof(uint32_t); + // Process the complete user string. + { + int servo; + int cnt; + int n; + char dummy; + n = sscanf(str, "%d=%d\n%c", &servo, &cnt, &dummy); + if (n != 2) { + printk(KERN_WARNING "ServoBlaster: Failed to parse command (n=%d)\n", n); + return -EINVAL; + } + if (servo < 0 || servo >= NUM_SERVOS) { + printk(KERN_WARNING "ServoBlaster: Bad servo number %d\n", servo); + return -EINVAL; + } + if (cnt < 0 || cnt > cycle_ticks / 8 - 1) { + printk(KERN_WARNING "ServoBlaster: Bad value %d\n", cnt); + return -EINVAL; + } + if (wait_for_servo(servo)) + return -EINTR; + + // Normally, the first GPIO transfer sets the output, while the second + // clears it after a delay. For the special case of a delay of 0, we + // ensure that the first GPIO transfer also clears the output. + if (cnt == 0) { + ctl->cb[servo*4+0].dst = ((GPIO_BASE + GPCLR0*4) & 0x00ffffff) | 0x7e000000; + } else { + ctl->cb[servo*4+0].dst = ((GPIO_BASE + GPSET0*4) & 0x00ffffff) | 0x7e000000; + ctl->cb[servo*4+1].length = cnt * sizeof(uint32_t); + ctl->cb[servo*4+3].length = (cycle_ticks / 8 - cnt) * sizeof(uint32_t); + } + written_data[servo] = cnt; // Record data for use by dev_read + local_irq_enable(); } - written_data[servo] = cnt; // Record data for use by dev_read - local_irq_enable(); return count; } diff --git a/ServoBlaster/servoblaster.ko b/ServoBlaster/servoblaster.ko index 93424f0a108960444e65da192899e0cda4730c40..eee1c25ed6594665b985a9ed28a946f404cf9f37 100644 GIT binary patch delta 2736 zcmZXUe{2**6vyA(kG5B+*;1fCxVG0H(neacz|m5K^h8iJpa-;A6x+kLP~?CDM?50t z4s8{IGgqc4BtVydkr-o3ssW88hkyYCNihWY17!D>jRnD=!RQ}^^S!$%InGITKl^=e zX5O1Ov-9nuhwiY0g?mbFzI1L;pAncH(d*^YdNC~4O)h0hu}dif#~vd?=7t4&R5J|8 zAS=@Vmgr7L$aonb6QDsK>j{}&1t^#yhoTnV$TqQq{5)GT$^we!bQ~~1-oxunb%hp( zqCJYmeg|;t$6~R}EKv2^vDlrlK;!n9ynz?1Z?mwXb-2TZG_)`Z(5RafMKcE#%?b*u z#ehSe(^|UpsRph+ zA%hZNo)4oLuv7m9W9%wXlat7RmolPDXOGiqZh}KpA{$?&C`IsCSGTqX7ff8y}W$0brS33hpZJP zK1|AD7LjuL3_oe;jnDRAOrOy?c-wlIF+UHb7h8Q8-p`MvPeOeoJ$IZRwF^T$z!iYw zgZLmnw`Htim3%`+Sr(;1tIrCmdL=)Uv6G$R)wXFkdWEfcidTf`6a+z^pkL4~>Ql*& z*(NZVU$i}&A29(8d~FUkVc`b`js}kq`_qEMgC&_OS?=_jnmNunbLUQV&YSwe)alcw z*F867&OCYW;HVv$V^959eYUpt>UWj(!q4ZHF*m=L zTVcIy1IXh&c{#i)PhxlZ?7RvV>jM0F_wq~mIs5|pZ}A&>6{fB%{z=|= zZqJvP%B%A$*b&}{?>7D(z9s%SzAy8O_;&HX@ondY1r=7;cz~_(K+6jx^sGf&7utZI zD#+nqp{;Q13K1k`eX{dmSk8WSH)Nc(H}FCtB& z0lp#K05AhP*q7t6#d6x)0h)--0BuAZK6xZv}7(x{)-lfrt}&$^JS(kcbI|iI~WK@~^bb+ajn~LgfOL0qZQqvNCEURd+qi8D&0G$nBP>8+gU?m!hkB%hi z=g~oWFO3)d>D(mur~6<;3Lwo%ocYhe0~r z!0#q}u(Wag2jjn%7MUI~{-|_vVASJUB`RMm^n4tV4NpOJioYgB&ri`UDSB;+eg`#` z=LBXm25=ugOzE&IMSq5xF6z1X-~c$B;-^bvq|wnio1(9z=--~u0f75Y7y$lB(T`Ge z2Hr*^jRKaWXgNjCPSFj?nvOy%50w{}yq|1F>&GdY^Lyp}td<{mI=8)cDzvn$UEkKy zx~0|I-r`%`x@MEJR{p=yx23b)SyLw*-qo$`>o%dGRv1=n_I0e^=&Y#`x~+Xv>&Dfc UzSZm3Ics?S#OA@?i6y500Co+QlK=n! delta 2641 zcmZ9Me{54#6vxkdZMSZ;rXVud&j(|yQ8cftY(ochG7S<2)qx^Tx49LVPM9zhlf{;} zMbu51wwkTLn8~n-F%@jW`go zXokZRHDpaQ79v=yFJ^k<%yc1v#A?luX_H|a`%*`OCyIz(FQlkWy;?fob5fTnh`uSk zuw65}>`hxmIGKr@#14yL^7plR3NGhOtw9`y92?5bvrDj2H|n|zDj_#smY45Xa2Dea0! zbZ>mn{3VkK7bgRg#%I{CThWa0%JbQ}yV|>Sr^?Jc<%n)mzEBYmwQfo0AyKzTbhbzo zzHFkOte#Hv0@kYc#LNQt?VkO5A=c#ydypi?25f)MZX#~$68|M01c#gVJdG%ULMVer~}yo zL_AS5S~J}*6>Em1Xz5ev8)YjUH3jkb^r$#{!f}H%!A?4=7fvFG-4@HvrfXwnf@_Lq z^>1@x=EV39juVoUU?cezj!A@1uy^xsfHv}ru1i1%5aKt&87NO>CncEMxgF{5bym80 zntV6zh@S3eC!Nnp=b5jd2D3v270q!GW(hn`6KD~jnm!Y$D^pf)A z`UgEUz@`drS&)#4#!kzTRy#O$Dxz_o&Wl_cuPWRo71jD0>-_$jTWi#1jrGfFZ}Ziy zsb6!uZ~Wz1&lb*oY{OV0`uOwPH&=aiTrFSnS@nmNe~bs_4N1~b_IXjIw4VK3R4pah zg89|bW!4DW&$?l~Yy@^K`v6vF25f{CEU1<)G9RqQ?uBh<`(a(|HP|GZf^A@bz|Ln2 zi>nHWxZ1tG9Q(*4!k0!HSXoJlc}?^C84_hNlNa;NUwQ;KU9NaH4cWocKc@6#h|8?CKrCuZ91jpf0!= zb4z#N2sx2>knQA;Gbl!XFXoHZUS>F@hdRhrdQ&hZcg(^yudllBVC%IdH>M(A>}zKJcwkMLgF$a z#o2Tix*zX+HLj0CM`q|(p$DKFME_~%_>BIKpeJVN3FyfgIsu*dU(0lX?O#-J>vwSb z@l>KqqI~)j?_2QT5VCp}>eK;UCp6!||7{kP$Sk$!rm*+Fa#FUu4MMNQ)Y)_mt+VvE zSaisu`z`uei;hC`!oH7O=8!apPFM!K#?Dn<8|G)zga<>i|AbuT{9L9iGg21)t3})K z>&P`e-)+%zExN=;t8(MBHL0=;SY^@87QK~?EUsvbSiH|$bj+e(vFI^2wfMAD%l20l z&8uBTZEcV2>T2tJqO&K|*4N$n@E(6Hd#h@G-SQQptEam&v~y3$zr0R3I`;PM*tOfg zyjJM0(4NlS-MxL?yLS4Qv%jkzDDCdrcayKKR$W26Lw$R9?+kS{b@X*`mrotvx@3|3 EFGih_yZ`_I