lpfc_debugfs.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002
  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 Put:%d nPut:%d localGet:%d hbaGet:%d\n",
  214. hbqs->entry_count, hbqs->hbqPutIdx, hbqs->next_hbqPutIdx,
  215. 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. hbqe->bde.addrLow, hbqe->bde.tus.w, hbqe->buffer_tag);
  221. i = 0;
  222. found = 0;
  223. /* First calculate if slot has an associated posted buffer */
  224. low = hbqs->hbqPutIdx - posted;
  225. if (low >= 0) {
  226. if ((j >= hbqs->hbqPutIdx) || (j < low)) {
  227. len += snprintf(buf+len, size-len, "Unused\n");
  228. goto skipit;
  229. }
  230. }
  231. else {
  232. if ((j >= hbqs->hbqPutIdx) &&
  233. (j < (hbqs->entry_count+low))) {
  234. len += snprintf(buf+len, size-len, "Unused\n");
  235. goto skipit;
  236. }
  237. }
  238. /* Get the Buffer info for the posted buffer */
  239. list_for_each_entry(d_buf, &hbqs->hbq_buffer_list, list) {
  240. hbq_buf = container_of(d_buf, struct hbq_dmabuf, dbuf);
  241. phys = ((uint64_t)hbq_buf->dbuf.phys & 0xffffffff);
  242. if (phys == hbqe->bde.addrLow) {
  243. len += snprintf(buf+len, size-len,
  244. "Buf%d: %p %06x\n", i,
  245. hbq_buf->dbuf.virt, hbq_buf->tag);
  246. found = 1;
  247. break;
  248. }
  249. i++;
  250. }
  251. if (!found) {
  252. len += snprintf(buf+len, size-len, "No DMAinfo?\n");
  253. }
  254. skipit:
  255. hbqe++;
  256. if (len > LPFC_HBQINFO_SIZE - 54)
  257. break;
  258. }
  259. spin_unlock_irq(&phba->hbalock);
  260. return len;
  261. }
  262. static int
  263. lpfc_debugfs_dumpslim_data(struct lpfc_hba *phba, char *buf, int size)
  264. {
  265. int len = 0;
  266. int cnt, i, off;
  267. uint32_t word0, word1, word2, word3;
  268. uint32_t *ptr;
  269. struct lpfc_pgp *pgpp;
  270. struct lpfc_sli *psli = &phba->sli;
  271. struct lpfc_sli_ring *pring;
  272. cnt = LPFC_DUMPSLIM_SIZE;
  273. off = 0;
  274. spin_lock_irq(&phba->hbalock);
  275. len += snprintf(buf+len, size-len, "SLIM Mailbox\n");
  276. ptr = (uint32_t *)phba->slim2p;
  277. i = sizeof(MAILBOX_t);
  278. while (i > 0) {
  279. len += snprintf(buf+len, size-len,
  280. "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
  281. off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4),
  282. *(ptr+5), *(ptr+6), *(ptr+7));
  283. ptr += 8;
  284. i -= (8 * sizeof(uint32_t));
  285. off += (8 * sizeof(uint32_t));
  286. }
  287. len += snprintf(buf+len, size-len, "SLIM PCB\n");
  288. ptr = (uint32_t *)&phba->slim2p->pcb;
  289. i = sizeof(PCB_t);
  290. while (i > 0) {
  291. len += snprintf(buf+len, size-len,
  292. "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
  293. off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4),
  294. *(ptr+5), *(ptr+6), *(ptr+7));
  295. ptr += 8;
  296. i -= (8 * sizeof(uint32_t));
  297. off += (8 * sizeof(uint32_t));
  298. }
  299. pgpp = (struct lpfc_pgp *)&phba->slim2p->mbx.us.s3_pgp.port;
  300. pring = &psli->ring[0];
  301. len += snprintf(buf+len, size-len,
  302. "Ring 0: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) "
  303. "RSP PutInx:%d Max:%d\n",
  304. pgpp->cmdGetInx, pring->numCiocb,
  305. pring->next_cmdidx, pring->local_getidx, pring->flag,
  306. pgpp->rspPutInx, pring->numRiocb);
  307. pgpp++;
  308. pring = &psli->ring[1];
  309. len += snprintf(buf+len, size-len,
  310. "Ring 1: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) "
  311. "RSP PutInx:%d Max:%d\n",
  312. pgpp->cmdGetInx, pring->numCiocb,
  313. pring->next_cmdidx, pring->local_getidx, pring->flag,
  314. pgpp->rspPutInx, pring->numRiocb);
  315. pgpp++;
  316. pring = &psli->ring[2];
  317. len += snprintf(buf+len, size-len,
  318. "Ring 2: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) "
  319. "RSP PutInx:%d Max:%d\n",
  320. pgpp->cmdGetInx, pring->numCiocb,
  321. pring->next_cmdidx, pring->local_getidx, pring->flag,
  322. pgpp->rspPutInx, pring->numRiocb);
  323. pgpp++;
  324. pring = &psli->ring[3];
  325. len += snprintf(buf+len, size-len,
  326. "Ring 3: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) "
  327. "RSP PutInx:%d Max:%d\n",
  328. pgpp->cmdGetInx, pring->numCiocb,
  329. pring->next_cmdidx, pring->local_getidx, pring->flag,
  330. pgpp->rspPutInx, pring->numRiocb);
  331. ptr = (uint32_t *)&phba->slim2p->mbx.us.s3_pgp.hbq_get;
  332. word0 = readl(phba->HAregaddr);
  333. word1 = readl(phba->CAregaddr);
  334. word2 = readl(phba->HSregaddr);
  335. word3 = readl(phba->HCregaddr);
  336. len += snprintf(buf+len, size-len, "HA:%08x CA:%08x HS:%08x HC:%08x\n",
  337. word0, word1, word2, word3);
  338. spin_unlock_irq(&phba->hbalock);
  339. return len;
  340. }
  341. static int
  342. lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
  343. {
  344. int len = 0;
  345. int cnt;
  346. struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
  347. struct lpfc_nodelist *ndlp;
  348. unsigned char *statep, *name;
  349. cnt = (LPFC_NODELIST_SIZE / LPFC_NODELIST_ENTRY_SIZE);
  350. spin_lock_irq(shost->host_lock);
  351. list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
  352. if (!cnt) {
  353. len += snprintf(buf+len, size-len,
  354. "Missing Nodelist Entries\n");
  355. break;
  356. }
  357. cnt--;
  358. switch (ndlp->nlp_state) {
  359. case NLP_STE_UNUSED_NODE:
  360. statep = "UNUSED";
  361. break;
  362. case NLP_STE_PLOGI_ISSUE:
  363. statep = "PLOGI ";
  364. break;
  365. case NLP_STE_ADISC_ISSUE:
  366. statep = "ADISC ";
  367. break;
  368. case NLP_STE_REG_LOGIN_ISSUE:
  369. statep = "REGLOG";
  370. break;
  371. case NLP_STE_PRLI_ISSUE:
  372. statep = "PRLI ";
  373. break;
  374. case NLP_STE_UNMAPPED_NODE:
  375. statep = "UNMAP ";
  376. break;
  377. case NLP_STE_MAPPED_NODE:
  378. statep = "MAPPED";
  379. break;
  380. case NLP_STE_NPR_NODE:
  381. statep = "NPR ";
  382. break;
  383. default:
  384. statep = "UNKNOWN";
  385. }
  386. len += snprintf(buf+len, size-len, "%s DID:x%06x ",
  387. statep, ndlp->nlp_DID);
  388. name = (unsigned char *)&ndlp->nlp_portname;
  389. len += snprintf(buf+len, size-len,
  390. "WWPN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ",
  391. *name, *(name+1), *(name+2), *(name+3),
  392. *(name+4), *(name+5), *(name+6), *(name+7));
  393. name = (unsigned char *)&ndlp->nlp_nodename;
  394. len += snprintf(buf+len, size-len,
  395. "WWNN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ",
  396. *name, *(name+1), *(name+2), *(name+3),
  397. *(name+4), *(name+5), *(name+6), *(name+7));
  398. len += snprintf(buf+len, size-len, "RPI:%03d flag:x%08x ",
  399. ndlp->nlp_rpi, ndlp->nlp_flag);
  400. if (!ndlp->nlp_type)
  401. len += snprintf(buf+len, size-len, "UNKNOWN_TYPE ");
  402. if (ndlp->nlp_type & NLP_FC_NODE)
  403. len += snprintf(buf+len, size-len, "FC_NODE ");
  404. if (ndlp->nlp_type & NLP_FABRIC)
  405. len += snprintf(buf+len, size-len, "FABRIC ");
  406. if (ndlp->nlp_type & NLP_FCP_TARGET)
  407. len += snprintf(buf+len, size-len, "FCP_TGT sid:%d ",
  408. ndlp->nlp_sid);
  409. if (ndlp->nlp_type & NLP_FCP_INITIATOR)
  410. len += snprintf(buf+len, size-len, "FCP_INITIATOR ");
  411. len += snprintf(buf+len, size-len, "refcnt:%x",
  412. atomic_read(&ndlp->kref.refcount));
  413. len += snprintf(buf+len, size-len, "\n");
  414. }
  415. spin_unlock_irq(shost->host_lock);
  416. return len;
  417. }
  418. #endif
  419. inline void
  420. lpfc_debugfs_disc_trc(struct lpfc_vport *vport, int mask, char *fmt,
  421. uint32_t data1, uint32_t data2, uint32_t data3)
  422. {
  423. #ifdef CONFIG_LPFC_DEBUG_FS
  424. struct lpfc_debugfs_trc *dtp;
  425. int index;
  426. if (!(lpfc_debugfs_mask_disc_trc & mask))
  427. return;
  428. if (!lpfc_debugfs_enable || !lpfc_debugfs_max_disc_trc ||
  429. !vport || !vport->disc_trc)
  430. return;
  431. index = atomic_inc_return(&vport->disc_trc_cnt) &
  432. (lpfc_debugfs_max_disc_trc - 1);
  433. dtp = vport->disc_trc + index;
  434. dtp->fmt = fmt;
  435. dtp->data1 = data1;
  436. dtp->data2 = data2;
  437. dtp->data3 = data3;
  438. dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt);
  439. dtp->jif = jiffies;
  440. #endif
  441. return;
  442. }
  443. inline void
  444. lpfc_debugfs_slow_ring_trc(struct lpfc_hba *phba, char *fmt,
  445. uint32_t data1, uint32_t data2, uint32_t data3)
  446. {
  447. #ifdef CONFIG_LPFC_DEBUG_FS
  448. struct lpfc_debugfs_trc *dtp;
  449. int index;
  450. if (!lpfc_debugfs_enable || !lpfc_debugfs_max_slow_ring_trc ||
  451. !phba || !phba->slow_ring_trc)
  452. return;
  453. index = atomic_inc_return(&phba->slow_ring_trc_cnt) &
  454. (lpfc_debugfs_max_slow_ring_trc - 1);
  455. dtp = phba->slow_ring_trc + index;
  456. dtp->fmt = fmt;
  457. dtp->data1 = data1;
  458. dtp->data2 = data2;
  459. dtp->data3 = data3;
  460. dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt);
  461. dtp->jif = jiffies;
  462. #endif
  463. return;
  464. }
  465. #ifdef CONFIG_LPFC_DEBUG_FS
  466. static int
  467. lpfc_debugfs_disc_trc_open(struct inode *inode, struct file *file)
  468. {
  469. struct lpfc_vport *vport = inode->i_private;
  470. struct lpfc_debug *debug;
  471. int size;
  472. int rc = -ENOMEM;
  473. if (!lpfc_debugfs_max_disc_trc) {
  474. rc = -ENOSPC;
  475. goto out;
  476. }
  477. debug = kmalloc(sizeof(*debug), GFP_KERNEL);
  478. if (!debug)
  479. goto out;
  480. /* Round to page boundry */
  481. size = (lpfc_debugfs_max_disc_trc * LPFC_DEBUG_TRC_ENTRY_SIZE);
  482. size = PAGE_ALIGN(size);
  483. debug->buffer = kmalloc(size, GFP_KERNEL);
  484. if (!debug->buffer) {
  485. kfree(debug);
  486. goto out;
  487. }
  488. debug->len = lpfc_debugfs_disc_trc_data(vport, debug->buffer, size);
  489. file->private_data = debug;
  490. rc = 0;
  491. out:
  492. return rc;
  493. }
  494. static int
  495. lpfc_debugfs_slow_ring_trc_open(struct inode *inode, struct file *file)
  496. {
  497. struct lpfc_hba *phba = inode->i_private;
  498. struct lpfc_debug *debug;
  499. int size;
  500. int rc = -ENOMEM;
  501. if (!lpfc_debugfs_max_slow_ring_trc) {
  502. rc = -ENOSPC;
  503. goto out;
  504. }
  505. debug = kmalloc(sizeof(*debug), GFP_KERNEL);
  506. if (!debug)
  507. goto out;
  508. /* Round to page boundry */
  509. size = (lpfc_debugfs_max_slow_ring_trc * LPFC_DEBUG_TRC_ENTRY_SIZE);
  510. size = PAGE_ALIGN(size);
  511. debug->buffer = kmalloc(size, GFP_KERNEL);
  512. if (!debug->buffer) {
  513. kfree(debug);
  514. goto out;
  515. }
  516. debug->len = lpfc_debugfs_slow_ring_trc_data(phba, debug->buffer, size);
  517. file->private_data = debug;
  518. rc = 0;
  519. out:
  520. return rc;
  521. }
  522. static int
  523. lpfc_debugfs_hbqinfo_open(struct inode *inode, struct file *file)
  524. {
  525. struct lpfc_hba *phba = inode->i_private;
  526. struct lpfc_debug *debug;
  527. int rc = -ENOMEM;
  528. debug = kmalloc(sizeof(*debug), GFP_KERNEL);
  529. if (!debug)
  530. goto out;
  531. /* Round to page boundry */
  532. debug->buffer = kmalloc(LPFC_HBQINFO_SIZE, GFP_KERNEL);
  533. if (!debug->buffer) {
  534. kfree(debug);
  535. goto out;
  536. }
  537. debug->len = lpfc_debugfs_hbqinfo_data(phba, debug->buffer,
  538. LPFC_HBQINFO_SIZE);
  539. file->private_data = debug;
  540. rc = 0;
  541. out:
  542. return rc;
  543. }
  544. static int
  545. lpfc_debugfs_dumpslim_open(struct inode *inode, struct file *file)
  546. {
  547. struct lpfc_hba *phba = inode->i_private;
  548. struct lpfc_debug *debug;
  549. int rc = -ENOMEM;
  550. debug = kmalloc(sizeof(*debug), GFP_KERNEL);
  551. if (!debug)
  552. goto out;
  553. /* Round to page boundry */
  554. debug->buffer = kmalloc(LPFC_DUMPSLIM_SIZE, GFP_KERNEL);
  555. if (!debug->buffer) {
  556. kfree(debug);
  557. goto out;
  558. }
  559. debug->len = lpfc_debugfs_dumpslim_data(phba, debug->buffer,
  560. LPFC_DUMPSLIM_SIZE);
  561. file->private_data = debug;
  562. rc = 0;
  563. out:
  564. return rc;
  565. }
  566. static int
  567. lpfc_debugfs_nodelist_open(struct inode *inode, struct file *file)
  568. {
  569. struct lpfc_vport *vport = inode->i_private;
  570. struct lpfc_debug *debug;
  571. int rc = -ENOMEM;
  572. debug = kmalloc(sizeof(*debug), GFP_KERNEL);
  573. if (!debug)
  574. goto out;
  575. /* Round to page boundry */
  576. debug->buffer = kmalloc(LPFC_NODELIST_SIZE, GFP_KERNEL);
  577. if (!debug->buffer) {
  578. kfree(debug);
  579. goto out;
  580. }
  581. debug->len = lpfc_debugfs_nodelist_data(vport, debug->buffer,
  582. LPFC_NODELIST_SIZE);
  583. file->private_data = debug;
  584. rc = 0;
  585. out:
  586. return rc;
  587. }
  588. static loff_t
  589. lpfc_debugfs_lseek(struct file *file, loff_t off, int whence)
  590. {
  591. struct lpfc_debug *debug;
  592. loff_t pos = -1;
  593. debug = file->private_data;
  594. switch (whence) {
  595. case 0:
  596. pos = off;
  597. break;
  598. case 1:
  599. pos = file->f_pos + off;
  600. break;
  601. case 2:
  602. pos = debug->len - off;
  603. }
  604. return (pos < 0 || pos > debug->len) ? -EINVAL : (file->f_pos = pos);
  605. }
  606. static ssize_t
  607. lpfc_debugfs_read(struct file *file, char __user *buf,
  608. size_t nbytes, loff_t *ppos)
  609. {
  610. struct lpfc_debug *debug = file->private_data;
  611. return simple_read_from_buffer(buf, nbytes, ppos, debug->buffer,
  612. debug->len);
  613. }
  614. static int
  615. lpfc_debugfs_release(struct inode *inode, struct file *file)
  616. {
  617. struct lpfc_debug *debug = file->private_data;
  618. kfree(debug->buffer);
  619. kfree(debug);
  620. return 0;
  621. }
  622. #undef lpfc_debugfs_op_disc_trc
  623. static struct file_operations lpfc_debugfs_op_disc_trc = {
  624. .owner = THIS_MODULE,
  625. .open = lpfc_debugfs_disc_trc_open,
  626. .llseek = lpfc_debugfs_lseek,
  627. .read = lpfc_debugfs_read,
  628. .release = lpfc_debugfs_release,
  629. };
  630. #undef lpfc_debugfs_op_nodelist
  631. static struct file_operations lpfc_debugfs_op_nodelist = {
  632. .owner = THIS_MODULE,
  633. .open = lpfc_debugfs_nodelist_open,
  634. .llseek = lpfc_debugfs_lseek,
  635. .read = lpfc_debugfs_read,
  636. .release = lpfc_debugfs_release,
  637. };
  638. #undef lpfc_debugfs_op_hbqinfo
  639. static struct file_operations lpfc_debugfs_op_hbqinfo = {
  640. .owner = THIS_MODULE,
  641. .open = lpfc_debugfs_hbqinfo_open,
  642. .llseek = lpfc_debugfs_lseek,
  643. .read = lpfc_debugfs_read,
  644. .release = lpfc_debugfs_release,
  645. };
  646. #undef lpfc_debugfs_op_dumpslim
  647. static struct file_operations lpfc_debugfs_op_dumpslim = {
  648. .owner = THIS_MODULE,
  649. .open = lpfc_debugfs_dumpslim_open,
  650. .llseek = lpfc_debugfs_lseek,
  651. .read = lpfc_debugfs_read,
  652. .release = lpfc_debugfs_release,
  653. };
  654. #undef lpfc_debugfs_op_slow_ring_trc
  655. static struct file_operations lpfc_debugfs_op_slow_ring_trc = {
  656. .owner = THIS_MODULE,
  657. .open = lpfc_debugfs_slow_ring_trc_open,
  658. .llseek = lpfc_debugfs_lseek,
  659. .read = lpfc_debugfs_read,
  660. .release = lpfc_debugfs_release,
  661. };
  662. static struct dentry *lpfc_debugfs_root = NULL;
  663. static atomic_t lpfc_debugfs_hba_count;
  664. #endif
  665. inline void
  666. lpfc_debugfs_initialize(struct lpfc_vport *vport)
  667. {
  668. #ifdef CONFIG_LPFC_DEBUG_FS
  669. struct lpfc_hba *phba = vport->phba;
  670. char name[64];
  671. uint32_t num, i;
  672. if (!lpfc_debugfs_enable)
  673. return;
  674. /* Setup lpfc root directory */
  675. if (!lpfc_debugfs_root) {
  676. lpfc_debugfs_root = debugfs_create_dir("lpfc", NULL);
  677. atomic_set(&lpfc_debugfs_hba_count, 0);
  678. if (!lpfc_debugfs_root) {
  679. lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
  680. "0409 Cannot create debugfs root\n");
  681. goto debug_failed;
  682. }
  683. }
  684. if (!lpfc_debugfs_start_time)
  685. lpfc_debugfs_start_time = jiffies;
  686. /* Setup lpfcX directory for specific HBA */
  687. snprintf(name, sizeof(name), "lpfc%d", phba->brd_no);
  688. if (!phba->hba_debugfs_root) {
  689. phba->hba_debugfs_root =
  690. debugfs_create_dir(name, lpfc_debugfs_root);
  691. if (!phba->hba_debugfs_root) {
  692. lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
  693. "0409 Cannot create debugfs hba\n");
  694. goto debug_failed;
  695. }
  696. atomic_inc(&lpfc_debugfs_hba_count);
  697. atomic_set(&phba->debugfs_vport_count, 0);
  698. /* Setup hbqinfo */
  699. snprintf(name, sizeof(name), "hbqinfo");
  700. phba->debug_hbqinfo =
  701. debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
  702. phba->hba_debugfs_root,
  703. phba, &lpfc_debugfs_op_hbqinfo);
  704. if (!phba->debug_hbqinfo) {
  705. lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
  706. "0409 Cannot create debugfs hbqinfo\n");
  707. goto debug_failed;
  708. }
  709. /* Setup dumpslim */
  710. snprintf(name, sizeof(name), "dumpslim");
  711. phba->debug_dumpslim =
  712. debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
  713. phba->hba_debugfs_root,
  714. phba, &lpfc_debugfs_op_dumpslim);
  715. if (!phba->debug_dumpslim) {
  716. lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
  717. "0409 Cannot create debugfs dumpslim\n");
  718. goto debug_failed;
  719. }
  720. /* Setup slow ring trace */
  721. if (lpfc_debugfs_max_slow_ring_trc) {
  722. num = lpfc_debugfs_max_slow_ring_trc - 1;
  723. if (num & lpfc_debugfs_max_slow_ring_trc) {
  724. /* Change to be a power of 2 */
  725. num = lpfc_debugfs_max_slow_ring_trc;
  726. i = 0;
  727. while (num > 1) {
  728. num = num >> 1;
  729. i++;
  730. }
  731. lpfc_debugfs_max_slow_ring_trc = (1 << i);
  732. printk(KERN_ERR
  733. "lpfc_debugfs_max_disc_trc changed to "
  734. "%d\n", lpfc_debugfs_max_disc_trc);
  735. }
  736. }
  737. snprintf(name, sizeof(name), "slow_ring_trace");
  738. phba->debug_slow_ring_trc =
  739. debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
  740. phba->hba_debugfs_root,
  741. phba, &lpfc_debugfs_op_slow_ring_trc);
  742. if (!phba->debug_slow_ring_trc) {
  743. lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
  744. "0409 Cannot create debugfs "
  745. "slow_ring_trace\n");
  746. goto debug_failed;
  747. }
  748. if (!phba->slow_ring_trc) {
  749. phba->slow_ring_trc = kmalloc(
  750. (sizeof(struct lpfc_debugfs_trc) *
  751. lpfc_debugfs_max_slow_ring_trc),
  752. GFP_KERNEL);
  753. if (!phba->slow_ring_trc) {
  754. lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
  755. "0409 Cannot create debugfs "
  756. "slow_ring buffer\n");
  757. goto debug_failed;
  758. }
  759. atomic_set(&phba->slow_ring_trc_cnt, 0);
  760. memset(phba->slow_ring_trc, 0,
  761. (sizeof(struct lpfc_debugfs_trc) *
  762. lpfc_debugfs_max_slow_ring_trc));
  763. }
  764. }
  765. snprintf(name, sizeof(name), "vport%d", vport->vpi);
  766. if (!vport->vport_debugfs_root) {
  767. vport->vport_debugfs_root =
  768. debugfs_create_dir(name, phba->hba_debugfs_root);
  769. if (!vport->vport_debugfs_root) {
  770. lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
  771. "0409 Cant create debugfs");
  772. goto debug_failed;
  773. }
  774. atomic_inc(&phba->debugfs_vport_count);
  775. }
  776. if (lpfc_debugfs_max_disc_trc) {
  777. num = lpfc_debugfs_max_disc_trc - 1;
  778. if (num & lpfc_debugfs_max_disc_trc) {
  779. /* Change to be a power of 2 */
  780. num = lpfc_debugfs_max_disc_trc;
  781. i = 0;
  782. while (num > 1) {
  783. num = num >> 1;
  784. i++;
  785. }
  786. lpfc_debugfs_max_disc_trc = (1 << i);
  787. printk(KERN_ERR
  788. "lpfc_debugfs_max_disc_trc changed to %d\n",
  789. lpfc_debugfs_max_disc_trc);
  790. }
  791. }
  792. vport->disc_trc = kmzlloc(
  793. (sizeof(struct lpfc_debugfs_trc) * lpfc_debugfs_max_disc_trc),
  794. GFP_KERNEL);
  795. if (!vport->disc_trc) {
  796. lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
  797. "0409 Cannot create debugfs disc trace "
  798. "buffer\n");
  799. goto debug_failed;
  800. }
  801. atomic_set(&vport->disc_trc_cnt, 0);
  802. snprintf(name, sizeof(name), "discovery_trace");
  803. vport->debug_disc_trc =
  804. debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
  805. vport->vport_debugfs_root,
  806. vport, &lpfc_debugfs_op_disc_trc);
  807. if (!vport->debug_disc_trc) {
  808. lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
  809. "0409 Cannot create debugfs "
  810. "discovery_trace\n");
  811. goto debug_failed;
  812. }
  813. snprintf(name, sizeof(name), "nodelist");
  814. vport->debug_nodelist =
  815. debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
  816. vport->vport_debugfs_root,
  817. vport, &lpfc_debugfs_op_nodelist);
  818. if (!vport->debug_nodelist) {
  819. lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
  820. "0409 Cant create debugfs nodelist");
  821. goto debug_failed;
  822. }
  823. debug_failed:
  824. return;
  825. #endif
  826. }
  827. inline void
  828. lpfc_debugfs_terminate(struct lpfc_vport *vport)
  829. {
  830. #ifdef CONFIG_LPFC_DEBUG_FS
  831. struct lpfc_hba *phba = vport->phba;
  832. if (vport->disc_trc) {
  833. kfree(vport->disc_trc);
  834. vport->disc_trc = NULL;
  835. }
  836. if (vport->debug_disc_trc) {
  837. debugfs_remove(vport->debug_disc_trc); /* discovery_trace */
  838. vport->debug_disc_trc = NULL;
  839. }
  840. if (vport->debug_nodelist) {
  841. debugfs_remove(vport->debug_nodelist); /* nodelist */
  842. vport->debug_nodelist = NULL;
  843. }
  844. if (vport->vport_debugfs_root) {
  845. debugfs_remove(vport->vport_debugfs_root); /* vportX */
  846. vport->vport_debugfs_root = NULL;
  847. atomic_dec(&phba->debugfs_vport_count);
  848. }
  849. if (atomic_read(&phba->debugfs_vport_count) == 0) {
  850. if (phba->debug_hbqinfo) {
  851. debugfs_remove(phba->debug_hbqinfo); /* hbqinfo */
  852. phba->debug_hbqinfo = NULL;
  853. }
  854. if (phba->debug_dumpslim) {
  855. debugfs_remove(phba->debug_dumpslim); /* dumpslim */
  856. phba->debug_dumpslim = NULL;
  857. }
  858. if (phba->slow_ring_trc) {
  859. kfree(phba->slow_ring_trc);
  860. phba->slow_ring_trc = NULL;
  861. }
  862. if (phba->debug_slow_ring_trc) {
  863. /* slow_ring_trace */
  864. debugfs_remove(phba->debug_slow_ring_trc);
  865. phba->debug_slow_ring_trc = NULL;
  866. }
  867. if (phba->hba_debugfs_root) {
  868. debugfs_remove(phba->hba_debugfs_root); /* lpfcX */
  869. phba->hba_debugfs_root = NULL;
  870. atomic_dec(&lpfc_debugfs_hba_count);
  871. }
  872. if (atomic_read(&lpfc_debugfs_hba_count) == 0) {
  873. debugfs_remove(lpfc_debugfs_root); /* lpfc */
  874. lpfc_debugfs_root = NULL;
  875. }
  876. }
  877. #endif
  878. return;
  879. }