aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHiral Shah <hishah@cisco.com>2014-04-18 15:28:19 -0400
committerChristoph Hellwig <hch@lst.de>2014-05-19 07:33:00 -0400
commitabb14148c0f850e7201efc3e7aea1762f993606b (patch)
tree8cc508236684996a2d036c84c6372b407dd7cac1
parent668186637e013f41bb3b275fa1a3b993b4da2ccb (diff)
fnic: fnic Control Path Trace Utility
Fnic Ctlr Path Trace utility is a tracing functionality built directly into fnic driver to trace the control path frames like discovery, FLOGI request/reply, PLOGI request/reply, link event etc. It will be one trace file for all fnics. It will help us to debug and resolve the discovery and initialization related issues in more convenient way. This trace information includes time stamp, Host Number, Frame type, Frame Length and Frame. By default,64 pages are allocated but we can change the number of allocated pages by module parameter fnic_fc_trace_max_page. Each entry is of 256 byte and available entries are depends on allocated number of pages. We can turn on or off the fnic control path trace functionality by module paramter fc_trace_enable and/or reset the trace contain by module paramter fc_trace_clear. Signed-off-by: Hiral Shah <hishah@cisco.com> Signed-off-by: Sesidhar Baddela <sebaddel@cisco.com> Signed-off-by: Christoph Hellwig <hch@lst.de>
-rw-r--r--drivers/scsi/fnic/fnic.h2
-rw-r--r--drivers/scsi/fnic/fnic_debugfs.c238
-rw-r--r--drivers/scsi/fnic/fnic_fcs.c56
-rw-r--r--drivers/scsi/fnic/fnic_main.c20
-rw-r--r--drivers/scsi/fnic/fnic_trace.c326
-rw-r--r--drivers/scsi/fnic/fnic_trace.h38
6 files changed, 637 insertions, 43 deletions
diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h
index ce88951af3d1..1d3521e13d77 100644
--- a/drivers/scsi/fnic/fnic.h
+++ b/drivers/scsi/fnic/fnic.h
@@ -39,7 +39,7 @@
39 39
40#define DRV_NAME "fnic" 40#define DRV_NAME "fnic"
41#define DRV_DESCRIPTION "Cisco FCoE HBA Driver" 41#define DRV_DESCRIPTION "Cisco FCoE HBA Driver"
42#define DRV_VERSION "1.5.0.45" 42#define DRV_VERSION "1.6.0.10"
43#define PFX DRV_NAME ": " 43#define PFX DRV_NAME ": "
44#define DFX DRV_NAME "%d: " 44#define DFX DRV_NAME "%d: "
45 45
diff --git a/drivers/scsi/fnic/fnic_debugfs.c b/drivers/scsi/fnic/fnic_debugfs.c
index b6073f875761..2c613bdea78f 100644
--- a/drivers/scsi/fnic/fnic_debugfs.c
+++ b/drivers/scsi/fnic/fnic_debugfs.c
@@ -25,6 +25,21 @@ static struct dentry *fnic_trace_debugfs_file;
25static struct dentry *fnic_trace_enable; 25static struct dentry *fnic_trace_enable;
26static struct dentry *fnic_stats_debugfs_root; 26static struct dentry *fnic_stats_debugfs_root;
27 27
28static struct dentry *fnic_fc_trace_debugfs_file;
29static struct dentry *fnic_fc_rdata_trace_debugfs_file;
30static struct dentry *fnic_fc_trace_enable;
31static struct dentry *fnic_fc_trace_clear;
32
33struct fc_trace_flag_type {
34 u8 fc_row_file;
35 u8 fc_normal_file;
36 u8 fnic_trace;
37 u8 fc_trace;
38 u8 fc_clear;
39};
40
41static struct fc_trace_flag_type *fc_trc_flag;
42
28/* 43/*
29 * fnic_debugfs_init - Initialize debugfs for fnic debug logging 44 * fnic_debugfs_init - Initialize debugfs for fnic debug logging
30 * 45 *
@@ -56,6 +71,18 @@ int fnic_debugfs_init(void)
56 return rc; 71 return rc;
57 } 72 }
58 73
74 /* Allocate memory to structure */
75 fc_trc_flag = (struct fc_trace_flag_type *)
76 vmalloc(sizeof(struct fc_trace_flag_type));
77
78 if (fc_trc_flag) {
79 fc_trc_flag->fc_row_file = 0;
80 fc_trc_flag->fc_normal_file = 1;
81 fc_trc_flag->fnic_trace = 2;
82 fc_trc_flag->fc_trace = 3;
83 fc_trc_flag->fc_clear = 4;
84 }
85
59 rc = 0; 86 rc = 0;
60 return rc; 87 return rc;
61} 88}
@@ -74,15 +101,19 @@ void fnic_debugfs_terminate(void)
74 101
75 debugfs_remove(fnic_trace_debugfs_root); 102 debugfs_remove(fnic_trace_debugfs_root);
76 fnic_trace_debugfs_root = NULL; 103 fnic_trace_debugfs_root = NULL;
104
105 if (fc_trc_flag)
106 vfree(fc_trc_flag);
77} 107}
78 108
79/* 109/*
80 * fnic_trace_ctrl_open - Open the trace_enable file 110 * fnic_trace_ctrl_open - Open the trace_enable file for fnic_trace
111 * Or Open fc_trace_enable file for fc_trace
81 * @inode: The inode pointer. 112 * @inode: The inode pointer.
82 * @file: The file pointer to attach the trace enable/disable flag. 113 * @file: The file pointer to attach the trace enable/disable flag.
83 * 114 *
84 * Description: 115 * Description:
85 * This routine opens a debugsfs file trace_enable. 116 * This routine opens a debugsfs file trace_enable or fc_trace_enable.
86 * 117 *
87 * Returns: 118 * Returns:
88 * This function returns zero if successful. 119 * This function returns zero if successful.
@@ -94,15 +125,19 @@ static int fnic_trace_ctrl_open(struct inode *inode, struct file *filp)
94} 125}
95 126
96/* 127/*
97 * fnic_trace_ctrl_read - Read a trace_enable debugfs file 128 * fnic_trace_ctrl_read -
129 * Read trace_enable ,fc_trace_enable
130 * or fc_trace_clear debugfs file
98 * @filp: The file pointer to read from. 131 * @filp: The file pointer to read from.
99 * @ubuf: The buffer to copy the data to. 132 * @ubuf: The buffer to copy the data to.
100 * @cnt: The number of bytes to read. 133 * @cnt: The number of bytes to read.
101 * @ppos: The position in the file to start reading from. 134 * @ppos: The position in the file to start reading from.
102 * 135 *
103 * Description: 136 * Description:
104 * This routine reads value of variable fnic_tracing_enabled 137 * This routine reads value of variable fnic_tracing_enabled or
105 * and stores into local @buf. It will start reading file at @ppos and 138 * fnic_fc_tracing_enabled or fnic_fc_trace_cleared
139 * and stores into local @buf.
140 * It will start reading file at @ppos and
106 * copy up to @cnt of data to @ubuf from @buf. 141 * copy up to @cnt of data to @ubuf from @buf.
107 * 142 *
108 * Returns: 143 * Returns:
@@ -114,13 +149,25 @@ static ssize_t fnic_trace_ctrl_read(struct file *filp,
114{ 149{
115 char buf[64]; 150 char buf[64];
116 int len; 151 int len;
117 len = sprintf(buf, "%u\n", fnic_tracing_enabled); 152 u8 *trace_type;
153 len = 0;
154 trace_type = (u8 *)filp->private_data;
155 if (*trace_type == fc_trc_flag->fnic_trace)
156 len = sprintf(buf, "%u\n", fnic_tracing_enabled);
157 else if (*trace_type == fc_trc_flag->fc_trace)
158 len = sprintf(buf, "%u\n", fnic_fc_tracing_enabled);
159 else if (*trace_type == fc_trc_flag->fc_clear)
160 len = sprintf(buf, "%u\n", fnic_fc_trace_cleared);
161 else
162 pr_err("fnic: Cannot read to any debugfs file\n");
118 163
119 return simple_read_from_buffer(ubuf, cnt, ppos, buf, len); 164 return simple_read_from_buffer(ubuf, cnt, ppos, buf, len);
120} 165}
121 166
122/* 167/*
123 * fnic_trace_ctrl_write - Write to trace_enable debugfs file 168 * fnic_trace_ctrl_write -
169 * Write to trace_enable, fc_trace_enable or
170 * fc_trace_clear debugfs file
124 * @filp: The file pointer to write from. 171 * @filp: The file pointer to write from.
125 * @ubuf: The buffer to copy the data from. 172 * @ubuf: The buffer to copy the data from.
126 * @cnt: The number of bytes to write. 173 * @cnt: The number of bytes to write.
@@ -128,7 +175,8 @@ static ssize_t fnic_trace_ctrl_read(struct file *filp,
128 * 175 *
129 * Description: 176 * Description:
130 * This routine writes data from user buffer @ubuf to buffer @buf and 177 * This routine writes data from user buffer @ubuf to buffer @buf and
131 * sets fnic_tracing_enabled value as per user input. 178 * sets fc_trace_enable ,tracing_enable or fnic_fc_trace_cleared
179 * value as per user input.
132 * 180 *
133 * Returns: 181 * Returns:
134 * This function returns the amount of data that was written. 182 * This function returns the amount of data that was written.
@@ -140,6 +188,8 @@ static ssize_t fnic_trace_ctrl_write(struct file *filp,
140 char buf[64]; 188 char buf[64];
141 unsigned long val; 189 unsigned long val;
142 int ret; 190 int ret;
191 u8 *trace_type;
192 trace_type = (u8 *)filp->private_data;
143 193
144 if (cnt >= sizeof(buf)) 194 if (cnt >= sizeof(buf))
145 return -EINVAL; 195 return -EINVAL;
@@ -153,12 +203,27 @@ static ssize_t fnic_trace_ctrl_write(struct file *filp,
153 if (ret < 0) 203 if (ret < 0)
154 return ret; 204 return ret;
155 205
156 fnic_tracing_enabled = val; 206 if (*trace_type == fc_trc_flag->fnic_trace)
207 fnic_tracing_enabled = val;
208 else if (*trace_type == fc_trc_flag->fc_trace)
209 fnic_fc_tracing_enabled = val;
210 else if (*trace_type == fc_trc_flag->fc_clear)
211 fnic_fc_trace_cleared = val;
212 else
213 pr_err("fnic: cannot write to any debufs file\n");
214
157 (*ppos)++; 215 (*ppos)++;
158 216
159 return cnt; 217 return cnt;
160} 218}
161 219
220static const struct file_operations fnic_trace_ctrl_fops = {
221 .owner = THIS_MODULE,
222 .open = fnic_trace_ctrl_open,
223 .read = fnic_trace_ctrl_read,
224 .write = fnic_trace_ctrl_write,
225};
226
162/* 227/*
163 * fnic_trace_debugfs_open - Open the fnic trace log 228 * fnic_trace_debugfs_open - Open the fnic trace log
164 * @inode: The inode pointer 229 * @inode: The inode pointer
@@ -178,19 +243,36 @@ static int fnic_trace_debugfs_open(struct inode *inode,
178 struct file *file) 243 struct file *file)
179{ 244{
180 fnic_dbgfs_t *fnic_dbg_prt; 245 fnic_dbgfs_t *fnic_dbg_prt;
246 u8 *rdata_ptr;
247 rdata_ptr = (u8 *)inode->i_private;
181 fnic_dbg_prt = kzalloc(sizeof(fnic_dbgfs_t), GFP_KERNEL); 248 fnic_dbg_prt = kzalloc(sizeof(fnic_dbgfs_t), GFP_KERNEL);
182 if (!fnic_dbg_prt) 249 if (!fnic_dbg_prt)
183 return -ENOMEM; 250 return -ENOMEM;
184 251
185 fnic_dbg_prt->buffer = vmalloc((3*(trace_max_pages * PAGE_SIZE))); 252 if (*rdata_ptr == fc_trc_flag->fnic_trace) {
186 if (!fnic_dbg_prt->buffer) { 253 fnic_dbg_prt->buffer = vmalloc(3 *
187 kfree(fnic_dbg_prt); 254 (trace_max_pages * PAGE_SIZE));
188 return -ENOMEM; 255 if (!fnic_dbg_prt->buffer) {
256 kfree(fnic_dbg_prt);
257 return -ENOMEM;
258 }
259 memset((void *)fnic_dbg_prt->buffer, 0,
260 3 * (trace_max_pages * PAGE_SIZE));
261 fnic_dbg_prt->buffer_len = fnic_get_trace_data(fnic_dbg_prt);
262 } else {
263 fnic_dbg_prt->buffer =
264 vmalloc(3 * (fnic_fc_trace_max_pages * PAGE_SIZE));
265 if (!fnic_dbg_prt->buffer) {
266 kfree(fnic_dbg_prt);
267 return -ENOMEM;
268 }
269 memset((void *)fnic_dbg_prt->buffer, 0,
270 3 * (fnic_fc_trace_max_pages * PAGE_SIZE));
271 fnic_dbg_prt->buffer_len =
272 fnic_fc_trace_get_data(fnic_dbg_prt, *rdata_ptr);
189 } 273 }
190 memset((void *)fnic_dbg_prt->buffer, 0,
191 (3*(trace_max_pages * PAGE_SIZE)));
192 fnic_dbg_prt->buffer_len = fnic_get_trace_data(fnic_dbg_prt);
193 file->private_data = fnic_dbg_prt; 274 file->private_data = fnic_dbg_prt;
275
194 return 0; 276 return 0;
195} 277}
196 278
@@ -272,13 +354,6 @@ static int fnic_trace_debugfs_release(struct inode *inode,
272 return 0; 354 return 0;
273} 355}
274 356
275static const struct file_operations fnic_trace_ctrl_fops = {
276 .owner = THIS_MODULE,
277 .open = fnic_trace_ctrl_open,
278 .read = fnic_trace_ctrl_read,
279 .write = fnic_trace_ctrl_write,
280};
281
282static const struct file_operations fnic_trace_debugfs_fops = { 357static const struct file_operations fnic_trace_debugfs_fops = {
283 .owner = THIS_MODULE, 358 .owner = THIS_MODULE,
284 .open = fnic_trace_debugfs_open, 359 .open = fnic_trace_debugfs_open,
@@ -306,9 +381,10 @@ int fnic_trace_debugfs_init(void)
306 return rc; 381 return rc;
307 } 382 }
308 fnic_trace_enable = debugfs_create_file("tracing_enable", 383 fnic_trace_enable = debugfs_create_file("tracing_enable",
309 S_IFREG|S_IRUGO|S_IWUSR, 384 S_IFREG|S_IRUGO|S_IWUSR,
310 fnic_trace_debugfs_root, 385 fnic_trace_debugfs_root,
311 NULL, &fnic_trace_ctrl_fops); 386 &(fc_trc_flag->fnic_trace),
387 &fnic_trace_ctrl_fops);
312 388
313 if (!fnic_trace_enable) { 389 if (!fnic_trace_enable) {
314 printk(KERN_DEBUG 390 printk(KERN_DEBUG
@@ -317,10 +393,10 @@ int fnic_trace_debugfs_init(void)
317 } 393 }
318 394
319 fnic_trace_debugfs_file = debugfs_create_file("trace", 395 fnic_trace_debugfs_file = debugfs_create_file("trace",
320 S_IFREG|S_IRUGO|S_IWUSR, 396 S_IFREG|S_IRUGO|S_IWUSR,
321 fnic_trace_debugfs_root, 397 fnic_trace_debugfs_root,
322 NULL, 398 &(fc_trc_flag->fnic_trace),
323 &fnic_trace_debugfs_fops); 399 &fnic_trace_debugfs_fops);
324 400
325 if (!fnic_trace_debugfs_file) { 401 if (!fnic_trace_debugfs_file) {
326 printk(KERN_DEBUG 402 printk(KERN_DEBUG
@@ -340,14 +416,104 @@ int fnic_trace_debugfs_init(void)
340 */ 416 */
341void fnic_trace_debugfs_terminate(void) 417void fnic_trace_debugfs_terminate(void)
342{ 418{
343 if (fnic_trace_debugfs_file) { 419 debugfs_remove(fnic_trace_debugfs_file);
344 debugfs_remove(fnic_trace_debugfs_file); 420 fnic_trace_debugfs_file = NULL;
345 fnic_trace_debugfs_file = NULL; 421
422 debugfs_remove(fnic_trace_enable);
423 fnic_trace_enable = NULL;
424}
425
426/*
427 * fnic_fc_trace_debugfs_init -
428 * Initialize debugfs for fnic control frame trace logging
429 *
430 * Description:
431 * When Debugfs is configured this routine sets up the fnic_fc debugfs
432 * file system. If not already created, this routine will create the
433 * create file trace to log fnic fc trace buffer output into debugfs and
434 * it will also create file fc_trace_enable to control enable/disable of
435 * trace logging into trace buffer.
436 */
437
438int fnic_fc_trace_debugfs_init(void)
439{
440 int rc = -1;
441
442 if (!fnic_trace_debugfs_root) {
443 pr_err("fnic:Debugfs root directory doesn't exist\n");
444 return rc;
445 }
446
447 fnic_fc_trace_enable = debugfs_create_file("fc_trace_enable",
448 S_IFREG|S_IRUGO|S_IWUSR,
449 fnic_trace_debugfs_root,
450 &(fc_trc_flag->fc_trace),
451 &fnic_trace_ctrl_fops);
452
453 if (!fnic_fc_trace_enable) {
454 pr_err("fnic: Failed create fc_trace_enable file\n");
455 return rc;
456 }
457
458 fnic_fc_trace_clear = debugfs_create_file("fc_trace_clear",
459 S_IFREG|S_IRUGO|S_IWUSR,
460 fnic_trace_debugfs_root,
461 &(fc_trc_flag->fc_clear),
462 &fnic_trace_ctrl_fops);
463
464 if (!fnic_fc_trace_clear) {
465 pr_err("fnic: Failed to create fc_trace_enable file\n");
466 return rc;
467 }
468
469 fnic_fc_rdata_trace_debugfs_file =
470 debugfs_create_file("fc_trace_rdata",
471 S_IFREG|S_IRUGO|S_IWUSR,
472 fnic_trace_debugfs_root,
473 &(fc_trc_flag->fc_normal_file),
474 &fnic_trace_debugfs_fops);
475
476 if (!fnic_fc_rdata_trace_debugfs_file) {
477 pr_err("fnic: Failed create fc_rdata_trace file\n");
478 return rc;
346 } 479 }
347 if (fnic_trace_enable) { 480
348 debugfs_remove(fnic_trace_enable); 481 fnic_fc_trace_debugfs_file =
349 fnic_trace_enable = NULL; 482 debugfs_create_file("fc_trace",
483 S_IFREG|S_IRUGO|S_IWUSR,
484 fnic_trace_debugfs_root,
485 &(fc_trc_flag->fc_row_file),
486 &fnic_trace_debugfs_fops);
487
488 if (!fnic_fc_trace_debugfs_file) {
489 pr_err("fnic: Failed to create fc_trace file\n");
490 return rc;
350 } 491 }
492 rc = 0;
493 return rc;
494}
495
496/*
497 * fnic_fc_trace_debugfs_terminate - Tear down debugfs infrastructure
498 *
499 * Description:
500 * When Debugfs is configured this routine removes debugfs file system
501 * elements that are specific to fnic_fc trace logging.
502 */
503
504void fnic_fc_trace_debugfs_terminate(void)
505{
506 debugfs_remove(fnic_fc_trace_debugfs_file);
507 fnic_fc_trace_debugfs_file = NULL;
508
509 debugfs_remove(fnic_fc_rdata_trace_debugfs_file);
510 fnic_fc_rdata_trace_debugfs_file = NULL;
511
512 debugfs_remove(fnic_fc_trace_enable);
513 fnic_fc_trace_enable = NULL;
514
515 debugfs_remove(fnic_fc_trace_clear);
516 fnic_fc_trace_clear = NULL;
351} 517}
352 518
353/* 519/*
diff --git a/drivers/scsi/fnic/fnic_fcs.c b/drivers/scsi/fnic/fnic_fcs.c
index 1711cd59dece..1b948f633fc5 100644
--- a/drivers/scsi/fnic/fnic_fcs.c
+++ b/drivers/scsi/fnic/fnic_fcs.c
@@ -66,19 +66,35 @@ void fnic_handle_link(struct work_struct *work)
66 fnic->link_down_cnt = vnic_dev_link_down_cnt(fnic->vdev); 66 fnic->link_down_cnt = vnic_dev_link_down_cnt(fnic->vdev);
67 67
68 if (old_link_status == fnic->link_status) { 68 if (old_link_status == fnic->link_status) {
69 if (!fnic->link_status) 69 if (!fnic->link_status) {
70 /* DOWN -> DOWN */ 70 /* DOWN -> DOWN */
71 spin_unlock_irqrestore(&fnic->fnic_lock, flags); 71 spin_unlock_irqrestore(&fnic->fnic_lock, flags);
72 else { 72 fnic_fc_trace_set_data(fnic->lport->host->host_no,
73 FNIC_FC_LE, "Link Status: DOWN->DOWN",
74 strlen("Link Status: DOWN->DOWN"));
75 } else {
73 if (old_link_down_cnt != fnic->link_down_cnt) { 76 if (old_link_down_cnt != fnic->link_down_cnt) {
74 /* UP -> DOWN -> UP */ 77 /* UP -> DOWN -> UP */
75 fnic->lport->host_stats.link_failure_count++; 78 fnic->lport->host_stats.link_failure_count++;
76 spin_unlock_irqrestore(&fnic->fnic_lock, flags); 79 spin_unlock_irqrestore(&fnic->fnic_lock, flags);
80 fnic_fc_trace_set_data(
81 fnic->lport->host->host_no,
82 FNIC_FC_LE,
83 "Link Status:UP_DOWN_UP",
84 strlen("Link_Status:UP_DOWN_UP")
85 );
77 FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, 86 FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host,
78 "link down\n"); 87 "link down\n");
79 fcoe_ctlr_link_down(&fnic->ctlr); 88 fcoe_ctlr_link_down(&fnic->ctlr);
80 if (fnic->config.flags & VFCF_FIP_CAPABLE) { 89 if (fnic->config.flags & VFCF_FIP_CAPABLE) {
81 /* start FCoE VLAN discovery */ 90 /* start FCoE VLAN discovery */
91 fnic_fc_trace_set_data(
92 fnic->lport->host->host_no,
93 FNIC_FC_LE,
94 "Link Status: UP_DOWN_UP_VLAN",
95 strlen(
96 "Link Status: UP_DOWN_UP_VLAN")
97 );
82 fnic_fcoe_send_vlan_req(fnic); 98 fnic_fcoe_send_vlan_req(fnic);
83 return; 99 return;
84 } 100 }
@@ -88,22 +104,36 @@ void fnic_handle_link(struct work_struct *work)
88 } else 104 } else
89 /* UP -> UP */ 105 /* UP -> UP */
90 spin_unlock_irqrestore(&fnic->fnic_lock, flags); 106 spin_unlock_irqrestore(&fnic->fnic_lock, flags);
107 fnic_fc_trace_set_data(
108 fnic->lport->host->host_no, FNIC_FC_LE,
109 "Link Status: UP_UP",
110 strlen("Link Status: UP_UP"));
91 } 111 }
92 } else if (fnic->link_status) { 112 } else if (fnic->link_status) {
93 /* DOWN -> UP */ 113 /* DOWN -> UP */
94 spin_unlock_irqrestore(&fnic->fnic_lock, flags); 114 spin_unlock_irqrestore(&fnic->fnic_lock, flags);
95 if (fnic->config.flags & VFCF_FIP_CAPABLE) { 115 if (fnic->config.flags & VFCF_FIP_CAPABLE) {
96 /* start FCoE VLAN discovery */ 116 /* start FCoE VLAN discovery */
117 fnic_fc_trace_set_data(
118 fnic->lport->host->host_no,
119 FNIC_FC_LE, "Link Status: DOWN_UP_VLAN",
120 strlen("Link Status: DOWN_UP_VLAN"));
97 fnic_fcoe_send_vlan_req(fnic); 121 fnic_fcoe_send_vlan_req(fnic);
98 return; 122 return;
99 } 123 }
100 FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, "link up\n"); 124 FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, "link up\n");
125 fnic_fc_trace_set_data(fnic->lport->host->host_no, FNIC_FC_LE,
126 "Link Status: DOWN_UP", strlen("Link Status: DOWN_UP"));
101 fcoe_ctlr_link_up(&fnic->ctlr); 127 fcoe_ctlr_link_up(&fnic->ctlr);
102 } else { 128 } else {
103 /* UP -> DOWN */ 129 /* UP -> DOWN */
104 fnic->lport->host_stats.link_failure_count++; 130 fnic->lport->host_stats.link_failure_count++;
105 spin_unlock_irqrestore(&fnic->fnic_lock, flags); 131 spin_unlock_irqrestore(&fnic->fnic_lock, flags);
106 FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, "link down\n"); 132 FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, "link down\n");
133 fnic_fc_trace_set_data(
134 fnic->lport->host->host_no, FNIC_FC_LE,
135 "Link Status: UP_DOWN",
136 strlen("Link Status: UP_DOWN"));
107 fcoe_ctlr_link_down(&fnic->ctlr); 137 fcoe_ctlr_link_down(&fnic->ctlr);
108 } 138 }
109 139
@@ -611,6 +641,10 @@ static inline int fnic_import_rq_eth_pkt(struct fnic *fnic, struct sk_buff *skb)
611 "using UCSM\n"); 641 "using UCSM\n");
612 goto drop; 642 goto drop;
613 } 643 }
644 if ((fnic_fc_trace_set_data(fnic->lport->host->host_no,
645 FNIC_FC_RECV|0x80, (char *)skb->data, skb->len)) != 0) {
646 printk(KERN_ERR "fnic ctlr frame trace error!!!");
647 }
614 skb_queue_tail(&fnic->fip_frame_queue, skb); 648 skb_queue_tail(&fnic->fip_frame_queue, skb);
615 queue_work(fnic_fip_queue, &fnic->fip_frame_work); 649 queue_work(fnic_fip_queue, &fnic->fip_frame_work);
616 return 1; /* let caller know packet was used */ 650 return 1; /* let caller know packet was used */
@@ -839,6 +873,10 @@ static void fnic_rq_cmpl_frame_recv(struct vnic_rq *rq, struct cq_desc
839 } 873 }
840 fr_dev(fp) = fnic->lport; 874 fr_dev(fp) = fnic->lport;
841 spin_unlock_irqrestore(&fnic->fnic_lock, flags); 875 spin_unlock_irqrestore(&fnic->fnic_lock, flags);
876 if ((fnic_fc_trace_set_data(fnic->lport->host->host_no, FNIC_FC_RECV,
877 (char *)skb->data, skb->len)) != 0) {
878 printk(KERN_ERR "fnic ctlr frame trace error!!!");
879 }
842 880
843 skb_queue_tail(&fnic->frame_queue, skb); 881 skb_queue_tail(&fnic->frame_queue, skb);
844 queue_work(fnic_event_queue, &fnic->frame_work); 882 queue_work(fnic_event_queue, &fnic->frame_work);
@@ -946,6 +984,15 @@ void fnic_eth_send(struct fcoe_ctlr *fip, struct sk_buff *skb)
946 vlan_hdr->h_vlan_proto = htons(ETH_P_8021Q); 984 vlan_hdr->h_vlan_proto = htons(ETH_P_8021Q);
947 vlan_hdr->h_vlan_encapsulated_proto = eth_hdr->h_proto; 985 vlan_hdr->h_vlan_encapsulated_proto = eth_hdr->h_proto;
948 vlan_hdr->h_vlan_TCI = htons(fnic->vlan_id); 986 vlan_hdr->h_vlan_TCI = htons(fnic->vlan_id);
987 if ((fnic_fc_trace_set_data(fnic->lport->host->host_no,
988 FNIC_FC_SEND|0x80, (char *)eth_hdr, skb->len)) != 0) {
989 printk(KERN_ERR "fnic ctlr frame trace error!!!");
990 }
991 } else {
992 if ((fnic_fc_trace_set_data(fnic->lport->host->host_no,
993 FNIC_FC_SEND|0x80, (char *)skb->data, skb->len)) != 0) {
994 printk(KERN_ERR "fnic ctlr frame trace error!!!");
995 }
949 } 996 }
950 997
951 pa = pci_map_single(fnic->pdev, skb->data, skb->len, PCI_DMA_TODEVICE); 998 pa = pci_map_single(fnic->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
@@ -1018,6 +1065,11 @@ static int fnic_send_frame(struct fnic *fnic, struct fc_frame *fp)
1018 1065
1019 pa = pci_map_single(fnic->pdev, eth_hdr, tot_len, PCI_DMA_TODEVICE); 1066 pa = pci_map_single(fnic->pdev, eth_hdr, tot_len, PCI_DMA_TODEVICE);
1020 1067
1068 if ((fnic_fc_trace_set_data(fnic->lport->host->host_no, FNIC_FC_SEND,
1069 (char *)eth_hdr, tot_len)) != 0) {
1070 printk(KERN_ERR "fnic ctlr frame trace error!!!");
1071 }
1072
1021 spin_lock_irqsave(&fnic->wq_lock[0], flags); 1073 spin_lock_irqsave(&fnic->wq_lock[0], flags);
1022 1074
1023 if (!vnic_wq_desc_avail(wq)) { 1075 if (!vnic_wq_desc_avail(wq)) {
diff --git a/drivers/scsi/fnic/fnic_main.c b/drivers/scsi/fnic/fnic_main.c
index 05657da583a2..8c56fdc3a456 100644
--- a/drivers/scsi/fnic/fnic_main.c
+++ b/drivers/scsi/fnic/fnic_main.c
@@ -74,6 +74,11 @@ module_param(fnic_trace_max_pages, uint, S_IRUGO|S_IWUSR);
74MODULE_PARM_DESC(fnic_trace_max_pages, "Total allocated memory pages " 74MODULE_PARM_DESC(fnic_trace_max_pages, "Total allocated memory pages "
75 "for fnic trace buffer"); 75 "for fnic trace buffer");
76 76
77unsigned int fnic_fc_trace_max_pages = 64;
78module_param(fnic_fc_trace_max_pages, uint, S_IRUGO|S_IWUSR);
79MODULE_PARM_DESC(fnic_fc_trace_max_pages,
80 "Total allocated memory pages for fc trace buffer");
81
77static unsigned int fnic_max_qdepth = FNIC_DFLT_QUEUE_DEPTH; 82static unsigned int fnic_max_qdepth = FNIC_DFLT_QUEUE_DEPTH;
78module_param(fnic_max_qdepth, uint, S_IRUGO|S_IWUSR); 83module_param(fnic_max_qdepth, uint, S_IRUGO|S_IWUSR);
79MODULE_PARM_DESC(fnic_max_qdepth, "Queue depth to report for each LUN"); 84MODULE_PARM_DESC(fnic_max_qdepth, "Queue depth to report for each LUN");
@@ -1034,11 +1039,20 @@ static int __init fnic_init_module(void)
1034 /* Allocate memory for trace buffer */ 1039 /* Allocate memory for trace buffer */
1035 err = fnic_trace_buf_init(); 1040 err = fnic_trace_buf_init();
1036 if (err < 0) { 1041 if (err < 0) {
1037 printk(KERN_ERR PFX "Trace buffer initialization Failed " 1042 printk(KERN_ERR PFX
1038 "Fnic Tracing utility is disabled\n"); 1043 "Trace buffer initialization Failed. "
1044 "Fnic Tracing utility is disabled\n");
1039 fnic_trace_free(); 1045 fnic_trace_free();
1040 } 1046 }
1041 1047
1048 /* Allocate memory for fc trace buffer */
1049 err = fnic_fc_trace_init();
1050 if (err < 0) {
1051 printk(KERN_ERR PFX "FC trace buffer initialization Failed "
1052 "FC frame tracing utility is disabled\n");
1053 fnic_fc_trace_free();
1054 }
1055
1042 /* Create a cache for allocation of default size sgls */ 1056 /* Create a cache for allocation of default size sgls */
1043 len = sizeof(struct fnic_dflt_sgl_list); 1057 len = sizeof(struct fnic_dflt_sgl_list);
1044 fnic_sgl_cache[FNIC_SGL_CACHE_DFLT] = kmem_cache_create 1058 fnic_sgl_cache[FNIC_SGL_CACHE_DFLT] = kmem_cache_create
@@ -1119,6 +1133,7 @@ err_create_fnic_sgl_slab_max:
1119 kmem_cache_destroy(fnic_sgl_cache[FNIC_SGL_CACHE_DFLT]); 1133 kmem_cache_destroy(fnic_sgl_cache[FNIC_SGL_CACHE_DFLT]);
1120err_create_fnic_sgl_slab_dflt: 1134err_create_fnic_sgl_slab_dflt:
1121 fnic_trace_free(); 1135 fnic_trace_free();
1136 fnic_fc_trace_free();
1122 fnic_debugfs_terminate(); 1137 fnic_debugfs_terminate();
1123 return err; 1138 return err;
1124} 1139}
@@ -1136,6 +1151,7 @@ static void __exit fnic_cleanup_module(void)
1136 kmem_cache_destroy(fnic_io_req_cache); 1151 kmem_cache_destroy(fnic_io_req_cache);
1137 fc_release_transport(fnic_fc_transport); 1152 fc_release_transport(fnic_fc_transport);
1138 fnic_trace_free(); 1153 fnic_trace_free();
1154 fnic_fc_trace_free();
1139 fnic_debugfs_terminate(); 1155 fnic_debugfs_terminate();
1140} 1156}
1141 1157
diff --git a/drivers/scsi/fnic/fnic_trace.c b/drivers/scsi/fnic/fnic_trace.c
index e002e7187dc0..c77285926827 100644
--- a/drivers/scsi/fnic/fnic_trace.c
+++ b/drivers/scsi/fnic/fnic_trace.c
@@ -20,6 +20,7 @@
20#include <linux/errno.h> 20#include <linux/errno.h>
21#include <linux/spinlock.h> 21#include <linux/spinlock.h>
22#include <linux/kallsyms.h> 22#include <linux/kallsyms.h>
23#include <linux/time.h>
23#include "fnic_io.h" 24#include "fnic_io.h"
24#include "fnic.h" 25#include "fnic.h"
25 26
@@ -32,6 +33,16 @@ static DEFINE_SPINLOCK(fnic_trace_lock);
32static fnic_trace_dbg_t fnic_trace_entries; 33static fnic_trace_dbg_t fnic_trace_entries;
33int fnic_tracing_enabled = 1; 34int fnic_tracing_enabled = 1;
34 35
36/* static char *fnic_fc_ctlr_trace_buf_p; */
37
38static int fc_trace_max_entries;
39static unsigned long fnic_fc_ctlr_trace_buf_p;
40static fnic_trace_dbg_t fc_trace_entries;
41int fnic_fc_tracing_enabled = 1;
42int fnic_fc_trace_cleared = 1;
43static DEFINE_SPINLOCK(fnic_fc_trace_lock);
44
45
35/* 46/*
36 * fnic_trace_get_buf - Give buffer pointer to user to fill up trace information 47 * fnic_trace_get_buf - Give buffer pointer to user to fill up trace information
37 * 48 *
@@ -428,10 +439,10 @@ int fnic_trace_buf_init(void)
428 } 439 }
429 err = fnic_trace_debugfs_init(); 440 err = fnic_trace_debugfs_init();
430 if (err < 0) { 441 if (err < 0) {
431 printk(KERN_ERR PFX "Failed to initialize debugfs for tracing\n"); 442 pr_err("fnic: Failed to initialize debugfs for tracing\n");
432 goto err_fnic_trace_debugfs_init; 443 goto err_fnic_trace_debugfs_init;
433 } 444 }
434 printk(KERN_INFO PFX "Successfully Initialized Trace Buffer\n"); 445 pr_info("fnic: Successfully Initialized Trace Buffer\n");
435 return err; 446 return err;
436err_fnic_trace_debugfs_init: 447err_fnic_trace_debugfs_init:
437 fnic_trace_free(); 448 fnic_trace_free();
@@ -456,3 +467,314 @@ void fnic_trace_free(void)
456 } 467 }
457 printk(KERN_INFO PFX "Successfully Freed Trace Buffer\n"); 468 printk(KERN_INFO PFX "Successfully Freed Trace Buffer\n");
458} 469}
470
471/*
472 * fnic_fc_ctlr_trace_buf_init -
473 * Initialize trace buffer to log fnic control frames
474 * Description:
475 * Initialize trace buffer data structure by allocating
476 * required memory for trace data as well as for Indexes.
477 * Frame size is 256 bytes and
478 * memory is allocated for 1024 entries of 256 bytes.
479 * Page_offset(Index) is set to the address of trace entry
480 * and page_offset is initialized by adding frame size
481 * to the previous page_offset entry.
482 */
483
484int fnic_fc_trace_init(void)
485{
486 unsigned long fc_trace_buf_head;
487 int err = 0;
488 int i;
489
490 fc_trace_max_entries = (fnic_fc_trace_max_pages * PAGE_SIZE)/
491 FC_TRC_SIZE_BYTES;
492 fnic_fc_ctlr_trace_buf_p = (unsigned long)vmalloc(
493 fnic_fc_trace_max_pages * PAGE_SIZE);
494 if (!fnic_fc_ctlr_trace_buf_p) {
495 pr_err("fnic: Failed to allocate memory for "
496 "FC Control Trace Buf\n");
497 err = -ENOMEM;
498 goto err_fnic_fc_ctlr_trace_buf_init;
499 }
500
501 memset((void *)fnic_fc_ctlr_trace_buf_p, 0,
502 fnic_fc_trace_max_pages * PAGE_SIZE);
503
504 /* Allocate memory for page offset */
505 fc_trace_entries.page_offset = vmalloc(fc_trace_max_entries *
506 sizeof(unsigned long));
507 if (!fc_trace_entries.page_offset) {
508 pr_err("fnic:Failed to allocate memory for page_offset\n");
509 if (fnic_fc_ctlr_trace_buf_p) {
510 pr_err("fnic: Freeing FC Control Trace Buf\n");
511 vfree((void *)fnic_fc_ctlr_trace_buf_p);
512 fnic_fc_ctlr_trace_buf_p = 0;
513 }
514 err = -ENOMEM;
515 goto err_fnic_fc_ctlr_trace_buf_init;
516 }
517 memset((void *)fc_trace_entries.page_offset, 0,
518 (fc_trace_max_entries * sizeof(unsigned long)));
519
520 fc_trace_entries.rd_idx = fc_trace_entries.wr_idx = 0;
521 fc_trace_buf_head = fnic_fc_ctlr_trace_buf_p;
522
523 /*
524 * Set up fc_trace_entries.page_offset field with memory location
525 * for every trace entry
526 */
527 for (i = 0; i < fc_trace_max_entries; i++) {
528 fc_trace_entries.page_offset[i] = fc_trace_buf_head;
529 fc_trace_buf_head += FC_TRC_SIZE_BYTES;
530 }
531 err = fnic_fc_trace_debugfs_init();
532 if (err < 0) {
533 pr_err("fnic: Failed to initialize FC_CTLR tracing.\n");
534 goto err_fnic_fc_ctlr_trace_debugfs_init;
535 }
536 pr_info("fnic: Successfully Initialized FC_CTLR Trace Buffer\n");
537 return err;
538
539err_fnic_fc_ctlr_trace_debugfs_init:
540 fnic_fc_trace_free();
541err_fnic_fc_ctlr_trace_buf_init:
542 return err;
543}
544
545/*
546 * Fnic_fc_ctlr_trace_free - Free memory of fnic_fc_ctlr trace data structures.
547 */
548void fnic_fc_trace_free(void)
549{
550 fnic_fc_tracing_enabled = 0;
551 fnic_fc_trace_debugfs_terminate();
552 if (fc_trace_entries.page_offset) {
553 vfree((void *)fc_trace_entries.page_offset);
554 fc_trace_entries.page_offset = NULL;
555 }
556 if (fnic_fc_ctlr_trace_buf_p) {
557 vfree((void *)fnic_fc_ctlr_trace_buf_p);
558 fnic_fc_ctlr_trace_buf_p = 0;
559 }
560 pr_info("fnic:Successfully FC_CTLR Freed Trace Buffer\n");
561}
562
563/*
564 * fnic_fc_ctlr_set_trace_data:
565 * Maintain rd & wr idx accordingly and set data
566 * Passed parameters:
567 * host_no: host number accociated with fnic
568 * frame_type: send_frame, rece_frame or link event
569 * fc_frame: pointer to fc_frame
570 * frame_len: Length of the fc_frame
571 * Description:
572 * This routine will get next available wr_idx and
573 * copy all passed trace data to the buffer pointed by wr_idx
574 * and increment wr_idx. It will also make sure that we dont
575 * overwrite the entry which we are reading and also
576 * wrap around if we reach the maximum entries.
577 * Returned Value:
578 * It will return 0 for success or -1 for failure
579 */
580int fnic_fc_trace_set_data(u32 host_no, u8 frame_type,
581 char *frame, u32 fc_trc_frame_len)
582{
583 unsigned long flags;
584 struct fc_trace_hdr *fc_buf;
585 unsigned long eth_fcoe_hdr_len;
586 char *fc_trace;
587
588 if (fnic_fc_tracing_enabled == 0)
589 return 0;
590
591 spin_lock_irqsave(&fnic_fc_trace_lock, flags);
592
593 if (fnic_fc_trace_cleared == 1) {
594 fc_trace_entries.rd_idx = fc_trace_entries.wr_idx = 0;
595 pr_info("fnic: Reseting the read idx\n");
596 memset((void *)fnic_fc_ctlr_trace_buf_p, 0,
597 fnic_fc_trace_max_pages * PAGE_SIZE);
598 fnic_fc_trace_cleared = 0;
599 }
600
601 fc_buf = (struct fc_trace_hdr *)
602 fc_trace_entries.page_offset[fc_trace_entries.wr_idx];
603
604 fc_trace_entries.wr_idx++;
605
606 if (fc_trace_entries.wr_idx >= fc_trace_max_entries)
607 fc_trace_entries.wr_idx = 0;
608
609 if (fc_trace_entries.wr_idx == fc_trace_entries.rd_idx) {
610 fc_trace_entries.rd_idx++;
611 if (fc_trace_entries.rd_idx >= fc_trace_max_entries)
612 fc_trace_entries.rd_idx = 0;
613 }
614
615 fc_buf->time_stamp = CURRENT_TIME;
616 fc_buf->host_no = host_no;
617 fc_buf->frame_type = frame_type;
618
619 fc_trace = (char *)FC_TRACE_ADDRESS(fc_buf);
620
621 /* During the receive path, we do not have eth hdr as well as fcoe hdr
622 * at trace entry point so we will stuff 0xff just to make it generic.
623 */
624 if (frame_type == FNIC_FC_RECV) {
625 eth_fcoe_hdr_len = sizeof(struct ethhdr) +
626 sizeof(struct fcoe_hdr);
627 fc_trc_frame_len = fc_trc_frame_len + eth_fcoe_hdr_len;
628 memset((char *)fc_trace, 0xff, eth_fcoe_hdr_len);
629 /* Copy the rest of data frame */
630 memcpy((char *)(fc_trace + eth_fcoe_hdr_len), (void *)frame,
631 min_t(u8, fc_trc_frame_len,
632 (u8)(FC_TRC_SIZE_BYTES - FC_TRC_HEADER_SIZE)));
633 } else {
634 memcpy((char *)fc_trace, (void *)frame,
635 min_t(u8, fc_trc_frame_len,
636 (u8)(FC_TRC_SIZE_BYTES - FC_TRC_HEADER_SIZE)));
637 }
638
639 /* Store the actual received length */
640 fc_buf->frame_len = fc_trc_frame_len;
641
642 spin_unlock_irqrestore(&fnic_fc_trace_lock, flags);
643 return 0;
644}
645
646/*
647 * fnic_fc_ctlr_get_trace_data: Copy trace buffer to a memory file
648 * Passed parameter:
649 * @fnic_dbgfs_t: pointer to debugfs trace buffer
650 * rdata_flag: 1 => Unformated file
651 * 0 => formated file
652 * Description:
653 * This routine will copy the trace data to memory file with
654 * proper formatting and also copy to another memory
655 * file without formatting for further procesing.
656 * Retrun Value:
657 * Number of bytes that were dumped into fnic_dbgfs_t
658 */
659
660int fnic_fc_trace_get_data(fnic_dbgfs_t *fnic_dbgfs_prt, u8 rdata_flag)
661{
662 int rd_idx, wr_idx;
663 unsigned long flags;
664 int len = 0, j;
665 struct fc_trace_hdr *tdata;
666 char *fc_trace;
667
668 spin_lock_irqsave(&fnic_fc_trace_lock, flags);
669 if (fc_trace_entries.wr_idx == fc_trace_entries.rd_idx) {
670 spin_unlock_irqrestore(&fnic_fc_trace_lock, flags);
671 pr_info("fnic: Buffer is empty\n");
672 return 0;
673 }
674 rd_idx = fc_trace_entries.rd_idx;
675 wr_idx = fc_trace_entries.wr_idx;
676 if (rdata_flag == 0) {
677 len += snprintf(fnic_dbgfs_prt->buffer + len,
678 (fnic_fc_trace_max_pages * PAGE_SIZE * 3) - len,
679 "Time Stamp (UTC)\t\t"
680 "Host No: F Type: len: FCoE_FRAME:\n");
681 }
682
683 while (rd_idx != wr_idx) {
684 tdata = (struct fc_trace_hdr *)
685 fc_trace_entries.page_offset[rd_idx];
686 if (!tdata) {
687 pr_info("fnic: Rd data is NULL\n");
688 spin_unlock_irqrestore(&fnic_fc_trace_lock, flags);
689 return 0;
690 }
691 if (rdata_flag == 0) {
692 copy_and_format_trace_data(tdata,
693 fnic_dbgfs_prt, &len, rdata_flag);
694 } else {
695 fc_trace = (char *)tdata;
696 for (j = 0; j < FC_TRC_SIZE_BYTES; j++) {
697 len += snprintf(fnic_dbgfs_prt->buffer + len,
698 (fnic_fc_trace_max_pages * PAGE_SIZE * 3)
699 - len, "%02x", fc_trace[j] & 0xff);
700 } /* for loop */
701 len += snprintf(fnic_dbgfs_prt->buffer + len,
702 (fnic_fc_trace_max_pages * PAGE_SIZE * 3) - len,
703 "\n");
704 }
705 rd_idx++;
706 if (rd_idx > (fc_trace_max_entries - 1))
707 rd_idx = 0;
708 }
709
710 spin_unlock_irqrestore(&fnic_fc_trace_lock, flags);
711 return len;
712}
713
714/*
715 * copy_and_format_trace_data: Copy formatted data to char * buffer
716 * Passed Parameter:
717 * @fc_trace_hdr_t: pointer to trace data
718 * @fnic_dbgfs_t: pointer to debugfs trace buffer
719 * @orig_len: pointer to len
720 * rdata_flag: 0 => Formated file, 1 => Unformated file
721 * Description:
722 * This routine will format and copy the passed trace data
723 * for formated file or unformated file accordingly.
724 */
725
726void copy_and_format_trace_data(struct fc_trace_hdr *tdata,
727 fnic_dbgfs_t *fnic_dbgfs_prt, int *orig_len,
728 u8 rdata_flag)
729{
730 struct tm tm;
731 int j, i = 1, len;
732 char *fc_trace, *fmt;
733 int ethhdr_len = sizeof(struct ethhdr) - 1;
734 int fcoehdr_len = sizeof(struct fcoe_hdr);
735 int fchdr_len = sizeof(struct fc_frame_header);
736 int max_size = fnic_fc_trace_max_pages * PAGE_SIZE * 3;
737
738 tdata->frame_type = tdata->frame_type & 0x7F;
739
740 len = *orig_len;
741
742 time_to_tm(tdata->time_stamp.tv_sec, 0, &tm);
743
744 fmt = "%02d:%02d:%04ld %02d:%02d:%02d.%09lu ns%8x %c%8x\t";
745 len += snprintf(fnic_dbgfs_prt->buffer + len,
746 (fnic_fc_trace_max_pages * PAGE_SIZE * 3) - len,
747 fmt,
748 tm.tm_mon + 1, tm.tm_mday, tm.tm_year + 1900,
749 tm.tm_hour, tm.tm_min, tm.tm_sec,
750 tdata->time_stamp.tv_nsec, tdata->host_no,
751 tdata->frame_type, tdata->frame_len);
752
753 fc_trace = (char *)FC_TRACE_ADDRESS(tdata);
754
755 for (j = 0; j < min_t(u8, tdata->frame_len,
756 (u8)(FC_TRC_SIZE_BYTES - FC_TRC_HEADER_SIZE)); j++) {
757 if (tdata->frame_type == FNIC_FC_LE) {
758 len += snprintf(fnic_dbgfs_prt->buffer + len,
759 max_size - len, "%c", fc_trace[j]);
760 } else {
761 len += snprintf(fnic_dbgfs_prt->buffer + len,
762 max_size - len, "%02x", fc_trace[j] & 0xff);
763 len += snprintf(fnic_dbgfs_prt->buffer + len,
764 max_size - len, " ");
765 if (j == ethhdr_len ||
766 j == ethhdr_len + fcoehdr_len ||
767 j == ethhdr_len + fcoehdr_len + fchdr_len ||
768 (i > 3 && j%fchdr_len == 0)) {
769 len += snprintf(fnic_dbgfs_prt->buffer
770 + len, (fnic_fc_trace_max_pages
771 * PAGE_SIZE * 3) - len,
772 "\n\t\t\t\t\t\t\t\t");
773 i++;
774 }
775 } /* end of else*/
776 } /* End of for loop*/
777 len += snprintf(fnic_dbgfs_prt->buffer + len,
778 max_size - len, "\n");
779 *orig_len = len;
780}
diff --git a/drivers/scsi/fnic/fnic_trace.h b/drivers/scsi/fnic/fnic_trace.h
index d412f2ee3c4f..a8aa0578fcb0 100644
--- a/drivers/scsi/fnic/fnic_trace.h
+++ b/drivers/scsi/fnic/fnic_trace.h
@@ -19,6 +19,17 @@
19#define __FNIC_TRACE_H__ 19#define __FNIC_TRACE_H__
20 20
21#define FNIC_ENTRY_SIZE_BYTES 64 21#define FNIC_ENTRY_SIZE_BYTES 64
22#define FC_TRC_SIZE_BYTES 256
23#define FC_TRC_HEADER_SIZE sizeof(struct fc_trace_hdr)
24
25/*
26 * Fisrt bit of FNIC_FC_RECV and FNIC_FC_SEND is used to represent the type
27 * of frame 1 => Eth frame, 0=> FC frame
28 */
29
30#define FNIC_FC_RECV 0x52 /* Character R */
31#define FNIC_FC_SEND 0x54 /* Character T */
32#define FNIC_FC_LE 0x4C /* Character L */
22 33
23extern ssize_t simple_read_from_buffer(void __user *to, 34extern ssize_t simple_read_from_buffer(void __user *to,
24 size_t count, 35 size_t count,
@@ -30,6 +41,10 @@ extern unsigned int fnic_trace_max_pages;
30extern int fnic_tracing_enabled; 41extern int fnic_tracing_enabled;
31extern unsigned int trace_max_pages; 42extern unsigned int trace_max_pages;
32 43
44extern unsigned int fnic_fc_trace_max_pages;
45extern int fnic_fc_tracing_enabled;
46extern int fnic_fc_trace_cleared;
47
33typedef struct fnic_trace_dbg { 48typedef struct fnic_trace_dbg {
34 int wr_idx; 49 int wr_idx;
35 int rd_idx; 50 int rd_idx;
@@ -56,6 +71,16 @@ struct fnic_trace_data {
56 71
57typedef struct fnic_trace_data fnic_trace_data_t; 72typedef struct fnic_trace_data fnic_trace_data_t;
58 73
74struct fc_trace_hdr {
75 struct timespec time_stamp;
76 u32 host_no;
77 u8 frame_type;
78 u8 frame_len;
79} __attribute__((__packed__));
80
81#define FC_TRACE_ADDRESS(a) \
82 ((unsigned long)(a) + sizeof(struct fc_trace_hdr))
83
59#define FNIC_TRACE_ENTRY_SIZE \ 84#define FNIC_TRACE_ENTRY_SIZE \
60 (FNIC_ENTRY_SIZE_BYTES - sizeof(fnic_trace_data_t)) 85 (FNIC_ENTRY_SIZE_BYTES - sizeof(fnic_trace_data_t))
61 86
@@ -88,4 +113,17 @@ int fnic_debugfs_init(void);
88void fnic_debugfs_terminate(void); 113void fnic_debugfs_terminate(void);
89int fnic_trace_debugfs_init(void); 114int fnic_trace_debugfs_init(void);
90void fnic_trace_debugfs_terminate(void); 115void fnic_trace_debugfs_terminate(void);
116
117/* Fnic FC CTLR Trace releated function */
118int fnic_fc_trace_init(void);
119void fnic_fc_trace_free(void);
120int fnic_fc_trace_set_data(u32 host_no, u8 frame_type,
121 char *frame, u32 fc_frame_len);
122int fnic_fc_trace_get_data(fnic_dbgfs_t *fnic_dbgfs_prt, u8 rdata_flag);
123void copy_and_format_trace_data(struct fc_trace_hdr *tdata,
124 fnic_dbgfs_t *fnic_dbgfs_prt,
125 int *len, u8 rdata_flag);
126int fnic_fc_trace_debugfs_init(void);
127void fnic_fc_trace_debugfs_terminate(void);
128
91#endif 129#endif