lpfc_debugfs.c 26 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004
  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 = kmalloc(
  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. memset(vport->disc_trc, 0,
  803. (sizeof(struct lpfc_debugfs_trc) * lpfc_debugfs_max_disc_trc));
  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. }