|
@@ -18,7 +18,7 @@
|
|
|
|
|
|
<h2 class='titleHead'>The Linux Kernel Module Programming Guide</h2>
|
|
|
<div class='author'><span class='ecrm-1200'>Peter Jay Salzman, Michael Burian, Ori Pomerantz, Bob Mottram, Jim Huang</span></div><br />
|
|
|
-<div class='date'><span class='ecrm-1200'>October 20, 2024</span></div>
|
|
|
+<div class='date'><span class='ecrm-1200'>October 25, 2024</span></div>
|
|
|
|
|
|
|
|
|
|
|
@@ -6112,141 +6112,143 @@ will generate the <code> <span class='ectt-1000'>class_attribute</span>
|
|
|
<a id='x1-61724r284'></a><span class='ecrm-0500'>284</span>
|
|
|
<a id='x1-61726r285'></a><span class='ecrm-0500'>285</span><span class='ectt-0800'>fail_register_vinput:</span>
|
|
|
<a id='x1-61728r286'></a><span class='ecrm-0500'>286</span><span class='ectt-0800'> device_unregister(&vinput->dev);</span>
|
|
|
-<a id='x1-61730r287'></a><span class='ecrm-0500'>287</span><span class='ectt-0800'>fail_register:</span>
|
|
|
-<a id='x1-61732r288'></a><span class='ecrm-0500'>288</span><span class='ectt-0800'> vinput_destroy_vdevice(vinput);</span>
|
|
|
-<a id='x1-61734r289'></a><span class='ecrm-0500'>289</span><span class='ectt-0800'>fail:</span>
|
|
|
-<a id='x1-61736r290'></a><span class='ecrm-0500'>290</span><span class='ectt-0800'> </span><span id='textcolor3226'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> err;</span>
|
|
|
-<a id='x1-61738r291'></a><span class='ecrm-0500'>291</span><span class='ectt-0800'>}</span>
|
|
|
-<a id='x1-61740r292'></a><span class='ecrm-0500'>292</span><span id='textcolor3227'><span class='ectt-0800'>/* This macro generates class_attr_export structure and export_store() */</span></span>
|
|
|
-<a id='x1-61742r293'></a><span class='ecrm-0500'>293</span><span id='textcolor3228'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> CLASS_ATTR_WO(export);</span>
|
|
|
-<a id='x1-61744r294'></a><span class='ecrm-0500'>294</span>
|
|
|
-<a id='x1-61746r295'></a><span class='ecrm-0500'>295</span><span id='textcolor3229'><span class='ectt-0800'>#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 4, 0)</span></span>
|
|
|
-<a id='x1-61748r296'></a><span class='ecrm-0500'>296</span><span id='textcolor3230'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3231'><span class='ectt-0800'>ssize_t</span></span><span class='ectt-0800'> unexport_store(</span><span id='textcolor3232'><span class='ectt-0800'>const</span></span><span class='ectt-0800'> </span><span id='textcolor3233'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> class *class,</span>
|
|
|
-<a id='x1-61750r297'></a><span class='ecrm-0500'>297</span><span class='ectt-0800'> </span><span id='textcolor3234'><span class='ectt-0800'>const</span></span><span class='ectt-0800'> </span><span id='textcolor3235'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> class_attribute *attr,</span>
|
|
|
-<a id='x1-61752r298'></a><span class='ecrm-0500'>298</span><span id='textcolor3236'><span class='ectt-0800'>#else</span></span>
|
|
|
-<a id='x1-61754r299'></a><span class='ecrm-0500'>299</span><span id='textcolor3237'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3238'><span class='ectt-0800'>ssize_t</span></span><span class='ectt-0800'> unexport_store(</span><span id='textcolor3239'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> class *class, </span><span id='textcolor3240'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> class_attribute *attr,</span>
|
|
|
-<a id='x1-61756r300'></a><span class='ecrm-0500'>300</span><span id='textcolor3241'><span class='ectt-0800'>#endif</span></span>
|
|
|
-<a id='x1-61758r301'></a><span class='ecrm-0500'>301</span><span class='ectt-0800'> </span><span id='textcolor3242'><span class='ectt-0800'>const</span></span><span class='ectt-0800'> </span><span id='textcolor3243'><span class='ectt-0800'>char</span></span><span class='ectt-0800'> *buf, </span><span id='textcolor3244'><span class='ectt-0800'>size_t</span></span><span class='ectt-0800'> len)</span>
|
|
|
-<a id='x1-61760r302'></a><span class='ecrm-0500'>302</span><span class='ectt-0800'>{</span>
|
|
|
-<a id='x1-61762r303'></a><span class='ecrm-0500'>303</span><span class='ectt-0800'> </span><span id='textcolor3245'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> err;</span>
|
|
|
-<a id='x1-61764r304'></a><span class='ecrm-0500'>304</span><span class='ectt-0800'> </span><span id='textcolor3246'><span class='ectt-0800'>unsigned</span></span><span class='ectt-0800'> </span><span id='textcolor3247'><span class='ectt-0800'>long</span></span><span class='ectt-0800'> id;</span>
|
|
|
-<a id='x1-61766r305'></a><span class='ecrm-0500'>305</span><span class='ectt-0800'> </span><span id='textcolor3248'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> vinput *vinput;</span>
|
|
|
-<a id='x1-61768r306'></a><span class='ecrm-0500'>306</span>
|
|
|
-<a id='x1-61770r307'></a><span class='ecrm-0500'>307</span><span class='ectt-0800'> err = kstrtol(buf, 10, &id);</span>
|
|
|
-<a id='x1-61772r308'></a><span class='ecrm-0500'>308</span><span class='ectt-0800'> </span><span id='textcolor3249'><span class='ectt-0800'>if</span></span><span class='ectt-0800'> (err) {</span>
|
|
|
-<a id='x1-61774r309'></a><span class='ecrm-0500'>309</span><span class='ectt-0800'> err = -EINVAL;</span>
|
|
|
-<a id='x1-61776r310'></a><span class='ecrm-0500'>310</span><span class='ectt-0800'> </span><span id='textcolor3250'><span class='ectt-0800'>goto</span></span><span class='ectt-0800'> failed;</span>
|
|
|
-<a id='x1-61778r311'></a><span class='ecrm-0500'>311</span><span class='ectt-0800'> }</span>
|
|
|
-<a id='x1-61780r312'></a><span class='ecrm-0500'>312</span>
|
|
|
-<a id='x1-61782r313'></a><span class='ecrm-0500'>313</span><span class='ectt-0800'> vinput = vinput_get_vdevice_by_id(id);</span>
|
|
|
-<a id='x1-61784r314'></a><span class='ecrm-0500'>314</span><span class='ectt-0800'> </span><span id='textcolor3251'><span class='ectt-0800'>if</span></span><span class='ectt-0800'> (IS_ERR(vinput)) {</span>
|
|
|
-<a id='x1-61786r315'></a><span class='ecrm-0500'>315</span><span class='ectt-0800'> pr_err(</span><span id='textcolor3252'><span class='ectt-0800'>"vinput: No such vinput device %ld</span></span><span id='textcolor3253'><span class='ectt-0800'>\n</span></span><span id='textcolor3254'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>, id);</span>
|
|
|
-<a id='x1-61788r316'></a><span class='ecrm-0500'>316</span><span class='ectt-0800'> err = PTR_ERR(vinput);</span>
|
|
|
-<a id='x1-61790r317'></a><span class='ecrm-0500'>317</span><span class='ectt-0800'> </span><span id='textcolor3255'><span class='ectt-0800'>goto</span></span><span class='ectt-0800'> failed;</span>
|
|
|
-<a id='x1-61792r318'></a><span class='ecrm-0500'>318</span><span class='ectt-0800'> }</span>
|
|
|
-<a id='x1-61794r319'></a><span class='ecrm-0500'>319</span>
|
|
|
-<a id='x1-61796r320'></a><span class='ecrm-0500'>320</span><span class='ectt-0800'> vinput_unregister_vdevice(vinput);</span>
|
|
|
-<a id='x1-61798r321'></a><span class='ecrm-0500'>321</span><span class='ectt-0800'> device_unregister(&vinput->dev);</span>
|
|
|
-<a id='x1-61800r322'></a><span class='ecrm-0500'>322</span>
|
|
|
-<a id='x1-61802r323'></a><span class='ecrm-0500'>323</span><span class='ectt-0800'> </span><span id='textcolor3256'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> len;</span>
|
|
|
-<a id='x1-61804r324'></a><span class='ecrm-0500'>324</span><span class='ectt-0800'>failed:</span>
|
|
|
-<a id='x1-61806r325'></a><span class='ecrm-0500'>325</span><span class='ectt-0800'> </span><span id='textcolor3257'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> err;</span>
|
|
|
-<a id='x1-61808r326'></a><span class='ecrm-0500'>326</span><span class='ectt-0800'>}</span>
|
|
|
-<a id='x1-61810r327'></a><span class='ecrm-0500'>327</span><span id='textcolor3258'><span class='ectt-0800'>/* This macro generates class_attr_unexport structure and unexport_store() */</span></span>
|
|
|
-<a id='x1-61812r328'></a><span class='ecrm-0500'>328</span><span id='textcolor3259'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> CLASS_ATTR_WO(unexport);</span>
|
|
|
-<a id='x1-61814r329'></a><span class='ecrm-0500'>329</span>
|
|
|
-<a id='x1-61816r330'></a><span class='ecrm-0500'>330</span><span id='textcolor3260'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3261'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> attribute *vinput_class_attrs[] = {</span>
|
|
|
-<a id='x1-61818r331'></a><span class='ecrm-0500'>331</span><span class='ectt-0800'> &class_attr_export.attr,</span>
|
|
|
-<a id='x1-61820r332'></a><span class='ecrm-0500'>332</span><span class='ectt-0800'> &class_attr_unexport.attr,</span>
|
|
|
-<a id='x1-61822r333'></a><span class='ecrm-0500'>333</span><span class='ectt-0800'> NULL,</span>
|
|
|
-<a id='x1-61824r334'></a><span class='ecrm-0500'>334</span><span class='ectt-0800'>};</span>
|
|
|
-<a id='x1-61826r335'></a><span class='ecrm-0500'>335</span>
|
|
|
-<a id='x1-61828r336'></a><span class='ecrm-0500'>336</span><span id='textcolor3262'><span class='ectt-0800'>/* This macro generates vinput_class_groups structure */</span></span>
|
|
|
-<a id='x1-61830r337'></a><span class='ecrm-0500'>337</span><span class='ectt-0800'>ATTRIBUTE_GROUPS(vinput_class);</span>
|
|
|
-<a id='x1-61832r338'></a><span class='ecrm-0500'>338</span>
|
|
|
-<a id='x1-61834r339'></a><span class='ecrm-0500'>339</span><span id='textcolor3263'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3264'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> class vinput_class = {</span>
|
|
|
-<a id='x1-61836r340'></a><span class='ecrm-0500'>340</span><span class='ectt-0800'> .name = </span><span id='textcolor3265'><span class='ectt-0800'>"vinput"</span></span><span class='ectt-0800'>,</span>
|
|
|
-<a id='x1-61838r341'></a><span class='ecrm-0500'>341</span><span id='textcolor3266'><span class='ectt-0800'>#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0)</span></span>
|
|
|
-<a id='x1-61840r342'></a><span class='ecrm-0500'>342</span><span class='ectt-0800'> .owner = THIS_MODULE,</span>
|
|
|
-<a id='x1-61842r343'></a><span class='ecrm-0500'>343</span><span id='textcolor3267'><span class='ectt-0800'>#endif</span></span>
|
|
|
-<a id='x1-61844r344'></a><span class='ecrm-0500'>344</span><span class='ectt-0800'> .class_groups = vinput_class_groups,</span>
|
|
|
-<a id='x1-61846r345'></a><span class='ecrm-0500'>345</span><span class='ectt-0800'>};</span>
|
|
|
-<a id='x1-61848r346'></a><span class='ecrm-0500'>346</span>
|
|
|
-<a id='x1-61850r347'></a><span class='ecrm-0500'>347</span><span id='textcolor3268'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> vinput_register(</span><span id='textcolor3269'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> vinput_device *dev)</span>
|
|
|
-<a id='x1-61852r348'></a><span class='ecrm-0500'>348</span><span class='ectt-0800'>{</span>
|
|
|
-<a id='x1-61854r349'></a><span class='ecrm-0500'>349</span><span class='ectt-0800'> spin_lock(&vinput_lock);</span>
|
|
|
-<a id='x1-61856r350'></a><span class='ecrm-0500'>350</span><span class='ectt-0800'> list_add(&dev->list, &vinput_devices);</span>
|
|
|
-<a id='x1-61858r351'></a><span class='ecrm-0500'>351</span><span class='ectt-0800'> spin_unlock(&vinput_lock);</span>
|
|
|
-<a id='x1-61860r352'></a><span class='ecrm-0500'>352</span>
|
|
|
-<a id='x1-61862r353'></a><span class='ecrm-0500'>353</span><span class='ectt-0800'> pr_info(</span><span id='textcolor3270'><span class='ectt-0800'>"vinput: registered new virtual input device </span><span class='tctt-0800'>'</span><span class='ectt-0800'>%s</span><span class='tctt-0800'>'</span></span><span id='textcolor3271'><span class='ectt-0800'>\n</span></span><span id='textcolor3272'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>, dev->name);</span>
|
|
|
+<a id='x1-61730r287'></a><span class='ecrm-0500'>287</span><span class='ectt-0800'> </span><span id='textcolor3226'><span class='ectt-0800'>/* avoid calling vinput_destroy_vdevice() twice */</span></span>
|
|
|
+<a id='x1-61732r288'></a><span class='ecrm-0500'>288</span><span class='ectt-0800'> </span><span id='textcolor3227'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> err;</span>
|
|
|
+<a id='x1-61734r289'></a><span class='ecrm-0500'>289</span><span class='ectt-0800'>fail_register:</span>
|
|
|
+<a id='x1-61736r290'></a><span class='ecrm-0500'>290</span><span class='ectt-0800'> vinput_destroy_vdevice(vinput);</span>
|
|
|
+<a id='x1-61738r291'></a><span class='ecrm-0500'>291</span><span class='ectt-0800'>fail:</span>
|
|
|
+<a id='x1-61740r292'></a><span class='ecrm-0500'>292</span><span class='ectt-0800'> </span><span id='textcolor3228'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> err;</span>
|
|
|
+<a id='x1-61742r293'></a><span class='ecrm-0500'>293</span><span class='ectt-0800'>}</span>
|
|
|
+<a id='x1-61744r294'></a><span class='ecrm-0500'>294</span><span id='textcolor3229'><span class='ectt-0800'>/* This macro generates class_attr_export structure and export_store() */</span></span>
|
|
|
+<a id='x1-61746r295'></a><span class='ecrm-0500'>295</span><span id='textcolor3230'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> CLASS_ATTR_WO(export);</span>
|
|
|
+<a id='x1-61748r296'></a><span class='ecrm-0500'>296</span>
|
|
|
+<a id='x1-61750r297'></a><span class='ecrm-0500'>297</span><span id='textcolor3231'><span class='ectt-0800'>#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 4, 0)</span></span>
|
|
|
+<a id='x1-61752r298'></a><span class='ecrm-0500'>298</span><span id='textcolor3232'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3233'><span class='ectt-0800'>ssize_t</span></span><span class='ectt-0800'> unexport_store(</span><span id='textcolor3234'><span class='ectt-0800'>const</span></span><span class='ectt-0800'> </span><span id='textcolor3235'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> class *class,</span>
|
|
|
+<a id='x1-61754r299'></a><span class='ecrm-0500'>299</span><span class='ectt-0800'> </span><span id='textcolor3236'><span class='ectt-0800'>const</span></span><span class='ectt-0800'> </span><span id='textcolor3237'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> class_attribute *attr,</span>
|
|
|
+<a id='x1-61756r300'></a><span class='ecrm-0500'>300</span><span id='textcolor3238'><span class='ectt-0800'>#else</span></span>
|
|
|
+<a id='x1-61758r301'></a><span class='ecrm-0500'>301</span><span id='textcolor3239'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3240'><span class='ectt-0800'>ssize_t</span></span><span class='ectt-0800'> unexport_store(</span><span id='textcolor3241'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> class *class, </span><span id='textcolor3242'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> class_attribute *attr,</span>
|
|
|
+<a id='x1-61760r302'></a><span class='ecrm-0500'>302</span><span id='textcolor3243'><span class='ectt-0800'>#endif</span></span>
|
|
|
+<a id='x1-61762r303'></a><span class='ecrm-0500'>303</span><span class='ectt-0800'> </span><span id='textcolor3244'><span class='ectt-0800'>const</span></span><span class='ectt-0800'> </span><span id='textcolor3245'><span class='ectt-0800'>char</span></span><span class='ectt-0800'> *buf, </span><span id='textcolor3246'><span class='ectt-0800'>size_t</span></span><span class='ectt-0800'> len)</span>
|
|
|
+<a id='x1-61764r304'></a><span class='ecrm-0500'>304</span><span class='ectt-0800'>{</span>
|
|
|
+<a id='x1-61766r305'></a><span class='ecrm-0500'>305</span><span class='ectt-0800'> </span><span id='textcolor3247'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> err;</span>
|
|
|
+<a id='x1-61768r306'></a><span class='ecrm-0500'>306</span><span class='ectt-0800'> </span><span id='textcolor3248'><span class='ectt-0800'>unsigned</span></span><span class='ectt-0800'> </span><span id='textcolor3249'><span class='ectt-0800'>long</span></span><span class='ectt-0800'> id;</span>
|
|
|
+<a id='x1-61770r307'></a><span class='ecrm-0500'>307</span><span class='ectt-0800'> </span><span id='textcolor3250'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> vinput *vinput;</span>
|
|
|
+<a id='x1-61772r308'></a><span class='ecrm-0500'>308</span>
|
|
|
+<a id='x1-61774r309'></a><span class='ecrm-0500'>309</span><span class='ectt-0800'> err = kstrtol(buf, 10, &id);</span>
|
|
|
+<a id='x1-61776r310'></a><span class='ecrm-0500'>310</span><span class='ectt-0800'> </span><span id='textcolor3251'><span class='ectt-0800'>if</span></span><span class='ectt-0800'> (err) {</span>
|
|
|
+<a id='x1-61778r311'></a><span class='ecrm-0500'>311</span><span class='ectt-0800'> err = -EINVAL;</span>
|
|
|
+<a id='x1-61780r312'></a><span class='ecrm-0500'>312</span><span class='ectt-0800'> </span><span id='textcolor3252'><span class='ectt-0800'>goto</span></span><span class='ectt-0800'> failed;</span>
|
|
|
+<a id='x1-61782r313'></a><span class='ecrm-0500'>313</span><span class='ectt-0800'> }</span>
|
|
|
+<a id='x1-61784r314'></a><span class='ecrm-0500'>314</span>
|
|
|
+<a id='x1-61786r315'></a><span class='ecrm-0500'>315</span><span class='ectt-0800'> vinput = vinput_get_vdevice_by_id(id);</span>
|
|
|
+<a id='x1-61788r316'></a><span class='ecrm-0500'>316</span><span class='ectt-0800'> </span><span id='textcolor3253'><span class='ectt-0800'>if</span></span><span class='ectt-0800'> (IS_ERR(vinput)) {</span>
|
|
|
+<a id='x1-61790r317'></a><span class='ecrm-0500'>317</span><span class='ectt-0800'> pr_err(</span><span id='textcolor3254'><span class='ectt-0800'>"vinput: No such vinput device %ld</span></span><span id='textcolor3255'><span class='ectt-0800'>\n</span></span><span id='textcolor3256'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>, id);</span>
|
|
|
+<a id='x1-61792r318'></a><span class='ecrm-0500'>318</span><span class='ectt-0800'> err = PTR_ERR(vinput);</span>
|
|
|
+<a id='x1-61794r319'></a><span class='ecrm-0500'>319</span><span class='ectt-0800'> </span><span id='textcolor3257'><span class='ectt-0800'>goto</span></span><span class='ectt-0800'> failed;</span>
|
|
|
+<a id='x1-61796r320'></a><span class='ecrm-0500'>320</span><span class='ectt-0800'> }</span>
|
|
|
+<a id='x1-61798r321'></a><span class='ecrm-0500'>321</span>
|
|
|
+<a id='x1-61800r322'></a><span class='ecrm-0500'>322</span><span class='ectt-0800'> vinput_unregister_vdevice(vinput);</span>
|
|
|
+<a id='x1-61802r323'></a><span class='ecrm-0500'>323</span><span class='ectt-0800'> device_unregister(&vinput->dev);</span>
|
|
|
+<a id='x1-61804r324'></a><span class='ecrm-0500'>324</span>
|
|
|
+<a id='x1-61806r325'></a><span class='ecrm-0500'>325</span><span class='ectt-0800'> </span><span id='textcolor3258'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> len;</span>
|
|
|
+<a id='x1-61808r326'></a><span class='ecrm-0500'>326</span><span class='ectt-0800'>failed:</span>
|
|
|
+<a id='x1-61810r327'></a><span class='ecrm-0500'>327</span><span class='ectt-0800'> </span><span id='textcolor3259'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> err;</span>
|
|
|
+<a id='x1-61812r328'></a><span class='ecrm-0500'>328</span><span class='ectt-0800'>}</span>
|
|
|
+<a id='x1-61814r329'></a><span class='ecrm-0500'>329</span><span id='textcolor3260'><span class='ectt-0800'>/* This macro generates class_attr_unexport structure and unexport_store() */</span></span>
|
|
|
+<a id='x1-61816r330'></a><span class='ecrm-0500'>330</span><span id='textcolor3261'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> CLASS_ATTR_WO(unexport);</span>
|
|
|
+<a id='x1-61818r331'></a><span class='ecrm-0500'>331</span>
|
|
|
+<a id='x1-61820r332'></a><span class='ecrm-0500'>332</span><span id='textcolor3262'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3263'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> attribute *vinput_class_attrs[] = {</span>
|
|
|
+<a id='x1-61822r333'></a><span class='ecrm-0500'>333</span><span class='ectt-0800'> &class_attr_export.attr,</span>
|
|
|
+<a id='x1-61824r334'></a><span class='ecrm-0500'>334</span><span class='ectt-0800'> &class_attr_unexport.attr,</span>
|
|
|
+<a id='x1-61826r335'></a><span class='ecrm-0500'>335</span><span class='ectt-0800'> NULL,</span>
|
|
|
+<a id='x1-61828r336'></a><span class='ecrm-0500'>336</span><span class='ectt-0800'>};</span>
|
|
|
+<a id='x1-61830r337'></a><span class='ecrm-0500'>337</span>
|
|
|
+<a id='x1-61832r338'></a><span class='ecrm-0500'>338</span><span id='textcolor3264'><span class='ectt-0800'>/* This macro generates vinput_class_groups structure */</span></span>
|
|
|
+<a id='x1-61834r339'></a><span class='ecrm-0500'>339</span><span class='ectt-0800'>ATTRIBUTE_GROUPS(vinput_class);</span>
|
|
|
+<a id='x1-61836r340'></a><span class='ecrm-0500'>340</span>
|
|
|
+<a id='x1-61838r341'></a><span class='ecrm-0500'>341</span><span id='textcolor3265'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3266'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> class vinput_class = {</span>
|
|
|
+<a id='x1-61840r342'></a><span class='ecrm-0500'>342</span><span class='ectt-0800'> .name = </span><span id='textcolor3267'><span class='ectt-0800'>"vinput"</span></span><span class='ectt-0800'>,</span>
|
|
|
+<a id='x1-61842r343'></a><span class='ecrm-0500'>343</span><span id='textcolor3268'><span class='ectt-0800'>#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0)</span></span>
|
|
|
+<a id='x1-61844r344'></a><span class='ecrm-0500'>344</span><span class='ectt-0800'> .owner = THIS_MODULE,</span>
|
|
|
+<a id='x1-61846r345'></a><span class='ecrm-0500'>345</span><span id='textcolor3269'><span class='ectt-0800'>#endif</span></span>
|
|
|
+<a id='x1-61848r346'></a><span class='ecrm-0500'>346</span><span class='ectt-0800'> .class_groups = vinput_class_groups,</span>
|
|
|
+<a id='x1-61850r347'></a><span class='ecrm-0500'>347</span><span class='ectt-0800'>};</span>
|
|
|
+<a id='x1-61852r348'></a><span class='ecrm-0500'>348</span>
|
|
|
+<a id='x1-61854r349'></a><span class='ecrm-0500'>349</span><span id='textcolor3270'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> vinput_register(</span><span id='textcolor3271'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> vinput_device *dev)</span>
|
|
|
+<a id='x1-61856r350'></a><span class='ecrm-0500'>350</span><span class='ectt-0800'>{</span>
|
|
|
+<a id='x1-61858r351'></a><span class='ecrm-0500'>351</span><span class='ectt-0800'> spin_lock(&vinput_lock);</span>
|
|
|
+<a id='x1-61860r352'></a><span class='ecrm-0500'>352</span><span class='ectt-0800'> list_add(&dev->list, &vinput_devices);</span>
|
|
|
+<a id='x1-61862r353'></a><span class='ecrm-0500'>353</span><span class='ectt-0800'> spin_unlock(&vinput_lock);</span>
|
|
|
<a id='x1-61864r354'></a><span class='ecrm-0500'>354</span>
|
|
|
-<a id='x1-61866r355'></a><span class='ecrm-0500'>355</span><span class='ectt-0800'> </span><span id='textcolor3273'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> 0;</span>
|
|
|
-<a id='x1-61868r356'></a><span class='ecrm-0500'>356</span><span class='ectt-0800'>}</span>
|
|
|
-<a id='x1-61870r357'></a><span class='ecrm-0500'>357</span><span class='ectt-0800'>EXPORT_SYMBOL(vinput_register);</span>
|
|
|
-<a id='x1-61872r358'></a><span class='ecrm-0500'>358</span>
|
|
|
-<a id='x1-61874r359'></a><span class='ecrm-0500'>359</span><span id='textcolor3274'><span class='ectt-0800'>void</span></span><span class='ectt-0800'> vinput_unregister(</span><span id='textcolor3275'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> vinput_device *dev)</span>
|
|
|
-<a id='x1-61876r360'></a><span class='ecrm-0500'>360</span><span class='ectt-0800'>{</span>
|
|
|
-<a id='x1-61878r361'></a><span class='ecrm-0500'>361</span><span class='ectt-0800'> </span><span id='textcolor3276'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> list_head *curr, *next;</span>
|
|
|
-<a id='x1-61880r362'></a><span class='ecrm-0500'>362</span>
|
|
|
-<a id='x1-61882r363'></a><span class='ecrm-0500'>363</span><span class='ectt-0800'> </span><span id='textcolor3277'><span class='ectt-0800'>/* Remove from the list first */</span></span>
|
|
|
-<a id='x1-61884r364'></a><span class='ecrm-0500'>364</span><span class='ectt-0800'> spin_lock(&vinput_lock);</span>
|
|
|
-<a id='x1-61886r365'></a><span class='ecrm-0500'>365</span><span class='ectt-0800'> list_del(&dev->list);</span>
|
|
|
-<a id='x1-61888r366'></a><span class='ecrm-0500'>366</span><span class='ectt-0800'> spin_unlock(&vinput_lock);</span>
|
|
|
-<a id='x1-61890r367'></a><span class='ecrm-0500'>367</span>
|
|
|
-<a id='x1-61892r368'></a><span class='ecrm-0500'>368</span><span class='ectt-0800'> </span><span id='textcolor3278'><span class='ectt-0800'>/* unregister all devices of this type */</span></span>
|
|
|
-<a id='x1-61894r369'></a><span class='ecrm-0500'>369</span><span class='ectt-0800'> list_for_each_safe (curr, next, &vinput_vdevices) {</span>
|
|
|
-<a id='x1-61896r370'></a><span class='ecrm-0500'>370</span><span class='ectt-0800'> </span><span id='textcolor3279'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> vinput *vinput = list_entry(curr, </span><span id='textcolor3280'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> vinput, list);</span>
|
|
|
-<a id='x1-61898r371'></a><span class='ecrm-0500'>371</span><span class='ectt-0800'> </span><span id='textcolor3281'><span class='ectt-0800'>if</span></span><span class='ectt-0800'> (vinput && vinput->type == dev) {</span>
|
|
|
-<a id='x1-61900r372'></a><span class='ecrm-0500'>372</span><span class='ectt-0800'> vinput_unregister_vdevice(vinput);</span>
|
|
|
-<a id='x1-61902r373'></a><span class='ecrm-0500'>373</span><span class='ectt-0800'> device_unregister(&vinput->dev);</span>
|
|
|
-<a id='x1-61904r374'></a><span class='ecrm-0500'>374</span><span class='ectt-0800'> }</span>
|
|
|
-<a id='x1-61906r375'></a><span class='ecrm-0500'>375</span><span class='ectt-0800'> }</span>
|
|
|
-<a id='x1-61908r376'></a><span class='ecrm-0500'>376</span>
|
|
|
-<a id='x1-61910r377'></a><span class='ecrm-0500'>377</span><span class='ectt-0800'> pr_info(</span><span id='textcolor3282'><span class='ectt-0800'>"vinput: unregistered virtual input device </span><span class='tctt-0800'>'</span><span class='ectt-0800'>%s</span><span class='tctt-0800'>'</span></span><span id='textcolor3283'><span class='ectt-0800'>\n</span></span><span id='textcolor3284'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>, dev->name);</span>
|
|
|
-<a id='x1-61912r378'></a><span class='ecrm-0500'>378</span><span class='ectt-0800'>}</span>
|
|
|
-<a id='x1-61914r379'></a><span class='ecrm-0500'>379</span><span class='ectt-0800'>EXPORT_SYMBOL(vinput_unregister);</span>
|
|
|
-<a id='x1-61916r380'></a><span class='ecrm-0500'>380</span>
|
|
|
-<a id='x1-61918r381'></a><span class='ecrm-0500'>381</span><span id='textcolor3285'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3286'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> __init vinput_init(</span><span id='textcolor3287'><span class='ectt-0800'>void</span></span><span class='ectt-0800'>)</span>
|
|
|
-<a id='x1-61920r382'></a><span class='ecrm-0500'>382</span><span class='ectt-0800'>{</span>
|
|
|
-<a id='x1-61922r383'></a><span class='ecrm-0500'>383</span><span class='ectt-0800'> </span><span id='textcolor3288'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> err = 0;</span>
|
|
|
-<a id='x1-61924r384'></a><span class='ecrm-0500'>384</span>
|
|
|
-<a id='x1-61926r385'></a><span class='ecrm-0500'>385</span><span class='ectt-0800'> pr_info(</span><span id='textcolor3289'><span class='ectt-0800'>"vinput: Loading virtual input driver</span></span><span id='textcolor3290'><span class='ectt-0800'>\n</span></span><span id='textcolor3291'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>);</span>
|
|
|
+<a id='x1-61866r355'></a><span class='ecrm-0500'>355</span><span class='ectt-0800'> pr_info(</span><span id='textcolor3272'><span class='ectt-0800'>"vinput: registered new virtual input device </span><span class='tctt-0800'>'</span><span class='ectt-0800'>%s</span><span class='tctt-0800'>'</span></span><span id='textcolor3273'><span class='ectt-0800'>\n</span></span><span id='textcolor3274'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>, dev->name);</span>
|
|
|
+<a id='x1-61868r356'></a><span class='ecrm-0500'>356</span>
|
|
|
+<a id='x1-61870r357'></a><span class='ecrm-0500'>357</span><span class='ectt-0800'> </span><span id='textcolor3275'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> 0;</span>
|
|
|
+<a id='x1-61872r358'></a><span class='ecrm-0500'>358</span><span class='ectt-0800'>}</span>
|
|
|
+<a id='x1-61874r359'></a><span class='ecrm-0500'>359</span><span class='ectt-0800'>EXPORT_SYMBOL(vinput_register);</span>
|
|
|
+<a id='x1-61876r360'></a><span class='ecrm-0500'>360</span>
|
|
|
+<a id='x1-61878r361'></a><span class='ecrm-0500'>361</span><span id='textcolor3276'><span class='ectt-0800'>void</span></span><span class='ectt-0800'> vinput_unregister(</span><span id='textcolor3277'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> vinput_device *dev)</span>
|
|
|
+<a id='x1-61880r362'></a><span class='ecrm-0500'>362</span><span class='ectt-0800'>{</span>
|
|
|
+<a id='x1-61882r363'></a><span class='ecrm-0500'>363</span><span class='ectt-0800'> </span><span id='textcolor3278'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> list_head *curr, *next;</span>
|
|
|
+<a id='x1-61884r364'></a><span class='ecrm-0500'>364</span>
|
|
|
+<a id='x1-61886r365'></a><span class='ecrm-0500'>365</span><span class='ectt-0800'> </span><span id='textcolor3279'><span class='ectt-0800'>/* Remove from the list first */</span></span>
|
|
|
+<a id='x1-61888r366'></a><span class='ecrm-0500'>366</span><span class='ectt-0800'> spin_lock(&vinput_lock);</span>
|
|
|
+<a id='x1-61890r367'></a><span class='ecrm-0500'>367</span><span class='ectt-0800'> list_del(&dev->list);</span>
|
|
|
+<a id='x1-61892r368'></a><span class='ecrm-0500'>368</span><span class='ectt-0800'> spin_unlock(&vinput_lock);</span>
|
|
|
+<a id='x1-61894r369'></a><span class='ecrm-0500'>369</span>
|
|
|
+<a id='x1-61896r370'></a><span class='ecrm-0500'>370</span><span class='ectt-0800'> </span><span id='textcolor3280'><span class='ectt-0800'>/* unregister all devices of this type */</span></span>
|
|
|
+<a id='x1-61898r371'></a><span class='ecrm-0500'>371</span><span class='ectt-0800'> list_for_each_safe (curr, next, &vinput_vdevices) {</span>
|
|
|
+<a id='x1-61900r372'></a><span class='ecrm-0500'>372</span><span class='ectt-0800'> </span><span id='textcolor3281'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> vinput *vinput = list_entry(curr, </span><span id='textcolor3282'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> vinput, list);</span>
|
|
|
+<a id='x1-61902r373'></a><span class='ecrm-0500'>373</span><span class='ectt-0800'> </span><span id='textcolor3283'><span class='ectt-0800'>if</span></span><span class='ectt-0800'> (vinput && vinput->type == dev) {</span>
|
|
|
+<a id='x1-61904r374'></a><span class='ecrm-0500'>374</span><span class='ectt-0800'> vinput_unregister_vdevice(vinput);</span>
|
|
|
+<a id='x1-61906r375'></a><span class='ecrm-0500'>375</span><span class='ectt-0800'> device_unregister(&vinput->dev);</span>
|
|
|
+<a id='x1-61908r376'></a><span class='ecrm-0500'>376</span><span class='ectt-0800'> }</span>
|
|
|
+<a id='x1-61910r377'></a><span class='ecrm-0500'>377</span><span class='ectt-0800'> }</span>
|
|
|
+<a id='x1-61912r378'></a><span class='ecrm-0500'>378</span>
|
|
|
+<a id='x1-61914r379'></a><span class='ecrm-0500'>379</span><span class='ectt-0800'> pr_info(</span><span id='textcolor3284'><span class='ectt-0800'>"vinput: unregistered virtual input device </span><span class='tctt-0800'>'</span><span class='ectt-0800'>%s</span><span class='tctt-0800'>'</span></span><span id='textcolor3285'><span class='ectt-0800'>\n</span></span><span id='textcolor3286'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>, dev->name);</span>
|
|
|
+<a id='x1-61916r380'></a><span class='ecrm-0500'>380</span><span class='ectt-0800'>}</span>
|
|
|
+<a id='x1-61918r381'></a><span class='ecrm-0500'>381</span><span class='ectt-0800'>EXPORT_SYMBOL(vinput_unregister);</span>
|
|
|
+<a id='x1-61920r382'></a><span class='ecrm-0500'>382</span>
|
|
|
+<a id='x1-61922r383'></a><span class='ecrm-0500'>383</span><span id='textcolor3287'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3288'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> __init vinput_init(</span><span id='textcolor3289'><span class='ectt-0800'>void</span></span><span class='ectt-0800'>)</span>
|
|
|
+<a id='x1-61924r384'></a><span class='ecrm-0500'>384</span><span class='ectt-0800'>{</span>
|
|
|
+<a id='x1-61926r385'></a><span class='ecrm-0500'>385</span><span class='ectt-0800'> </span><span id='textcolor3290'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> err = 0;</span>
|
|
|
<a id='x1-61928r386'></a><span class='ecrm-0500'>386</span>
|
|
|
-<a id='x1-61930r387'></a><span class='ecrm-0500'>387</span><span class='ectt-0800'> vinput_dev = register_chrdev(0, DRIVER_NAME, &vinput_fops);</span>
|
|
|
-<a id='x1-61932r388'></a><span class='ecrm-0500'>388</span><span class='ectt-0800'> </span><span id='textcolor3292'><span class='ectt-0800'>if</span></span><span class='ectt-0800'> (vinput_dev < 0) {</span>
|
|
|
-<a id='x1-61934r389'></a><span class='ecrm-0500'>389</span><span class='ectt-0800'> pr_err(</span><span id='textcolor3293'><span class='ectt-0800'>"vinput: Unable to allocate char dev region</span></span><span id='textcolor3294'><span class='ectt-0800'>\n</span></span><span id='textcolor3295'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>);</span>
|
|
|
-<a id='x1-61936r390'></a><span class='ecrm-0500'>390</span><span class='ectt-0800'> err = vinput_dev;</span>
|
|
|
-<a id='x1-61938r391'></a><span class='ecrm-0500'>391</span><span class='ectt-0800'> </span><span id='textcolor3296'><span class='ectt-0800'>goto</span></span><span class='ectt-0800'> failed_alloc;</span>
|
|
|
-<a id='x1-61940r392'></a><span class='ecrm-0500'>392</span><span class='ectt-0800'> }</span>
|
|
|
-<a id='x1-61942r393'></a><span class='ecrm-0500'>393</span>
|
|
|
-<a id='x1-61944r394'></a><span class='ecrm-0500'>394</span><span class='ectt-0800'> spin_lock_init(&vinput_lock);</span>
|
|
|
+<a id='x1-61930r387'></a><span class='ecrm-0500'>387</span><span class='ectt-0800'> pr_info(</span><span id='textcolor3291'><span class='ectt-0800'>"vinput: Loading virtual input driver</span></span><span id='textcolor3292'><span class='ectt-0800'>\n</span></span><span id='textcolor3293'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>);</span>
|
|
|
+<a id='x1-61932r388'></a><span class='ecrm-0500'>388</span>
|
|
|
+<a id='x1-61934r389'></a><span class='ecrm-0500'>389</span><span class='ectt-0800'> vinput_dev = register_chrdev(0, DRIVER_NAME, &vinput_fops);</span>
|
|
|
+<a id='x1-61936r390'></a><span class='ecrm-0500'>390</span><span class='ectt-0800'> </span><span id='textcolor3294'><span class='ectt-0800'>if</span></span><span class='ectt-0800'> (vinput_dev < 0) {</span>
|
|
|
+<a id='x1-61938r391'></a><span class='ecrm-0500'>391</span><span class='ectt-0800'> pr_err(</span><span id='textcolor3295'><span class='ectt-0800'>"vinput: Unable to allocate char dev region</span></span><span id='textcolor3296'><span class='ectt-0800'>\n</span></span><span id='textcolor3297'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>);</span>
|
|
|
+<a id='x1-61940r392'></a><span class='ecrm-0500'>392</span><span class='ectt-0800'> err = vinput_dev;</span>
|
|
|
+<a id='x1-61942r393'></a><span class='ecrm-0500'>393</span><span class='ectt-0800'> </span><span id='textcolor3298'><span class='ectt-0800'>goto</span></span><span class='ectt-0800'> failed_alloc;</span>
|
|
|
+<a id='x1-61944r394'></a><span class='ecrm-0500'>394</span><span class='ectt-0800'> }</span>
|
|
|
<a id='x1-61946r395'></a><span class='ecrm-0500'>395</span>
|
|
|
-<a id='x1-61948r396'></a><span class='ecrm-0500'>396</span><span class='ectt-0800'> err = class_register(&vinput_class);</span>
|
|
|
-<a id='x1-61950r397'></a><span class='ecrm-0500'>397</span><span class='ectt-0800'> </span><span id='textcolor3297'><span class='ectt-0800'>if</span></span><span class='ectt-0800'> (err < 0) {</span>
|
|
|
-<a id='x1-61952r398'></a><span class='ecrm-0500'>398</span><span class='ectt-0800'> pr_err(</span><span id='textcolor3298'><span class='ectt-0800'>"vinput: Unable to register vinput class</span></span><span id='textcolor3299'><span class='ectt-0800'>\n</span></span><span id='textcolor3300'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>);</span>
|
|
|
-<a id='x1-61954r399'></a><span class='ecrm-0500'>399</span><span class='ectt-0800'> </span><span id='textcolor3301'><span class='ectt-0800'>goto</span></span><span class='ectt-0800'> failed_class;</span>
|
|
|
-<a id='x1-61956r400'></a><span class='ecrm-0500'>400</span><span class='ectt-0800'> }</span>
|
|
|
-<a id='x1-61958r401'></a><span class='ecrm-0500'>401</span>
|
|
|
-<a id='x1-61960r402'></a><span class='ecrm-0500'>402</span><span class='ectt-0800'> </span><span id='textcolor3302'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> 0;</span>
|
|
|
-<a id='x1-61962r403'></a><span class='ecrm-0500'>403</span><span class='ectt-0800'>failed_class:</span>
|
|
|
-<a id='x1-61964r404'></a><span class='ecrm-0500'>404</span><span class='ectt-0800'> unregister_chrdev(vinput_dev, DRIVER_NAME);</span>
|
|
|
-<a id='x1-61966r405'></a><span class='ecrm-0500'>405</span><span class='ectt-0800'>failed_alloc:</span>
|
|
|
-<a id='x1-61968r406'></a><span class='ecrm-0500'>406</span><span class='ectt-0800'> </span><span id='textcolor3303'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> err;</span>
|
|
|
-<a id='x1-61970r407'></a><span class='ecrm-0500'>407</span><span class='ectt-0800'>}</span>
|
|
|
-<a id='x1-61972r408'></a><span class='ecrm-0500'>408</span>
|
|
|
-<a id='x1-61974r409'></a><span class='ecrm-0500'>409</span><span id='textcolor3304'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3305'><span class='ectt-0800'>void</span></span><span class='ectt-0800'> __exit vinput_end(</span><span id='textcolor3306'><span class='ectt-0800'>void</span></span><span class='ectt-0800'>)</span>
|
|
|
-<a id='x1-61976r410'></a><span class='ecrm-0500'>410</span><span class='ectt-0800'>{</span>
|
|
|
-<a id='x1-61978r411'></a><span class='ecrm-0500'>411</span><span class='ectt-0800'> pr_info(</span><span id='textcolor3307'><span class='ectt-0800'>"vinput: Unloading virtual input driver</span></span><span id='textcolor3308'><span class='ectt-0800'>\n</span></span><span id='textcolor3309'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>);</span>
|
|
|
-<a id='x1-61980r412'></a><span class='ecrm-0500'>412</span>
|
|
|
-<a id='x1-61982r413'></a><span class='ecrm-0500'>413</span><span class='ectt-0800'> unregister_chrdev(vinput_dev, DRIVER_NAME);</span>
|
|
|
-<a id='x1-61984r414'></a><span class='ecrm-0500'>414</span><span class='ectt-0800'> class_unregister(&vinput_class);</span>
|
|
|
-<a id='x1-61986r415'></a><span class='ecrm-0500'>415</span><span class='ectt-0800'>}</span>
|
|
|
-<a id='x1-61988r416'></a><span class='ecrm-0500'>416</span>
|
|
|
-<a id='x1-61990r417'></a><span class='ecrm-0500'>417</span><span class='ectt-0800'>module_init(vinput_init);</span>
|
|
|
-<a id='x1-61992r418'></a><span class='ecrm-0500'>418</span><span class='ectt-0800'>module_exit(vinput_end);</span>
|
|
|
-<a id='x1-61994r419'></a><span class='ecrm-0500'>419</span>
|
|
|
-<a id='x1-61996r420'></a><span class='ecrm-0500'>420</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor3310'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span>
|
|
|
-<a id='x1-61998r421'></a><span class='ecrm-0500'>421</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor3311'><span class='ectt-0800'>"Emulate input events"</span></span><span class='ectt-0800'>);</span></pre>
|
|
|
+<a id='x1-61948r396'></a><span class='ecrm-0500'>396</span><span class='ectt-0800'> spin_lock_init(&vinput_lock);</span>
|
|
|
+<a id='x1-61950r397'></a><span class='ecrm-0500'>397</span>
|
|
|
+<a id='x1-61952r398'></a><span class='ecrm-0500'>398</span><span class='ectt-0800'> err = class_register(&vinput_class);</span>
|
|
|
+<a id='x1-61954r399'></a><span class='ecrm-0500'>399</span><span class='ectt-0800'> </span><span id='textcolor3299'><span class='ectt-0800'>if</span></span><span class='ectt-0800'> (err < 0) {</span>
|
|
|
+<a id='x1-61956r400'></a><span class='ecrm-0500'>400</span><span class='ectt-0800'> pr_err(</span><span id='textcolor3300'><span class='ectt-0800'>"vinput: Unable to register vinput class</span></span><span id='textcolor3301'><span class='ectt-0800'>\n</span></span><span id='textcolor3302'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>);</span>
|
|
|
+<a id='x1-61958r401'></a><span class='ecrm-0500'>401</span><span class='ectt-0800'> </span><span id='textcolor3303'><span class='ectt-0800'>goto</span></span><span class='ectt-0800'> failed_class;</span>
|
|
|
+<a id='x1-61960r402'></a><span class='ecrm-0500'>402</span><span class='ectt-0800'> }</span>
|
|
|
+<a id='x1-61962r403'></a><span class='ecrm-0500'>403</span>
|
|
|
+<a id='x1-61964r404'></a><span class='ecrm-0500'>404</span><span class='ectt-0800'> </span><span id='textcolor3304'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> 0;</span>
|
|
|
+<a id='x1-61966r405'></a><span class='ecrm-0500'>405</span><span class='ectt-0800'>failed_class:</span>
|
|
|
+<a id='x1-61968r406'></a><span class='ecrm-0500'>406</span><span class='ectt-0800'> unregister_chrdev(vinput_dev, DRIVER_NAME);</span>
|
|
|
+<a id='x1-61970r407'></a><span class='ecrm-0500'>407</span><span class='ectt-0800'>failed_alloc:</span>
|
|
|
+<a id='x1-61972r408'></a><span class='ecrm-0500'>408</span><span class='ectt-0800'> </span><span id='textcolor3305'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> err;</span>
|
|
|
+<a id='x1-61974r409'></a><span class='ecrm-0500'>409</span><span class='ectt-0800'>}</span>
|
|
|
+<a id='x1-61976r410'></a><span class='ecrm-0500'>410</span>
|
|
|
+<a id='x1-61978r411'></a><span class='ecrm-0500'>411</span><span id='textcolor3306'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3307'><span class='ectt-0800'>void</span></span><span class='ectt-0800'> __exit vinput_end(</span><span id='textcolor3308'><span class='ectt-0800'>void</span></span><span class='ectt-0800'>)</span>
|
|
|
+<a id='x1-61980r412'></a><span class='ecrm-0500'>412</span><span class='ectt-0800'>{</span>
|
|
|
+<a id='x1-61982r413'></a><span class='ecrm-0500'>413</span><span class='ectt-0800'> pr_info(</span><span id='textcolor3309'><span class='ectt-0800'>"vinput: Unloading virtual input driver</span></span><span id='textcolor3310'><span class='ectt-0800'>\n</span></span><span id='textcolor3311'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>);</span>
|
|
|
+<a id='x1-61984r414'></a><span class='ecrm-0500'>414</span>
|
|
|
+<a id='x1-61986r415'></a><span class='ecrm-0500'>415</span><span class='ectt-0800'> unregister_chrdev(vinput_dev, DRIVER_NAME);</span>
|
|
|
+<a id='x1-61988r416'></a><span class='ecrm-0500'>416</span><span class='ectt-0800'> class_unregister(&vinput_class);</span>
|
|
|
+<a id='x1-61990r417'></a><span class='ecrm-0500'>417</span><span class='ectt-0800'>}</span>
|
|
|
+<a id='x1-61992r418'></a><span class='ecrm-0500'>418</span>
|
|
|
+<a id='x1-61994r419'></a><span class='ecrm-0500'>419</span><span class='ectt-0800'>module_init(vinput_init);</span>
|
|
|
+<a id='x1-61996r420'></a><span class='ecrm-0500'>420</span><span class='ectt-0800'>module_exit(vinput_end);</span>
|
|
|
+<a id='x1-61998r421'></a><span class='ecrm-0500'>421</span>
|
|
|
+<a id='x1-62000r422'></a><span class='ecrm-0500'>422</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor3312'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span>
|
|
|
+<a id='x1-62002r423'></a><span class='ecrm-0500'>423</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor3313'><span class='ectt-0800'>"Emulate input events"</span></span><span class='ectt-0800'>);</span></pre>
|
|
|
<!-- l. 2045 --><p class='indent'> Here the virtual keyboard is one of example to use vinput. It supports all
|
|
|
<code> <span class='ectt-1000'>KEY_MAX</span>
|
|
|
</code> keycodes. The injection format is the <code> <span class='ectt-1000'>KEY_CODE</span>
|
|
@@ -6259,7 +6261,7 @@ following demonstrates how simulation work.
|
|
|
</code> = 34):
|
|
|
</p><!-- l. 1 --><p class='indent'>
|
|
|
</p>
|
|
|
- <pre class='fancyvrb' id='fancyvrb91'><a id='x1-62006r1'></a><span class='ecrm-0500'>1</span><span class='ectt-1000'>echo </span><span id='textcolor3312'><span class='ectt-1000'>"+34"</span></span><span class='ectt-1000'> | sudo tee /dev/vinput0</span></pre>
|
|
|
+ <pre class='fancyvrb' id='fancyvrb91'><a id='x1-62010r1'></a><span class='ecrm-0500'>1</span><span class='ectt-1000'>echo </span><span id='textcolor3314'><span class='ectt-1000'>"+34"</span></span><span class='ectt-1000'> | sudo tee /dev/vinput0</span></pre>
|
|
|
<!-- l. 2058 --><p class='indent'> Simulate a key release on "g" (<code> <span class='ectt-1000'>KEY_G</span>
|
|
|
</code> = 34):
|
|
|
</p><!-- l. 1 --><p class='indent'>
|
|
@@ -6267,120 +6269,120 @@ following demonstrates how simulation work.
|
|
|
|
|
|
|
|
|
</p>
|
|
|
- <pre class='fancyvrb' id='fancyvrb92'><a id='x1-62010r1'></a><span class='ecrm-0500'>1</span><span class='ectt-1000'>echo </span><span id='textcolor3313'><span class='ectt-1000'>"-34"</span></span><span class='ectt-1000'> | sudo tee /dev/vinput0</span></pre>
|
|
|
+ <pre class='fancyvrb' id='fancyvrb92'><a id='x1-62014r1'></a><span class='ecrm-0500'>1</span><span class='ectt-1000'>echo </span><span id='textcolor3315'><span class='ectt-1000'>"-34"</span></span><span class='ectt-1000'> | sudo tee /dev/vinput0</span></pre>
|
|
|
|
|
|
<!-- l. 1 --><p class='indent'>
|
|
|
</p>
|
|
|
- <pre class='fancyvrb' id='fancyvrb93'><a id='x1-62012r1'></a><span class='ecrm-0500'>1</span><span id='textcolor3314'><span class='ectt-0800'>/*</span></span>
|
|
|
-<a id='x1-62014r2'></a><span class='ecrm-0500'>2</span><span id='textcolor3315'><span class='ectt-0800'> * vkbd.c</span></span>
|
|
|
-<a id='x1-62016r3'></a><span class='ecrm-0500'>3</span><span id='textcolor3316'><span class='ectt-0800'> */</span></span>
|
|
|
-<a id='x1-62018r4'></a><span class='ecrm-0500'>4</span>
|
|
|
-<a id='x1-62020r5'></a><span class='ecrm-0500'>5</span><span id='textcolor3317'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor3318'><span class='ectt-0800'><linux/init.h></span></span>
|
|
|
-<a id='x1-62022r6'></a><span class='ecrm-0500'>6</span><span id='textcolor3319'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor3320'><span class='ectt-0800'><linux/input.h></span></span>
|
|
|
-<a id='x1-62024r7'></a><span class='ecrm-0500'>7</span><span id='textcolor3321'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor3322'><span class='ectt-0800'><linux/module.h></span></span>
|
|
|
-<a id='x1-62026r8'></a><span class='ecrm-0500'>8</span><span id='textcolor3323'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor3324'><span class='ectt-0800'><linux/spinlock.h></span></span>
|
|
|
-<a id='x1-62028r9'></a><span class='ecrm-0500'>9</span>
|
|
|
-<a id='x1-62030r10'></a><span class='ecrm-0500'>10</span><span id='textcolor3325'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor3326'><span class='ectt-0800'>"vinput.h"</span></span>
|
|
|
-<a id='x1-62032r11'></a><span class='ecrm-0500'>11</span>
|
|
|
-<a id='x1-62034r12'></a><span class='ecrm-0500'>12</span><span id='textcolor3327'><span class='ectt-0800'>#define VINPUT_KBD "vkbd"</span></span>
|
|
|
-<a id='x1-62036r13'></a><span class='ecrm-0500'>13</span><span id='textcolor3328'><span class='ectt-0800'>#define VINPUT_RELEASE 0</span></span>
|
|
|
-<a id='x1-62038r14'></a><span class='ecrm-0500'>14</span><span id='textcolor3329'><span class='ectt-0800'>#define VINPUT_PRESS 1</span></span>
|
|
|
-<a id='x1-62040r15'></a><span class='ecrm-0500'>15</span>
|
|
|
-<a id='x1-62042r16'></a><span class='ecrm-0500'>16</span><span id='textcolor3330'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3331'><span class='ectt-0800'>unsigned</span></span><span class='ectt-0800'> </span><span id='textcolor3332'><span class='ectt-0800'>short</span></span><span class='ectt-0800'> vkeymap[KEY_MAX];</span>
|
|
|
-<a id='x1-62044r17'></a><span class='ecrm-0500'>17</span>
|
|
|
-<a id='x1-62046r18'></a><span class='ecrm-0500'>18</span><span id='textcolor3333'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3334'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> vinput_vkbd_init(</span><span id='textcolor3335'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> vinput *vinput)</span>
|
|
|
-<a id='x1-62048r19'></a><span class='ecrm-0500'>19</span><span class='ectt-0800'>{</span>
|
|
|
-<a id='x1-62050r20'></a><span class='ecrm-0500'>20</span><span class='ectt-0800'> </span><span id='textcolor3336'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> i;</span>
|
|
|
-<a id='x1-62052r21'></a><span class='ecrm-0500'>21</span>
|
|
|
-<a id='x1-62054r22'></a><span class='ecrm-0500'>22</span><span class='ectt-0800'> </span><span id='textcolor3337'><span class='ectt-0800'>/* Set up the input bitfield */</span></span>
|
|
|
-<a id='x1-62056r23'></a><span class='ecrm-0500'>23</span><span class='ectt-0800'> vinput->input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);</span>
|
|
|
-<a id='x1-62058r24'></a><span class='ecrm-0500'>24</span><span class='ectt-0800'> vinput->input->keycodesize = </span><span id='textcolor3338'><span class='ectt-0800'>sizeof</span></span><span class='ectt-0800'>(</span><span id='textcolor3339'><span class='ectt-0800'>unsigned</span></span><span class='ectt-0800'> </span><span id='textcolor3340'><span class='ectt-0800'>short</span></span><span class='ectt-0800'>);</span>
|
|
|
-<a id='x1-62060r25'></a><span class='ecrm-0500'>25</span><span class='ectt-0800'> vinput->input->keycodemax = KEY_MAX;</span>
|
|
|
-<a id='x1-62062r26'></a><span class='ecrm-0500'>26</span><span class='ectt-0800'> vinput->input->keycode = vkeymap;</span>
|
|
|
-<a id='x1-62064r27'></a><span class='ecrm-0500'>27</span>
|
|
|
-<a id='x1-62066r28'></a><span class='ecrm-0500'>28</span><span class='ectt-0800'> </span><span id='textcolor3341'><span class='ectt-0800'>for</span></span><span class='ectt-0800'> (i = 0; i < KEY_MAX; i++)</span>
|
|
|
-<a id='x1-62068r29'></a><span class='ecrm-0500'>29</span><span class='ectt-0800'> set_bit(vkeymap[i], vinput->input->keybit);</span>
|
|
|
-<a id='x1-62070r30'></a><span class='ecrm-0500'>30</span>
|
|
|
-<a id='x1-62072r31'></a><span class='ecrm-0500'>31</span><span class='ectt-0800'> </span><span id='textcolor3342'><span class='ectt-0800'>/* vinput will help us allocate new input device structure via</span></span>
|
|
|
-<a id='x1-62074r32'></a><span class='ecrm-0500'>32</span><span id='textcolor3343'><span class='ectt-0800'> * input_allocate_device(). So, we can register it straightforwardly.</span></span>
|
|
|
-<a id='x1-62076r33'></a><span class='ecrm-0500'>33</span><span id='textcolor3344'><span class='ectt-0800'> */</span></span>
|
|
|
-<a id='x1-62078r34'></a><span class='ecrm-0500'>34</span><span class='ectt-0800'> </span><span id='textcolor3345'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> input_register_device(vinput->input);</span>
|
|
|
-<a id='x1-62080r35'></a><span class='ecrm-0500'>35</span><span class='ectt-0800'>}</span>
|
|
|
-<a id='x1-62082r36'></a><span class='ecrm-0500'>36</span>
|
|
|
-<a id='x1-62084r37'></a><span class='ecrm-0500'>37</span><span id='textcolor3346'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3347'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> vinput_vkbd_read(</span><span id='textcolor3348'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> vinput *vinput, </span><span id='textcolor3349'><span class='ectt-0800'>char</span></span><span class='ectt-0800'> *buff, </span><span id='textcolor3350'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> len)</span>
|
|
|
-<a id='x1-62086r38'></a><span class='ecrm-0500'>38</span><span class='ectt-0800'>{</span>
|
|
|
-<a id='x1-62088r39'></a><span class='ecrm-0500'>39</span><span class='ectt-0800'> spin_lock(&vinput->lock);</span>
|
|
|
-<a id='x1-62090r40'></a><span class='ecrm-0500'>40</span><span class='ectt-0800'> len = snprintf(buff, len, </span><span id='textcolor3351'><span class='ectt-0800'>"%+ld</span></span><span id='textcolor3352'><span class='ectt-0800'>\n</span></span><span id='textcolor3353'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>, vinput->last_entry);</span>
|
|
|
-<a id='x1-62092r41'></a><span class='ecrm-0500'>41</span><span class='ectt-0800'> spin_unlock(&vinput->lock);</span>
|
|
|
-<a id='x1-62094r42'></a><span class='ecrm-0500'>42</span>
|
|
|
-<a id='x1-62096r43'></a><span class='ecrm-0500'>43</span><span class='ectt-0800'> </span><span id='textcolor3354'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> len;</span>
|
|
|
-<a id='x1-62098r44'></a><span class='ecrm-0500'>44</span><span class='ectt-0800'>}</span>
|
|
|
-<a id='x1-62100r45'></a><span class='ecrm-0500'>45</span>
|
|
|
-<a id='x1-62102r46'></a><span class='ecrm-0500'>46</span><span id='textcolor3355'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3356'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> vinput_vkbd_send(</span><span id='textcolor3357'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> vinput *vinput, </span><span id='textcolor3358'><span class='ectt-0800'>char</span></span><span class='ectt-0800'> *buff, </span><span id='textcolor3359'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> len)</span>
|
|
|
-<a id='x1-62104r47'></a><span class='ecrm-0500'>47</span><span class='ectt-0800'>{</span>
|
|
|
-<a id='x1-62106r48'></a><span class='ecrm-0500'>48</span><span class='ectt-0800'> </span><span id='textcolor3360'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> ret;</span>
|
|
|
-<a id='x1-62108r49'></a><span class='ecrm-0500'>49</span><span class='ectt-0800'> </span><span id='textcolor3361'><span class='ectt-0800'>long</span></span><span class='ectt-0800'> key = 0;</span>
|
|
|
-<a id='x1-62110r50'></a><span class='ecrm-0500'>50</span><span class='ectt-0800'> </span><span id='textcolor3362'><span class='ectt-0800'>short</span></span><span class='ectt-0800'> type = VINPUT_PRESS;</span>
|
|
|
-<a id='x1-62112r51'></a><span class='ecrm-0500'>51</span>
|
|
|
-<a id='x1-62114r52'></a><span class='ecrm-0500'>52</span><span class='ectt-0800'> </span><span id='textcolor3363'><span class='ectt-0800'>/* Determine which event was received (press or release)</span></span>
|
|
|
-<a id='x1-62116r53'></a><span class='ecrm-0500'>53</span><span id='textcolor3364'><span class='ectt-0800'> * and store the state.</span></span>
|
|
|
-<a id='x1-62118r54'></a><span class='ecrm-0500'>54</span><span id='textcolor3365'><span class='ectt-0800'> */</span></span>
|
|
|
-<a id='x1-62120r55'></a><span class='ecrm-0500'>55</span><span class='ectt-0800'> </span><span id='textcolor3366'><span class='ectt-0800'>if</span></span><span class='ectt-0800'> (buff[0] == </span><span id='textcolor3367'><span class='tctt-0800'>'</span><span class='ectt-0800'>+</span><span class='tctt-0800'>'</span></span><span class='ectt-0800'>)</span>
|
|
|
-<a id='x1-62122r56'></a><span class='ecrm-0500'>56</span><span class='ectt-0800'> ret = kstrtol(buff + 1, 10, &key);</span>
|
|
|
-<a id='x1-62124r57'></a><span class='ecrm-0500'>57</span><span class='ectt-0800'> </span><span id='textcolor3368'><span class='ectt-0800'>else</span></span>
|
|
|
-<a id='x1-62126r58'></a><span class='ecrm-0500'>58</span><span class='ectt-0800'> ret = kstrtol(buff, 10, &key);</span>
|
|
|
-<a id='x1-62128r59'></a><span class='ecrm-0500'>59</span><span class='ectt-0800'> </span><span id='textcolor3369'><span class='ectt-0800'>if</span></span><span class='ectt-0800'> (ret)</span>
|
|
|
-<a id='x1-62130r60'></a><span class='ecrm-0500'>60</span><span class='ectt-0800'> dev_err(&vinput->dev, </span><span id='textcolor3370'><span class='ectt-0800'>"error during kstrtol: -%d</span></span><span id='textcolor3371'><span class='ectt-0800'>\n</span></span><span id='textcolor3372'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>, ret);</span>
|
|
|
-<a id='x1-62132r61'></a><span class='ecrm-0500'>61</span><span class='ectt-0800'> spin_lock(&vinput->lock);</span>
|
|
|
-<a id='x1-62134r62'></a><span class='ecrm-0500'>62</span><span class='ectt-0800'> vinput->last_entry = key;</span>
|
|
|
-<a id='x1-62136r63'></a><span class='ecrm-0500'>63</span><span class='ectt-0800'> spin_unlock(&vinput->lock);</span>
|
|
|
-<a id='x1-62138r64'></a><span class='ecrm-0500'>64</span>
|
|
|
-<a id='x1-62140r65'></a><span class='ecrm-0500'>65</span><span class='ectt-0800'> </span><span id='textcolor3373'><span class='ectt-0800'>if</span></span><span class='ectt-0800'> (key < 0) {</span>
|
|
|
-<a id='x1-62142r66'></a><span class='ecrm-0500'>66</span><span class='ectt-0800'> type = VINPUT_RELEASE;</span>
|
|
|
-<a id='x1-62144r67'></a><span class='ecrm-0500'>67</span><span class='ectt-0800'> key = -key;</span>
|
|
|
-<a id='x1-62146r68'></a><span class='ecrm-0500'>68</span><span class='ectt-0800'> }</span>
|
|
|
-<a id='x1-62148r69'></a><span class='ecrm-0500'>69</span>
|
|
|
-<a id='x1-62150r70'></a><span class='ecrm-0500'>70</span><span class='ectt-0800'> dev_info(&vinput->dev, </span><span id='textcolor3374'><span class='ectt-0800'>"Event %s code %ld</span></span><span id='textcolor3375'><span class='ectt-0800'>\n</span></span><span id='textcolor3376'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>,</span>
|
|
|
-<a id='x1-62152r71'></a><span class='ecrm-0500'>71</span><span class='ectt-0800'> (type == VINPUT_RELEASE) ? </span><span id='textcolor3377'><span class='ectt-0800'>"VINPUT_RELEASE"</span></span><span class='ectt-0800'> : </span><span id='textcolor3378'><span class='ectt-0800'>"VINPUT_PRESS"</span></span><span class='ectt-0800'>, key);</span>
|
|
|
-<a id='x1-62154r72'></a><span class='ecrm-0500'>72</span>
|
|
|
-<a id='x1-62156r73'></a><span class='ecrm-0500'>73</span><span class='ectt-0800'> </span><span id='textcolor3379'><span class='ectt-0800'>/* Report the state received to input subsystem. */</span></span>
|
|
|
-<a id='x1-62158r74'></a><span class='ecrm-0500'>74</span><span class='ectt-0800'> input_report_key(vinput->input, key, type);</span>
|
|
|
-<a id='x1-62160r75'></a><span class='ecrm-0500'>75</span><span class='ectt-0800'> </span><span id='textcolor3380'><span class='ectt-0800'>/* Tell input subsystem that it finished the report. */</span></span>
|
|
|
-<a id='x1-62162r76'></a><span class='ecrm-0500'>76</span><span class='ectt-0800'> input_sync(vinput->input);</span>
|
|
|
-<a id='x1-62164r77'></a><span class='ecrm-0500'>77</span>
|
|
|
-<a id='x1-62166r78'></a><span class='ecrm-0500'>78</span><span class='ectt-0800'> </span><span id='textcolor3381'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> len;</span>
|
|
|
-<a id='x1-62168r79'></a><span class='ecrm-0500'>79</span><span class='ectt-0800'>}</span>
|
|
|
-<a id='x1-62170r80'></a><span class='ecrm-0500'>80</span>
|
|
|
-<a id='x1-62172r81'></a><span class='ecrm-0500'>81</span><span id='textcolor3382'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3383'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> vinput_ops vkbd_ops = {</span>
|
|
|
-<a id='x1-62174r82'></a><span class='ecrm-0500'>82</span><span class='ectt-0800'> .init = vinput_vkbd_init,</span>
|
|
|
-<a id='x1-62176r83'></a><span class='ecrm-0500'>83</span><span class='ectt-0800'> .send = vinput_vkbd_send,</span>
|
|
|
-<a id='x1-62178r84'></a><span class='ecrm-0500'>84</span><span class='ectt-0800'> .read = vinput_vkbd_read,</span>
|
|
|
-<a id='x1-62180r85'></a><span class='ecrm-0500'>85</span><span class='ectt-0800'>};</span>
|
|
|
-<a id='x1-62182r86'></a><span class='ecrm-0500'>86</span>
|
|
|
-<a id='x1-62184r87'></a><span class='ecrm-0500'>87</span><span id='textcolor3384'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3385'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> vinput_device vkbd_dev = {</span>
|
|
|
-<a id='x1-62186r88'></a><span class='ecrm-0500'>88</span><span class='ectt-0800'> .name = VINPUT_KBD,</span>
|
|
|
-<a id='x1-62188r89'></a><span class='ecrm-0500'>89</span><span class='ectt-0800'> .ops = &vkbd_ops,</span>
|
|
|
-<a id='x1-62190r90'></a><span class='ecrm-0500'>90</span><span class='ectt-0800'>};</span>
|
|
|
-<a id='x1-62192r91'></a><span class='ecrm-0500'>91</span>
|
|
|
-<a id='x1-62194r92'></a><span class='ecrm-0500'>92</span><span id='textcolor3386'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3387'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> __init vkbd_init(</span><span id='textcolor3388'><span class='ectt-0800'>void</span></span><span class='ectt-0800'>)</span>
|
|
|
-<a id='x1-62196r93'></a><span class='ecrm-0500'>93</span><span class='ectt-0800'>{</span>
|
|
|
-<a id='x1-62198r94'></a><span class='ecrm-0500'>94</span><span class='ectt-0800'> </span><span id='textcolor3389'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> i;</span>
|
|
|
-<a id='x1-62200r95'></a><span class='ecrm-0500'>95</span>
|
|
|
-<a id='x1-62202r96'></a><span class='ecrm-0500'>96</span><span class='ectt-0800'> </span><span id='textcolor3390'><span class='ectt-0800'>for</span></span><span class='ectt-0800'> (i = 0; i < KEY_MAX; i++)</span>
|
|
|
-<a id='x1-62204r97'></a><span class='ecrm-0500'>97</span><span class='ectt-0800'> vkeymap[i] = i;</span>
|
|
|
-<a id='x1-62206r98'></a><span class='ecrm-0500'>98</span><span class='ectt-0800'> </span><span id='textcolor3391'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> vinput_register(&vkbd_dev);</span>
|
|
|
-<a id='x1-62208r99'></a><span class='ecrm-0500'>99</span><span class='ectt-0800'>}</span>
|
|
|
-<a id='x1-62210r100'></a><span class='ecrm-0500'>100</span>
|
|
|
-<a id='x1-62212r101'></a><span class='ecrm-0500'>101</span><span id='textcolor3392'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3393'><span class='ectt-0800'>void</span></span><span class='ectt-0800'> __exit vkbd_end(</span><span id='textcolor3394'><span class='ectt-0800'>void</span></span><span class='ectt-0800'>)</span>
|
|
|
-<a id='x1-62214r102'></a><span class='ecrm-0500'>102</span><span class='ectt-0800'>{</span>
|
|
|
-<a id='x1-62216r103'></a><span class='ecrm-0500'>103</span><span class='ectt-0800'> vinput_unregister(&vkbd_dev);</span>
|
|
|
-<a id='x1-62218r104'></a><span class='ecrm-0500'>104</span><span class='ectt-0800'>}</span>
|
|
|
-<a id='x1-62220r105'></a><span class='ecrm-0500'>105</span>
|
|
|
-<a id='x1-62222r106'></a><span class='ecrm-0500'>106</span><span class='ectt-0800'>module_init(vkbd_init);</span>
|
|
|
-<a id='x1-62224r107'></a><span class='ecrm-0500'>107</span><span class='ectt-0800'>module_exit(vkbd_end);</span>
|
|
|
-<a id='x1-62226r108'></a><span class='ecrm-0500'>108</span>
|
|
|
-<a id='x1-62228r109'></a><span class='ecrm-0500'>109</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor3395'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span>
|
|
|
-<a id='x1-62230r110'></a><span class='ecrm-0500'>110</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor3396'><span class='ectt-0800'>"Emulate keyboard input events through /dev/vinput"</span></span><span class='ectt-0800'>);</span></pre>
|
|
|
+ <pre class='fancyvrb' id='fancyvrb93'><a id='x1-62016r1'></a><span class='ecrm-0500'>1</span><span id='textcolor3316'><span class='ectt-0800'>/*</span></span>
|
|
|
+<a id='x1-62018r2'></a><span class='ecrm-0500'>2</span><span id='textcolor3317'><span class='ectt-0800'> * vkbd.c</span></span>
|
|
|
+<a id='x1-62020r3'></a><span class='ecrm-0500'>3</span><span id='textcolor3318'><span class='ectt-0800'> */</span></span>
|
|
|
+<a id='x1-62022r4'></a><span class='ecrm-0500'>4</span>
|
|
|
+<a id='x1-62024r5'></a><span class='ecrm-0500'>5</span><span id='textcolor3319'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor3320'><span class='ectt-0800'><linux/init.h></span></span>
|
|
|
+<a id='x1-62026r6'></a><span class='ecrm-0500'>6</span><span id='textcolor3321'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor3322'><span class='ectt-0800'><linux/input.h></span></span>
|
|
|
+<a id='x1-62028r7'></a><span class='ecrm-0500'>7</span><span id='textcolor3323'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor3324'><span class='ectt-0800'><linux/module.h></span></span>
|
|
|
+<a id='x1-62030r8'></a><span class='ecrm-0500'>8</span><span id='textcolor3325'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor3326'><span class='ectt-0800'><linux/spinlock.h></span></span>
|
|
|
+<a id='x1-62032r9'></a><span class='ecrm-0500'>9</span>
|
|
|
+<a id='x1-62034r10'></a><span class='ecrm-0500'>10</span><span id='textcolor3327'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor3328'><span class='ectt-0800'>"vinput.h"</span></span>
|
|
|
+<a id='x1-62036r11'></a><span class='ecrm-0500'>11</span>
|
|
|
+<a id='x1-62038r12'></a><span class='ecrm-0500'>12</span><span id='textcolor3329'><span class='ectt-0800'>#define VINPUT_KBD "vkbd"</span></span>
|
|
|
+<a id='x1-62040r13'></a><span class='ecrm-0500'>13</span><span id='textcolor3330'><span class='ectt-0800'>#define VINPUT_RELEASE 0</span></span>
|
|
|
+<a id='x1-62042r14'></a><span class='ecrm-0500'>14</span><span id='textcolor3331'><span class='ectt-0800'>#define VINPUT_PRESS 1</span></span>
|
|
|
+<a id='x1-62044r15'></a><span class='ecrm-0500'>15</span>
|
|
|
+<a id='x1-62046r16'></a><span class='ecrm-0500'>16</span><span id='textcolor3332'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3333'><span class='ectt-0800'>unsigned</span></span><span class='ectt-0800'> </span><span id='textcolor3334'><span class='ectt-0800'>short</span></span><span class='ectt-0800'> vkeymap[KEY_MAX];</span>
|
|
|
+<a id='x1-62048r17'></a><span class='ecrm-0500'>17</span>
|
|
|
+<a id='x1-62050r18'></a><span class='ecrm-0500'>18</span><span id='textcolor3335'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3336'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> vinput_vkbd_init(</span><span id='textcolor3337'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> vinput *vinput)</span>
|
|
|
+<a id='x1-62052r19'></a><span class='ecrm-0500'>19</span><span class='ectt-0800'>{</span>
|
|
|
+<a id='x1-62054r20'></a><span class='ecrm-0500'>20</span><span class='ectt-0800'> </span><span id='textcolor3338'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> i;</span>
|
|
|
+<a id='x1-62056r21'></a><span class='ecrm-0500'>21</span>
|
|
|
+<a id='x1-62058r22'></a><span class='ecrm-0500'>22</span><span class='ectt-0800'> </span><span id='textcolor3339'><span class='ectt-0800'>/* Set up the input bitfield */</span></span>
|
|
|
+<a id='x1-62060r23'></a><span class='ecrm-0500'>23</span><span class='ectt-0800'> vinput->input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);</span>
|
|
|
+<a id='x1-62062r24'></a><span class='ecrm-0500'>24</span><span class='ectt-0800'> vinput->input->keycodesize = </span><span id='textcolor3340'><span class='ectt-0800'>sizeof</span></span><span class='ectt-0800'>(</span><span id='textcolor3341'><span class='ectt-0800'>unsigned</span></span><span class='ectt-0800'> </span><span id='textcolor3342'><span class='ectt-0800'>short</span></span><span class='ectt-0800'>);</span>
|
|
|
+<a id='x1-62064r25'></a><span class='ecrm-0500'>25</span><span class='ectt-0800'> vinput->input->keycodemax = KEY_MAX;</span>
|
|
|
+<a id='x1-62066r26'></a><span class='ecrm-0500'>26</span><span class='ectt-0800'> vinput->input->keycode = vkeymap;</span>
|
|
|
+<a id='x1-62068r27'></a><span class='ecrm-0500'>27</span>
|
|
|
+<a id='x1-62070r28'></a><span class='ecrm-0500'>28</span><span class='ectt-0800'> </span><span id='textcolor3343'><span class='ectt-0800'>for</span></span><span class='ectt-0800'> (i = 0; i < KEY_MAX; i++)</span>
|
|
|
+<a id='x1-62072r29'></a><span class='ecrm-0500'>29</span><span class='ectt-0800'> set_bit(vkeymap[i], vinput->input->keybit);</span>
|
|
|
+<a id='x1-62074r30'></a><span class='ecrm-0500'>30</span>
|
|
|
+<a id='x1-62076r31'></a><span class='ecrm-0500'>31</span><span class='ectt-0800'> </span><span id='textcolor3344'><span class='ectt-0800'>/* vinput will help us allocate new input device structure via</span></span>
|
|
|
+<a id='x1-62078r32'></a><span class='ecrm-0500'>32</span><span id='textcolor3345'><span class='ectt-0800'> * input_allocate_device(). So, we can register it straightforwardly.</span></span>
|
|
|
+<a id='x1-62080r33'></a><span class='ecrm-0500'>33</span><span id='textcolor3346'><span class='ectt-0800'> */</span></span>
|
|
|
+<a id='x1-62082r34'></a><span class='ecrm-0500'>34</span><span class='ectt-0800'> </span><span id='textcolor3347'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> input_register_device(vinput->input);</span>
|
|
|
+<a id='x1-62084r35'></a><span class='ecrm-0500'>35</span><span class='ectt-0800'>}</span>
|
|
|
+<a id='x1-62086r36'></a><span class='ecrm-0500'>36</span>
|
|
|
+<a id='x1-62088r37'></a><span class='ecrm-0500'>37</span><span id='textcolor3348'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3349'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> vinput_vkbd_read(</span><span id='textcolor3350'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> vinput *vinput, </span><span id='textcolor3351'><span class='ectt-0800'>char</span></span><span class='ectt-0800'> *buff, </span><span id='textcolor3352'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> len)</span>
|
|
|
+<a id='x1-62090r38'></a><span class='ecrm-0500'>38</span><span class='ectt-0800'>{</span>
|
|
|
+<a id='x1-62092r39'></a><span class='ecrm-0500'>39</span><span class='ectt-0800'> spin_lock(&vinput->lock);</span>
|
|
|
+<a id='x1-62094r40'></a><span class='ecrm-0500'>40</span><span class='ectt-0800'> len = snprintf(buff, len, </span><span id='textcolor3353'><span class='ectt-0800'>"%+ld</span></span><span id='textcolor3354'><span class='ectt-0800'>\n</span></span><span id='textcolor3355'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>, vinput->last_entry);</span>
|
|
|
+<a id='x1-62096r41'></a><span class='ecrm-0500'>41</span><span class='ectt-0800'> spin_unlock(&vinput->lock);</span>
|
|
|
+<a id='x1-62098r42'></a><span class='ecrm-0500'>42</span>
|
|
|
+<a id='x1-62100r43'></a><span class='ecrm-0500'>43</span><span class='ectt-0800'> </span><span id='textcolor3356'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> len;</span>
|
|
|
+<a id='x1-62102r44'></a><span class='ecrm-0500'>44</span><span class='ectt-0800'>}</span>
|
|
|
+<a id='x1-62104r45'></a><span class='ecrm-0500'>45</span>
|
|
|
+<a id='x1-62106r46'></a><span class='ecrm-0500'>46</span><span id='textcolor3357'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3358'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> vinput_vkbd_send(</span><span id='textcolor3359'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> vinput *vinput, </span><span id='textcolor3360'><span class='ectt-0800'>char</span></span><span class='ectt-0800'> *buff, </span><span id='textcolor3361'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> len)</span>
|
|
|
+<a id='x1-62108r47'></a><span class='ecrm-0500'>47</span><span class='ectt-0800'>{</span>
|
|
|
+<a id='x1-62110r48'></a><span class='ecrm-0500'>48</span><span class='ectt-0800'> </span><span id='textcolor3362'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> ret;</span>
|
|
|
+<a id='x1-62112r49'></a><span class='ecrm-0500'>49</span><span class='ectt-0800'> </span><span id='textcolor3363'><span class='ectt-0800'>long</span></span><span class='ectt-0800'> key = 0;</span>
|
|
|
+<a id='x1-62114r50'></a><span class='ecrm-0500'>50</span><span class='ectt-0800'> </span><span id='textcolor3364'><span class='ectt-0800'>short</span></span><span class='ectt-0800'> type = VINPUT_PRESS;</span>
|
|
|
+<a id='x1-62116r51'></a><span class='ecrm-0500'>51</span>
|
|
|
+<a id='x1-62118r52'></a><span class='ecrm-0500'>52</span><span class='ectt-0800'> </span><span id='textcolor3365'><span class='ectt-0800'>/* Determine which event was received (press or release)</span></span>
|
|
|
+<a id='x1-62120r53'></a><span class='ecrm-0500'>53</span><span id='textcolor3366'><span class='ectt-0800'> * and store the state.</span></span>
|
|
|
+<a id='x1-62122r54'></a><span class='ecrm-0500'>54</span><span id='textcolor3367'><span class='ectt-0800'> */</span></span>
|
|
|
+<a id='x1-62124r55'></a><span class='ecrm-0500'>55</span><span class='ectt-0800'> </span><span id='textcolor3368'><span class='ectt-0800'>if</span></span><span class='ectt-0800'> (buff[0] == </span><span id='textcolor3369'><span class='tctt-0800'>'</span><span class='ectt-0800'>+</span><span class='tctt-0800'>'</span></span><span class='ectt-0800'>)</span>
|
|
|
+<a id='x1-62126r56'></a><span class='ecrm-0500'>56</span><span class='ectt-0800'> ret = kstrtol(buff + 1, 10, &key);</span>
|
|
|
+<a id='x1-62128r57'></a><span class='ecrm-0500'>57</span><span class='ectt-0800'> </span><span id='textcolor3370'><span class='ectt-0800'>else</span></span>
|
|
|
+<a id='x1-62130r58'></a><span class='ecrm-0500'>58</span><span class='ectt-0800'> ret = kstrtol(buff, 10, &key);</span>
|
|
|
+<a id='x1-62132r59'></a><span class='ecrm-0500'>59</span><span class='ectt-0800'> </span><span id='textcolor3371'><span class='ectt-0800'>if</span></span><span class='ectt-0800'> (ret)</span>
|
|
|
+<a id='x1-62134r60'></a><span class='ecrm-0500'>60</span><span class='ectt-0800'> dev_err(&vinput->dev, </span><span id='textcolor3372'><span class='ectt-0800'>"error during kstrtol: -%d</span></span><span id='textcolor3373'><span class='ectt-0800'>\n</span></span><span id='textcolor3374'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>, ret);</span>
|
|
|
+<a id='x1-62136r61'></a><span class='ecrm-0500'>61</span><span class='ectt-0800'> spin_lock(&vinput->lock);</span>
|
|
|
+<a id='x1-62138r62'></a><span class='ecrm-0500'>62</span><span class='ectt-0800'> vinput->last_entry = key;</span>
|
|
|
+<a id='x1-62140r63'></a><span class='ecrm-0500'>63</span><span class='ectt-0800'> spin_unlock(&vinput->lock);</span>
|
|
|
+<a id='x1-62142r64'></a><span class='ecrm-0500'>64</span>
|
|
|
+<a id='x1-62144r65'></a><span class='ecrm-0500'>65</span><span class='ectt-0800'> </span><span id='textcolor3375'><span class='ectt-0800'>if</span></span><span class='ectt-0800'> (key < 0) {</span>
|
|
|
+<a id='x1-62146r66'></a><span class='ecrm-0500'>66</span><span class='ectt-0800'> type = VINPUT_RELEASE;</span>
|
|
|
+<a id='x1-62148r67'></a><span class='ecrm-0500'>67</span><span class='ectt-0800'> key = -key;</span>
|
|
|
+<a id='x1-62150r68'></a><span class='ecrm-0500'>68</span><span class='ectt-0800'> }</span>
|
|
|
+<a id='x1-62152r69'></a><span class='ecrm-0500'>69</span>
|
|
|
+<a id='x1-62154r70'></a><span class='ecrm-0500'>70</span><span class='ectt-0800'> dev_info(&vinput->dev, </span><span id='textcolor3376'><span class='ectt-0800'>"Event %s code %ld</span></span><span id='textcolor3377'><span class='ectt-0800'>\n</span></span><span id='textcolor3378'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>,</span>
|
|
|
+<a id='x1-62156r71'></a><span class='ecrm-0500'>71</span><span class='ectt-0800'> (type == VINPUT_RELEASE) ? </span><span id='textcolor3379'><span class='ectt-0800'>"VINPUT_RELEASE"</span></span><span class='ectt-0800'> : </span><span id='textcolor3380'><span class='ectt-0800'>"VINPUT_PRESS"</span></span><span class='ectt-0800'>, key);</span>
|
|
|
+<a id='x1-62158r72'></a><span class='ecrm-0500'>72</span>
|
|
|
+<a id='x1-62160r73'></a><span class='ecrm-0500'>73</span><span class='ectt-0800'> </span><span id='textcolor3381'><span class='ectt-0800'>/* Report the state received to input subsystem. */</span></span>
|
|
|
+<a id='x1-62162r74'></a><span class='ecrm-0500'>74</span><span class='ectt-0800'> input_report_key(vinput->input, key, type);</span>
|
|
|
+<a id='x1-62164r75'></a><span class='ecrm-0500'>75</span><span class='ectt-0800'> </span><span id='textcolor3382'><span class='ectt-0800'>/* Tell input subsystem that it finished the report. */</span></span>
|
|
|
+<a id='x1-62166r76'></a><span class='ecrm-0500'>76</span><span class='ectt-0800'> input_sync(vinput->input);</span>
|
|
|
+<a id='x1-62168r77'></a><span class='ecrm-0500'>77</span>
|
|
|
+<a id='x1-62170r78'></a><span class='ecrm-0500'>78</span><span class='ectt-0800'> </span><span id='textcolor3383'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> len;</span>
|
|
|
+<a id='x1-62172r79'></a><span class='ecrm-0500'>79</span><span class='ectt-0800'>}</span>
|
|
|
+<a id='x1-62174r80'></a><span class='ecrm-0500'>80</span>
|
|
|
+<a id='x1-62176r81'></a><span class='ecrm-0500'>81</span><span id='textcolor3384'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3385'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> vinput_ops vkbd_ops = {</span>
|
|
|
+<a id='x1-62178r82'></a><span class='ecrm-0500'>82</span><span class='ectt-0800'> .init = vinput_vkbd_init,</span>
|
|
|
+<a id='x1-62180r83'></a><span class='ecrm-0500'>83</span><span class='ectt-0800'> .send = vinput_vkbd_send,</span>
|
|
|
+<a id='x1-62182r84'></a><span class='ecrm-0500'>84</span><span class='ectt-0800'> .read = vinput_vkbd_read,</span>
|
|
|
+<a id='x1-62184r85'></a><span class='ecrm-0500'>85</span><span class='ectt-0800'>};</span>
|
|
|
+<a id='x1-62186r86'></a><span class='ecrm-0500'>86</span>
|
|
|
+<a id='x1-62188r87'></a><span class='ecrm-0500'>87</span><span id='textcolor3386'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3387'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> vinput_device vkbd_dev = {</span>
|
|
|
+<a id='x1-62190r88'></a><span class='ecrm-0500'>88</span><span class='ectt-0800'> .name = VINPUT_KBD,</span>
|
|
|
+<a id='x1-62192r89'></a><span class='ecrm-0500'>89</span><span class='ectt-0800'> .ops = &vkbd_ops,</span>
|
|
|
+<a id='x1-62194r90'></a><span class='ecrm-0500'>90</span><span class='ectt-0800'>};</span>
|
|
|
+<a id='x1-62196r91'></a><span class='ecrm-0500'>91</span>
|
|
|
+<a id='x1-62198r92'></a><span class='ecrm-0500'>92</span><span id='textcolor3388'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3389'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> __init vkbd_init(</span><span id='textcolor3390'><span class='ectt-0800'>void</span></span><span class='ectt-0800'>)</span>
|
|
|
+<a id='x1-62200r93'></a><span class='ecrm-0500'>93</span><span class='ectt-0800'>{</span>
|
|
|
+<a id='x1-62202r94'></a><span class='ecrm-0500'>94</span><span class='ectt-0800'> </span><span id='textcolor3391'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> i;</span>
|
|
|
+<a id='x1-62204r95'></a><span class='ecrm-0500'>95</span>
|
|
|
+<a id='x1-62206r96'></a><span class='ecrm-0500'>96</span><span class='ectt-0800'> </span><span id='textcolor3392'><span class='ectt-0800'>for</span></span><span class='ectt-0800'> (i = 0; i < KEY_MAX; i++)</span>
|
|
|
+<a id='x1-62208r97'></a><span class='ecrm-0500'>97</span><span class='ectt-0800'> vkeymap[i] = i;</span>
|
|
|
+<a id='x1-62210r98'></a><span class='ecrm-0500'>98</span><span class='ectt-0800'> </span><span id='textcolor3393'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> vinput_register(&vkbd_dev);</span>
|
|
|
+<a id='x1-62212r99'></a><span class='ecrm-0500'>99</span><span class='ectt-0800'>}</span>
|
|
|
+<a id='x1-62214r100'></a><span class='ecrm-0500'>100</span>
|
|
|
+<a id='x1-62216r101'></a><span class='ecrm-0500'>101</span><span id='textcolor3394'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3395'><span class='ectt-0800'>void</span></span><span class='ectt-0800'> __exit vkbd_end(</span><span id='textcolor3396'><span class='ectt-0800'>void</span></span><span class='ectt-0800'>)</span>
|
|
|
+<a id='x1-62218r102'></a><span class='ecrm-0500'>102</span><span class='ectt-0800'>{</span>
|
|
|
+<a id='x1-62220r103'></a><span class='ecrm-0500'>103</span><span class='ectt-0800'> vinput_unregister(&vkbd_dev);</span>
|
|
|
+<a id='x1-62222r104'></a><span class='ecrm-0500'>104</span><span class='ectt-0800'>}</span>
|
|
|
+<a id='x1-62224r105'></a><span class='ecrm-0500'>105</span>
|
|
|
+<a id='x1-62226r106'></a><span class='ecrm-0500'>106</span><span class='ectt-0800'>module_init(vkbd_init);</span>
|
|
|
+<a id='x1-62228r107'></a><span class='ecrm-0500'>107</span><span class='ectt-0800'>module_exit(vkbd_end);</span>
|
|
|
+<a id='x1-62230r108'></a><span class='ecrm-0500'>108</span>
|
|
|
+<a id='x1-62232r109'></a><span class='ecrm-0500'>109</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor3397'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span>
|
|
|
+<a id='x1-62234r110'></a><span class='ecrm-0500'>110</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor3398'><span class='ectt-0800'>"Emulate keyboard input events through /dev/vinput"</span></span><span class='ectt-0800'>);</span></pre>
|
|
|
<!-- l. 2068 --><p class='noindent'>
|
|
|
</p>
|
|
|
<h3 class='sectionHead' id='standardizing-the-interfaces-the-device-model'><span class='titlemark'>17 </span> <a id='x1-6300017'></a>Standardizing the interfaces: The Device Model</h3>
|
|
@@ -6392,59 +6394,59 @@ use this as a template to add your own suspend, resume or other interface
|
|
|
functions.
|
|
|
</p><!-- l. 1 --><p class='indent'>
|
|
|
</p>
|
|
|
- <pre class='fancyvrb' id='fancyvrb94'><a id='x1-63002r1'></a><span class='ecrm-0500'>1</span><span id='textcolor3397'><span class='ectt-0800'>/*</span></span>
|
|
|
-<a id='x1-63004r2'></a><span class='ecrm-0500'>2</span><span id='textcolor3398'><span class='ectt-0800'> * devicemodel.c</span></span>
|
|
|
-<a id='x1-63006r3'></a><span class='ecrm-0500'>3</span><span id='textcolor3399'><span class='ectt-0800'> */</span></span>
|
|
|
-<a id='x1-63008r4'></a><span class='ecrm-0500'>4</span><span id='textcolor3400'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor3401'><span class='ectt-0800'><linux/kernel.h></span></span>
|
|
|
-<a id='x1-63010r5'></a><span class='ecrm-0500'>5</span><span id='textcolor3402'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor3403'><span class='ectt-0800'><linux/module.h></span></span>
|
|
|
-<a id='x1-63012r6'></a><span class='ecrm-0500'>6</span><span id='textcolor3404'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor3405'><span class='ectt-0800'><linux/platform_device.h></span></span>
|
|
|
+ <pre class='fancyvrb' id='fancyvrb94'><a id='x1-63002r1'></a><span class='ecrm-0500'>1</span><span id='textcolor3399'><span class='ectt-0800'>/*</span></span>
|
|
|
+<a id='x1-63004r2'></a><span class='ecrm-0500'>2</span><span id='textcolor3400'><span class='ectt-0800'> * devicemodel.c</span></span>
|
|
|
+<a id='x1-63006r3'></a><span class='ecrm-0500'>3</span><span id='textcolor3401'><span class='ectt-0800'> */</span></span>
|
|
|
+<a id='x1-63008r4'></a><span class='ecrm-0500'>4</span><span id='textcolor3402'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor3403'><span class='ectt-0800'><linux/kernel.h></span></span>
|
|
|
+<a id='x1-63010r5'></a><span class='ecrm-0500'>5</span><span id='textcolor3404'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor3405'><span class='ectt-0800'><linux/module.h></span></span>
|
|
|
+<a id='x1-63012r6'></a><span class='ecrm-0500'>6</span><span id='textcolor3406'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor3407'><span class='ectt-0800'><linux/platform_device.h></span></span>
|
|
|
<a id='x1-63014r7'></a><span class='ecrm-0500'>7</span>
|
|
|
-<a id='x1-63016r8'></a><span class='ecrm-0500'>8</span><span id='textcolor3406'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> devicemodel_data {</span>
|
|
|
-<a id='x1-63018r9'></a><span class='ecrm-0500'>9</span><span class='ectt-0800'> </span><span id='textcolor3407'><span class='ectt-0800'>char</span></span><span class='ectt-0800'> *greeting;</span>
|
|
|
-<a id='x1-63020r10'></a><span class='ecrm-0500'>10</span><span class='ectt-0800'> </span><span id='textcolor3408'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> number;</span>
|
|
|
+<a id='x1-63016r8'></a><span class='ecrm-0500'>8</span><span id='textcolor3408'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> devicemodel_data {</span>
|
|
|
+<a id='x1-63018r9'></a><span class='ecrm-0500'>9</span><span class='ectt-0800'> </span><span id='textcolor3409'><span class='ectt-0800'>char</span></span><span class='ectt-0800'> *greeting;</span>
|
|
|
+<a id='x1-63020r10'></a><span class='ecrm-0500'>10</span><span class='ectt-0800'> </span><span id='textcolor3410'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> number;</span>
|
|
|
<a id='x1-63022r11'></a><span class='ecrm-0500'>11</span><span class='ectt-0800'>};</span>
|
|
|
<a id='x1-63024r12'></a><span class='ecrm-0500'>12</span>
|
|
|
-<a id='x1-63026r13'></a><span class='ecrm-0500'>13</span><span id='textcolor3409'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3410'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> devicemodel_probe(</span><span id='textcolor3411'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> platform_device *dev)</span>
|
|
|
+<a id='x1-63026r13'></a><span class='ecrm-0500'>13</span><span id='textcolor3411'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3412'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> devicemodel_probe(</span><span id='textcolor3413'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> platform_device *dev)</span>
|
|
|
<a id='x1-63028r14'></a><span class='ecrm-0500'>14</span><span class='ectt-0800'>{</span>
|
|
|
-<a id='x1-63030r15'></a><span class='ecrm-0500'>15</span><span class='ectt-0800'> </span><span id='textcolor3412'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> devicemodel_data *pd =</span>
|
|
|
-<a id='x1-63032r16'></a><span class='ecrm-0500'>16</span><span class='ectt-0800'> (</span><span id='textcolor3413'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> devicemodel_data *)(dev->dev.platform_data);</span>
|
|
|
+<a id='x1-63030r15'></a><span class='ecrm-0500'>15</span><span class='ectt-0800'> </span><span id='textcolor3414'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> devicemodel_data *pd =</span>
|
|
|
+<a id='x1-63032r16'></a><span class='ecrm-0500'>16</span><span class='ectt-0800'> (</span><span id='textcolor3415'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> devicemodel_data *)(dev->dev.platform_data);</span>
|
|
|
<a id='x1-63034r17'></a><span class='ecrm-0500'>17</span>
|
|
|
-<a id='x1-63036r18'></a><span class='ecrm-0500'>18</span><span class='ectt-0800'> pr_info(</span><span id='textcolor3414'><span class='ectt-0800'>"devicemodel probe</span></span><span id='textcolor3415'><span class='ectt-0800'>\n</span></span><span id='textcolor3416'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>);</span>
|
|
|
-<a id='x1-63038r19'></a><span class='ecrm-0500'>19</span><span class='ectt-0800'> pr_info(</span><span id='textcolor3417'><span class='ectt-0800'>"devicemodel greeting: %s; %d</span></span><span id='textcolor3418'><span class='ectt-0800'>\n</span></span><span id='textcolor3419'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>, pd->greeting, pd->number);</span>
|
|
|
+<a id='x1-63036r18'></a><span class='ecrm-0500'>18</span><span class='ectt-0800'> pr_info(</span><span id='textcolor3416'><span class='ectt-0800'>"devicemodel probe</span></span><span id='textcolor3417'><span class='ectt-0800'>\n</span></span><span id='textcolor3418'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>);</span>
|
|
|
+<a id='x1-63038r19'></a><span class='ecrm-0500'>19</span><span class='ectt-0800'> pr_info(</span><span id='textcolor3419'><span class='ectt-0800'>"devicemodel greeting: %s; %d</span></span><span id='textcolor3420'><span class='ectt-0800'>\n</span></span><span id='textcolor3421'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>, pd->greeting, pd->number);</span>
|
|
|
<a id='x1-63040r20'></a><span class='ecrm-0500'>20</span>
|
|
|
-<a id='x1-63042r21'></a><span class='ecrm-0500'>21</span><span class='ectt-0800'> </span><span id='textcolor3420'><span class='ectt-0800'>/* Your device initialization code */</span></span>
|
|
|
+<a id='x1-63042r21'></a><span class='ecrm-0500'>21</span><span class='ectt-0800'> </span><span id='textcolor3422'><span class='ectt-0800'>/* Your device initialization code */</span></span>
|
|
|
<a id='x1-63044r22'></a><span class='ecrm-0500'>22</span>
|
|
|
-<a id='x1-63046r23'></a><span class='ecrm-0500'>23</span><span class='ectt-0800'> </span><span id='textcolor3421'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> 0;</span>
|
|
|
+<a id='x1-63046r23'></a><span class='ecrm-0500'>23</span><span class='ectt-0800'> </span><span id='textcolor3423'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> 0;</span>
|
|
|
<a id='x1-63048r24'></a><span class='ecrm-0500'>24</span><span class='ectt-0800'>}</span>
|
|
|
<a id='x1-63050r25'></a><span class='ecrm-0500'>25</span>
|
|
|
-<a id='x1-63052r26'></a><span class='ecrm-0500'>26</span><span id='textcolor3422'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3423'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> devicemodel_remove(</span><span id='textcolor3424'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> platform_device *dev)</span>
|
|
|
+<a id='x1-63052r26'></a><span class='ecrm-0500'>26</span><span id='textcolor3424'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3425'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> devicemodel_remove(</span><span id='textcolor3426'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> platform_device *dev)</span>
|
|
|
<a id='x1-63054r27'></a><span class='ecrm-0500'>27</span><span class='ectt-0800'>{</span>
|
|
|
-<a id='x1-63056r28'></a><span class='ecrm-0500'>28</span><span class='ectt-0800'> pr_info(</span><span id='textcolor3425'><span class='ectt-0800'>"devicemodel example removed</span></span><span id='textcolor3426'><span class='ectt-0800'>\n</span></span><span id='textcolor3427'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>);</span>
|
|
|
+<a id='x1-63056r28'></a><span class='ecrm-0500'>28</span><span class='ectt-0800'> pr_info(</span><span id='textcolor3427'><span class='ectt-0800'>"devicemodel example removed</span></span><span id='textcolor3428'><span class='ectt-0800'>\n</span></span><span id='textcolor3429'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>);</span>
|
|
|
<a id='x1-63058r29'></a><span class='ecrm-0500'>29</span>
|
|
|
-<a id='x1-63060r30'></a><span class='ecrm-0500'>30</span><span class='ectt-0800'> </span><span id='textcolor3428'><span class='ectt-0800'>/* Your device removal code */</span></span>
|
|
|
+<a id='x1-63060r30'></a><span class='ecrm-0500'>30</span><span class='ectt-0800'> </span><span id='textcolor3430'><span class='ectt-0800'>/* Your device removal code */</span></span>
|
|
|
<a id='x1-63062r31'></a><span class='ecrm-0500'>31</span>
|
|
|
-<a id='x1-63064r32'></a><span class='ecrm-0500'>32</span><span class='ectt-0800'> </span><span id='textcolor3429'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> 0;</span>
|
|
|
+<a id='x1-63064r32'></a><span class='ecrm-0500'>32</span><span class='ectt-0800'> </span><span id='textcolor3431'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> 0;</span>
|
|
|
<a id='x1-63066r33'></a><span class='ecrm-0500'>33</span><span class='ectt-0800'>}</span>
|
|
|
<a id='x1-63068r34'></a><span class='ecrm-0500'>34</span>
|
|
|
-<a id='x1-63070r35'></a><span class='ecrm-0500'>35</span><span id='textcolor3430'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3431'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> devicemodel_suspend(</span><span id='textcolor3432'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> device *dev)</span>
|
|
|
+<a id='x1-63070r35'></a><span class='ecrm-0500'>35</span><span id='textcolor3432'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3433'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> devicemodel_suspend(</span><span id='textcolor3434'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> device *dev)</span>
|
|
|
<a id='x1-63072r36'></a><span class='ecrm-0500'>36</span><span class='ectt-0800'>{</span>
|
|
|
-<a id='x1-63074r37'></a><span class='ecrm-0500'>37</span><span class='ectt-0800'> pr_info(</span><span id='textcolor3433'><span class='ectt-0800'>"devicemodel example suspend</span></span><span id='textcolor3434'><span class='ectt-0800'>\n</span></span><span id='textcolor3435'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>);</span>
|
|
|
+<a id='x1-63074r37'></a><span class='ecrm-0500'>37</span><span class='ectt-0800'> pr_info(</span><span id='textcolor3435'><span class='ectt-0800'>"devicemodel example suspend</span></span><span id='textcolor3436'><span class='ectt-0800'>\n</span></span><span id='textcolor3437'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>);</span>
|
|
|
<a id='x1-63076r38'></a><span class='ecrm-0500'>38</span>
|
|
|
-<a id='x1-63078r39'></a><span class='ecrm-0500'>39</span><span class='ectt-0800'> </span><span id='textcolor3436'><span class='ectt-0800'>/* Your device suspend code */</span></span>
|
|
|
+<a id='x1-63078r39'></a><span class='ecrm-0500'>39</span><span class='ectt-0800'> </span><span id='textcolor3438'><span class='ectt-0800'>/* Your device suspend code */</span></span>
|
|
|
<a id='x1-63080r40'></a><span class='ecrm-0500'>40</span>
|
|
|
-<a id='x1-63082r41'></a><span class='ecrm-0500'>41</span><span class='ectt-0800'> </span><span id='textcolor3437'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> 0;</span>
|
|
|
+<a id='x1-63082r41'></a><span class='ecrm-0500'>41</span><span class='ectt-0800'> </span><span id='textcolor3439'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> 0;</span>
|
|
|
<a id='x1-63084r42'></a><span class='ecrm-0500'>42</span><span class='ectt-0800'>}</span>
|
|
|
<a id='x1-63086r43'></a><span class='ecrm-0500'>43</span>
|
|
|
-<a id='x1-63088r44'></a><span class='ecrm-0500'>44</span><span id='textcolor3438'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3439'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> devicemodel_resume(</span><span id='textcolor3440'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> device *dev)</span>
|
|
|
+<a id='x1-63088r44'></a><span class='ecrm-0500'>44</span><span id='textcolor3440'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3441'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> devicemodel_resume(</span><span id='textcolor3442'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> device *dev)</span>
|
|
|
<a id='x1-63090r45'></a><span class='ecrm-0500'>45</span><span class='ectt-0800'>{</span>
|
|
|
-<a id='x1-63092r46'></a><span class='ecrm-0500'>46</span><span class='ectt-0800'> pr_info(</span><span id='textcolor3441'><span class='ectt-0800'>"devicemodel example resume</span></span><span id='textcolor3442'><span class='ectt-0800'>\n</span></span><span id='textcolor3443'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>);</span>
|
|
|
+<a id='x1-63092r46'></a><span class='ecrm-0500'>46</span><span class='ectt-0800'> pr_info(</span><span id='textcolor3443'><span class='ectt-0800'>"devicemodel example resume</span></span><span id='textcolor3444'><span class='ectt-0800'>\n</span></span><span id='textcolor3445'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>);</span>
|
|
|
<a id='x1-63094r47'></a><span class='ecrm-0500'>47</span>
|
|
|
-<a id='x1-63096r48'></a><span class='ecrm-0500'>48</span><span class='ectt-0800'> </span><span id='textcolor3444'><span class='ectt-0800'>/* Your device resume code */</span></span>
|
|
|
+<a id='x1-63096r48'></a><span class='ecrm-0500'>48</span><span class='ectt-0800'> </span><span id='textcolor3446'><span class='ectt-0800'>/* Your device resume code */</span></span>
|
|
|
<a id='x1-63098r49'></a><span class='ecrm-0500'>49</span>
|
|
|
-<a id='x1-63100r50'></a><span class='ecrm-0500'>50</span><span class='ectt-0800'> </span><span id='textcolor3445'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> 0;</span>
|
|
|
+<a id='x1-63100r50'></a><span class='ecrm-0500'>50</span><span class='ectt-0800'> </span><span id='textcolor3447'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> 0;</span>
|
|
|
<a id='x1-63102r51'></a><span class='ecrm-0500'>51</span><span class='ectt-0800'>}</span>
|
|
|
<a id='x1-63104r52'></a><span class='ecrm-0500'>52</span>
|
|
|
-<a id='x1-63106r53'></a><span class='ecrm-0500'>53</span><span id='textcolor3446'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3447'><span class='ectt-0800'>const</span></span><span class='ectt-0800'> </span><span id='textcolor3448'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> dev_pm_ops devicemodel_pm_ops = {</span>
|
|
|
+<a id='x1-63106r53'></a><span class='ecrm-0500'>53</span><span id='textcolor3448'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3449'><span class='ectt-0800'>const</span></span><span class='ectt-0800'> </span><span id='textcolor3450'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> dev_pm_ops devicemodel_pm_ops = {</span>
|
|
|
<a id='x1-63108r54'></a><span class='ecrm-0500'>54</span><span class='ectt-0800'> .suspend = devicemodel_suspend,</span>
|
|
|
<a id='x1-63110r55'></a><span class='ecrm-0500'>55</span><span class='ectt-0800'> .resume = devicemodel_resume,</span>
|
|
|
<a id='x1-63112r56'></a><span class='ecrm-0500'>56</span><span class='ectt-0800'> .poweroff = devicemodel_suspend,</span>
|
|
@@ -6453,43 +6455,43 @@ functions.
|
|
|
<a id='x1-63118r59'></a><span class='ecrm-0500'>59</span><span class='ectt-0800'> .restore = devicemodel_resume,</span>
|
|
|
<a id='x1-63120r60'></a><span class='ecrm-0500'>60</span><span class='ectt-0800'>};</span>
|
|
|
<a id='x1-63122r61'></a><span class='ecrm-0500'>61</span>
|
|
|
-<a id='x1-63124r62'></a><span class='ecrm-0500'>62</span><span id='textcolor3449'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3450'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> platform_driver devicemodel_driver = {</span>
|
|
|
+<a id='x1-63124r62'></a><span class='ecrm-0500'>62</span><span id='textcolor3451'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3452'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> platform_driver devicemodel_driver = {</span>
|
|
|
<a id='x1-63126r63'></a><span class='ecrm-0500'>63</span><span class='ectt-0800'> .driver =</span>
|
|
|
<a id='x1-63128r64'></a><span class='ecrm-0500'>64</span><span class='ectt-0800'> {</span>
|
|
|
-<a id='x1-63130r65'></a><span class='ecrm-0500'>65</span><span class='ectt-0800'> .name = </span><span id='textcolor3451'><span class='ectt-0800'>"devicemodel_example"</span></span><span class='ectt-0800'>,</span>
|
|
|
+<a id='x1-63130r65'></a><span class='ecrm-0500'>65</span><span class='ectt-0800'> .name = </span><span id='textcolor3453'><span class='ectt-0800'>"devicemodel_example"</span></span><span class='ectt-0800'>,</span>
|
|
|
<a id='x1-63132r66'></a><span class='ecrm-0500'>66</span><span class='ectt-0800'> .pm = &devicemodel_pm_ops,</span>
|
|
|
<a id='x1-63134r67'></a><span class='ecrm-0500'>67</span><span class='ectt-0800'> },</span>
|
|
|
<a id='x1-63136r68'></a><span class='ecrm-0500'>68</span><span class='ectt-0800'> .probe = devicemodel_probe,</span>
|
|
|
<a id='x1-63138r69'></a><span class='ecrm-0500'>69</span><span class='ectt-0800'> .remove = devicemodel_remove,</span>
|
|
|
<a id='x1-63140r70'></a><span class='ecrm-0500'>70</span><span class='ectt-0800'>};</span>
|
|
|
<a id='x1-63142r71'></a><span class='ecrm-0500'>71</span>
|
|
|
-<a id='x1-63144r72'></a><span class='ecrm-0500'>72</span><span id='textcolor3452'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3453'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> __init devicemodel_init(</span><span id='textcolor3454'><span class='ectt-0800'>void</span></span><span class='ectt-0800'>)</span>
|
|
|
+<a id='x1-63144r72'></a><span class='ecrm-0500'>72</span><span id='textcolor3454'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3455'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> __init devicemodel_init(</span><span id='textcolor3456'><span class='ectt-0800'>void</span></span><span class='ectt-0800'>)</span>
|
|
|
<a id='x1-63146r73'></a><span class='ecrm-0500'>73</span><span class='ectt-0800'>{</span>
|
|
|
-<a id='x1-63148r74'></a><span class='ecrm-0500'>74</span><span class='ectt-0800'> </span><span id='textcolor3455'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> ret;</span>
|
|
|
+<a id='x1-63148r74'></a><span class='ecrm-0500'>74</span><span class='ectt-0800'> </span><span id='textcolor3457'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> ret;</span>
|
|
|
<a id='x1-63150r75'></a><span class='ecrm-0500'>75</span>
|
|
|
-<a id='x1-63152r76'></a><span class='ecrm-0500'>76</span><span class='ectt-0800'> pr_info(</span><span id='textcolor3456'><span class='ectt-0800'>"devicemodel init</span></span><span id='textcolor3457'><span class='ectt-0800'>\n</span></span><span id='textcolor3458'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>);</span>
|
|
|
+<a id='x1-63152r76'></a><span class='ecrm-0500'>76</span><span class='ectt-0800'> pr_info(</span><span id='textcolor3458'><span class='ectt-0800'>"devicemodel init</span></span><span id='textcolor3459'><span class='ectt-0800'>\n</span></span><span id='textcolor3460'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>);</span>
|
|
|
<a id='x1-63154r77'></a><span class='ecrm-0500'>77</span>
|
|
|
<a id='x1-63156r78'></a><span class='ecrm-0500'>78</span><span class='ectt-0800'> ret = platform_driver_register(&devicemodel_driver);</span>
|
|
|
<a id='x1-63158r79'></a><span class='ecrm-0500'>79</span>
|
|
|
-<a id='x1-63160r80'></a><span class='ecrm-0500'>80</span><span class='ectt-0800'> </span><span id='textcolor3459'><span class='ectt-0800'>if</span></span><span class='ectt-0800'> (ret) {</span>
|
|
|
-<a id='x1-63162r81'></a><span class='ecrm-0500'>81</span><span class='ectt-0800'> pr_err(</span><span id='textcolor3460'><span class='ectt-0800'>"Unable to register driver</span></span><span id='textcolor3461'><span class='ectt-0800'>\n</span></span><span id='textcolor3462'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>);</span>
|
|
|
-<a id='x1-63164r82'></a><span class='ecrm-0500'>82</span><span class='ectt-0800'> </span><span id='textcolor3463'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> ret;</span>
|
|
|
+<a id='x1-63160r80'></a><span class='ecrm-0500'>80</span><span class='ectt-0800'> </span><span id='textcolor3461'><span class='ectt-0800'>if</span></span><span class='ectt-0800'> (ret) {</span>
|
|
|
+<a id='x1-63162r81'></a><span class='ecrm-0500'>81</span><span class='ectt-0800'> pr_err(</span><span id='textcolor3462'><span class='ectt-0800'>"Unable to register driver</span></span><span id='textcolor3463'><span class='ectt-0800'>\n</span></span><span id='textcolor3464'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>);</span>
|
|
|
+<a id='x1-63164r82'></a><span class='ecrm-0500'>82</span><span class='ectt-0800'> </span><span id='textcolor3465'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> ret;</span>
|
|
|
<a id='x1-63166r83'></a><span class='ecrm-0500'>83</span><span class='ectt-0800'> }</span>
|
|
|
<a id='x1-63168r84'></a><span class='ecrm-0500'>84</span>
|
|
|
-<a id='x1-63170r85'></a><span class='ecrm-0500'>85</span><span class='ectt-0800'> </span><span id='textcolor3464'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> 0;</span>
|
|
|
+<a id='x1-63170r85'></a><span class='ecrm-0500'>85</span><span class='ectt-0800'> </span><span id='textcolor3466'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> 0;</span>
|
|
|
<a id='x1-63172r86'></a><span class='ecrm-0500'>86</span><span class='ectt-0800'>}</span>
|
|
|
<a id='x1-63174r87'></a><span class='ecrm-0500'>87</span>
|
|
|
-<a id='x1-63176r88'></a><span class='ecrm-0500'>88</span><span id='textcolor3465'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3466'><span class='ectt-0800'>void</span></span><span class='ectt-0800'> __exit devicemodel_exit(</span><span id='textcolor3467'><span class='ectt-0800'>void</span></span><span class='ectt-0800'>)</span>
|
|
|
+<a id='x1-63176r88'></a><span class='ecrm-0500'>88</span><span id='textcolor3467'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3468'><span class='ectt-0800'>void</span></span><span class='ectt-0800'> __exit devicemodel_exit(</span><span id='textcolor3469'><span class='ectt-0800'>void</span></span><span class='ectt-0800'>)</span>
|
|
|
<a id='x1-63178r89'></a><span class='ecrm-0500'>89</span><span class='ectt-0800'>{</span>
|
|
|
-<a id='x1-63180r90'></a><span class='ecrm-0500'>90</span><span class='ectt-0800'> pr_info(</span><span id='textcolor3468'><span class='ectt-0800'>"devicemodel exit</span></span><span id='textcolor3469'><span class='ectt-0800'>\n</span></span><span id='textcolor3470'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>);</span>
|
|
|
+<a id='x1-63180r90'></a><span class='ecrm-0500'>90</span><span class='ectt-0800'> pr_info(</span><span id='textcolor3470'><span class='ectt-0800'>"devicemodel exit</span></span><span id='textcolor3471'><span class='ectt-0800'>\n</span></span><span id='textcolor3472'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>);</span>
|
|
|
<a id='x1-63182r91'></a><span class='ecrm-0500'>91</span><span class='ectt-0800'> platform_driver_unregister(&devicemodel_driver);</span>
|
|
|
<a id='x1-63184r92'></a><span class='ecrm-0500'>92</span><span class='ectt-0800'>}</span>
|
|
|
<a id='x1-63186r93'></a><span class='ecrm-0500'>93</span>
|
|
|
<a id='x1-63188r94'></a><span class='ecrm-0500'>94</span><span class='ectt-0800'>module_init(devicemodel_init);</span>
|
|
|
<a id='x1-63190r95'></a><span class='ecrm-0500'>95</span><span class='ectt-0800'>module_exit(devicemodel_exit);</span>
|
|
|
<a id='x1-63192r96'></a><span class='ecrm-0500'>96</span>
|
|
|
-<a id='x1-63194r97'></a><span class='ecrm-0500'>97</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor3471'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span>
|
|
|
-<a id='x1-63196r98'></a><span class='ecrm-0500'>98</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor3472'><span class='ectt-0800'>"Linux Device Model example"</span></span><span class='ectt-0800'>);</span></pre>
|
|
|
+<a id='x1-63194r97'></a><span class='ecrm-0500'>97</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor3473'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span>
|
|
|
+<a id='x1-63196r98'></a><span class='ecrm-0500'>98</span><span class='ectt-0800'>MODULE_DESCRIPTION(</span><span id='textcolor3474'><span class='ectt-0800'>"Linux Device Model example"</span></span><span class='ectt-0800'>);</span></pre>
|
|
|
<!-- l. 2076 --><p class='noindent'>
|
|
|
</p>
|
|
|
<h3 class='sectionHead' id='optimizations'><span class='titlemark'>18 </span> <a id='x1-6400018'></a>Optimizations</h3>
|
|
@@ -6513,10 +6515,10 @@ to succeed.
|
|
|
|
|
|
</p>
|
|
|
<pre class='fancyvrb' id='fancyvrb95'><a id='x1-65012r1'></a><span class='ecrm-0500'>1</span><span class='ectt-0800'>bvl = bvec_alloc(gfp_mask, nr_iovecs, &idx);</span>
|
|
|
-<a id='x1-65014r2'></a><span class='ecrm-0500'>2</span><span id='textcolor3473'><span class='ectt-0800'>if</span></span><span class='ectt-0800'> (unlikely(!bvl)) {</span>
|
|
|
+<a id='x1-65014r2'></a><span class='ecrm-0500'>2</span><span id='textcolor3475'><span class='ectt-0800'>if</span></span><span class='ectt-0800'> (unlikely(!bvl)) {</span>
|
|
|
<a id='x1-65016r3'></a><span class='ecrm-0500'>3</span><span class='ectt-0800'> mempool_free(bio, bio_pool);</span>
|
|
|
<a id='x1-65018r4'></a><span class='ecrm-0500'>4</span><span class='ectt-0800'> bio = NULL;</span>
|
|
|
-<a id='x1-65020r5'></a><span class='ecrm-0500'>5</span><span class='ectt-0800'> </span><span id='textcolor3474'><span class='ectt-0800'>goto</span></span><span class='ectt-0800'> out;</span>
|
|
|
+<a id='x1-65020r5'></a><span class='ecrm-0500'>5</span><span class='ectt-0800'> </span><span id='textcolor3476'><span class='ectt-0800'>goto</span></span><span class='ectt-0800'> out;</span>
|
|
|
<a id='x1-65022r6'></a><span class='ecrm-0500'>6</span><span class='ectt-0800'>}</span></pre>
|
|
|
<!-- l. 2094 --><p class='indent'> When the <code> <span class='ectt-1000'>unlikely</span>
|
|
|
</code> macro is used, the compiler alters its machine instruction output, so that it
|
|
@@ -6534,7 +6536,7 @@ prediction. The most typical use case of static keys is for performance-sensitiv
|
|
|
code, such as tracepoints, context switching, networking, etc. These hot paths of the
|
|
|
kernel often contain branches and can be optimized easily using this technique.
|
|
|
Before we can use static keys in the kernel, we need to make sure that gcc supports
|
|
|
-<code> <span id='textcolor3475'><span class='ectt-1000'>asm</span></span><span class='ectt-1000'> </span><span id='textcolor3476'><span class='ectt-1000'>goto</span></span>
|
|
|
+<code> <span id='textcolor3477'><span class='ectt-1000'>asm</span></span><span class='ectt-1000'> </span><span id='textcolor3478'><span class='ectt-1000'>goto</span></span>
|
|
|
</code> inline assembly, and the following kernel configurations are set:
|
|
|
</p><!-- l. 1 --><p class='indent'>
|
|
|
</p>
|
|
@@ -6557,10 +6559,10 @@ no-op instruction will be generated at compile time as the key is initialized to
|
|
|
and the branch is unlikely to be taken.
|
|
|
</p><!-- l. 1 --><p class='indent'>
|
|
|
</p>
|
|
|
- <pre class='fancyvrb' id='fancyvrb98'><a id='x1-66021r1'></a><span class='ecrm-0500'>1</span><span class='ectt-0800'>pr_info(</span><span id='textcolor3477'><span class='ectt-0800'>"fastpath 1</span></span><span id='textcolor3478'><span class='ectt-0800'>\n</span></span><span id='textcolor3479'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>);</span>
|
|
|
-<a id='x1-66023r2'></a><span class='ecrm-0500'>2</span><span id='textcolor3480'><span class='ectt-0800'>if</span></span><span class='ectt-0800'> (static_branch_unlikely(&fkey))</span>
|
|
|
-<a id='x1-66025r3'></a><span class='ecrm-0500'>3</span><span class='ectt-0800'> pr_alert(</span><span id='textcolor3481'><span class='ectt-0800'>"do unlikely thing</span></span><span id='textcolor3482'><span class='ectt-0800'>\n</span></span><span id='textcolor3483'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>);</span>
|
|
|
-<a id='x1-66027r4'></a><span class='ecrm-0500'>4</span><span class='ectt-0800'>pr_info(</span><span id='textcolor3484'><span class='ectt-0800'>"fastpath 2</span></span><span id='textcolor3485'><span class='ectt-0800'>\n</span></span><span id='textcolor3486'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>);</span></pre>
|
|
|
+ <pre class='fancyvrb' id='fancyvrb98'><a id='x1-66021r1'></a><span class='ecrm-0500'>1</span><span class='ectt-0800'>pr_info(</span><span id='textcolor3479'><span class='ectt-0800'>"fastpath 1</span></span><span id='textcolor3480'><span class='ectt-0800'>\n</span></span><span id='textcolor3481'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>);</span>
|
|
|
+<a id='x1-66023r2'></a><span class='ecrm-0500'>2</span><span id='textcolor3482'><span class='ectt-0800'>if</span></span><span class='ectt-0800'> (static_branch_unlikely(&fkey))</span>
|
|
|
+<a id='x1-66025r3'></a><span class='ecrm-0500'>3</span><span class='ectt-0800'> pr_alert(</span><span id='textcolor3483'><span class='ectt-0800'>"do unlikely thing</span></span><span id='textcolor3484'><span class='ectt-0800'>\n</span></span><span id='textcolor3485'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>);</span>
|
|
|
+<a id='x1-66027r4'></a><span class='ecrm-0500'>4</span><span class='ectt-0800'>pr_info(</span><span id='textcolor3486'><span class='ectt-0800'>"fastpath 2</span></span><span id='textcolor3487'><span class='ectt-0800'>\n</span></span><span id='textcolor3488'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>);</span></pre>
|
|
|
|
|
|
|
|
|
|
|
@@ -6573,159 +6575,159 @@ code <code> <span class='ectt-1000'>pr_alert</span>
|
|
|
static key works.
|
|
|
</p><!-- l. 1 --><p class='indent'>
|
|
|
</p>
|
|
|
- <pre class='fancyvrb' id='fancyvrb99'><a id='x1-66031r1'></a><span class='ecrm-0500'>1</span><span id='textcolor3487'><span class='ectt-0800'>/*</span></span>
|
|
|
-<a id='x1-66033r2'></a><span class='ecrm-0500'>2</span><span id='textcolor3488'><span class='ectt-0800'> * static_key.c</span></span>
|
|
|
-<a id='x1-66035r3'></a><span class='ecrm-0500'>3</span><span id='textcolor3489'><span class='ectt-0800'> */</span></span>
|
|
|
+ <pre class='fancyvrb' id='fancyvrb99'><a id='x1-66031r1'></a><span class='ecrm-0500'>1</span><span id='textcolor3489'><span class='ectt-0800'>/*</span></span>
|
|
|
+<a id='x1-66033r2'></a><span class='ecrm-0500'>2</span><span id='textcolor3490'><span class='ectt-0800'> * static_key.c</span></span>
|
|
|
+<a id='x1-66035r3'></a><span class='ecrm-0500'>3</span><span id='textcolor3491'><span class='ectt-0800'> */</span></span>
|
|
|
<a id='x1-66037r4'></a><span class='ecrm-0500'>4</span>
|
|
|
-<a id='x1-66039r5'></a><span class='ecrm-0500'>5</span><span id='textcolor3490'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor3491'><span class='ectt-0800'><linux/atomic.h></span></span>
|
|
|
-<a id='x1-66041r6'></a><span class='ecrm-0500'>6</span><span id='textcolor3492'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor3493'><span class='ectt-0800'><linux/device.h></span></span>
|
|
|
-<a id='x1-66043r7'></a><span class='ecrm-0500'>7</span><span id='textcolor3494'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor3495'><span class='ectt-0800'><linux/fs.h></span></span>
|
|
|
-<a id='x1-66045r8'></a><span class='ecrm-0500'>8</span><span id='textcolor3496'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor3497'><span class='ectt-0800'><linux/kernel.h> /* for sprintf() */</span></span>
|
|
|
-<a id='x1-66047r9'></a><span class='ecrm-0500'>9</span><span id='textcolor3498'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor3499'><span class='ectt-0800'><linux/module.h></span></span>
|
|
|
-<a id='x1-66049r10'></a><span class='ecrm-0500'>10</span><span id='textcolor3500'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor3501'><span class='ectt-0800'><linux/printk.h></span></span>
|
|
|
-<a id='x1-66051r11'></a><span class='ecrm-0500'>11</span><span id='textcolor3502'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor3503'><span class='ectt-0800'><linux/types.h></span></span>
|
|
|
-<a id='x1-66053r12'></a><span class='ecrm-0500'>12</span><span id='textcolor3504'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor3505'><span class='ectt-0800'><linux/uaccess.h> /* for get_user and put_user */</span></span>
|
|
|
-<a id='x1-66055r13'></a><span class='ecrm-0500'>13</span><span id='textcolor3506'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor3507'><span class='ectt-0800'><linux/jump_label.h> /* for static key macros */</span></span>
|
|
|
-<a id='x1-66057r14'></a><span class='ecrm-0500'>14</span><span id='textcolor3508'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor3509'><span class='ectt-0800'><linux/version.h></span></span>
|
|
|
+<a id='x1-66039r5'></a><span class='ecrm-0500'>5</span><span id='textcolor3492'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor3493'><span class='ectt-0800'><linux/atomic.h></span></span>
|
|
|
+<a id='x1-66041r6'></a><span class='ecrm-0500'>6</span><span id='textcolor3494'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor3495'><span class='ectt-0800'><linux/device.h></span></span>
|
|
|
+<a id='x1-66043r7'></a><span class='ecrm-0500'>7</span><span id='textcolor3496'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor3497'><span class='ectt-0800'><linux/fs.h></span></span>
|
|
|
+<a id='x1-66045r8'></a><span class='ecrm-0500'>8</span><span id='textcolor3498'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor3499'><span class='ectt-0800'><linux/kernel.h> /* for sprintf() */</span></span>
|
|
|
+<a id='x1-66047r9'></a><span class='ecrm-0500'>9</span><span id='textcolor3500'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor3501'><span class='ectt-0800'><linux/module.h></span></span>
|
|
|
+<a id='x1-66049r10'></a><span class='ecrm-0500'>10</span><span id='textcolor3502'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor3503'><span class='ectt-0800'><linux/printk.h></span></span>
|
|
|
+<a id='x1-66051r11'></a><span class='ecrm-0500'>11</span><span id='textcolor3504'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor3505'><span class='ectt-0800'><linux/types.h></span></span>
|
|
|
+<a id='x1-66053r12'></a><span class='ecrm-0500'>12</span><span id='textcolor3506'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor3507'><span class='ectt-0800'><linux/uaccess.h> /* for get_user and put_user */</span></span>
|
|
|
+<a id='x1-66055r13'></a><span class='ecrm-0500'>13</span><span id='textcolor3508'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor3509'><span class='ectt-0800'><linux/jump_label.h> /* for static key macros */</span></span>
|
|
|
+<a id='x1-66057r14'></a><span class='ecrm-0500'>14</span><span id='textcolor3510'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor3511'><span class='ectt-0800'><linux/version.h></span></span>
|
|
|
<a id='x1-66059r15'></a><span class='ecrm-0500'>15</span>
|
|
|
-<a id='x1-66061r16'></a><span class='ecrm-0500'>16</span><span id='textcolor3510'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor3511'><span class='ectt-0800'><asm/errno.h></span></span>
|
|
|
+<a id='x1-66061r16'></a><span class='ecrm-0500'>16</span><span id='textcolor3512'><span class='ectt-0800'>#include</span></span><span class='ectt-0800'> </span><span id='textcolor3513'><span class='ectt-0800'><asm/errno.h></span></span>
|
|
|
<a id='x1-66063r17'></a><span class='ecrm-0500'>17</span>
|
|
|
-<a id='x1-66065r18'></a><span class='ecrm-0500'>18</span><span id='textcolor3512'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3513'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> device_open(</span><span id='textcolor3514'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> inode *inode, </span><span id='textcolor3515'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> file *file);</span>
|
|
|
-<a id='x1-66067r19'></a><span class='ecrm-0500'>19</span><span id='textcolor3516'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3517'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> device_release(</span><span id='textcolor3518'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> inode *inode, </span><span id='textcolor3519'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> file *file);</span>
|
|
|
-<a id='x1-66069r20'></a><span class='ecrm-0500'>20</span><span id='textcolor3520'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3521'><span class='ectt-0800'>ssize_t</span></span><span class='ectt-0800'> device_read(</span><span id='textcolor3522'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> file *file, </span><span id='textcolor3523'><span class='ectt-0800'>char</span></span><span class='ectt-0800'> __user *buf, </span><span id='textcolor3524'><span class='ectt-0800'>size_t</span></span><span class='ectt-0800'> count,</span>
|
|
|
+<a id='x1-66065r18'></a><span class='ecrm-0500'>18</span><span id='textcolor3514'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3515'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> device_open(</span><span id='textcolor3516'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> inode *inode, </span><span id='textcolor3517'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> file *file);</span>
|
|
|
+<a id='x1-66067r19'></a><span class='ecrm-0500'>19</span><span id='textcolor3518'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3519'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> device_release(</span><span id='textcolor3520'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> inode *inode, </span><span id='textcolor3521'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> file *file);</span>
|
|
|
+<a id='x1-66069r20'></a><span class='ecrm-0500'>20</span><span id='textcolor3522'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3523'><span class='ectt-0800'>ssize_t</span></span><span class='ectt-0800'> device_read(</span><span id='textcolor3524'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> file *file, </span><span id='textcolor3525'><span class='ectt-0800'>char</span></span><span class='ectt-0800'> __user *buf, </span><span id='textcolor3526'><span class='ectt-0800'>size_t</span></span><span class='ectt-0800'> count,</span>
|
|
|
<a id='x1-66071r21'></a><span class='ecrm-0500'>21</span><span class='ectt-0800'> loff_t *ppos);</span>
|
|
|
-<a id='x1-66073r22'></a><span class='ecrm-0500'>22</span><span id='textcolor3525'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3526'><span class='ectt-0800'>ssize_t</span></span><span class='ectt-0800'> device_write(</span><span id='textcolor3527'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> file *file, </span><span id='textcolor3528'><span class='ectt-0800'>const</span></span><span class='ectt-0800'> </span><span id='textcolor3529'><span class='ectt-0800'>char</span></span><span class='ectt-0800'> __user *buf,</span>
|
|
|
-<a id='x1-66075r23'></a><span class='ecrm-0500'>23</span><span class='ectt-0800'> </span><span id='textcolor3530'><span class='ectt-0800'>size_t</span></span><span class='ectt-0800'> count, loff_t *ppos);</span>
|
|
|
+<a id='x1-66073r22'></a><span class='ecrm-0500'>22</span><span id='textcolor3527'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3528'><span class='ectt-0800'>ssize_t</span></span><span class='ectt-0800'> device_write(</span><span id='textcolor3529'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> file *file, </span><span id='textcolor3530'><span class='ectt-0800'>const</span></span><span class='ectt-0800'> </span><span id='textcolor3531'><span class='ectt-0800'>char</span></span><span class='ectt-0800'> __user *buf,</span>
|
|
|
+<a id='x1-66075r23'></a><span class='ecrm-0500'>23</span><span class='ectt-0800'> </span><span id='textcolor3532'><span class='ectt-0800'>size_t</span></span><span class='ectt-0800'> count, loff_t *ppos);</span>
|
|
|
<a id='x1-66077r24'></a><span class='ecrm-0500'>24</span>
|
|
|
-<a id='x1-66079r25'></a><span class='ecrm-0500'>25</span><span id='textcolor3531'><span class='ectt-0800'>#define SUCCESS 0</span></span>
|
|
|
-<a id='x1-66081r26'></a><span class='ecrm-0500'>26</span><span id='textcolor3532'><span class='ectt-0800'>#define DEVICE_NAME "key_state"</span></span>
|
|
|
-<a id='x1-66083r27'></a><span class='ecrm-0500'>27</span><span id='textcolor3533'><span class='ectt-0800'>#define BUF_LEN 10</span></span>
|
|
|
+<a id='x1-66079r25'></a><span class='ecrm-0500'>25</span><span id='textcolor3533'><span class='ectt-0800'>#define SUCCESS 0</span></span>
|
|
|
+<a id='x1-66081r26'></a><span class='ecrm-0500'>26</span><span id='textcolor3534'><span class='ectt-0800'>#define DEVICE_NAME "key_state"</span></span>
|
|
|
+<a id='x1-66083r27'></a><span class='ecrm-0500'>27</span><span id='textcolor3535'><span class='ectt-0800'>#define BUF_LEN 10</span></span>
|
|
|
<a id='x1-66085r28'></a><span class='ecrm-0500'>28</span>
|
|
|
-<a id='x1-66087r29'></a><span class='ecrm-0500'>29</span><span id='textcolor3534'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3535'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> major;</span>
|
|
|
+<a id='x1-66087r29'></a><span class='ecrm-0500'>29</span><span id='textcolor3536'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3537'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> major;</span>
|
|
|
<a id='x1-66089r30'></a><span class='ecrm-0500'>30</span>
|
|
|
-<a id='x1-66091r31'></a><span class='ecrm-0500'>31</span><span id='textcolor3536'><span class='ectt-0800'>enum</span></span><span class='ectt-0800'> {</span>
|
|
|
+<a id='x1-66091r31'></a><span class='ecrm-0500'>31</span><span id='textcolor3538'><span class='ectt-0800'>enum</span></span><span class='ectt-0800'> {</span>
|
|
|
<a id='x1-66093r32'></a><span class='ecrm-0500'>32</span><span class='ectt-0800'> CDEV_NOT_USED = 0,</span>
|
|
|
<a id='x1-66095r33'></a><span class='ecrm-0500'>33</span><span class='ectt-0800'> CDEV_EXCLUSIVE_OPEN = 1,</span>
|
|
|
<a id='x1-66097r34'></a><span class='ecrm-0500'>34</span><span class='ectt-0800'>};</span>
|
|
|
<a id='x1-66099r35'></a><span class='ecrm-0500'>35</span>
|
|
|
-<a id='x1-66101r36'></a><span class='ecrm-0500'>36</span><span id='textcolor3537'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> atomic_t already_open = ATOMIC_INIT(CDEV_NOT_USED);</span>
|
|
|
+<a id='x1-66101r36'></a><span class='ecrm-0500'>36</span><span id='textcolor3539'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> atomic_t already_open = ATOMIC_INIT(CDEV_NOT_USED);</span>
|
|
|
<a id='x1-66103r37'></a><span class='ecrm-0500'>37</span>
|
|
|
-<a id='x1-66105r38'></a><span class='ecrm-0500'>38</span><span id='textcolor3538'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3539'><span class='ectt-0800'>char</span></span><span class='ectt-0800'> msg[BUF_LEN + 1];</span>
|
|
|
+<a id='x1-66105r38'></a><span class='ecrm-0500'>38</span><span id='textcolor3540'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3541'><span class='ectt-0800'>char</span></span><span class='ectt-0800'> msg[BUF_LEN + 1];</span>
|
|
|
<a id='x1-66107r39'></a><span class='ecrm-0500'>39</span>
|
|
|
-<a id='x1-66109r40'></a><span class='ecrm-0500'>40</span><span id='textcolor3540'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3541'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> class *cls;</span>
|
|
|
+<a id='x1-66109r40'></a><span class='ecrm-0500'>40</span><span id='textcolor3542'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3543'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> class *cls;</span>
|
|
|
<a id='x1-66111r41'></a><span class='ecrm-0500'>41</span>
|
|
|
-<a id='x1-66113r42'></a><span class='ecrm-0500'>42</span><span id='textcolor3542'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> DEFINE_STATIC_KEY_FALSE(fkey);</span>
|
|
|
+<a id='x1-66113r42'></a><span class='ecrm-0500'>42</span><span id='textcolor3544'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> DEFINE_STATIC_KEY_FALSE(fkey);</span>
|
|
|
<a id='x1-66115r43'></a><span class='ecrm-0500'>43</span>
|
|
|
-<a id='x1-66117r44'></a><span class='ecrm-0500'>44</span><span id='textcolor3543'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3544'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> file_operations chardev_fops = {</span>
|
|
|
-<a id='x1-66119r45'></a><span class='ecrm-0500'>45</span><span id='textcolor3545'><span class='ectt-0800'>#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0)</span></span>
|
|
|
+<a id='x1-66117r44'></a><span class='ecrm-0500'>44</span><span id='textcolor3545'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3546'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> file_operations chardev_fops = {</span>
|
|
|
+<a id='x1-66119r45'></a><span class='ecrm-0500'>45</span><span id='textcolor3547'><span class='ectt-0800'>#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0)</span></span>
|
|
|
<a id='x1-66121r46'></a><span class='ecrm-0500'>46</span><span class='ectt-0800'> .owner = THIS_MODULE,</span>
|
|
|
-<a id='x1-66123r47'></a><span class='ecrm-0500'>47</span><span id='textcolor3546'><span class='ectt-0800'>#endif</span></span>
|
|
|
+<a id='x1-66123r47'></a><span class='ecrm-0500'>47</span><span id='textcolor3548'><span class='ectt-0800'>#endif</span></span>
|
|
|
<a id='x1-66125r48'></a><span class='ecrm-0500'>48</span><span class='ectt-0800'> .open = device_open,</span>
|
|
|
<a id='x1-66127r49'></a><span class='ecrm-0500'>49</span><span class='ectt-0800'> .release = device_release,</span>
|
|
|
<a id='x1-66129r50'></a><span class='ecrm-0500'>50</span><span class='ectt-0800'> .read = device_read,</span>
|
|
|
<a id='x1-66131r51'></a><span class='ecrm-0500'>51</span><span class='ectt-0800'> .write = device_write,</span>
|
|
|
<a id='x1-66133r52'></a><span class='ecrm-0500'>52</span><span class='ectt-0800'>};</span>
|
|
|
<a id='x1-66135r53'></a><span class='ecrm-0500'>53</span>
|
|
|
-<a id='x1-66137r54'></a><span class='ecrm-0500'>54</span><span id='textcolor3547'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3548'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> __init chardev_init(</span><span id='textcolor3549'><span class='ectt-0800'>void</span></span><span class='ectt-0800'>)</span>
|
|
|
+<a id='x1-66137r54'></a><span class='ecrm-0500'>54</span><span id='textcolor3549'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3550'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> __init chardev_init(</span><span id='textcolor3551'><span class='ectt-0800'>void</span></span><span class='ectt-0800'>)</span>
|
|
|
<a id='x1-66139r55'></a><span class='ecrm-0500'>55</span><span class='ectt-0800'>{</span>
|
|
|
<a id='x1-66141r56'></a><span class='ecrm-0500'>56</span><span class='ectt-0800'> major = register_chrdev(0, DEVICE_NAME, &chardev_fops);</span>
|
|
|
-<a id='x1-66143r57'></a><span class='ecrm-0500'>57</span><span class='ectt-0800'> </span><span id='textcolor3550'><span class='ectt-0800'>if</span></span><span class='ectt-0800'> (major < 0) {</span>
|
|
|
-<a id='x1-66145r58'></a><span class='ecrm-0500'>58</span><span class='ectt-0800'> pr_alert(</span><span id='textcolor3551'><span class='ectt-0800'>"Registering char device failed with %d</span></span><span id='textcolor3552'><span class='ectt-0800'>\n</span></span><span id='textcolor3553'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>, major);</span>
|
|
|
-<a id='x1-66147r59'></a><span class='ecrm-0500'>59</span><span class='ectt-0800'> </span><span id='textcolor3554'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> major;</span>
|
|
|
+<a id='x1-66143r57'></a><span class='ecrm-0500'>57</span><span class='ectt-0800'> </span><span id='textcolor3552'><span class='ectt-0800'>if</span></span><span class='ectt-0800'> (major < 0) {</span>
|
|
|
+<a id='x1-66145r58'></a><span class='ecrm-0500'>58</span><span class='ectt-0800'> pr_alert(</span><span id='textcolor3553'><span class='ectt-0800'>"Registering char device failed with %d</span></span><span id='textcolor3554'><span class='ectt-0800'>\n</span></span><span id='textcolor3555'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>, major);</span>
|
|
|
+<a id='x1-66147r59'></a><span class='ecrm-0500'>59</span><span class='ectt-0800'> </span><span id='textcolor3556'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> major;</span>
|
|
|
<a id='x1-66149r60'></a><span class='ecrm-0500'>60</span><span class='ectt-0800'> }</span>
|
|
|
<a id='x1-66151r61'></a><span class='ecrm-0500'>61</span>
|
|
|
-<a id='x1-66153r62'></a><span class='ecrm-0500'>62</span><span class='ectt-0800'> pr_info(</span><span id='textcolor3555'><span class='ectt-0800'>"I was assigned major number %d</span></span><span id='textcolor3556'><span class='ectt-0800'>\n</span></span><span id='textcolor3557'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>, major);</span>
|
|
|
+<a id='x1-66153r62'></a><span class='ecrm-0500'>62</span><span class='ectt-0800'> pr_info(</span><span id='textcolor3557'><span class='ectt-0800'>"I was assigned major number %d</span></span><span id='textcolor3558'><span class='ectt-0800'>\n</span></span><span id='textcolor3559'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>, major);</span>
|
|
|
<a id='x1-66155r63'></a><span class='ecrm-0500'>63</span>
|
|
|
-<a id='x1-66157r64'></a><span class='ecrm-0500'>64</span><span id='textcolor3558'><span class='ectt-0800'>#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0)</span></span>
|
|
|
+<a id='x1-66157r64'></a><span class='ecrm-0500'>64</span><span id='textcolor3560'><span class='ectt-0800'>#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0)</span></span>
|
|
|
<a id='x1-66159r65'></a><span class='ecrm-0500'>65</span><span class='ectt-0800'> cls = class_create(THIS_MODULE, DEVICE_NAME);</span>
|
|
|
-<a id='x1-66161r66'></a><span class='ecrm-0500'>66</span><span id='textcolor3559'><span class='ectt-0800'>#else</span></span>
|
|
|
+<a id='x1-66161r66'></a><span class='ecrm-0500'>66</span><span id='textcolor3561'><span class='ectt-0800'>#else</span></span>
|
|
|
<a id='x1-66163r67'></a><span class='ecrm-0500'>67</span><span class='ectt-0800'> cls = class_create(DEVICE_NAME);</span>
|
|
|
-<a id='x1-66165r68'></a><span class='ecrm-0500'>68</span><span id='textcolor3560'><span class='ectt-0800'>#endif</span></span>
|
|
|
+<a id='x1-66165r68'></a><span class='ecrm-0500'>68</span><span id='textcolor3562'><span class='ectt-0800'>#endif</span></span>
|
|
|
<a id='x1-66167r69'></a><span class='ecrm-0500'>69</span>
|
|
|
<a id='x1-66169r70'></a><span class='ecrm-0500'>70</span><span class='ectt-0800'> device_create(cls, NULL, MKDEV(major, 0), NULL, DEVICE_NAME);</span>
|
|
|
<a id='x1-66171r71'></a><span class='ecrm-0500'>71</span>
|
|
|
-<a id='x1-66173r72'></a><span class='ecrm-0500'>72</span><span class='ectt-0800'> pr_info(</span><span id='textcolor3561'><span class='ectt-0800'>"Device created on /dev/%s</span></span><span id='textcolor3562'><span class='ectt-0800'>\n</span></span><span id='textcolor3563'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>, DEVICE_NAME);</span>
|
|
|
+<a id='x1-66173r72'></a><span class='ecrm-0500'>72</span><span class='ectt-0800'> pr_info(</span><span id='textcolor3563'><span class='ectt-0800'>"Device created on /dev/%s</span></span><span id='textcolor3564'><span class='ectt-0800'>\n</span></span><span id='textcolor3565'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>, DEVICE_NAME);</span>
|
|
|
<a id='x1-66175r73'></a><span class='ecrm-0500'>73</span>
|
|
|
-<a id='x1-66177r74'></a><span class='ecrm-0500'>74</span><span class='ectt-0800'> </span><span id='textcolor3564'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> SUCCESS;</span>
|
|
|
+<a id='x1-66177r74'></a><span class='ecrm-0500'>74</span><span class='ectt-0800'> </span><span id='textcolor3566'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> SUCCESS;</span>
|
|
|
<a id='x1-66179r75'></a><span class='ecrm-0500'>75</span><span class='ectt-0800'>}</span>
|
|
|
<a id='x1-66181r76'></a><span class='ecrm-0500'>76</span>
|
|
|
-<a id='x1-66183r77'></a><span class='ecrm-0500'>77</span><span id='textcolor3565'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3566'><span class='ectt-0800'>void</span></span><span class='ectt-0800'> __exit chardev_exit(</span><span id='textcolor3567'><span class='ectt-0800'>void</span></span><span class='ectt-0800'>)</span>
|
|
|
+<a id='x1-66183r77'></a><span class='ecrm-0500'>77</span><span id='textcolor3567'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3568'><span class='ectt-0800'>void</span></span><span class='ectt-0800'> __exit chardev_exit(</span><span id='textcolor3569'><span class='ectt-0800'>void</span></span><span class='ectt-0800'>)</span>
|
|
|
<a id='x1-66185r78'></a><span class='ecrm-0500'>78</span><span class='ectt-0800'>{</span>
|
|
|
<a id='x1-66187r79'></a><span class='ecrm-0500'>79</span><span class='ectt-0800'> device_destroy(cls, MKDEV(major, 0));</span>
|
|
|
<a id='x1-66189r80'></a><span class='ecrm-0500'>80</span><span class='ectt-0800'> class_destroy(cls);</span>
|
|
|
<a id='x1-66191r81'></a><span class='ecrm-0500'>81</span>
|
|
|
-<a id='x1-66193r82'></a><span class='ecrm-0500'>82</span><span class='ectt-0800'> </span><span id='textcolor3568'><span class='ectt-0800'>/* Unregister the device */</span></span>
|
|
|
+<a id='x1-66193r82'></a><span class='ecrm-0500'>82</span><span class='ectt-0800'> </span><span id='textcolor3570'><span class='ectt-0800'>/* Unregister the device */</span></span>
|
|
|
<a id='x1-66195r83'></a><span class='ecrm-0500'>83</span><span class='ectt-0800'> unregister_chrdev(major, DEVICE_NAME);</span>
|
|
|
<a id='x1-66197r84'></a><span class='ecrm-0500'>84</span><span class='ectt-0800'>}</span>
|
|
|
<a id='x1-66199r85'></a><span class='ecrm-0500'>85</span>
|
|
|
-<a id='x1-66201r86'></a><span class='ecrm-0500'>86</span><span id='textcolor3569'><span class='ectt-0800'>/* Methods */</span></span>
|
|
|
+<a id='x1-66201r86'></a><span class='ecrm-0500'>86</span><span id='textcolor3571'><span class='ectt-0800'>/* Methods */</span></span>
|
|
|
<a id='x1-66203r87'></a><span class='ecrm-0500'>87</span>
|
|
|
-<a id='x1-66205r88'></a><span class='ecrm-0500'>88</span><span id='textcolor3570'><span class='ectt-0800'>/**</span></span>
|
|
|
-<a id='x1-66207r89'></a><span class='ecrm-0500'>89</span><span id='textcolor3571'><span class='ectt-0800'> * Called when a process tried to open the device file, like</span></span>
|
|
|
-<a id='x1-66209r90'></a><span class='ecrm-0500'>90</span><span id='textcolor3572'><span class='ectt-0800'> * cat /dev/key_state</span></span>
|
|
|
-<a id='x1-66211r91'></a><span class='ecrm-0500'>91</span><span id='textcolor3573'><span class='ectt-0800'> */</span></span>
|
|
|
-<a id='x1-66213r92'></a><span class='ecrm-0500'>92</span><span id='textcolor3574'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3575'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> device_open(</span><span id='textcolor3576'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> inode *inode, </span><span id='textcolor3577'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> file *file)</span>
|
|
|
+<a id='x1-66205r88'></a><span class='ecrm-0500'>88</span><span id='textcolor3572'><span class='ectt-0800'>/**</span></span>
|
|
|
+<a id='x1-66207r89'></a><span class='ecrm-0500'>89</span><span id='textcolor3573'><span class='ectt-0800'> * Called when a process tried to open the device file, like</span></span>
|
|
|
+<a id='x1-66209r90'></a><span class='ecrm-0500'>90</span><span id='textcolor3574'><span class='ectt-0800'> * cat /dev/key_state</span></span>
|
|
|
+<a id='x1-66211r91'></a><span class='ecrm-0500'>91</span><span id='textcolor3575'><span class='ectt-0800'> */</span></span>
|
|
|
+<a id='x1-66213r92'></a><span class='ecrm-0500'>92</span><span id='textcolor3576'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3577'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> device_open(</span><span id='textcolor3578'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> inode *inode, </span><span id='textcolor3579'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> file *file)</span>
|
|
|
<a id='x1-66215r93'></a><span class='ecrm-0500'>93</span><span class='ectt-0800'>{</span>
|
|
|
-<a id='x1-66217r94'></a><span class='ecrm-0500'>94</span><span class='ectt-0800'> </span><span id='textcolor3578'><span class='ectt-0800'>if</span></span><span class='ectt-0800'> (atomic_cmpxchg(&already_open, CDEV_NOT_USED, CDEV_EXCLUSIVE_OPEN))</span>
|
|
|
-<a id='x1-66219r95'></a><span class='ecrm-0500'>95</span><span class='ectt-0800'> </span><span id='textcolor3579'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> -EBUSY;</span>
|
|
|
+<a id='x1-66217r94'></a><span class='ecrm-0500'>94</span><span class='ectt-0800'> </span><span id='textcolor3580'><span class='ectt-0800'>if</span></span><span class='ectt-0800'> (atomic_cmpxchg(&already_open, CDEV_NOT_USED, CDEV_EXCLUSIVE_OPEN))</span>
|
|
|
+<a id='x1-66219r95'></a><span class='ecrm-0500'>95</span><span class='ectt-0800'> </span><span id='textcolor3581'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> -EBUSY;</span>
|
|
|
<a id='x1-66221r96'></a><span class='ecrm-0500'>96</span>
|
|
|
-<a id='x1-66223r97'></a><span class='ecrm-0500'>97</span><span class='ectt-0800'> sprintf(msg, static_key_enabled(&fkey) ? </span><span id='textcolor3580'><span class='ectt-0800'>"enabled</span></span><span id='textcolor3581'><span class='ectt-0800'>\n</span></span><span id='textcolor3582'><span class='ectt-0800'>"</span></span><span class='ectt-0800'> : </span><span id='textcolor3583'><span class='ectt-0800'>"disabled</span></span><span id='textcolor3584'><span class='ectt-0800'>\n</span></span><span id='textcolor3585'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>);</span>
|
|
|
+<a id='x1-66223r97'></a><span class='ecrm-0500'>97</span><span class='ectt-0800'> sprintf(msg, static_key_enabled(&fkey) ? </span><span id='textcolor3582'><span class='ectt-0800'>"enabled</span></span><span id='textcolor3583'><span class='ectt-0800'>\n</span></span><span id='textcolor3584'><span class='ectt-0800'>"</span></span><span class='ectt-0800'> : </span><span id='textcolor3585'><span class='ectt-0800'>"disabled</span></span><span id='textcolor3586'><span class='ectt-0800'>\n</span></span><span id='textcolor3587'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>);</span>
|
|
|
<a id='x1-66225r98'></a><span class='ecrm-0500'>98</span>
|
|
|
-<a id='x1-66227r99'></a><span class='ecrm-0500'>99</span><span class='ectt-0800'> pr_info(</span><span id='textcolor3586'><span class='ectt-0800'>"fastpath 1</span></span><span id='textcolor3587'><span class='ectt-0800'>\n</span></span><span id='textcolor3588'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>);</span>
|
|
|
-<a id='x1-66229r100'></a><span class='ecrm-0500'>100</span><span class='ectt-0800'> </span><span id='textcolor3589'><span class='ectt-0800'>if</span></span><span class='ectt-0800'> (static_branch_unlikely(&fkey))</span>
|
|
|
-<a id='x1-66231r101'></a><span class='ecrm-0500'>101</span><span class='ectt-0800'> pr_alert(</span><span id='textcolor3590'><span class='ectt-0800'>"do unlikely thing</span></span><span id='textcolor3591'><span class='ectt-0800'>\n</span></span><span id='textcolor3592'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>);</span>
|
|
|
-<a id='x1-66233r102'></a><span class='ecrm-0500'>102</span><span class='ectt-0800'> pr_info(</span><span id='textcolor3593'><span class='ectt-0800'>"fastpath 2</span></span><span id='textcolor3594'><span class='ectt-0800'>\n</span></span><span id='textcolor3595'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>);</span>
|
|
|
+<a id='x1-66227r99'></a><span class='ecrm-0500'>99</span><span class='ectt-0800'> pr_info(</span><span id='textcolor3588'><span class='ectt-0800'>"fastpath 1</span></span><span id='textcolor3589'><span class='ectt-0800'>\n</span></span><span id='textcolor3590'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>);</span>
|
|
|
+<a id='x1-66229r100'></a><span class='ecrm-0500'>100</span><span class='ectt-0800'> </span><span id='textcolor3591'><span class='ectt-0800'>if</span></span><span class='ectt-0800'> (static_branch_unlikely(&fkey))</span>
|
|
|
+<a id='x1-66231r101'></a><span class='ecrm-0500'>101</span><span class='ectt-0800'> pr_alert(</span><span id='textcolor3592'><span class='ectt-0800'>"do unlikely thing</span></span><span id='textcolor3593'><span class='ectt-0800'>\n</span></span><span id='textcolor3594'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>);</span>
|
|
|
+<a id='x1-66233r102'></a><span class='ecrm-0500'>102</span><span class='ectt-0800'> pr_info(</span><span id='textcolor3595'><span class='ectt-0800'>"fastpath 2</span></span><span id='textcolor3596'><span class='ectt-0800'>\n</span></span><span id='textcolor3597'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>);</span>
|
|
|
<a id='x1-66235r103'></a><span class='ecrm-0500'>103</span>
|
|
|
<a id='x1-66237r104'></a><span class='ecrm-0500'>104</span><span class='ectt-0800'> try_module_get(THIS_MODULE);</span>
|
|
|
<a id='x1-66239r105'></a><span class='ecrm-0500'>105</span>
|
|
|
-<a id='x1-66241r106'></a><span class='ecrm-0500'>106</span><span class='ectt-0800'> </span><span id='textcolor3596'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> SUCCESS;</span>
|
|
|
+<a id='x1-66241r106'></a><span class='ecrm-0500'>106</span><span class='ectt-0800'> </span><span id='textcolor3598'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> SUCCESS;</span>
|
|
|
<a id='x1-66243r107'></a><span class='ecrm-0500'>107</span><span class='ectt-0800'>}</span>
|
|
|
<a id='x1-66245r108'></a><span class='ecrm-0500'>108</span>
|
|
|
-<a id='x1-66247r109'></a><span class='ecrm-0500'>109</span><span id='textcolor3597'><span class='ectt-0800'>/**</span></span>
|
|
|
-<a id='x1-66249r110'></a><span class='ecrm-0500'>110</span><span id='textcolor3598'><span class='ectt-0800'> * Called when a process closes the device file</span></span>
|
|
|
-<a id='x1-66251r111'></a><span class='ecrm-0500'>111</span><span id='textcolor3599'><span class='ectt-0800'> */</span></span>
|
|
|
-<a id='x1-66253r112'></a><span class='ecrm-0500'>112</span><span id='textcolor3600'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3601'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> device_release(</span><span id='textcolor3602'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> inode *inode, </span><span id='textcolor3603'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> file *file)</span>
|
|
|
+<a id='x1-66247r109'></a><span class='ecrm-0500'>109</span><span id='textcolor3599'><span class='ectt-0800'>/**</span></span>
|
|
|
+<a id='x1-66249r110'></a><span class='ecrm-0500'>110</span><span id='textcolor3600'><span class='ectt-0800'> * Called when a process closes the device file</span></span>
|
|
|
+<a id='x1-66251r111'></a><span class='ecrm-0500'>111</span><span id='textcolor3601'><span class='ectt-0800'> */</span></span>
|
|
|
+<a id='x1-66253r112'></a><span class='ecrm-0500'>112</span><span id='textcolor3602'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3603'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> device_release(</span><span id='textcolor3604'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> inode *inode, </span><span id='textcolor3605'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> file *file)</span>
|
|
|
<a id='x1-66255r113'></a><span class='ecrm-0500'>113</span><span class='ectt-0800'>{</span>
|
|
|
-<a id='x1-66257r114'></a><span class='ecrm-0500'>114</span><span class='ectt-0800'> </span><span id='textcolor3604'><span class='ectt-0800'>/* We are now ready for our next caller. */</span></span>
|
|
|
+<a id='x1-66257r114'></a><span class='ecrm-0500'>114</span><span class='ectt-0800'> </span><span id='textcolor3606'><span class='ectt-0800'>/* We are now ready for our next caller. */</span></span>
|
|
|
<a id='x1-66259r115'></a><span class='ecrm-0500'>115</span><span class='ectt-0800'> atomic_set(&already_open, CDEV_NOT_USED);</span>
|
|
|
<a id='x1-66261r116'></a><span class='ecrm-0500'>116</span>
|
|
|
-<a id='x1-66263r117'></a><span class='ecrm-0500'>117</span><span class='ectt-0800'> </span><span id='textcolor3605'><span class='ectt-0800'>/**</span></span>
|
|
|
-<a id='x1-66265r118'></a><span class='ecrm-0500'>118</span><span id='textcolor3606'><span class='ectt-0800'> * Decrement the usage count, or else once you opened the file, you will</span></span>
|
|
|
-<a id='x1-66267r119'></a><span class='ecrm-0500'>119</span><span id='textcolor3607'><span class='ectt-0800'> * never get rid of the module.</span></span>
|
|
|
-<a id='x1-66269r120'></a><span class='ecrm-0500'>120</span><span id='textcolor3608'><span class='ectt-0800'> */</span></span>
|
|
|
+<a id='x1-66263r117'></a><span class='ecrm-0500'>117</span><span class='ectt-0800'> </span><span id='textcolor3607'><span class='ectt-0800'>/**</span></span>
|
|
|
+<a id='x1-66265r118'></a><span class='ecrm-0500'>118</span><span id='textcolor3608'><span class='ectt-0800'> * Decrement the usage count, or else once you opened the file, you will</span></span>
|
|
|
+<a id='x1-66267r119'></a><span class='ecrm-0500'>119</span><span id='textcolor3609'><span class='ectt-0800'> * never get rid of the module.</span></span>
|
|
|
+<a id='x1-66269r120'></a><span class='ecrm-0500'>120</span><span id='textcolor3610'><span class='ectt-0800'> */</span></span>
|
|
|
<a id='x1-66271r121'></a><span class='ecrm-0500'>121</span><span class='ectt-0800'> module_put(THIS_MODULE);</span>
|
|
|
<a id='x1-66273r122'></a><span class='ecrm-0500'>122</span>
|
|
|
-<a id='x1-66275r123'></a><span class='ecrm-0500'>123</span><span class='ectt-0800'> </span><span id='textcolor3609'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> SUCCESS;</span>
|
|
|
+<a id='x1-66275r123'></a><span class='ecrm-0500'>123</span><span class='ectt-0800'> </span><span id='textcolor3611'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> SUCCESS;</span>
|
|
|
<a id='x1-66277r124'></a><span class='ecrm-0500'>124</span><span class='ectt-0800'>}</span>
|
|
|
<a id='x1-66279r125'></a><span class='ecrm-0500'>125</span>
|
|
|
-<a id='x1-66281r126'></a><span class='ecrm-0500'>126</span><span id='textcolor3610'><span class='ectt-0800'>/**</span></span>
|
|
|
-<a id='x1-66283r127'></a><span class='ecrm-0500'>127</span><span id='textcolor3611'><span class='ectt-0800'> * Called when a process, which already opened the dev file, attempts to</span></span>
|
|
|
-<a id='x1-66285r128'></a><span class='ecrm-0500'>128</span><span id='textcolor3612'><span class='ectt-0800'> * read from it.</span></span>
|
|
|
-<a id='x1-66287r129'></a><span class='ecrm-0500'>129</span><span id='textcolor3613'><span class='ectt-0800'> */</span></span>
|
|
|
-<a id='x1-66289r130'></a><span class='ecrm-0500'>130</span><span id='textcolor3614'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3615'><span class='ectt-0800'>ssize_t</span></span><span class='ectt-0800'> device_read(</span><span id='textcolor3616'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> file *filp, </span><span id='textcolor3617'><span class='ectt-0800'>/* see include/linux/fs.h */</span></span>
|
|
|
-<a id='x1-66291r131'></a><span class='ecrm-0500'>131</span><span class='ectt-0800'> </span><span id='textcolor3618'><span class='ectt-0800'>char</span></span><span class='ectt-0800'> __user *buffer, </span><span id='textcolor3619'><span class='ectt-0800'>/* buffer to fill with data */</span></span>
|
|
|
-<a id='x1-66293r132'></a><span class='ecrm-0500'>132</span><span class='ectt-0800'> </span><span id='textcolor3620'><span class='ectt-0800'>size_t</span></span><span class='ectt-0800'> length, </span><span id='textcolor3621'><span class='ectt-0800'>/* length of the buffer */</span></span>
|
|
|
+<a id='x1-66281r126'></a><span class='ecrm-0500'>126</span><span id='textcolor3612'><span class='ectt-0800'>/**</span></span>
|
|
|
+<a id='x1-66283r127'></a><span class='ecrm-0500'>127</span><span id='textcolor3613'><span class='ectt-0800'> * Called when a process, which already opened the dev file, attempts to</span></span>
|
|
|
+<a id='x1-66285r128'></a><span class='ecrm-0500'>128</span><span id='textcolor3614'><span class='ectt-0800'> * read from it.</span></span>
|
|
|
+<a id='x1-66287r129'></a><span class='ecrm-0500'>129</span><span id='textcolor3615'><span class='ectt-0800'> */</span></span>
|
|
|
+<a id='x1-66289r130'></a><span class='ecrm-0500'>130</span><span id='textcolor3616'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3617'><span class='ectt-0800'>ssize_t</span></span><span class='ectt-0800'> device_read(</span><span id='textcolor3618'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> file *filp, </span><span id='textcolor3619'><span class='ectt-0800'>/* see include/linux/fs.h */</span></span>
|
|
|
+<a id='x1-66291r131'></a><span class='ecrm-0500'>131</span><span class='ectt-0800'> </span><span id='textcolor3620'><span class='ectt-0800'>char</span></span><span class='ectt-0800'> __user *buffer, </span><span id='textcolor3621'><span class='ectt-0800'>/* buffer to fill with data */</span></span>
|
|
|
+<a id='x1-66293r132'></a><span class='ecrm-0500'>132</span><span class='ectt-0800'> </span><span id='textcolor3622'><span class='ectt-0800'>size_t</span></span><span class='ectt-0800'> length, </span><span id='textcolor3623'><span class='ectt-0800'>/* length of the buffer */</span></span>
|
|
|
<a id='x1-66295r133'></a><span class='ecrm-0500'>133</span><span class='ectt-0800'> loff_t *offset)</span>
|
|
|
<a id='x1-66297r134'></a><span class='ecrm-0500'>134</span><span class='ectt-0800'>{</span>
|
|
|
-<a id='x1-66299r135'></a><span class='ecrm-0500'>135</span><span class='ectt-0800'> </span><span id='textcolor3622'><span class='ectt-0800'>/* Number of the bytes actually written to the buffer */</span></span>
|
|
|
-<a id='x1-66301r136'></a><span class='ecrm-0500'>136</span><span class='ectt-0800'> </span><span id='textcolor3623'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> bytes_read = 0;</span>
|
|
|
-<a id='x1-66303r137'></a><span class='ecrm-0500'>137</span><span class='ectt-0800'> </span><span id='textcolor3624'><span class='ectt-0800'>const</span></span><span class='ectt-0800'> </span><span id='textcolor3625'><span class='ectt-0800'>char</span></span><span class='ectt-0800'> *msg_ptr = msg;</span>
|
|
|
+<a id='x1-66299r135'></a><span class='ecrm-0500'>135</span><span class='ectt-0800'> </span><span id='textcolor3624'><span class='ectt-0800'>/* Number of the bytes actually written to the buffer */</span></span>
|
|
|
+<a id='x1-66301r136'></a><span class='ecrm-0500'>136</span><span class='ectt-0800'> </span><span id='textcolor3625'><span class='ectt-0800'>int</span></span><span class='ectt-0800'> bytes_read = 0;</span>
|
|
|
+<a id='x1-66303r137'></a><span class='ecrm-0500'>137</span><span class='ectt-0800'> </span><span id='textcolor3626'><span class='ectt-0800'>const</span></span><span class='ectt-0800'> </span><span id='textcolor3627'><span class='ectt-0800'>char</span></span><span class='ectt-0800'> *msg_ptr = msg;</span>
|
|
|
<a id='x1-66305r138'></a><span class='ecrm-0500'>138</span>
|
|
|
-<a id='x1-66307r139'></a><span class='ecrm-0500'>139</span><span class='ectt-0800'> </span><span id='textcolor3626'><span class='ectt-0800'>if</span></span><span class='ectt-0800'> (!*(msg_ptr + *offset)) { </span><span id='textcolor3627'><span class='ectt-0800'>/* We are at the end of the message */</span></span>
|
|
|
-<a id='x1-66309r140'></a><span class='ecrm-0500'>140</span><span class='ectt-0800'> *offset = 0; </span><span id='textcolor3628'><span class='ectt-0800'>/* reset the offset */</span></span>
|
|
|
-<a id='x1-66311r141'></a><span class='ecrm-0500'>141</span><span class='ectt-0800'> </span><span id='textcolor3629'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> 0; </span><span id='textcolor3630'><span class='ectt-0800'>/* signify end of file */</span></span>
|
|
|
+<a id='x1-66307r139'></a><span class='ecrm-0500'>139</span><span class='ectt-0800'> </span><span id='textcolor3628'><span class='ectt-0800'>if</span></span><span class='ectt-0800'> (!*(msg_ptr + *offset)) { </span><span id='textcolor3629'><span class='ectt-0800'>/* We are at the end of the message */</span></span>
|
|
|
+<a id='x1-66309r140'></a><span class='ecrm-0500'>140</span><span class='ectt-0800'> *offset = 0; </span><span id='textcolor3630'><span class='ectt-0800'>/* reset the offset */</span></span>
|
|
|
+<a id='x1-66311r141'></a><span class='ecrm-0500'>141</span><span class='ectt-0800'> </span><span id='textcolor3631'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> 0; </span><span id='textcolor3632'><span class='ectt-0800'>/* signify end of file */</span></span>
|
|
|
<a id='x1-66313r142'></a><span class='ecrm-0500'>142</span><span class='ectt-0800'> }</span>
|
|
|
<a id='x1-66315r143'></a><span class='ecrm-0500'>143</span>
|
|
|
<a id='x1-66317r144'></a><span class='ecrm-0500'>144</span><span class='ectt-0800'> msg_ptr += *offset;</span>
|
|
|
<a id='x1-66319r145'></a><span class='ecrm-0500'>145</span>
|
|
|
-<a id='x1-66321r146'></a><span class='ecrm-0500'>146</span><span class='ectt-0800'> </span><span id='textcolor3631'><span class='ectt-0800'>/* Actually put the data into the buffer */</span></span>
|
|
|
-<a id='x1-66323r147'></a><span class='ecrm-0500'>147</span><span class='ectt-0800'> </span><span id='textcolor3632'><span class='ectt-0800'>while</span></span><span class='ectt-0800'> (length && *msg_ptr) {</span>
|
|
|
-<a id='x1-66325r148'></a><span class='ecrm-0500'>148</span><span class='ectt-0800'> </span><span id='textcolor3633'><span class='ectt-0800'>/**</span></span>
|
|
|
-<a id='x1-66327r149'></a><span class='ecrm-0500'>149</span><span id='textcolor3634'><span class='ectt-0800'> * The buffer is in the user data segment, not the kernel</span></span>
|
|
|
-<a id='x1-66329r150'></a><span class='ecrm-0500'>150</span><span id='textcolor3635'><span class='ectt-0800'> * segment so "*" assignment won</span><span class='tctt-0800'>'</span><span class='ectt-0800'>t work. We have to use</span></span>
|
|
|
-<a id='x1-66331r151'></a><span class='ecrm-0500'>151</span><span id='textcolor3636'><span class='ectt-0800'> * put_user which copies data from the kernel data segment to</span></span>
|
|
|
-<a id='x1-66333r152'></a><span class='ecrm-0500'>152</span><span id='textcolor3637'><span class='ectt-0800'> * the user data segment.</span></span>
|
|
|
-<a id='x1-66335r153'></a><span class='ecrm-0500'>153</span><span id='textcolor3638'><span class='ectt-0800'> */</span></span>
|
|
|
+<a id='x1-66321r146'></a><span class='ecrm-0500'>146</span><span class='ectt-0800'> </span><span id='textcolor3633'><span class='ectt-0800'>/* Actually put the data into the buffer */</span></span>
|
|
|
+<a id='x1-66323r147'></a><span class='ecrm-0500'>147</span><span class='ectt-0800'> </span><span id='textcolor3634'><span class='ectt-0800'>while</span></span><span class='ectt-0800'> (length && *msg_ptr) {</span>
|
|
|
+<a id='x1-66325r148'></a><span class='ecrm-0500'>148</span><span class='ectt-0800'> </span><span id='textcolor3635'><span class='ectt-0800'>/**</span></span>
|
|
|
+<a id='x1-66327r149'></a><span class='ecrm-0500'>149</span><span id='textcolor3636'><span class='ectt-0800'> * The buffer is in the user data segment, not the kernel</span></span>
|
|
|
+<a id='x1-66329r150'></a><span class='ecrm-0500'>150</span><span id='textcolor3637'><span class='ectt-0800'> * segment so "*" assignment won</span><span class='tctt-0800'>'</span><span class='ectt-0800'>t work. We have to use</span></span>
|
|
|
+<a id='x1-66331r151'></a><span class='ecrm-0500'>151</span><span id='textcolor3638'><span class='ectt-0800'> * put_user which copies data from the kernel data segment to</span></span>
|
|
|
+<a id='x1-66333r152'></a><span class='ecrm-0500'>152</span><span id='textcolor3639'><span class='ectt-0800'> * the user data segment.</span></span>
|
|
|
+<a id='x1-66335r153'></a><span class='ecrm-0500'>153</span><span id='textcolor3640'><span class='ectt-0800'> */</span></span>
|
|
|
<a id='x1-66337r154'></a><span class='ecrm-0500'>154</span><span class='ectt-0800'> put_user(*(msg_ptr++), buffer++);</span>
|
|
|
<a id='x1-66339r155'></a><span class='ecrm-0500'>155</span><span class='ectt-0800'> length--;</span>
|
|
|
<a id='x1-66341r156'></a><span class='ecrm-0500'>156</span><span class='ectt-0800'> bytes_read++;</span>
|
|
@@ -6733,41 +6735,41 @@ static key works.
|
|
|
<a id='x1-66345r158'></a><span class='ecrm-0500'>158</span>
|
|
|
<a id='x1-66347r159'></a><span class='ecrm-0500'>159</span><span class='ectt-0800'> *offset += bytes_read;</span>
|
|
|
<a id='x1-66349r160'></a><span class='ecrm-0500'>160</span>
|
|
|
-<a id='x1-66351r161'></a><span class='ecrm-0500'>161</span><span class='ectt-0800'> </span><span id='textcolor3639'><span class='ectt-0800'>/* Most read functions return the number of bytes put into the buffer. */</span></span>
|
|
|
-<a id='x1-66353r162'></a><span class='ecrm-0500'>162</span><span class='ectt-0800'> </span><span id='textcolor3640'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> bytes_read;</span>
|
|
|
+<a id='x1-66351r161'></a><span class='ecrm-0500'>161</span><span class='ectt-0800'> </span><span id='textcolor3641'><span class='ectt-0800'>/* Most read functions return the number of bytes put into the buffer. */</span></span>
|
|
|
+<a id='x1-66353r162'></a><span class='ecrm-0500'>162</span><span class='ectt-0800'> </span><span id='textcolor3642'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> bytes_read;</span>
|
|
|
<a id='x1-66355r163'></a><span class='ecrm-0500'>163</span><span class='ectt-0800'>}</span>
|
|
|
<a id='x1-66357r164'></a><span class='ecrm-0500'>164</span>
|
|
|
-<a id='x1-66359r165'></a><span class='ecrm-0500'>165</span><span id='textcolor3641'><span class='ectt-0800'>/* Called when a process writes to dev file; echo "enable" > /dev/key_state */</span></span>
|
|
|
-<a id='x1-66361r166'></a><span class='ecrm-0500'>166</span><span id='textcolor3642'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3643'><span class='ectt-0800'>ssize_t</span></span><span class='ectt-0800'> device_write(</span><span id='textcolor3644'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> file *filp, </span><span id='textcolor3645'><span class='ectt-0800'>const</span></span><span class='ectt-0800'> </span><span id='textcolor3646'><span class='ectt-0800'>char</span></span><span class='ectt-0800'> __user *buffer,</span>
|
|
|
-<a id='x1-66363r167'></a><span class='ecrm-0500'>167</span><span class='ectt-0800'> </span><span id='textcolor3647'><span class='ectt-0800'>size_t</span></span><span class='ectt-0800'> length, loff_t *offset)</span>
|
|
|
+<a id='x1-66359r165'></a><span class='ecrm-0500'>165</span><span id='textcolor3643'><span class='ectt-0800'>/* Called when a process writes to dev file; echo "enable" > /dev/key_state */</span></span>
|
|
|
+<a id='x1-66361r166'></a><span class='ecrm-0500'>166</span><span id='textcolor3644'><span class='ectt-0800'>static</span></span><span class='ectt-0800'> </span><span id='textcolor3645'><span class='ectt-0800'>ssize_t</span></span><span class='ectt-0800'> device_write(</span><span id='textcolor3646'><span class='ectt-0800'>struct</span></span><span class='ectt-0800'> file *filp, </span><span id='textcolor3647'><span class='ectt-0800'>const</span></span><span class='ectt-0800'> </span><span id='textcolor3648'><span class='ectt-0800'>char</span></span><span class='ectt-0800'> __user *buffer,</span>
|
|
|
+<a id='x1-66363r167'></a><span class='ecrm-0500'>167</span><span class='ectt-0800'> </span><span id='textcolor3649'><span class='ectt-0800'>size_t</span></span><span class='ectt-0800'> length, loff_t *offset)</span>
|
|
|
<a id='x1-66365r168'></a><span class='ecrm-0500'>168</span><span class='ectt-0800'>{</span>
|
|
|
-<a id='x1-66367r169'></a><span class='ecrm-0500'>169</span><span class='ectt-0800'> </span><span id='textcolor3648'><span class='ectt-0800'>char</span></span><span class='ectt-0800'> command[10];</span>
|
|
|
+<a id='x1-66367r169'></a><span class='ecrm-0500'>169</span><span class='ectt-0800'> </span><span id='textcolor3650'><span class='ectt-0800'>char</span></span><span class='ectt-0800'> command[10];</span>
|
|
|
<a id='x1-66369r170'></a><span class='ecrm-0500'>170</span>
|
|
|
-<a id='x1-66371r171'></a><span class='ecrm-0500'>171</span><span class='ectt-0800'> </span><span id='textcolor3649'><span class='ectt-0800'>if</span></span><span class='ectt-0800'> (length > 10) {</span>
|
|
|
-<a id='x1-66373r172'></a><span class='ecrm-0500'>172</span><span class='ectt-0800'> pr_err(</span><span id='textcolor3650'><span class='ectt-0800'>"command exceeded 10 char</span></span><span id='textcolor3651'><span class='ectt-0800'>\n</span></span><span id='textcolor3652'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>);</span>
|
|
|
-<a id='x1-66375r173'></a><span class='ecrm-0500'>173</span><span class='ectt-0800'> </span><span id='textcolor3653'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> -EINVAL;</span>
|
|
|
+<a id='x1-66371r171'></a><span class='ecrm-0500'>171</span><span class='ectt-0800'> </span><span id='textcolor3651'><span class='ectt-0800'>if</span></span><span class='ectt-0800'> (length > 10) {</span>
|
|
|
+<a id='x1-66373r172'></a><span class='ecrm-0500'>172</span><span class='ectt-0800'> pr_err(</span><span id='textcolor3652'><span class='ectt-0800'>"command exceeded 10 char</span></span><span id='textcolor3653'><span class='ectt-0800'>\n</span></span><span id='textcolor3654'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>);</span>
|
|
|
+<a id='x1-66375r173'></a><span class='ecrm-0500'>173</span><span class='ectt-0800'> </span><span id='textcolor3655'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> -EINVAL;</span>
|
|
|
<a id='x1-66377r174'></a><span class='ecrm-0500'>174</span><span class='ectt-0800'> }</span>
|
|
|
<a id='x1-66379r175'></a><span class='ecrm-0500'>175</span>
|
|
|
-<a id='x1-66381r176'></a><span class='ecrm-0500'>176</span><span class='ectt-0800'> </span><span id='textcolor3654'><span class='ectt-0800'>if</span></span><span class='ectt-0800'> (copy_from_user(command, buffer, length))</span>
|
|
|
-<a id='x1-66383r177'></a><span class='ecrm-0500'>177</span><span class='ectt-0800'> </span><span id='textcolor3655'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> -EFAULT;</span>
|
|
|
+<a id='x1-66381r176'></a><span class='ecrm-0500'>176</span><span class='ectt-0800'> </span><span id='textcolor3656'><span class='ectt-0800'>if</span></span><span class='ectt-0800'> (copy_from_user(command, buffer, length))</span>
|
|
|
+<a id='x1-66383r177'></a><span class='ecrm-0500'>177</span><span class='ectt-0800'> </span><span id='textcolor3657'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> -EFAULT;</span>
|
|
|
<a id='x1-66385r178'></a><span class='ecrm-0500'>178</span>
|
|
|
-<a id='x1-66387r179'></a><span class='ecrm-0500'>179</span><span class='ectt-0800'> </span><span id='textcolor3656'><span class='ectt-0800'>if</span></span><span class='ectt-0800'> (strncmp(command, </span><span id='textcolor3657'><span class='ectt-0800'>"enable"</span></span><span class='ectt-0800'>, strlen(</span><span id='textcolor3658'><span class='ectt-0800'>"enable"</span></span><span class='ectt-0800'>)) == 0)</span>
|
|
|
+<a id='x1-66387r179'></a><span class='ecrm-0500'>179</span><span class='ectt-0800'> </span><span id='textcolor3658'><span class='ectt-0800'>if</span></span><span class='ectt-0800'> (strncmp(command, </span><span id='textcolor3659'><span class='ectt-0800'>"enable"</span></span><span class='ectt-0800'>, strlen(</span><span id='textcolor3660'><span class='ectt-0800'>"enable"</span></span><span class='ectt-0800'>)) == 0)</span>
|
|
|
<a id='x1-66389r180'></a><span class='ecrm-0500'>180</span><span class='ectt-0800'> static_branch_enable(&fkey);</span>
|
|
|
-<a id='x1-66391r181'></a><span class='ecrm-0500'>181</span><span class='ectt-0800'> </span><span id='textcolor3659'><span class='ectt-0800'>else</span></span><span class='ectt-0800'> </span><span id='textcolor3660'><span class='ectt-0800'>if</span></span><span class='ectt-0800'> (strncmp(command, </span><span id='textcolor3661'><span class='ectt-0800'>"disable"</span></span><span class='ectt-0800'>, strlen(</span><span id='textcolor3662'><span class='ectt-0800'>"disable"</span></span><span class='ectt-0800'>)) == 0)</span>
|
|
|
+<a id='x1-66391r181'></a><span class='ecrm-0500'>181</span><span class='ectt-0800'> </span><span id='textcolor3661'><span class='ectt-0800'>else</span></span><span class='ectt-0800'> </span><span id='textcolor3662'><span class='ectt-0800'>if</span></span><span class='ectt-0800'> (strncmp(command, </span><span id='textcolor3663'><span class='ectt-0800'>"disable"</span></span><span class='ectt-0800'>, strlen(</span><span id='textcolor3664'><span class='ectt-0800'>"disable"</span></span><span class='ectt-0800'>)) == 0)</span>
|
|
|
<a id='x1-66393r182'></a><span class='ecrm-0500'>182</span><span class='ectt-0800'> static_branch_disable(&fkey);</span>
|
|
|
-<a id='x1-66395r183'></a><span class='ecrm-0500'>183</span><span class='ectt-0800'> </span><span id='textcolor3663'><span class='ectt-0800'>else</span></span><span class='ectt-0800'> {</span>
|
|
|
-<a id='x1-66397r184'></a><span class='ecrm-0500'>184</span><span class='ectt-0800'> pr_err(</span><span id='textcolor3664'><span class='ectt-0800'>"Invalid command: %s</span></span><span id='textcolor3665'><span class='ectt-0800'>\n</span></span><span id='textcolor3666'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>, command);</span>
|
|
|
-<a id='x1-66399r185'></a><span class='ecrm-0500'>185</span><span class='ectt-0800'> </span><span id='textcolor3667'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> -EINVAL;</span>
|
|
|
+<a id='x1-66395r183'></a><span class='ecrm-0500'>183</span><span class='ectt-0800'> </span><span id='textcolor3665'><span class='ectt-0800'>else</span></span><span class='ectt-0800'> {</span>
|
|
|
+<a id='x1-66397r184'></a><span class='ecrm-0500'>184</span><span class='ectt-0800'> pr_err(</span><span id='textcolor3666'><span class='ectt-0800'>"Invalid command: %s</span></span><span id='textcolor3667'><span class='ectt-0800'>\n</span></span><span id='textcolor3668'><span class='ectt-0800'>"</span></span><span class='ectt-0800'>, command);</span>
|
|
|
+<a id='x1-66399r185'></a><span class='ecrm-0500'>185</span><span class='ectt-0800'> </span><span id='textcolor3669'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> -EINVAL;</span>
|
|
|
<a id='x1-66401r186'></a><span class='ecrm-0500'>186</span><span class='ectt-0800'> }</span>
|
|
|
<a id='x1-66403r187'></a><span class='ecrm-0500'>187</span>
|
|
|
-<a id='x1-66405r188'></a><span class='ecrm-0500'>188</span><span class='ectt-0800'> </span><span id='textcolor3668'><span class='ectt-0800'>/* Again, return the number of input characters used. */</span></span>
|
|
|
-<a id='x1-66407r189'></a><span class='ecrm-0500'>189</span><span class='ectt-0800'> </span><span id='textcolor3669'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> length;</span>
|
|
|
+<a id='x1-66405r188'></a><span class='ecrm-0500'>188</span><span class='ectt-0800'> </span><span id='textcolor3670'><span class='ectt-0800'>/* Again, return the number of input characters used. */</span></span>
|
|
|
+<a id='x1-66407r189'></a><span class='ecrm-0500'>189</span><span class='ectt-0800'> </span><span id='textcolor3671'><span class='ectt-0800'>return</span></span><span class='ectt-0800'> length;</span>
|
|
|
<a id='x1-66409r190'></a><span class='ecrm-0500'>190</span><span class='ectt-0800'>}</span>
|
|
|
<a id='x1-66411r191'></a><span class='ecrm-0500'>191</span>
|
|
|
<a id='x1-66413r192'></a><span class='ecrm-0500'>192</span><span class='ectt-0800'>module_init(chardev_init);</span>
|
|
|
<a id='x1-66415r193'></a><span class='ecrm-0500'>193</span><span class='ectt-0800'>module_exit(chardev_exit);</span>
|
|
|
<a id='x1-66417r194'></a><span class='ecrm-0500'>194</span>
|
|
|
-<a id='x1-66419r195'></a><span class='ecrm-0500'>195</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor3670'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
|
|
+<a id='x1-66419r195'></a><span class='ecrm-0500'>195</span><span class='ectt-0800'>MODULE_LICENSE(</span><span id='textcolor3672'><span class='ectt-0800'>"GPL"</span></span><span class='ectt-0800'>);</span></pre>
|
|
|
<!-- l. 2133 --><p class='indent'> To check the state of the static key, we can use the <span class='obeylines-h'><span class='verb'><span class='ectt-1000'>/dev/key_state</span></span></span>
|
|
|
interface.
|
|
|
</p><!-- l. 1 --><p class='indent'>
|