diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-01-25 17:19:08 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-01-25 17:19:08 -0800 |
commit | 9b73e76f3cf63379dcf45fcd4f112f5812418d0a (patch) | |
tree | 4e6bef87cd0cd6d848fc39a5ae25b981dbbe035b /drivers/scsi/qla2xxx/qla_dfs.c | |
parent | 50d9a126240f9961cfdd063336bbeb91f77a7dce (diff) | |
parent | 23c3e290fb9ce38cabc2822b47583fc8702411bf (diff) | |
download | kernel-crypto-9b73e76f3cf63379dcf45fcd4f112f5812418d0a.tar.gz kernel-crypto-9b73e76f3cf63379dcf45fcd4f112f5812418d0a.tar.xz kernel-crypto-9b73e76f3cf63379dcf45fcd4f112f5812418d0a.zip |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (200 commits)
[SCSI] usbstorage: use last_sector_bug flag universally
[SCSI] libsas: abstract STP task status into a function
[SCSI] ultrastor: clean up inline asm warnings
[SCSI] aic7xxx: fix firmware build
[SCSI] aacraid: fib context lock for management ioctls
[SCSI] ch: remove forward declarations
[SCSI] ch: fix device minor number management bug
[SCSI] ch: handle class_device_create failure properly
[SCSI] NCR5380: fix section mismatch
[SCSI] sg: fix /proc/scsi/sg/devices when no SCSI devices
[SCSI] IB/iSER: add logical unit reset support
[SCSI] don't use __GFP_DMA for sense buffers if not required
[SCSI] use dynamically allocated sense buffer
[SCSI] scsi.h: add macro for enclosure bit of inquiry data
[SCSI] sd: add fix for devices with last sector access problems
[SCSI] fix pcmcia compile problem
[SCSI] aacraid: add Voodoo Lite class of cards.
[SCSI] aacraid: add new driver features flags
[SCSI] qla2xxx: Update version number to 8.02.00-k7.
[SCSI] qla2xxx: Issue correct MBC_INITIALIZE_FIRMWARE command.
...
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_dfs.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_dfs.c | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c new file mode 100644 index 00000000000..1479c60441c --- /dev/null +++ b/drivers/scsi/qla2xxx/qla_dfs.c @@ -0,0 +1,175 @@ +/* + * QLogic Fibre Channel HBA Driver + * Copyright (c) 2003-2005 QLogic Corporation + * + * See LICENSE.qla2xxx for copyright and licensing details. + */ +#include "qla_def.h" + +#include <linux/debugfs.h> +#include <linux/seq_file.h> + +static struct dentry *qla2x00_dfs_root; +static atomic_t qla2x00_dfs_root_count; + +static int +qla2x00_dfs_fce_show(struct seq_file *s, void *unused) +{ + scsi_qla_host_t *ha = s->private; + uint32_t cnt; + uint32_t *fce; + uint64_t fce_start; + + mutex_lock(&ha->fce_mutex); + + seq_printf(s, "FCE Trace Buffer\n"); + seq_printf(s, "In Pointer = %llx\n\n", ha->fce_wr); + seq_printf(s, "Base = %llx\n\n", (unsigned long long) ha->fce_dma); + seq_printf(s, "FCE Enable Registers\n"); + seq_printf(s, "%08x %08x %08x %08x %08x %08x\n", + ha->fce_mb[0], ha->fce_mb[2], ha->fce_mb[3], ha->fce_mb[4], + ha->fce_mb[5], ha->fce_mb[6]); + + fce = (uint32_t *) ha->fce; + fce_start = (unsigned long long) ha->fce_dma; + for (cnt = 0; cnt < fce_calc_size(ha->fce_bufs) / 4; cnt++) { + if (cnt % 8 == 0) + seq_printf(s, "\n%llx: ", + (unsigned long long)((cnt * 4) + fce_start)); + else + seq_printf(s, " "); + seq_printf(s, "%08x", *fce++); + } + + seq_printf(s, "\nEnd\n"); + + mutex_unlock(&ha->fce_mutex); + + return 0; +} + +static int +qla2x00_dfs_fce_open(struct inode *inode, struct file *file) +{ + scsi_qla_host_t *ha = inode->i_private; + int rval; + + if (!ha->flags.fce_enabled) + goto out; + + mutex_lock(&ha->fce_mutex); + + /* Pause tracing to flush FCE buffers. */ + rval = qla2x00_disable_fce_trace(ha, &ha->fce_wr, &ha->fce_rd); + if (rval) + qla_printk(KERN_WARNING, ha, + "DebugFS: Unable to disable FCE (%d).\n", rval); + + ha->flags.fce_enabled = 0; + + mutex_unlock(&ha->fce_mutex); +out: + return single_open(file, qla2x00_dfs_fce_show, ha); +} + +static int +qla2x00_dfs_fce_release(struct inode *inode, struct file *file) +{ + scsi_qla_host_t *ha = inode->i_private; + int rval; + + if (ha->flags.fce_enabled) + goto out; + + mutex_lock(&ha->fce_mutex); + + /* Re-enable FCE tracing. */ + ha->flags.fce_enabled = 1; + memset(ha->fce, 0, fce_calc_size(ha->fce_bufs)); + rval = qla2x00_enable_fce_trace(ha, ha->fce_dma, ha->fce_bufs, + ha->fce_mb, &ha->fce_bufs); + if (rval) { + qla_printk(KERN_WARNING, ha, + "DebugFS: Unable to reinitialize FCE (%d).\n", rval); + ha->flags.fce_enabled = 0; + } + + mutex_unlock(&ha->fce_mutex); +out: + return single_release(inode, file); +} + +static const struct file_operations dfs_fce_ops = { + .open = qla2x00_dfs_fce_open, + .read = seq_read, + .llseek = seq_lseek, + .release = qla2x00_dfs_fce_release, +}; + +int +qla2x00_dfs_setup(scsi_qla_host_t *ha) +{ + if (!IS_QLA25XX(ha)) + goto out; + if (!ha->fce) + goto out; + + if (qla2x00_dfs_root) + goto create_dir; + + atomic_set(&qla2x00_dfs_root_count, 0); + qla2x00_dfs_root = debugfs_create_dir(QLA2XXX_DRIVER_NAME, NULL); + if (!qla2x00_dfs_root) { + qla_printk(KERN_NOTICE, ha, + "DebugFS: Unable to create root directory.\n"); + goto out; + } + +create_dir: + if (ha->dfs_dir) + goto create_nodes; + + mutex_init(&ha->fce_mutex); + ha->dfs_dir = debugfs_create_dir(ha->host_str, qla2x00_dfs_root); + if (!ha->dfs_dir) { + qla_printk(KERN_NOTICE, ha, + "DebugFS: Unable to create ha directory.\n"); + goto out; + } + + atomic_inc(&qla2x00_dfs_root_count); + +create_nodes: + ha->dfs_fce = debugfs_create_file("fce", S_IRUSR, ha->dfs_dir, ha, + &dfs_fce_ops); + if (!ha->dfs_fce) { + qla_printk(KERN_NOTICE, ha, + "DebugFS: Unable to fce node.\n"); + goto out; + } +out: + return 0; +} + +int +qla2x00_dfs_remove(scsi_qla_host_t *ha) +{ + if (ha->dfs_fce) { + debugfs_remove(ha->dfs_fce); + ha->dfs_fce = NULL; + } + + if (ha->dfs_dir) { + debugfs_remove(ha->dfs_dir); + ha->dfs_dir = NULL; + atomic_dec(&qla2x00_dfs_root_count); + } + + if (atomic_read(&qla2x00_dfs_root_count) == 0 && + qla2x00_dfs_root) { + debugfs_remove(qla2x00_dfs_root); + qla2x00_dfs_root = NULL; + } + + return 0; +} |