lpfc_debugfs.c 26 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003
  1. /*******************************************************************
  2. * This file is part of the Emulex Linux Device Driver for *
  3. * Fibre Channel Host Bus Adapters. *
  4. * Copyright (C) 2007 Emulex. All rights reserved. *
  5. * EMULEX and SLI are trademarks of Emulex. *
  6. * www.emulex.com *
  7. * *
  8. * This program is free software; you can redistribute it and/or *
  9. * modify it under the terms of version 2 of the GNU General *
  10. * Public License as published by the Free Software Foundation. *
  11. * This program is distributed in the hope that it will be useful. *
  12. * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND *
  13. * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, *
  14. * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE *
  15. * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
  16. * TO BE LEGALLY INVALID. See the GNU General Public License for *
  17. * more details, a copy of which can be found in the file COPYING *
  18. * included with this package. *
  19. *******************************************************************/
  20. #include <linux/blkdev.h>
  21. #include <linux/delay.h>
  22. #include <linux/dma-mapping.h>
  23. #include <linux/idr.h>
  24. #include <linux/interrupt.h>
  25. #include <linux/kthread.h>
  26. #include <linux/pci.h>
  27. #include <linux/spinlock.h>
  28. #include <linux/ctype.h>
  29. #include <linux/version.h>
  30. #include <scsi/scsi.h>
  31. #include <scsi/scsi_device.h>
  32. #include <scsi/scsi_host.h>
  33. #include <scsi/scsi_transport_fc.h>
  34. #include "lpfc_hw.h"
  35. #include "lpfc_sli.h"
  36. #include "lpfc_disc.h"
  37. #include "lpfc_scsi.h"
  38. #include "lpfc.h"
  39. #include "lpfc_logmsg.h"
  40. #include "lpfc_crtn.h"
  41. #include "lpfc_vport.h"
  42. #include "lpfc_version.h"
  43. #include "lpfc_debugfs.h"
  44. #ifdef CONFIG_LPFC_DEBUG_FS
  45. /* debugfs interface
  46. *
  47. * To access this interface the user should:
  48. * # mkdir /debug
  49. * # mount -t debugfs none /debug
  50. *
  51. * The lpfc debugfs directory hierachy is:
  52. * lpfc/lpfcX/vportY
  53. * where X is the lpfc hba unique_id
  54. * where Y is the vport VPI on that hba
  55. *
  56. * Debugging services available per vport:
  57. * discovery_trace
  58. * This is an ACSII readable file that contains a trace of the last
  59. * lpfc_debugfs_max_disc_trc events that happened on a specific vport.
  60. * See lpfc_debugfs.h for different categories of
  61. * discovery events. To enable the discovery trace, the following
  62. * module parameters must be set:
  63. * lpfc_debugfs_enable=1 Turns on lpfc debugfs filesystem support
  64. * lpfc_debugfs_max_disc_trc=X Where X is the event trace depth for
  65. * EACH vport. X MUST also be a power of 2.
  66. * lpfc_debugfs_mask_disc_trc=Y Where Y is an event mask as defined in
  67. * lpfc_debugfs.h .
  68. */
  69. static int lpfc_debugfs_enable = 1;
  70. module_param(lpfc_debugfs_enable, int, 0);
  71. MODULE_PARM_DESC(lpfc_debugfs_enable, "Enable debugfs services");
  72. /* This MUST be a power of 2 */
  73. static int lpfc_debugfs_max_disc_trc = 0;
  74. module_param(lpfc_debugfs_max_disc_trc, int, 0);
  75. MODULE_PARM_DESC(lpfc_debugfs_max_disc_trc,
  76. "Set debugfs discovery trace depth");
  77. /* This MUST be a power of 2 */
  78. static int lpfc_debugfs_max_slow_ring_trc = 0;
  79. module_param(lpfc_debugfs_max_slow_ring_trc, int, 0);
  80. MODULE_PARM_DESC(lpfc_debugfs_max_slow_ring_trc,
  81. "Set debugfs slow ring trace depth");
  82. static int lpfc_debugfs_mask_disc_trc = 0;
  83. module_param(lpfc_debugfs_mask_disc_trc, int, 0);
  84. MODULE_PARM_DESC(lpfc_debugfs_mask_disc_trc,
  85. "Set debugfs discovery trace mask");
  86. #include <linux/debugfs.h>
  87. /* size of output line, for discovery_trace and slow_ring_trace */
  88. #define LPFC_DEBUG_TRC_ENTRY_SIZE 100
  89. /* nodelist output buffer size */
  90. #define LPFC_NODELIST_SIZE 8192
  91. #define LPFC_NODELIST_ENTRY_SIZE 120
  92. /* dumpslim output buffer size */
  93. #define LPFC_DUMPSLIM_SIZE 4096
  94. /* hbqinfo output buffer size */
  95. #define LPFC_HBQINFO_SIZE 8192
  96. struct lpfc_debug {
  97. char *buffer;
  98. int len;
  99. };
  100. static atomic_t lpfc_debugfs_seq_trc_cnt = ATOMIC_INIT(0);
  101. static unsigned long lpfc_debugfs_start_time = 0L;
  102. static int
  103. lpfc_debugfs_disc_trc_data(struct lpfc_vport *vport, char *buf, int size)
  104. {
  105. int i, index, len, enable;
  106. uint32_t ms;
  107. struct lpfc_debugfs_trc *dtp;
  108. char buffer[LPFC_DEBUG_TRC_ENTRY_SIZE];
  109. enable = lpfc_debugfs_enable;
  110. lpfc_debugfs_enable = 0;
  111. len = 0;
  112. index = (atomic_read(&vport->disc_trc_cnt) + 1) &
  113. (lpfc_debugfs_max_disc_trc - 1);
  114. for (i = index; i < lpfc_debugfs_max_disc_trc; i++) {
  115. dtp = vport->disc_trc + i;
  116. if (!dtp->fmt)
  117. continue;
  118. ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
  119. snprintf(buffer,
  120. LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
  121. dtp->seq_cnt, ms, dtp->fmt);
  122. len += snprintf(buf+len, size-len, buffer,
  123. dtp->data1, dtp->data2, dtp->data3);
  124. }
  125. for (i = 0; i < index; i++) {
  126. dtp = vport->disc_trc + i;
  127. if (!dtp->fmt)
  128. continue;
  129. ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
  130. snprintf(buffer,
  131. LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
  132. dtp->seq_cnt, ms, dtp->fmt);
  133. len += snprintf(buf+len, size-len, buffer,
  134. dtp->data1, dtp->data2, dtp->data3);
  135. }
  136. lpfc_debugfs_enable = enable;
  137. return len;
  138. }
  139. static int
  140. lpfc_debugfs_slow_ring_trc_data(struct lpfc_hba *phba, char *buf, int size)
  141. {
  142. int i, index, len, enable;
  143. uint32_t ms;
  144. struct lpfc_debugfs_trc *dtp;
  145. char buffer[LPFC_DEBUG_TRC_ENTRY_SIZE];
  146. enable = lpfc_debugfs_enable;
  147. lpfc_debugfs_enable = 0;
  148. len = 0;
  149. index = (atomic_read(&phba->slow_ring_trc_cnt) + 1) &
  150. (lpfc_debugfs_max_slow_ring_trc - 1);
  151. for (i = index; i < lpfc_debugfs_max_slow_ring_trc; i++) {
  152. dtp = phba->slow_ring_trc + i;
  153. if (!dtp->fmt)
  154. continue;
  155. ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
  156. snprintf(buffer,
  157. LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
  158. dtp->seq_cnt, ms, dtp->fmt);
  159. len += snprintf(buf+len, size-len, buffer,
  160. dtp->data1, dtp->data2, dtp->data3);
  161. }
  162. for (i = 0; i < index; i++) {
  163. dtp = phba->slow_ring_trc + i;
  164. if (!dtp->fmt)
  165. continue;
  166. ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
  167. snprintf(buffer,
  168. LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
  169. dtp->seq_cnt, ms, dtp->fmt);
  170. len += snprintf(buf+len, size-len, buffer,
  171. dtp->data1, dtp->data2, dtp->data3);
  172. }
  173. lpfc_debugfs_enable = enable;
  174. return len;
  175. }
  176. static int lpfc_debugfs_last_hbq = -1;
  177. static int
  178. lpfc_debugfs_hbqinfo_data(struct lpfc_hba *phba, char *buf, int size)
  179. {
  180. int len = 0;
  181. int cnt, i, j, found, posted, low;
  182. uint32_t phys, raw_index, getidx;
  183. struct lpfc_hbq_init *hip;
  184. struct hbq_s *hbqs;
  185. struct lpfc_hbq_entry *hbqe;
  186. struct lpfc_dmabuf *d_buf;
  187. struct hbq_dmabuf *hbq_buf;
  188. cnt = LPFC_HBQINFO_SIZE;
  189. spin_lock_irq(&phba->hbalock);
  190. /* toggle between multiple hbqs, if any */
  191. i = lpfc_sli_hbq_count();
  192. if (i > 1) {
  193. lpfc_debugfs_last_hbq++;
  194. if (lpfc_debugfs_last_hbq >= i)
  195. lpfc_debugfs_last_hbq = 0;
  196. }
  197. else
  198. lpfc_debugfs_last_hbq = 0;
  199. i = lpfc_debugfs_last_hbq;
  200. len += snprintf(buf+len, size-len, "HBQ %d Info\n", i);
  201. hbqs = &phba->hbqs[i];
  202. posted = 0;
  203. list_for_each_entry(d_buf, &hbqs->hbq_buffer_list, list)
  204. posted++;
  205. hip = lpfc_hbq_defs[i];
  206. len += snprintf(buf+len, size-len,
  207. "idx:%d prof:%d rn:%d bufcnt:%d icnt:%d acnt:%d posted %d\n",
  208. hip->hbq_index, hip->profile, hip->rn,
  209. hip->buffer_count, hip->init_count, hip->add_count, posted);
  210. raw_index = phba->hbq_get[i];
  211. getidx = le32_to_cpu(raw_index);
  212. len += snprintf(buf+len, size-len,
  213. "entrys:%d bufcnt:%d Put:%d nPut:%d localGet:%d hbaGet:%d\n",
  214. hbqs->entry_count, hbqs->buffer_count, hbqs->hbqPutIdx,
  215. hbqs->next_hbqPutIdx, hbqs->local_hbqGetIdx, getidx);
  216. hbqe = (struct lpfc_hbq_entry *) phba->hbqs[i].hbq_virt;
  217. for (j=0; j<hbqs->entry_count; j++) {
  218. len += snprintf(buf+len, size-len,
  219. "%03d: %08x %04x %05x ", j,
  220. le32_to_cpu(hbqe->bde.addrLow),
  221. le32_to_cpu(hbqe->bde.tus.w),
  222. le32_to_cpu(hbqe->buffer_tag));
  223. i = 0;
  224. found = 0;
  225. /* First calculate if slot has an associated posted buffer */
  226. low = hbqs->hbqPutIdx - posted;
  227. if (low >= 0) {
  228. if ((j >= hbqs->hbqPutIdx) || (j < low)) {
  229. len += snprintf(buf+len, size-len, "Unused\n");
  230. goto skipit;
  231. }
  232. }
  233. else {
  234. if ((j >= hbqs->hbqPutIdx) &&
  235. (j < (hbqs->entry_count+low))) {
  236. len += snprintf(buf+len, size-len, "Unused\n");
  237. goto skipit;
  238. }
  239. }
  240. /* Get the Buffer info for the posted buffer */
  241. list_for_each_entry(d_buf, &hbqs->hbq_buffer_list, list) {
  242. hbq_buf = container_of(d_buf, struct hbq_dmabuf, dbuf);
  243. phys = ((uint64_t)hbq_buf->dbuf.phys & 0xffffffff);
  244. if (phys == le32_to_cpu(hbqe->bde.addrLow)) {
  245. len += snprintf(buf+len, size-len,
  246. "Buf%d: %p %06x\n", i,
  247. hbq_buf->dbuf.virt, hbq_buf->tag);
  248. found = 1;
  249. break;
  250. }
  251. i++;
  252. }
  253. if (!found) {
  254. len += snprintf(buf+len, size-len, "No DMAinfo?\n");
  255. }
  256. skipit:
  257. hbqe++;
  258. if (len > LPFC_HBQINFO_SIZE - 54)
  259. break;
  260. }
  261. spin_unlock_irq(&phba->hbalock);
  262. return len;
  263. }
  264. static int
  265. lpfc_debugfs_dumpslim_data(struct lpfc_hba *phba, char *buf, int size)
  266. {
  267. int len = 0;
  268. int cnt, i, off;
  269. uint32_t word0, word1, word2, word3;
  270. uint32_t *ptr;
  271. struct lpfc_pgp *pgpp;
  272. struct lpfc_sli *psli = &phba->sli;
  273. struct lpfc_sli_ring *pring;
  274. cnt = LPFC_DUMPSLIM_SIZE;
  275. off = 0;
  276. spin_lock_irq(&phba->hbalock);
  277. len += snprintf(buf+len, size-len, "SLIM Mailbox\n");
  278. ptr = (uint32_t *)phba->slim2p;
  279. i = sizeof(MAILBOX_t);
  280. while (i > 0) {
  281. len += snprintf(buf+len, size-len,
  282. "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
  283. off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4),
  284. *(ptr+5), *(ptr+6), *(ptr+7));
  285. ptr += 8;
  286. i -= (8 * sizeof(uint32_t));
  287. off += (8 * sizeof(uint32_t));
  288. }
  289. len += snprintf(buf+len, size-len, "SLIM PCB\n");
  290. ptr = (uint32_t *)&phba->slim2p->pcb;
  291. i = sizeof(PCB_t);
  292. while (i > 0) {
  293. len += snprintf(buf+len, size-len,
  294. "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
  295. off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4),
  296. *(ptr+5), *(ptr+6), *(ptr+7));
  297. ptr += 8;
  298. i -= (8 * sizeof(uint32_t));
  299. off += (8 * sizeof(uint32_t));
  300. }
  301. pgpp = (struct lpfc_pgp *)&phba->slim2p->mbx.us.s3_pgp.port;
  302. pring = &psli->ring[0];
  303. len += snprintf(buf+len, size-len,
  304. "Ring 0: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) "
  305. "RSP PutInx:%d Max:%d\n",
  306. pgpp->cmdGetInx, pring->numCiocb,
  307. pring->next_cmdidx, pring->local_getidx, pring->flag,
  308. pgpp->rspPutInx, pring->numRiocb);
  309. pgpp++;
  310. pring = &psli->ring[1];
  311. len += snprintf(buf+len, size-len,
  312. "Ring 1: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) "
  313. "RSP PutInx:%d Max:%d\n",
  314. pgpp->cmdGetInx, pring->numCiocb,
  315. pring->next_cmdidx, pring->local_getidx, pring->flag,
  316. pgpp->rspPutInx, pring->numRiocb);
  317. pgpp++;
  318. pring = &psli->ring[2];
  319. len += snprintf(buf+len, size-len,
  320. "Ring 2: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) "
  321. "RSP PutInx:%d Max:%d\n",
  322. pgpp->cmdGetInx, pring->numCiocb,
  323. pring->next_cmdidx, pring->local_getidx, pring->flag,
  324. pgpp->rspPutInx, pring->numRiocb);
  325. pgpp++;
  326. pring = &psli->ring[3];
  327. len += snprintf(buf+len, size-len,
  328. "Ring 3: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) "
  329. "RSP PutInx:%d Max:%d\n",
  330. pgpp->cmdGetInx, pring->numCiocb,
  331. pring->next_cmdidx, pring->local_getidx, pring->flag,
  332. pgpp->rspPutInx, pring->numRiocb);
  333. ptr = (uint32_t *)&phba->slim2p->mbx.us.s3_pgp.hbq_get;
  334. word0 = readl(phba->HAregaddr);
  335. word1 = readl(phba->CAregaddr);
  336. word2 = readl(phba->HSregaddr);
  337. word3 = readl(phba->HCregaddr);
  338. len += snprintf(buf+len, size-len, "HA:%08x CA:%08x HS:%08x HC:%08x\n",
  339. word0, word1, word2, word3);
  340. spin_unlock_irq(&phba->hbalock);
  341. return len;
  342. }
  343. static int
  344. lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
  345. {
  346. int len = 0;
  347. int cnt;
  348. struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
  349. struct lpfc_nodelist *ndlp;
  350. unsigned char *statep, *name;
  351. cnt = (LPFC_NODELIST_SIZE / LPFC_NODELIST_ENTRY_SIZE);
  352. spin_lock_irq(shost->host_lock);
  353. list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
  354. if (!cnt) {
  355. len += snprintf(buf+len, size-len,
  356. "Missing Nodelist Entries\n");
  357. break;
  358. }
  359. cnt--;
  360. switch (ndlp->nlp_state) {
  361. case NLP_STE_UNUSED_NODE:
  362. statep = "UNUSED";
  363. break;
  364. case NLP_STE_PLOGI_ISSUE:
  365. statep = "PLOGI ";
  366. break;
  367. case NLP_STE_ADISC_ISSUE:
  368. statep = "ADISC ";
  369. break;
  370. case NLP_STE_REG_LOGIN_ISSUE:
  371. statep = "REGLOG";
  372. break;
  373. case NLP_STE_PRLI_ISSUE:
  374. statep = "PRLI ";
  375. break;
  376. case NLP_STE_UNMAPPED_NODE:
  377. statep = "UNMAP ";
  378. break;
  379. case NLP_STE_MAPPED_NODE:
  380. statep = "MAPPED";
  381. break;
  382. case NLP_STE_NPR_NODE:
  383. statep = "NPR ";
  384. break;
  385. default:
  386. statep = "UNKNOWN";
  387. }
  388. len += snprintf(buf+len, size-len, "%s DID:x%06x ",
  389. statep, ndlp->nlp_DID);
  390. name = (unsigned char *)&ndlp->nlp_portname;
  391. len += snprintf(buf+len, size-len,
  392. "WWPN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ",
  393. *name, *(name+1), *(name+2), *(name+3),
  394. *(name+4), *(name+5), *(name+6), *(name+7));
  395. name = (unsigned char *)&ndlp->nlp_nodename;
  396. len += snprintf(buf+len, size-len,
  397. "WWNN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ",
  398. *name, *(name+1), *(name+2), *(name+3),
  399. *(name+4), *(name+5), *(name+6), *(name+7));
  400. len += snprintf(buf+len, size-len, "RPI:%03d flag:x%08x ",
  401. ndlp->nlp_rpi, ndlp->nlp_flag);
  402. if (!ndlp->nlp_type)
  403. len += snprintf(buf+len, size-len, "UNKNOWN_TYPE ");
  404. if (ndlp->nlp_type & NLP_FC_NODE)
  405. len += snprintf(buf+len, size-len, "FC_NODE ");
  406. if (ndlp->nlp_type & NLP_FABRIC)
  407. len += snprintf(buf+len, size-len, "FABRIC ");
  408. if (ndlp->nlp_type & NLP_FCP_TARGET)
  409. len += snprintf(buf+len, size-len, "FCP_TGT sid:%d ",
  410. ndlp->nlp_sid);
  411. if (ndlp->nlp_type & NLP_FCP_INITIATOR)
  412. len += snprintf(buf+len, size-len, "FCP_INITIATOR ");
  413. len += snprintf(buf+len, size-len, "refcnt:%x",
  414. atomic_read(&ndlp->kref.refcount));
  415. len += snprintf(buf+len, size-len, "\n");
  416. }
  417. spin_unlock_irq(shost->host_lock);
  418. return len;
  419. }
  420. #endif
  421. inline void
  422. lpfc_debugfs_disc_trc(struct lpfc_vport *vport, int mask, char *fmt,
  423. uint32_t data1, uint32_t data2, uint32_t data3)
  424. {
  425. #ifdef CONFIG_LPFC_DEBUG_FS
  426. struct lpfc_debugfs_trc *dtp;
  427. int index;
  428. if (!(lpfc_debugfs_mask_disc_trc & mask))
  429. return;
  430. if (!lpfc_debugfs_enable || !lpfc_debugfs_max_disc_trc ||
  431. !vport || !vport->disc_trc)
  432. return;
  433. index = atomic_inc_return(&vport->disc_trc_cnt) &
  434. (lpfc_debugfs_max_disc_trc - 1);
  435. dtp = vport->disc_trc + index;
  436. dtp->fmt = fmt;
  437. dtp->data1 = data1;
  438. dtp->data2 = data2;
  439. dtp->data3 = data3;
  440. dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt);
  441. dtp->jif = jiffies;
  442. #endif
  443. return;
  444. }
  445. inline void
  446. lpfc_debugfs_slow_ring_trc(struct lpfc_hba *phba, char *fmt,
  447. uint32_t data1, uint32_t data2, uint32_t data3)
  448. {
  449. #ifdef CONFIG_LPFC_DEBUG_FS
  450. struct lpfc_debugfs_trc *dtp;
  451. int index;
  452. if (!lpfc_debugfs_enable || !lpfc_debugfs_max_slow_ring_trc ||
  453. !phba || !phba->slow_ring_trc)
  454. return;
  455. index = atomic_inc_return(&phba->slow_ring_trc_cnt) &
  456. (lpfc_debugfs_max_slow_ring_trc - 1);
  457. dtp = phba->slow_ring_trc + index;
  458. dtp->fmt = fmt;
  459. dtp->data1 = data1;
  460. dtp->data2 = data2;
  461. dtp->data3 = data3;
  462. dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt);
  463. dtp->jif = jiffies;
  464. #endif
  465. return;
  466. }
  467. #ifdef CONFIG_LPFC_DEBUG_FS
  468. static int
  469. lpfc_debugfs_disc_trc_open(struct inode *inode, struct file *file)
  470. {
  471. struct lpfc_vport *vport = inode->i_private;
  472. struct lpfc_debug *debug;
  473. int size;
  474. int rc = -ENOMEM;
  475. if (!lpfc_debugfs_max_disc_trc) {
  476. rc = -ENOSPC;
  477. goto out;
  478. }
  479. debug = kmalloc(sizeof(*debug), GFP_KERNEL);
  480. if (!debug)
  481. goto out;
  482. /* Round to page boundry */
  483. size = (lpfc_debugfs_max_disc_trc * LPFC_DEBUG_TRC_ENTRY_SIZE);
  484. size = PAGE_ALIGN(size);
  485. debug->buffer = kmalloc(size, GFP_KERNEL);
  486. if (!debug->buffer) {
  487. kfree(debug);
  488. goto out;
  489. }
  490. debug->len = lpfc_debugfs_disc_trc_data(vport, debug->buffer, size);
  491. file->private_data = debug;
  492. rc = 0;
  493. out:
  494. return rc;
  495. }
  496. static int
  497. lpfc_debugfs_slow_ring_trc_open(struct inode *inode, struct file *file)
  498. {
  499. struct lpfc_hba *phba = inode->i_private;
  500. struct lpfc_debug *debug;
  501. int size;
  502. int rc = -ENOMEM;
  503. if (!lpfc_debugfs_max_slow_ring_trc) {
  504. rc = -ENOSPC;
  505. goto out;
  506. }
  507. debug = kmalloc(sizeof(*debug), GFP_KERNEL);
  508. if (!debug)
  509. goto out;
  510. /* Round to page boundry */
  511. size = (lpfc_debugfs_max_slow_ring_trc * LPFC_DEBUG_TRC_ENTRY_SIZE);
  512. size = PAGE_ALIGN(size);
  513. debug->buffer = kmalloc(size, GFP_KERNEL);
  514. if (!debug->buffer) {
  515. kfree(debug);
  516. goto out;
  517. }
  518. debug->len = lpfc_debugfs_slow_ring_trc_data(phba, debug->buffer, size);
  519. file->private_data = debug;
  520. rc = 0;
  521. out:
  522. return rc;
  523. }
  524. static int
  525. lpfc_debugfs_hbqinfo_open(struct inode *inode, struct file *file)
  526. {
  527. struct lpfc_hba *phba = inode->i_private;
  528. struct lpfc_debug *debug;
  529. int rc = -ENOMEM;
  530. debug = kmalloc(sizeof(*debug), GFP_KERNEL);
  531. if (!debug)
  532. goto out;
  533. /* Round to page boundry */
  534. debug->buffer = kmalloc(LPFC_HBQINFO_SIZE, GFP_KERNEL);
  535. if (!debug->buffer) {
  536. kfree(debug);
  537. goto out;
  538. }
  539. debug->len = lpfc_debugfs_hbqinfo_data(phba, debug->buffer,
  540. LPFC_HBQINFO_SIZE);
  541. file->private_data = debug;
  542. rc = 0;
  543. out:
  544. return rc;
  545. }
  546. static int
  547. lpfc_debugfs_dumpslim_open(struct inode *inode, struct file *file)
  548. {
  549. struct lpfc_hba *phba = inode->i_private;
  550. struct lpfc_debug *debug;
  551. int rc = -ENOMEM;
  552. debug = kmalloc(sizeof(*debug), GFP_KERNEL);
  553. if (!debug)
  554. goto out;
  555. /* Round to page boundry */
  556. debug->buffer = kmalloc(LPFC_DUMPSLIM_SIZE, GFP_KERNEL);
  557. if (!debug->buffer) {
  558. kfree(debug);
  559. goto out;
  560. }
  561. debug->len = lpfc_debugfs_dumpslim_data(phba, debug->buffer,
  562. LPFC_DUMPSLIM_SIZE);
  563. file->private_data = debug;
  564. rc = 0;
  565. out:
  566. return rc;
  567. }
  568. static int
  569. lpfc_debugfs_nodelist_open(struct inode *inode, struct file *file)
  570. {
  571. struct lpfc_vport *vport = inode->i_private;
  572. struct lpfc_debug *debug;
  573. int rc = -ENOMEM;
  574. debug = kmalloc(sizeof(*debug), GFP_KERNEL);
  575. if (!debug)
  576. goto out;
  577. /* Round to page boundry */
  578. debug->buffer = kmalloc(LPFC_NODELIST_SIZE, GFP_KERNEL);
  579. if (!debug->buffer) {
  580. kfree(debug);
  581. goto out;
  582. }
  583. debug->len = lpfc_debugfs_nodelist_data(vport, debug->buffer,
  584. LPFC_NODELIST_SIZE);
  585. file->private_data = debug;
  586. rc = 0;
  587. out:
  588. return rc;
  589. }
  590. static loff_t
  591. lpfc_debugfs_lseek(struct file *file, loff_t off, int whence)
  592. {
  593. struct lpfc_debug *debug;
  594. loff_t pos = -1;
  595. debug = file->private_data;
  596. switch (whence) {
  597. case 0:
  598. pos = off;
  599. break;
  600. case 1:
  601. pos = file->f_pos + off;
  602. break;
  603. case 2:
  604. pos = debug->len - off;
  605. }
  606. return (pos < 0 || pos > debug->len) ? -EINVAL : (file->f_pos = pos);
  607. }
  608. static ssize_t
  609. lpfc_debugfs_read(struct file *file, char __user *buf,
  610. size_t nbytes, loff_t *ppos)
  611. {
  612. struct lpfc_debug *debug = file->private_data;
  613. return simple_read_from_buffer(buf, nbytes, ppos, debug->buffer,
  614. debug->len);
  615. }
  616. static int
  617. lpfc_debugfs_release(struct inode *inode, struct file *file)
  618. {
  619. struct lpfc_debug *debug = file->private_data;
  620. kfree(debug->buffer);
  621. kfree(debug);
  622. return 0;
  623. }
  624. #undef lpfc_debugfs_op_disc_trc
  625. static struct file_operations lpfc_debugfs_op_disc_trc = {
  626. .owner = THIS_MODULE,
  627. .open = lpfc_debugfs_disc_trc_open,
  628. .llseek = lpfc_debugfs_lseek,
  629. .read = lpfc_debugfs_read,
  630. .release = lpfc_debugfs_release,
  631. };
  632. #undef lpfc_debugfs_op_nodelist
  633. static struct file_operations lpfc_debugfs_op_nodelist = {
  634. .owner = THIS_MODULE,
  635. .open = lpfc_debugfs_nodelist_open,
  636. .llseek = lpfc_debugfs_lseek,
  637. .read = lpfc_debugfs_read,
  638. .release = lpfc_debugfs_release,
  639. };
  640. #undef lpfc_debugfs_op_hbqinfo
  641. static struct file_operations lpfc_debugfs_op_hbqinfo = {
  642. .owner = THIS_MODULE,
  643. .open = lpfc_debugfs_hbqinfo_open,
  644. .llseek = lpfc_debugfs_lseek,
  645. .read = lpfc_debugfs_read,
  646. .release = lpfc_debugfs_release,
  647. };
  648. #undef lpfc_debugfs_op_dumpslim
  649. static struct file_operations lpfc_debugfs_op_dumpslim = {
  650. .owner = THIS_MODULE,
  651. .open = lpfc_debugfs_dumpslim_open,
  652. .llseek = lpfc_debugfs_lseek,
  653. .read = lpfc_debugfs_read,
  654. .release = lpfc_debugfs_release,
  655. };
  656. #undef lpfc_debugfs_op_slow_ring_trc
  657. static struct file_operations lpfc_debugfs_op_slow_ring_trc = {
  658. .owner = THIS_MODULE,
  659. .open = lpfc_debugfs_slow_ring_trc_open,
  660. .llseek = lpfc_debugfs_lseek,
  661. .read = lpfc_debugfs_read,
  662. .release = lpfc_debugfs_release,
  663. };
  664. static struct dentry *lpfc_debugfs_root = NULL;
  665. static atomic_t lpfc_debugfs_hba_count;
  666. #endif
  667. inline void
  668. lpfc_debugfs_initialize(struct lpfc_vport *vport)
  669. {
  670. #ifdef CONFIG_LPFC_DEBUG_FS
  671. struct lpfc_hba *phba = vport->phba;
  672. char name[64];
  673. uint32_t num, i;
  674. if (!lpfc_debugfs_enable)
  675. return;
  676. /* Setup lpfc root directory */
  677. if (!lpfc_debugfs_root) {
  678. lpfc_debugfs_root = debugfs_create_dir("lpfc", NULL);
  679. atomic_set(&lpfc_debugfs_hba_count, 0);
  680. if (!lpfc_debugfs_root) {
  681. lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
  682. "0409 Cannot create debugfs root\n");
  683. goto debug_failed;
  684. }
  685. }
  686. if (!lpfc_debugfs_start_time)
  687. lpfc_debugfs_start_time = jiffies;
  688. /* Setup lpfcX directory for specific HBA */
  689. snprintf(name, sizeof(name), "lpfc%d", phba->brd_no);
  690. if (!phba->hba_debugfs_root) {
  691. phba->hba_debugfs_root =
  692. debugfs_create_dir(name, lpfc_debugfs_root);
  693. if (!phba->hba_debugfs_root) {
  694. lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
  695. "0409 Cannot create debugfs hba\n");
  696. goto debug_failed;
  697. }
  698. atomic_inc(&lpfc_debugfs_hba_count);
  699. atomic_set(&phba->debugfs_vport_count, 0);
  700. /* Setup hbqinfo */
  701. snprintf(name, sizeof(name), "hbqinfo");
  702. phba->debug_hbqinfo =
  703. debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
  704. phba->hba_debugfs_root,
  705. phba, &lpfc_debugfs_op_hbqinfo);
  706. if (!phba->debug_hbqinfo) {
  707. lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
  708. "0409 Cannot create debugfs hbqinfo\n");
  709. goto debug_failed;
  710. }
  711. /* Setup dumpslim */
  712. snprintf(name, sizeof(name), "dumpslim");
  713. phba->debug_dumpslim =
  714. debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
  715. phba->hba_debugfs_root,
  716. phba, &lpfc_debugfs_op_dumpslim);
  717. if (!phba->debug_dumpslim) {
  718. lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
  719. "0409 Cannot create debugfs dumpslim\n");
  720. goto debug_failed;
  721. }
  722. /* Setup slow ring trace */
  723. if (lpfc_debugfs_max_slow_ring_trc) {
  724. num = lpfc_debugfs_max_slow_ring_trc - 1;
  725. if (num & lpfc_debugfs_max_slow_ring_trc) {
  726. /* Change to be a power of 2 */
  727. num = lpfc_debugfs_max_slow_ring_trc;
  728. i = 0;
  729. while (num > 1) {
  730. num = num >> 1;
  731. i++;
  732. }
  733. lpfc_debugfs_max_slow_ring_trc = (1 << i);
  734. printk(KERN_ERR
  735. "lpfc_debugfs_max_disc_trc changed to "
  736. "%d\n", lpfc_debugfs_max_disc_trc);
  737. }
  738. }
  739. snprintf(name, sizeof(name), "slow_ring_trace");
  740. phba->debug_slow_ring_trc =
  741. debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
  742. phba->hba_debugfs_root,
  743. phba, &lpfc_debugfs_op_slow_ring_trc);
  744. if (!phba->debug_slow_ring_trc) {
  745. lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
  746. "0409 Cannot create debugfs "
  747. "slow_ring_trace\n");
  748. goto debug_failed;
  749. }
  750. if (!phba->slow_ring_trc) {
  751. phba->slow_ring_trc = kmalloc(
  752. (sizeof(struct lpfc_debugfs_trc) *
  753. lpfc_debugfs_max_slow_ring_trc),
  754. GFP_KERNEL);
  755. if (!phba->slow_ring_trc) {
  756. lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
  757. "0409 Cannot create debugfs "
  758. "slow_ring buffer\n");
  759. goto debug_failed;
  760. }
  761. atomic_set(&phba->slow_ring_trc_cnt, 0);
  762. memset(phba->slow_ring_trc, 0,
  763. (sizeof(struct lpfc_debugfs_trc) *
  764. lpfc_debugfs_max_slow_ring_trc));
  765. }
  766. }
  767. snprintf(name, sizeof(name), "vport%d", vport->vpi);
  768. if (!vport->vport_debugfs_root) {
  769. vport->vport_debugfs_root =
  770. debugfs_create_dir(name, phba->hba_debugfs_root);
  771. if (!vport->vport_debugfs_root) {
  772. lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
  773. "0409 Cant create debugfs");
  774. goto debug_failed;
  775. }
  776. atomic_inc(&phba->debugfs_vport_count);
  777. }
  778. if (lpfc_debugfs_max_disc_trc) {
  779. num = lpfc_debugfs_max_disc_trc - 1;
  780. if (num & lpfc_debugfs_max_disc_trc) {
  781. /* Change to be a power of 2 */
  782. num = lpfc_debugfs_max_disc_trc;
  783. i = 0;
  784. while (num > 1) {
  785. num = num >> 1;
  786. i++;
  787. }
  788. lpfc_debugfs_max_disc_trc = (1 << i);
  789. printk(KERN_ERR
  790. "lpfc_debugfs_max_disc_trc changed to %d\n",
  791. lpfc_debugfs_max_disc_trc);
  792. }
  793. }
  794. vport->disc_trc = kzalloc(
  795. (sizeof(struct lpfc_debugfs_trc) * lpfc_debugfs_max_disc_trc),
  796. GFP_KERNEL);
  797. if (!vport->disc_trc) {
  798. lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
  799. "0409 Cannot create debugfs disc trace "
  800. "buffer\n");
  801. goto debug_failed;
  802. }
  803. atomic_set(&vport->disc_trc_cnt, 0);
  804. snprintf(name, sizeof(name), "discovery_trace");
  805. vport->debug_disc_trc =
  806. debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
  807. vport->vport_debugfs_root,
  808. vport, &lpfc_debugfs_op_disc_trc);
  809. if (!vport->debug_disc_trc) {
  810. lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
  811. "0409 Cannot create debugfs "
  812. "discovery_trace\n");
  813. goto debug_failed;
  814. }
  815. snprintf(name, sizeof(name), "nodelist");
  816. vport->debug_nodelist =
  817. debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
  818. vport->vport_debugfs_root,
  819. vport, &lpfc_debugfs_op_nodelist);
  820. if (!vport->debug_nodelist) {
  821. lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
  822. "0409 Cant create debugfs nodelist");
  823. goto debug_failed;
  824. }
  825. debug_failed:
  826. return;
  827. #endif
  828. }
  829. inline void
  830. lpfc_debugfs_terminate(struct lpfc_vport *vport)
  831. {
  832. #ifdef CONFIG_LPFC_DEBUG_FS
  833. struct lpfc_hba *phba = vport->phba;
  834. if (vport->disc_trc) {
  835. kfree(vport->disc_trc);
  836. vport->disc_trc = NULL;
  837. }
  838. if (vport->debug_disc_trc) {
  839. debugfs_remove(vport->debug_disc_trc); /* discovery_trace */
  840. vport->debug_disc_trc = NULL;
  841. }
  842. if (vport->debug_nodelist) {
  843. debugfs_remove(vport->debug_nodelist); /* nodelist */
  844. vport->debug_nodelist = NULL;
  845. }
  846. if (vport->vport_debugfs_root) {
  847. debugfs_remove(vport->vport_debugfs_root); /* vportX */
  848. vport->vport_debugfs_root = NULL;
  849. atomic_dec(&phba->debugfs_vport_count);
  850. }
  851. if (atomic_read(&phba->debugfs_vport_count) == 0) {
  852. if (phba->debug_hbqinfo) {
  853. debugfs_remove(phba->debug_hbqinfo); /* hbqinfo */
  854. phba->debug_hbqinfo = NULL;
  855. }
  856. if (phba->debug_dumpslim) {
  857. debugfs_remove(phba->debug_dumpslim); /* dumpslim */
  858. phba->debug_dumpslim = NULL;
  859. }
  860. if (phba->slow_ring_trc) {
  861. kfree(phba->slow_ring_trc);
  862. phba->slow_ring_trc = NULL;
  863. }
  864. if (phba->debug_slow_ring_trc) {
  865. /* slow_ring_trace */
  866. debugfs_remove(phba->debug_slow_ring_trc);
  867. phba->debug_slow_ring_trc = NULL;
  868. }
  869. if (phba->hba_debugfs_root) {
  870. debugfs_remove(phba->hba_debugfs_root); /* lpfcX */
  871. phba->hba_debugfs_root = NULL;
  872. atomic_dec(&lpfc_debugfs_hba_count);
  873. }
  874. if (atomic_read(&lpfc_debugfs_hba_count) == 0) {
  875. debugfs_remove(lpfc_debugfs_root); /* lpfc */
  876. lpfc_debugfs_root = NULL;
  877. }
  878. }
  879. #endif
  880. return;
  881. }