2 * Copyright (C) 1997 Claus-Justus Heine
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; see the file COPYING. If not, write to
16 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
19 * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-proc.c,v $
21 * $Date: 1997/10/24 14:47:37 $
23 * This file contains the procfs interface for the
24 * QIC-40/80/3010/3020 floppy-tape driver "ftape" for Linux.
27 #include <linux/config.h>
29 #if defined(CONFIG_PROC_FS) && defined(CONFIG_FT_PROC_FS)
31 /* adding proc entries from inside a module is REALLY complicated
32 * for pre-2.1.28 kernels. I don't want to care about it.
35 #include <linux/proc_fs.h>
37 #include <linux/ftape.h>
38 #if LINUX_VERSION_CODE <= KERNEL_VER(1,2,13) /* bail out */
40 Please disable CONFIG_FT_PROC_FS in "MCONFIG" or upgrade to a newer kernel!
42 #if LINUX_VERSION_CODE >= KERNEL_VER(2,1,16)
43 #include <linux/init.h>
46 #define __initfunc(__arg) __arg
48 #include <linux/qic117.h>
51 #include "../lowlevel/ftape-io.h"
52 #include "../lowlevel/ftape-ctl.h"
53 #include "../lowlevel/ftape-proc.h"
54 #include "../lowlevel/ftape-tracing.h"
56 static int ftape_read_proc(char *page
, char **start
, off_t off
,
57 int count
, int *eof
, void *data
);
59 #if LINUX_VERSION_CODE < KERNEL_VER(2,1,28)
61 #include <asm/segment.h> /* for memcpy_tofs() */
63 #if LINUX_VERSION_CODE >= KERNEL_VER(2,1,0)
64 static long ftape_proc_read(struct inode
* inode
, struct file
* file
,
65 char* buf
, unsigned long count
);
67 static int ftape_proc_read(struct inode
* inode
, struct file
* file
,
68 char* buf
, int count
);
71 #define FT_PROC_REGISTER(parent, child) proc_register_dynamic(parent, child)
74 * Structures for interfacing with the /proc filesystem.
75 * Router creates its own directory /proc/net/router with the folowing
77 * config device configuration
78 * status global device statistics
79 * <device> entry for each WAN device
83 * Generic /proc/net/ftape/<file> file and inode operations
87 static struct file_operations ftape_proc_fops
=
90 ftape_proc_read
, /* read */
96 NULL
, /* no special open code */
98 NULL
, /* no special release code */
99 NULL
, /* can't fsync */
102 static struct inode_operations ftape_proc_inode_operations
=
115 NULL
, /* get_block */
117 NULL
, /* writepage */
118 NULL
, /* flushpage */
120 NULL
, /* permission */
122 NULL
, /* revalidate */
126 * Proc filesystem directory entries.
129 static int ftape_get_info(char *page
, char **start
, off_t off
,
130 int count
, int dummy
)
134 return ftape_read_proc(page
, start
, off
, count
, &dummy_eof
, NULL
);
137 static struct proc_dir_entry proc_ftape
= {
139 sizeof("ftape")-1, /* namelen */
141 S_IFREG
| S_IRUGO
, /* mode */
146 &ftape_proc_inode_operations
, /* ops */
147 ftape_get_info
, /* get_info */
148 NULL
, /* fill_inode */
155 /* Read ftape proc directory entry.
158 #define PROC_BLOCK_SIZE PAGE_SIZE
160 #if LINUX_VERSION_CODE >= KERNEL_VER(2,1,0)
161 static long ftape_proc_read(struct inode
* inode
, struct file
* file
,
162 char * buf
, unsigned long nbytes
)
164 static int ftape_proc_read(struct inode
* inode
, struct file
* file
,
165 char * buf
, int nbytes
)
173 struct proc_dir_entry
* dp
;
177 dp
= (struct proc_dir_entry
*) inode
->u
.generic_ip
;
178 if (!(page
= (char*) __get_free_page(GFP_KERNEL
)))
181 while ((nbytes
> 0) && !eof
)
183 count
= PROC_BLOCK_SIZE
<= nbytes
? PROC_BLOCK_SIZE
: nbytes
;
188 * Handle backwards compatibility with the old net
191 * XXX What gives with the file->f_flags & O_ACCMODE
192 * test? Seems stupid to me....
194 n
= dp
->get_info(page
, &start
, file
->f_pos
, count
,
195 (file
->f_flags
& O_ACCMODE
) == O_RDWR
);
203 * For proc files that are less than 4k
205 start
= page
+ file
->f_pos
;
213 break; /* End of file */
219 #if LINUX_VERSION_CODE > KERNEL_VER(2,1,3)
220 copy_to_user(buf
, start
, n
);
222 memcpy_tofs(buf
, start
, n
);
224 file
->f_pos
+= n
; /* Move down the file */
229 free_page((unsigned long) page
);
233 #else /* LINUX_VERSION_CODE < KERNEL_VER(2,1,28) */
235 #define FT_PROC_REGISTER(parent, child) proc_register(parent, child)
238 * Proc filesystem directory entries.
241 static struct proc_dir_entry proc_ftape
= {
243 sizeof("ftape")-1, /* namelen */
245 S_IFREG
| S_IRUGO
, /* mode */
252 NULL
, /* fill_inode */
257 ftape_read_proc
, /* read_proc */
258 NULL
/* write_proc */
263 static size_t get_driver_info(char *buf
)
265 const char *debug_level
[] = { "bugs" ,
277 "used data rate: %d kbit/sec\n"
278 "dma memory : %d kb\n"
279 "debug messages: %s\n",
282 FT_BUFF_SIZE
* ft_nr_buffers
>> 10,
283 debug_level
[TRACE_LEVEL
]);
286 static size_t get_tapedrive_info(char *buf
)
289 "vendor id : 0x%04x\n"
291 "wind speed: %d ips\n"
293 "max. rate : %d kbit/sec\n",
294 ft_drive_type
.vendor_id
,
297 ((ft_drive_type
.wake_up
== no_wake_up
)
298 ? "No wakeup needed" :
299 ((ft_drive_type
.wake_up
== wake_up_colorado
)
301 ((ft_drive_type
.wake_up
== wake_up_mountain
)
303 ((ft_drive_type
.wake_up
== wake_up_insight
)
309 static size_t get_cartridge_info(char *buf
)
311 if (ftape_init_drive_needed
) {
312 return sprintf(buf
, "uninitialized\n");
315 return sprintf(buf
, "no cartridge inserted\n");
323 "QIC spec. : QIC-%s\n"
325 ft_segments_per_track
,
328 (ft_formatted
== 1) ? "yes" : "no",
329 (ft_write_protected
== 1) ? "no" : "yes",
330 ((ft_qic_std
== QIC_TAPE_QIC40
) ? "40" :
331 ((ft_qic_std
== QIC_TAPE_QIC80
) ? "80" :
332 ((ft_qic_std
== QIC_TAPE_QIC3010
) ? "3010" :
333 ((ft_qic_std
== QIC_TAPE_QIC3020
) ? "3020" :
338 static size_t get_controller_info(char *buf
)
340 const char *fdc_name
[] = { "no fdc",
344 "Colorado FC-10 or FC-20",
350 "FDC base : 0x%03x\n"
354 "max. rate : %d kbit/sec\n",
355 ft_mach2
? "Mountain MACH-2" : fdc_name
[fdc
.type
],
356 fdc
.sra
, fdc
.irq
, fdc
.dma
,
357 ft_fdc_threshold
, ft_fdc_max_rate
);
360 static size_t get_history_info(char *buf
)
365 "\nFDC isr statistics\n"
366 " id_am_errors : %3d\n"
367 " id_crc_errors : %3d\n"
368 " data_am_errors : %3d\n"
369 " data_crc_errors : %3d\n"
370 " overrun_errors : %3d\n"
371 " no_data_errors : %3d\n"
373 ft_history
.id_am_errors
, ft_history
.id_crc_errors
,
374 ft_history
.data_am_errors
, ft_history
.data_crc_errors
,
375 ft_history
.overrun_errors
, ft_history
.no_data_errors
,
377 len
+= sprintf(buf
+ len
,
379 " crc_errors : %3d\n"
380 " crc_failures : %3d\n"
381 " ecc_failures : %3d\n"
382 " sectors corrected: %3d\n",
383 ft_history
.crc_errors
, ft_history
.crc_failures
,
384 ft_history
.ecc_failures
, ft_history
.corrected
);
385 len
+= sprintf(buf
+ len
,
386 "\ntape quality statistics\n"
387 " media defects : %3d\n",
389 len
+= sprintf(buf
+ len
,
390 "\ntape motion statistics\n"
391 " repositions : %3d\n",
396 int ftape_read_proc(char *page
, char **start
, off_t off
,
397 int count
, int *eof
, void *data
)
402 ptr
+= sprintf(ptr
, "Kernel Driver\n\n");
403 ptr
+= get_driver_info(ptr
);
404 ptr
+= sprintf(ptr
, "\nTape Drive\n\n");
405 ptr
+= get_tapedrive_info(ptr
);
406 ptr
+= sprintf(ptr
, "\nFDC Controller\n\n");
407 ptr
+= get_controller_info(ptr
);
408 ptr
+= sprintf(ptr
, "\nTape Cartridge\n\n");
409 ptr
+= get_cartridge_info(ptr
);
410 ptr
+= sprintf(ptr
, "\nHistory Record\n\n");
411 ptr
+= get_history_info(ptr
);
415 if (off
+count
>= len
) {
423 __initfunc(int ftape_proc_init(void))
425 return FT_PROC_REGISTER(&proc_root
, &proc_ftape
);
429 void ftape_proc_destroy(void)
431 proc_unregister(&proc_root
, proc_ftape
.low_ino
);
435 #endif /* defined(CONFIG_PROC_FS) && defined(CONFIG_FT_PROC_FS) */