2 * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved.
3 * Copyright (c) 2006 PathScale, Inc. All rights reserved.
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
34 #include <linux/module.h>
36 #include <linux/mount.h>
37 #include <linux/pagemap.h>
38 #include <linux/init.h>
39 #include <linux/namei.h>
40 #include <linux/slab.h>
42 #include "ipath_kernel.h"
44 #define IPATHFS_MAGIC 0x726a77
46 static struct super_block
*ipath_super
;
48 static int ipathfs_mknod(struct inode
*dir
, struct dentry
*dentry
,
49 int mode
, const struct file_operations
*fops
,
53 struct inode
*inode
= new_inode(dir
->i_sb
);
61 inode
->i_atime
= inode
->i_mtime
= inode
->i_ctime
= CURRENT_TIME
;
62 inode
->i_private
= data
;
63 if ((mode
& S_IFMT
) == S_IFDIR
) {
64 inode
->i_op
= &simple_dir_inode_operations
;
71 d_instantiate(dentry
, inode
);
78 static int create_file(const char *name
, mode_t mode
,
79 struct dentry
*parent
, struct dentry
**dentry
,
80 const struct file_operations
*fops
, void *data
)
85 mutex_lock(&parent
->d_inode
->i_mutex
);
86 *dentry
= lookup_one_len(name
, parent
, strlen(name
));
88 error
= ipathfs_mknod(parent
->d_inode
, *dentry
,
91 error
= PTR_ERR(dentry
);
92 mutex_unlock(&parent
->d_inode
->i_mutex
);
97 static ssize_t
atomic_stats_read(struct file
*file
, char __user
*buf
,
98 size_t count
, loff_t
*ppos
)
100 return simple_read_from_buffer(buf
, count
, ppos
, &ipath_stats
,
104 static const struct file_operations atomic_stats_ops
= {
105 .read
= atomic_stats_read
,
106 .llseek
= default_llseek
,
109 static ssize_t
atomic_counters_read(struct file
*file
, char __user
*buf
,
110 size_t count
, loff_t
*ppos
)
112 struct infinipath_counters counters
;
113 struct ipath_devdata
*dd
;
115 dd
= file
->f_path
.dentry
->d_inode
->i_private
;
116 dd
->ipath_f_read_counters(dd
, &counters
);
118 return simple_read_from_buffer(buf
, count
, ppos
, &counters
,
122 static const struct file_operations atomic_counters_ops
= {
123 .read
= atomic_counters_read
,
124 .llseek
= default_llseek
,
127 static ssize_t
flash_read(struct file
*file
, char __user
*buf
,
128 size_t count
, loff_t
*ppos
)
130 struct ipath_devdata
*dd
;
142 if (pos
>= sizeof(struct ipath_flash
)) {
147 if (count
> sizeof(struct ipath_flash
) - pos
)
148 count
= sizeof(struct ipath_flash
) - pos
;
150 tmp
= kmalloc(count
, GFP_KERNEL
);
156 dd
= file
->f_path
.dentry
->d_inode
->i_private
;
157 if (ipath_eeprom_read(dd
, pos
, tmp
, count
)) {
158 ipath_dev_err(dd
, "failed to read from flash\n");
163 if (copy_to_user(buf
, tmp
, count
)) {
178 static ssize_t
flash_write(struct file
*file
, const char __user
*buf
,
179 size_t count
, loff_t
*ppos
)
181 struct ipath_devdata
*dd
;
193 if (count
!= sizeof(struct ipath_flash
)) {
198 tmp
= kmalloc(count
, GFP_KERNEL
);
204 if (copy_from_user(tmp
, buf
, count
)) {
209 dd
= file
->f_path
.dentry
->d_inode
->i_private
;
210 if (ipath_eeprom_write(dd
, pos
, tmp
, count
)) {
212 ipath_dev_err(dd
, "failed to write to flash\n");
226 static const struct file_operations flash_ops
= {
228 .write
= flash_write
,
229 .llseek
= default_llseek
,
232 static int create_device_files(struct super_block
*sb
,
233 struct ipath_devdata
*dd
)
235 struct dentry
*dir
, *tmp
;
239 snprintf(unit
, sizeof unit
, "%02d", dd
->ipath_unit
);
240 ret
= create_file(unit
, S_IFDIR
|S_IRUGO
|S_IXUGO
, sb
->s_root
, &dir
,
241 &simple_dir_operations
, dd
);
243 printk(KERN_ERR
"create_file(%s) failed: %d\n", unit
, ret
);
247 ret
= create_file("atomic_counters", S_IFREG
|S_IRUGO
, dir
, &tmp
,
248 &atomic_counters_ops
, dd
);
250 printk(KERN_ERR
"create_file(%s/atomic_counters) "
251 "failed: %d\n", unit
, ret
);
255 ret
= create_file("flash", S_IFREG
|S_IWUSR
|S_IRUGO
, dir
, &tmp
,
258 printk(KERN_ERR
"create_file(%s/flash) "
259 "failed: %d\n", unit
, ret
);
267 static int remove_file(struct dentry
*parent
, char *name
)
272 tmp
= lookup_one_len(name
, parent
, strlen(name
));
279 spin_lock(&dcache_lock
);
280 spin_lock(&tmp
->d_lock
);
281 if (!(d_unhashed(tmp
) && tmp
->d_inode
)) {
284 spin_unlock(&tmp
->d_lock
);
285 spin_unlock(&dcache_lock
);
286 simple_unlink(parent
->d_inode
, tmp
);
288 spin_unlock(&tmp
->d_lock
);
289 spin_unlock(&dcache_lock
);
295 * We don't expect clients to care about the return value, but
296 * it's there if they need it.
301 static int remove_device_files(struct super_block
*sb
,
302 struct ipath_devdata
*dd
)
304 struct dentry
*dir
, *root
;
308 root
= dget(sb
->s_root
);
309 mutex_lock(&root
->d_inode
->i_mutex
);
310 snprintf(unit
, sizeof unit
, "%02d", dd
->ipath_unit
);
311 dir
= lookup_one_len(unit
, root
, strlen(unit
));
315 printk(KERN_ERR
"Lookup of %s failed\n", unit
);
319 remove_file(dir
, "flash");
320 remove_file(dir
, "atomic_counters");
322 ret
= simple_rmdir(root
->d_inode
, dir
);
325 mutex_unlock(&root
->d_inode
->i_mutex
);
330 static int ipathfs_fill_super(struct super_block
*sb
, void *data
,
333 struct ipath_devdata
*dd
, *tmp
;
337 static struct tree_descr files
[] = {
338 [2] = {"atomic_stats", &atomic_stats_ops
, S_IRUGO
},
342 ret
= simple_fill_super(sb
, IPATHFS_MAGIC
, files
);
344 printk(KERN_ERR
"simple_fill_super failed: %d\n", ret
);
348 spin_lock_irqsave(&ipath_devs_lock
, flags
);
350 list_for_each_entry_safe(dd
, tmp
, &ipath_dev_list
, ipath_list
) {
351 spin_unlock_irqrestore(&ipath_devs_lock
, flags
);
352 ret
= create_device_files(sb
, dd
);
355 spin_lock_irqsave(&ipath_devs_lock
, flags
);
358 spin_unlock_irqrestore(&ipath_devs_lock
, flags
);
364 static int ipathfs_get_sb(struct file_system_type
*fs_type
, int flags
,
365 const char *dev_name
, void *data
, struct vfsmount
*mnt
)
367 int ret
= get_sb_single(fs_type
, flags
, data
,
368 ipathfs_fill_super
, mnt
);
370 ipath_super
= mnt
->mnt_sb
;
374 static void ipathfs_kill_super(struct super_block
*s
)
376 kill_litter_super(s
);
380 int ipathfs_add_device(struct ipath_devdata
*dd
)
384 if (ipath_super
== NULL
) {
389 ret
= create_device_files(ipath_super
, dd
);
395 int ipathfs_remove_device(struct ipath_devdata
*dd
)
399 if (ipath_super
== NULL
) {
404 ret
= remove_device_files(ipath_super
, dd
);
410 static struct file_system_type ipathfs_fs_type
= {
411 .owner
= THIS_MODULE
,
413 .get_sb
= ipathfs_get_sb
,
414 .kill_sb
= ipathfs_kill_super
,
417 int __init
ipath_init_ipathfs(void)
419 return register_filesystem(&ipathfs_fs_type
);
422 void __exit
ipath_exit_ipathfs(void)
424 unregister_filesystem(&ipathfs_fs_type
);