1141cc406Sopenharmony_ci/* @file plustek-pp_procfs.c
2141cc406Sopenharmony_ci * @brief this is the interface to the proc filesystem
3141cc406Sopenharmony_ci *
4141cc406Sopenharmony_ci * Copyright (C) 2000-2013 Gerhard Jaeger <gerhard@gjaeger.de>
5141cc406Sopenharmony_ci *
6141cc406Sopenharmony_ci * History:
7141cc406Sopenharmony_ci * - 0.37 - initial version
8141cc406Sopenharmony_ci * - 0.38 - changes according to generic structure changes
9141cc406Sopenharmony_ci * - 0.39 - added info about forceMode and slowIO
10141cc406Sopenharmony_ci * - 0.40 - no changes
11141cc406Sopenharmony_ci * - 0.41 - no changes
12141cc406Sopenharmony_ci * - 0.42 - changed include names
13141cc406Sopenharmony_ci * - 0.43 - replace _PTDRV_VERx by _PTDRV_VERSTR
14141cc406Sopenharmony_ci *        - cleanup
15141cc406Sopenharmony_ci * - 0.44 - PROC_FS changes for newer kernel
16141cc406Sopenharmony_ci *        - fix format string issues, as Long types default to int32_t
17141cc406Sopenharmony_ci *          now
18141cc406Sopenharmony_ci * .
19141cc406Sopenharmony_ci * <hr>
20141cc406Sopenharmony_ci * This file is part of the SANE package.
21141cc406Sopenharmony_ci *
22141cc406Sopenharmony_ci * This program is free software; you can redistribute it and/or
23141cc406Sopenharmony_ci * modify it under the terms of the GNU General Public License as
24141cc406Sopenharmony_ci * published by the Free Software Foundation; either version 2 of the
25141cc406Sopenharmony_ci * License, or (at your option) any later version.
26141cc406Sopenharmony_ci *
27141cc406Sopenharmony_ci * This program is distributed in the hope that it will be useful, but
28141cc406Sopenharmony_ci * WITHOUT ANY WARRANTY; without even the implied warranty of
29141cc406Sopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
30141cc406Sopenharmony_ci * General Public License for more details.
31141cc406Sopenharmony_ci *
32141cc406Sopenharmony_ci * You should have received a copy of the GNU General Public License
33141cc406Sopenharmony_ci * along with this program.  If not, see <https://www.gnu.org/licenses/>.
34141cc406Sopenharmony_ci *
35141cc406Sopenharmony_ci * As a special exception, the authors of SANE give permission for
36141cc406Sopenharmony_ci * additional uses of the libraries contained in this release of SANE.
37141cc406Sopenharmony_ci *
38141cc406Sopenharmony_ci * The exception is that, if you link a SANE library with other files
39141cc406Sopenharmony_ci * to produce an executable, this does not by itself cause the
40141cc406Sopenharmony_ci * resulting executable to be covered by the GNU General Public
41141cc406Sopenharmony_ci * License.  Your use of that executable is in no way restricted on
42141cc406Sopenharmony_ci * account of linking the SANE library code into it.
43141cc406Sopenharmony_ci *
44141cc406Sopenharmony_ci * This exception does not, however, invalidate any other reasons why
45141cc406Sopenharmony_ci * the executable file might be covered by the GNU General Public
46141cc406Sopenharmony_ci * License.
47141cc406Sopenharmony_ci *
48141cc406Sopenharmony_ci * If you submit changes to SANE to the maintainers to be included in
49141cc406Sopenharmony_ci * a subsequent release, you agree by submitting the changes that
50141cc406Sopenharmony_ci * those changes may be distributed with this exception intact.
51141cc406Sopenharmony_ci *
52141cc406Sopenharmony_ci * If you write modifications of your own for SANE, it is your choice
53141cc406Sopenharmony_ci * whether to permit this exception to apply to your modifications.
54141cc406Sopenharmony_ci * If you do not wish that, delete this exception notice.
55141cc406Sopenharmony_ci * <hr>
56141cc406Sopenharmony_ci */
57141cc406Sopenharmony_ci#ifdef __KERNEL__
58141cc406Sopenharmony_ci#include <linux/proc_fs.h>
59141cc406Sopenharmony_ci
60141cc406Sopenharmony_ci#include "plustek-pp_scan.h"
61141cc406Sopenharmony_ci
62141cc406Sopenharmony_ci/* toggled by your kernel configuration */
63141cc406Sopenharmony_ci#ifdef CONFIG_PROC_FS
64141cc406Sopenharmony_ci
65141cc406Sopenharmony_ci/****************************** static vars **********************************/
66141cc406Sopenharmony_ci
67141cc406Sopenharmony_ci/** for the proc filesystem
68141cc406Sopenharmony_ci */
69141cc406Sopenharmony_ci#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
70141cc406Sopenharmony_ciextern struct proc_dir_entry proc_root;
71141cc406Sopenharmony_ci#endif
72141cc406Sopenharmony_cistatic struct proc_dir_entry *base  = NULL;
73141cc406Sopenharmony_cistatic struct proc_dir_entry *binfo = NULL;
74141cc406Sopenharmony_cistatic ULong                  devcount;
75141cc406Sopenharmony_ci
76141cc406Sopenharmony_ci/** parallel port modes... */
77141cc406Sopenharmony_cistatic char *procfsPortModes[] = {
78141cc406Sopenharmony_ci	"EPP",
79141cc406Sopenharmony_ci	"SPP",
80141cc406Sopenharmony_ci	"BiDi (PS/2)",
81141cc406Sopenharmony_ci	"ECP"
82141cc406Sopenharmony_ci	"unknown",
83141cc406Sopenharmony_ci	NULL
84141cc406Sopenharmony_ci};
85141cc406Sopenharmony_ci
86141cc406Sopenharmony_ci/** CCD-Types (as for ASIC 98001 based series) */
87141cc406Sopenharmony_cistatic TabDef procfsCCDTypes98001[] = {
88141cc406Sopenharmony_ci
89141cc406Sopenharmony_ci	{ _CCD_3797, "3797" },
90141cc406Sopenharmony_ci	{ _CCD_3717, "3717" },
91141cc406Sopenharmony_ci	{ _CCD_535,  "535"  },
92141cc406Sopenharmony_ci	{ _CCD_2556, "2556" },
93141cc406Sopenharmony_ci	{ _CCD_518,  "518"  },
94141cc406Sopenharmony_ci	{ _CCD_539,  "539"  },
95141cc406Sopenharmony_ci    { -1 ,       "unknown" }
96141cc406Sopenharmony_ci};
97141cc406Sopenharmony_ci
98141cc406Sopenharmony_ci/** CCD-Types (as for ASIC 98003 based series) */
99141cc406Sopenharmony_cistatic TabDef procfsCCDTypes98003[] = {
100141cc406Sopenharmony_ci
101141cc406Sopenharmony_ci	{ _CCD_3797, "3797" },
102141cc406Sopenharmony_ci	{ _CCD_3799, "3799" },
103141cc406Sopenharmony_ci	{ _CCD_535,  "535"  },
104141cc406Sopenharmony_ci	{ _CCD_2556, "2556" },
105141cc406Sopenharmony_ci	{ _CCD_518,  "518"  },
106141cc406Sopenharmony_ci	{ _CCD_539,  "539"  },
107141cc406Sopenharmony_ci    { _CCD_3777, "3777"	},
108141cc406Sopenharmony_ci    { _CCD_548 , "548"	},
109141cc406Sopenharmony_ci    { -1 ,       "unknown" }
110141cc406Sopenharmony_ci};
111141cc406Sopenharmony_ci
112141cc406Sopenharmony_ci/****************************** local functions ******************************/
113141cc406Sopenharmony_ci
114141cc406Sopenharmony_ci#ifndef LINUX_24
115141cc406Sopenharmony_ci/** This is called as the fill_inode function when an inode
116141cc406Sopenharmony_ci * is going into (fill = 1) or out of service (fill = 0).
117141cc406Sopenharmony_ci *
118141cc406Sopenharmony_ci * Note: only the top-level directory needs to do this; if
119141cc406Sopenharmony_ci * a lower level is referenced, the parent will be as well.
120141cc406Sopenharmony_ci *
121141cc406Sopenharmony_ci * Here simply a dummy function
122141cc406Sopenharmony_ci */
123141cc406Sopenharmony_cistatic void procfsFillFunc( struct inode *inode, int fill )
124141cc406Sopenharmony_ci{
125141cc406Sopenharmony_ci}
126141cc406Sopenharmony_ci#endif
127141cc406Sopenharmony_ci
128141cc406Sopenharmony_ci/** returns a pointer to the port-mode string
129141cc406Sopenharmony_ci */
130141cc406Sopenharmony_cistatic const char* procfsGetMode( int mode )
131141cc406Sopenharmony_ci{
132141cc406Sopenharmony_ci	if((mode < _PORT_EPP) || (mode > _PORT_ECP))
133141cc406Sopenharmony_ci		return procfsPortModes[_PORT_ECP+1];
134141cc406Sopenharmony_ci
135141cc406Sopenharmony_ci	return procfsPortModes[mode];
136141cc406Sopenharmony_ci}
137141cc406Sopenharmony_ci
138141cc406Sopenharmony_ci/** determines CCD-Type string
139141cc406Sopenharmony_ci */
140141cc406Sopenharmony_cistatic const char* procfsGetCCDType( pScanData ps )
141141cc406Sopenharmony_ci{
142141cc406Sopenharmony_ci	int     i;
143141cc406Sopenharmony_ci	int     ccd_id = ps->Device.bCCDID;
144141cc406Sopenharmony_ci	pTabDef tab = procfsCCDTypes98001;
145141cc406Sopenharmony_ci
146141cc406Sopenharmony_ci	if( _IS_ASIC98(ps->sCaps.AsicID)) {
147141cc406Sopenharmony_ci
148141cc406Sopenharmony_ci        if(_ASIC_IS_98003 == ps->sCaps.AsicID)
149141cc406Sopenharmony_ci            tab = procfsCCDTypes98003;
150141cc406Sopenharmony_ci
151141cc406Sopenharmony_ci        /* seek down the description table */
152141cc406Sopenharmony_ci        for( i = 0; -1 != tab[i].id; i++ ) {
153141cc406Sopenharmony_ci
154141cc406Sopenharmony_ci            if( tab[i].id == ccd_id )
155141cc406Sopenharmony_ci                return tab[i].desc;
156141cc406Sopenharmony_ci        }
157141cc406Sopenharmony_ci    } else {
158141cc406Sopenharmony_ci
159141cc406Sopenharmony_ci        /* for older scanners only this info is available */
160141cc406Sopenharmony_ci        if( ps->fSonyCCD )
161141cc406Sopenharmony_ci            return "SONY Type";
162141cc406Sopenharmony_ci        else
163141cc406Sopenharmony_ci            return "NEC/TOSHIBA Type";
164141cc406Sopenharmony_ci    }
165141cc406Sopenharmony_ci
166141cc406Sopenharmony_ci	/* return the last entry if nothing applies! */
167141cc406Sopenharmony_ci	return tab[(sizeof(procfsCCDTypes98001)/sizeof(TabDef)-1)].desc;
168141cc406Sopenharmony_ci}
169141cc406Sopenharmony_ci
170141cc406Sopenharmony_ci/** will be called when reading the proc filesystem:
171141cc406Sopenharmony_ci * cat /proc/pt_drv/info
172141cc406Sopenharmony_ci */
173141cc406Sopenharmony_cistatic int procfsBInfoReadProc( char *buf, char **start, off_t offset,
174141cc406Sopenharmony_ci                                int count, int *eof, void *data )
175141cc406Sopenharmony_ci{
176141cc406Sopenharmony_ci	int len = 0;
177141cc406Sopenharmony_ci
178141cc406Sopenharmony_ci	len += sprintf( buf, "Plustek Flatbed Scanner Driver version "_PTDRV_VERSTR"\n" );
179141cc406Sopenharmony_ci	len += sprintf( buf + len, "IOCTL-Version: 0x%08x\n",_PTDRV_IOCTL_VERSION);
180141cc406Sopenharmony_ci	return len;
181141cc406Sopenharmony_ci}
182141cc406Sopenharmony_ci
183141cc406Sopenharmony_ci/** will be called when reading the proc filesystem:
184141cc406Sopenharmony_ci * cat /proc/pt_drv/deviceX/info
185141cc406Sopenharmony_ci */
186141cc406Sopenharmony_cistatic int procfsInfoReadProc( char *buf, char **start, off_t offset,
187141cc406Sopenharmony_ci                               int count, int *eof, void *data )
188141cc406Sopenharmony_ci{
189141cc406Sopenharmony_ci	int       len = 0;
190141cc406Sopenharmony_ci	pScanData ps  = (pScanData)data;
191141cc406Sopenharmony_ci
192141cc406Sopenharmony_ci	/* Tell us something about the device... */
193141cc406Sopenharmony_ci	if( NULL != ps ) {
194141cc406Sopenharmony_ci		len += sprintf( buf+len, "Model       : %s\n",
195141cc406Sopenharmony_ci					    MiscGetModelName(ps->sCaps.Model));
196141cc406Sopenharmony_ci		len += sprintf( buf+len, "Portaddress : 0x%X\n", ps->IO.portBase );
197141cc406Sopenharmony_ci		len += sprintf( buf+len, "Portmode    : %s (%s I/O, %s)\n",
198141cc406Sopenharmony_ci					    procfsGetMode(ps->IO.portMode),
199141cc406Sopenharmony_ci						(ps->IO.slowIO == _TRUE?"delayed":"fast"),
200141cc406Sopenharmony_ci                        (ps->IO.forceMode == 0?"autodetect":"forced"));
201141cc406Sopenharmony_ci		len += sprintf( buf+len, "Buttons     : %u\n",  ps->Device.buttons);
202141cc406Sopenharmony_ci		len += sprintf( buf+len, "Warmuptime  : %us\n", ps->warmup        );
203141cc406Sopenharmony_ci		len += sprintf( buf+len, "Lamp timeout: %us\n", ps->lampoff       );
204141cc406Sopenharmony_ci		len += sprintf( buf+len, "mov-switch  : %u\n",  ps->ModelOverride );
205141cc406Sopenharmony_ci		len += sprintf( buf+len, "I/O-delay   : %u\n",  ps->IO.delay      );
206141cc406Sopenharmony_ci		len += sprintf( buf+len, "CCD-Type    : %s\n",  procfsGetCCDType(ps));
207141cc406Sopenharmony_ci        len += sprintf( buf+len, "TPA         : %s\n",
208141cc406Sopenharmony_ci                        (ps->sCaps.dwFlag & SFLAG_TPA) ? "yes":"no" );
209141cc406Sopenharmony_ci	}
210141cc406Sopenharmony_ci
211141cc406Sopenharmony_ci	return len;
212141cc406Sopenharmony_ci}
213141cc406Sopenharmony_ci
214141cc406Sopenharmony_ci/** will be called when reading the proc filesystem:
215141cc406Sopenharmony_ci * cat /proc/pt_drv/devicex/buttony
216141cc406Sopenharmony_ci */
217141cc406Sopenharmony_cistatic int procfsButtonsReadProc( char *buf, char **start, off_t offset,
218141cc406Sopenharmony_ci                                  int count, int *eof, void *data )
219141cc406Sopenharmony_ci{
220141cc406Sopenharmony_ci	Byte	  b;
221141cc406Sopenharmony_ci	int       bc  = 0;
222141cc406Sopenharmony_ci	int       len = 0;
223141cc406Sopenharmony_ci	pScanData ps  = (pScanData)data;
224141cc406Sopenharmony_ci
225141cc406Sopenharmony_ci	if( NULL != ps ) {
226141cc406Sopenharmony_ci		bc = ps->Device.buttons;
227141cc406Sopenharmony_ci	}
228141cc406Sopenharmony_ci
229141cc406Sopenharmony_ci	/* Check the buttons... */
230141cc406Sopenharmony_ci	if( 0 != bc ) {
231141cc406Sopenharmony_ci
232141cc406Sopenharmony_ci		if ( _ASIC_IS_96003 == ps->sCaps.AsicID ) {
233141cc406Sopenharmony_ci			MiscClaimPort( ps );
234141cc406Sopenharmony_ci			b = IODataRegisterFromScanner( ps, ps->RegStatus );
235141cc406Sopenharmony_ci			if(_FLAG_P96_KEY == (b & _FLAG_P96_KEY))
236141cc406Sopenharmony_ci				b = 0;
237141cc406Sopenharmony_ci			else
238141cc406Sopenharmony_ci				b = 1;
239141cc406Sopenharmony_ci			MiscReleasePort( ps );
240141cc406Sopenharmony_ci			len += sprintf( buf + len, "%u\n", b );
241141cc406Sopenharmony_ci		} else
242141cc406Sopenharmony_ci			bc = 0;
243141cc406Sopenharmony_ci	}
244141cc406Sopenharmony_ci
245141cc406Sopenharmony_ci	if( 0 == bc )
246141cc406Sopenharmony_ci		len += sprintf( buf + len, "none\n" );
247141cc406Sopenharmony_ci
248141cc406Sopenharmony_ci	return len;
249141cc406Sopenharmony_ci}
250141cc406Sopenharmony_ci
251141cc406Sopenharmony_ci/** create a procfs entry
252141cc406Sopenharmony_ci */
253141cc406Sopenharmony_cistatic struct proc_dir_entry *new_entry( const char *name, mode_t mode,
254141cc406Sopenharmony_ci                                         struct proc_dir_entry *parent )
255141cc406Sopenharmony_ci{
256141cc406Sopenharmony_ci#ifndef LINUX_24
257141cc406Sopenharmony_ci	int len;
258141cc406Sopenharmony_ci#endif
259141cc406Sopenharmony_ci	struct proc_dir_entry *ent;
260141cc406Sopenharmony_ci
261141cc406Sopenharmony_ci	if (mode == S_IFDIR)
262141cc406Sopenharmony_ci		mode |= S_IRUGO | S_IXUGO;
263141cc406Sopenharmony_ci	else if (mode == 0)
264141cc406Sopenharmony_ci		mode = S_IFREG | S_IRUGO;
265141cc406Sopenharmony_ci
266141cc406Sopenharmony_ci#ifndef LINUX_24
267141cc406Sopenharmony_ci	len = strlen(name) + 1;
268141cc406Sopenharmony_ci
269141cc406Sopenharmony_ci	/* allocate memory for the entry and the name */
270141cc406Sopenharmony_ci	ent = kmalloc(sizeof(struct proc_dir_entry) + len, GFP_KERNEL);
271141cc406Sopenharmony_ci	if( NULL == ent )
272141cc406Sopenharmony_ci		return NULL;
273141cc406Sopenharmony_ci
274141cc406Sopenharmony_ci	memset(ent, 0, sizeof(struct proc_dir_entry));
275141cc406Sopenharmony_ci
276141cc406Sopenharmony_ci	/* position pointer of name to end of the structure*/
277141cc406Sopenharmony_ci	ent->name = ((char *) ent) + sizeof(*ent);
278141cc406Sopenharmony_ci	strcpy((char *)ent->name, name );
279141cc406Sopenharmony_ci
280141cc406Sopenharmony_ci	ent->namelen = strlen(name);
281141cc406Sopenharmony_ci	ent->mode    = mode;
282141cc406Sopenharmony_ci
283141cc406Sopenharmony_ci	if (S_ISDIR(mode)) {
284141cc406Sopenharmony_ci		ent->nlink      = 2;
285141cc406Sopenharmony_ci		ent->fill_inode = &procfsFillFunc;
286141cc406Sopenharmony_ci	} else {
287141cc406Sopenharmony_ci		ent->nlink = 1;
288141cc406Sopenharmony_ci	}
289141cc406Sopenharmony_ci
290141cc406Sopenharmony_ci	proc_register( parent, ent );
291141cc406Sopenharmony_ci#else
292141cc406Sopenharmony_ci	if (mode == S_IFDIR)
293141cc406Sopenharmony_ci		ent = proc_mkdir( name, parent );
294141cc406Sopenharmony_ci	else
295141cc406Sopenharmony_ci		ent = create_proc_entry( name, mode, parent );
296141cc406Sopenharmony_ci#endif
297141cc406Sopenharmony_ci
298141cc406Sopenharmony_ci	return ent;
299141cc406Sopenharmony_ci}
300141cc406Sopenharmony_ci
301141cc406Sopenharmony_ci/** shutdown one proc fs entry
302141cc406Sopenharmony_ci */
303141cc406Sopenharmony_cistatic inline void destroy_proc_entry( struct proc_dir_entry *root,
304141cc406Sopenharmony_ci                                       struct proc_dir_entry **d )
305141cc406Sopenharmony_ci{
306141cc406Sopenharmony_ci#ifndef LINUX_24
307141cc406Sopenharmony_ci	proc_unregister( root, (*d)->low_ino );
308141cc406Sopenharmony_ci	kfree(*d);
309141cc406Sopenharmony_ci#else
310141cc406Sopenharmony_ci	DBG(DBG_HIGH, "pt_drv: proc del '%s' root='%s'\n", (*d)->name, root->name);
311141cc406Sopenharmony_ci
312141cc406Sopenharmony_ci	remove_proc_entry((*d)->name, root );
313141cc406Sopenharmony_ci#endif
314141cc406Sopenharmony_ci
315141cc406Sopenharmony_ci	*d = NULL;
316141cc406Sopenharmony_ci}
317141cc406Sopenharmony_ci
318141cc406Sopenharmony_ci/** shutdown the proc-tree for one device
319141cc406Sopenharmony_ci */
320141cc406Sopenharmony_cistatic void destroy_proc_tree( pScanData ps )
321141cc406Sopenharmony_ci{
322141cc406Sopenharmony_ci	int i;
323141cc406Sopenharmony_ci
324141cc406Sopenharmony_ci	DBG( DBG_HIGH, "pt_drv: destroy_proc_tree !\n" );
325141cc406Sopenharmony_ci
326141cc406Sopenharmony_ci	if( ps ) {
327141cc406Sopenharmony_ci
328141cc406Sopenharmony_ci		if( ps->procDir.entry ) {
329141cc406Sopenharmony_ci
330141cc406Sopenharmony_ci			if( ps->procDir.info )
331141cc406Sopenharmony_ci				destroy_proc_entry( ps->procDir.entry, &ps->procDir.info );
332141cc406Sopenharmony_ci
333141cc406Sopenharmony_ci			for( i = 0; i < ps->Device.buttons; i++ ) {
334141cc406Sopenharmony_ci
335141cc406Sopenharmony_ci				if( ps->procDir.buttons[i] )
336141cc406Sopenharmony_ci    				destroy_proc_entry(ps->procDir.entry, &ps->procDir.buttons[i]);
337141cc406Sopenharmony_ci			}
338141cc406Sopenharmony_ci
339141cc406Sopenharmony_ci			destroy_proc_entry( base, &ps->procDir.entry );
340141cc406Sopenharmony_ci		}
341141cc406Sopenharmony_ci	}
342141cc406Sopenharmony_ci}
343141cc406Sopenharmony_ci
344141cc406Sopenharmony_ci/*************************** exported functions ******************************/
345141cc406Sopenharmony_ci
346141cc406Sopenharmony_ci/** initialize our proc-fs stuff
347141cc406Sopenharmony_ci */
348141cc406Sopenharmony_ciint ProcFsInitialize( void )
349141cc406Sopenharmony_ci{
350141cc406Sopenharmony_ci	DBG( DBG_HIGH, "ProcFsInitialize()\n" );
351141cc406Sopenharmony_ci
352141cc406Sopenharmony_ci#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
353141cc406Sopenharmony_ci	base = new_entry( _DRV_NAME, S_IFDIR, &proc_root );
354141cc406Sopenharmony_ci#else
355141cc406Sopenharmony_ci	base = new_entry( _DRV_NAME, S_IFDIR, NULL );
356141cc406Sopenharmony_ci#endif
357141cc406Sopenharmony_ci
358141cc406Sopenharmony_ci	if( NULL != base ) {
359141cc406Sopenharmony_ci
360141cc406Sopenharmony_ci		devcount = 0;
361141cc406Sopenharmony_ci
362141cc406Sopenharmony_ci		binfo = new_entry( "info", 0, base );
363141cc406Sopenharmony_ci		if( NULL != binfo ) {
364141cc406Sopenharmony_ci			binfo->read_proc = procfsBInfoReadProc;
365141cc406Sopenharmony_ci			binfo->data      = &devcount;
366141cc406Sopenharmony_ci		}
367141cc406Sopenharmony_ci	}
368141cc406Sopenharmony_ci
369141cc406Sopenharmony_ci	return _OK;
370141cc406Sopenharmony_ci}
371141cc406Sopenharmony_ci
372141cc406Sopenharmony_ci/** cleanup the base entry
373141cc406Sopenharmony_ci */
374141cc406Sopenharmony_civoid ProcFsShutdown( void )
375141cc406Sopenharmony_ci{
376141cc406Sopenharmony_ci	DBG( DBG_HIGH, "ProcFsShutdown()\n" );
377141cc406Sopenharmony_ci
378141cc406Sopenharmony_ci	if( NULL != base ) {
379141cc406Sopenharmony_ci
380141cc406Sopenharmony_ci		if( NULL != binfo )
381141cc406Sopenharmony_ci			destroy_proc_entry( base, &binfo );
382141cc406Sopenharmony_ci
383141cc406Sopenharmony_ci#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
384141cc406Sopenharmony_ci		destroy_proc_entry( &proc_root, &base );
385141cc406Sopenharmony_ci#else
386141cc406Sopenharmony_ci		destroy_proc_entry( NULL, &base );
387141cc406Sopenharmony_ci#endif
388141cc406Sopenharmony_ci	}
389141cc406Sopenharmony_ci
390141cc406Sopenharmony_ci	devcount = 0;
391141cc406Sopenharmony_ci}
392141cc406Sopenharmony_ci
393141cc406Sopenharmony_ci/** will be called for each device, that has been found
394141cc406Sopenharmony_ci */
395141cc406Sopenharmony_civoid ProcFsRegisterDevice( pScanData ps )
396141cc406Sopenharmony_ci{
397141cc406Sopenharmony_ci	int	 i;
398141cc406Sopenharmony_ci	char str[20];
399141cc406Sopenharmony_ci
400141cc406Sopenharmony_ci	if( NULL == base ) {
401141cc406Sopenharmony_ci	    printk( KERN_ERR "pt_drv : proc not initialised yet!\n");
402141cc406Sopenharmony_ci		return;
403141cc406Sopenharmony_ci	}
404141cc406Sopenharmony_ci
405141cc406Sopenharmony_ci	memset( &ps->procDir, 0, sizeof(ProcDirDef));
406141cc406Sopenharmony_ci
407141cc406Sopenharmony_ci	sprintf( str, "device%u", ps->devno );
408141cc406Sopenharmony_ci
409141cc406Sopenharmony_ci	ps->procDir.entry = new_entry( str, S_IFDIR, base );
410141cc406Sopenharmony_ci	if( NULL == ps->procDir.entry )
411141cc406Sopenharmony_ci		goto error_exit;
412141cc406Sopenharmony_ci
413141cc406Sopenharmony_ci	ps->procDir.info = new_entry( "info", 0, ps->procDir.entry );
414141cc406Sopenharmony_ci	if( NULL == ps->procDir.info )
415141cc406Sopenharmony_ci		goto error_exit;
416141cc406Sopenharmony_ci
417141cc406Sopenharmony_ci	ps->procDir.info->read_proc = procfsInfoReadProc;
418141cc406Sopenharmony_ci	ps->procDir.info->data      = ps;
419141cc406Sopenharmony_ci
420141cc406Sopenharmony_ci	for( i = 0; i < ps->Device.buttons; i++ ) {
421141cc406Sopenharmony_ci
422141cc406Sopenharmony_ci		sprintf( str, "button%u", i );
423141cc406Sopenharmony_ci
424141cc406Sopenharmony_ci		ps->procDir.buttons[i] = new_entry( str, 0, ps->procDir.entry );
425141cc406Sopenharmony_ci		if( NULL == ps->procDir.buttons[i] )
426141cc406Sopenharmony_ci			goto error_exit;
427141cc406Sopenharmony_ci
428141cc406Sopenharmony_ci		ps->procDir.buttons[i]->read_proc = procfsButtonsReadProc;
429141cc406Sopenharmony_ci		ps->procDir.buttons[i]->data      = ps;
430141cc406Sopenharmony_ci	}
431141cc406Sopenharmony_ci
432141cc406Sopenharmony_ci	devcount++;
433141cc406Sopenharmony_ci	return;
434141cc406Sopenharmony_ci
435141cc406Sopenharmony_ci
436141cc406Sopenharmony_cierror_exit:
437141cc406Sopenharmony_ci
438141cc406Sopenharmony_ci	printk(KERN_ERR "pt_drv: failure registering /proc/ entry %s.\n", str );
439141cc406Sopenharmony_ci	destroy_proc_tree( ps );
440141cc406Sopenharmony_ci}
441141cc406Sopenharmony_ci
442141cc406Sopenharmony_ci/** cleanup the proc-fs for a certain device
443141cc406Sopenharmony_ci */
444141cc406Sopenharmony_civoid ProcFsUnregisterDevice( pScanData ps )
445141cc406Sopenharmony_ci{
446141cc406Sopenharmony_ci	destroy_proc_tree( ps );
447141cc406Sopenharmony_ci}
448141cc406Sopenharmony_ci
449141cc406Sopenharmony_ci#else 	/* CONFIG_PROC_FS */
450141cc406Sopenharmony_ci
451141cc406Sopenharmony_ciint  ProcFsInitialize( void )
452141cc406Sopenharmony_ci{
453141cc406Sopenharmony_ci	return _OK;
454141cc406Sopenharmony_ci}
455141cc406Sopenharmony_ci
456141cc406Sopenharmony_civoid ProcFsShutdown( void )
457141cc406Sopenharmony_ci{
458141cc406Sopenharmony_ci}
459141cc406Sopenharmony_ci
460141cc406Sopenharmony_civoid ProcFsRegisterDevice( pScanData ps )
461141cc406Sopenharmony_ci{
462141cc406Sopenharmony_ci}
463141cc406Sopenharmony_ci
464141cc406Sopenharmony_civoid ProcFsUnregisterDevice( pScanData ps )
465141cc406Sopenharmony_ci{
466141cc406Sopenharmony_ci}
467141cc406Sopenharmony_ci
468141cc406Sopenharmony_ci#endif
469141cc406Sopenharmony_ci
470141cc406Sopenharmony_ci#endif /* guard __KERNEL__ */
471141cc406Sopenharmony_ci
472141cc406Sopenharmony_ci/* END PLUSTEK-PP_PROCFS.C ..................................................*/
473