lpfc_debugfs.c 26 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007
  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_vport.h"
  44. #include "lpfc_debugfs.h"
  45. #ifdef CONFIG_LPFC_DEBUG_FS
  46. /* debugfs interface
  47. *
  48. * To access this interface the user should:
  49. * # mkdir /debug
  50. * # mount -t debugfs none /debug
  51. *
  52. * The lpfc debugfs directory hierachy is:
  53. * lpfc/lpfcX/vportY
  54. * where X is the lpfc hba unique_id
  55. * where Y is the vport VPI on that hba
  56. *
  57. * Debugging services available per vport:
  58. * discovery_trace
  59. * This is an ACSII readable file that contains a trace of the last
  60. * lpfc_debugfs_max_disc_trc events that happened on a specific vport.
  61. * See lpfc_debugfs.h for different categories of
  62. * discovery events. To enable the discovery trace, the following
  63. * module parameters must be set:
  64. * lpfc_debugfs_enable=1 Turns on lpfc debugfs filesystem support
  65. * lpfc_debugfs_max_disc_trc=X Where X is the event trace depth for
  66. * EACH vport. X MUST also be a power of 2.
  67. * lpfc_debugfs_mask_disc_trc=Y Where Y is an event mask as defined in
  68. * lpfc_debugfs.h .
  69. */
  70. static int lpfc_debugfs_enable = 1;
  71. module_param(lpfc_debugfs_enable, int, 0);
  72. MODULE_PARM_DESC(lpfc_debugfs_enable, "Enable debugfs services");
  73. /* This MUST be a power of 2 */
  74. static int lpfc_debugfs_max_disc_trc = 0;
  75. module_param(lpfc_debugfs_max_disc_trc, int, 0);
  76. MODULE_PARM_DESC(lpfc_debugfs_max_disc_trc,
  77. "Set debugfs discovery trace depth");
  78. /* This MUST be a power of 2 */
  79. static int lpfc_debugfs_max_slow_ring_trc = 0;
  80. module_param(lpfc_debugfs_max_slow_ring_trc, int, 0);
  81. MODULE_PARM_DESC(lpfc_debugfs_max_slow_ring_trc,
  82. "Set debugfs slow ring trace depth");
  83. static int lpfc_debugfs_mask_disc_trc = 0;
  84. module_param(lpfc_debugfs_mask_disc_trc, int, 0);
  85. MODULE_PARM_DESC(lpfc_debugfs_mask_disc_trc,
  86. "Set debugfs discovery trace mask");
  87. #include <linux/debugfs.h>
  88. /* size of output line, for discovery_trace and slow_ring_trace */
  89. #define LPFC_DEBUG_TRC_ENTRY_SIZE 100
  90. /* nodelist output buffer size */
  91. #define LPFC_NODELIST_SIZE 8192
  92. #define LPFC_NODELIST_ENTRY_SIZE 120
  93. /* dumpslim output buffer size */
  94. #define LPFC_DUMPSLIM_SIZE 4096
  95. /* hbqinfo output buffer size */
  96. #define LPFC_HBQINFO_SIZE 8192
  97. struct lpfc_debug {
  98. char *buffer;
  99. int len;
  100. };
  101. extern struct lpfc_hbq_init *lpfc_hbq_defs[];
  102. atomic_t lpfc_debugfs_seq_trc_cnt = ATOMIC_INIT(0);
  103. unsigned long lpfc_debugfs_start_time = 0L;
  104. static int
  105. lpfc_debugfs_disc_trc_data(struct lpfc_vport *vport, char *buf, int size)
  106. {
  107. int i, index, len, enable;
  108. uint32_t ms;
  109. struct lpfc_debugfs_trc *dtp;
  110. char buffer[LPFC_DEBUG_TRC_ENTRY_SIZE];
  111. enable = lpfc_debugfs_enable;
  112. lpfc_debugfs_enable = 0;
  113. len = 0;
  114. index = (atomic_read(&vport->disc_trc_cnt) + 1) &
  115. (lpfc_debugfs_max_disc_trc - 1);
  116. for (i = index; i < lpfc_debugfs_max_disc_trc; i++) {
  117. dtp = vport->disc_trc + i;
  118. if (!dtp->fmt)
  119. continue;
  120. ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
  121. snprintf(buffer,
  122. LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
  123. dtp->seq_cnt, ms, dtp->fmt);
  124. len += snprintf(buf+len, size-len, buffer,
  125. dtp->data1, dtp->data2, dtp->data3);
  126. }
  127. for (i = 0; i < index; i++) {
  128. dtp = vport->disc_trc + i;
  129. if (!dtp->fmt)
  130. continue;
  131. ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
  132. snprintf(buffer,
  133. LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
  134. dtp->seq_cnt, ms, dtp->fmt);
  135. len += snprintf(buf+len, size-len, buffer,
  136. dtp->data1, dtp->data2, dtp->data3);
  137. }
  138. lpfc_debugfs_enable = enable;
  139. return len;
  140. }
  141. static int
  142. lpfc_debugfs_slow_ring_trc_data(struct lpfc_hba *phba, char *buf, int size)
  143. {
  144. int i, index, len, enable;
  145. uint32_t ms;
  146. struct lpfc_debugfs_trc *dtp;
  147. char buffer[LPFC_DEBUG_TRC_ENTRY_SIZE];
  148. enable = lpfc_debugfs_enable;
  149. lpfc_debugfs_enable = 0;
  150. len = 0;
  151. index = (atomic_read(&phba->slow_ring_trc_cnt) + 1) &
  152. (lpfc_debugfs_max_slow_ring_trc - 1);
  153. for (i = index; i < lpfc_debugfs_max_slow_ring_trc; i++) {
  154. dtp = phba->slow_ring_trc + i;
  155. if (!dtp->fmt)
  156. continue;
  157. ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
  158. snprintf(buffer,
  159. LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
  160. dtp->seq_cnt, ms, dtp->fmt);
  161. len += snprintf(buf+len, size-len, buffer,
  162. dtp->data1, dtp->data2, dtp->data3);
  163. }
  164. for (i = 0; i < index; i++) {
  165. dtp = phba->slow_ring_trc + i;
  166. if (!dtp->fmt)
  167. continue;
  168. ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
  169. snprintf(buffer,
  170. LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
  171. dtp->seq_cnt, ms, dtp->fmt);
  172. len += snprintf(buf+len, size-len, buffer,
  173. dtp->data1, dtp->data2, dtp->data3);
  174. }
  175. lpfc_debugfs_enable = enable;
  176. return len;
  177. }
  178. int lpfc_debugfs_last_hbq = -1;
  179. static int
  180. lpfc_debugfs_hbqinfo_data(struct lpfc_hba *phba, char *buf, int size)
  181. {
  182. int len = 0;
  183. int cnt, i, j, found, posted, low;
  184. uint32_t phys, raw_index, getidx;
  185. struct lpfc_hbq_init *hip;
  186. struct hbq_s *hbqs;
  187. struct lpfc_hbq_entry *hbqe;
  188. struct lpfc_dmabuf *d_buf;
  189. struct hbq_dmabuf *hbq_buf;
  190. cnt = LPFC_HBQINFO_SIZE;
  191. spin_lock_irq(&phba->hbalock);
  192. /* toggle between multiple hbqs, if any */
  193. i = lpfc_sli_hbq_count();
  194. if (i > 1) {
  195. lpfc_debugfs_last_hbq++;
  196. if (lpfc_debugfs_last_hbq >= i)
  197. lpfc_debugfs_last_hbq = 0;
  198. }
  199. else
  200. lpfc_debugfs_last_hbq = 0;
  201. i = lpfc_debugfs_last_hbq;
  202. len += snprintf(buf+len, size-len, "HBQ %d Info\n", i);
  203. hbqs = &phba->hbqs[i];
  204. posted = 0;
  205. list_for_each_entry(d_buf, &hbqs->hbq_buffer_list, list)
  206. posted++;
  207. hip = lpfc_hbq_defs[i];
  208. len += snprintf(buf+len, size-len,
  209. "idx:%d prof:%d rn:%d bufcnt:%d icnt:%d acnt:%d posted %d\n",
  210. hip->hbq_index, hip->profile, hip->rn,
  211. hip->buffer_count, hip->init_count, hip->add_count, posted);
  212. raw_index = phba->hbq_get[i];
  213. getidx = le32_to_cpu(raw_index);
  214. len += snprintf(buf+len, size-len,
  215. "entrys:%d Put:%d nPut:%d localGet:%d hbaGet:%d\n",
  216. hbqs->entry_count, hbqs->hbqPutIdx, hbqs->next_hbqPutIdx,
  217. hbqs->local_hbqGetIdx, getidx);
  218. hbqe = (struct lpfc_hbq_entry *) phba->hbqs[i].hbq_virt;
  219. for (j=0; j<hbqs->entry_count; j++) {
  220. len += snprintf(buf+len, size-len,
  221. "%03d: %08x %04x %05x ", j,
  222. hbqe->bde.addrLow, hbqe->bde.tus.w, 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 == 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 = kmalloc(
  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. memset(vport->disc_trc, 0,
  805. (sizeof(struct lpfc_debugfs_trc) * lpfc_debugfs_max_disc_trc));
  806. snprintf(name, sizeof(name), "discovery_trace");
  807. vport->debug_disc_trc =
  808. debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
  809. vport->vport_debugfs_root,
  810. vport, &lpfc_debugfs_op_disc_trc);
  811. if (!vport->debug_disc_trc) {
  812. lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
  813. "0409 Cannot create debugfs "
  814. "discovery_trace\n");
  815. goto debug_failed;
  816. }
  817. snprintf(name, sizeof(name), "nodelist");
  818. vport->debug_nodelist =
  819. debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
  820. vport->vport_debugfs_root,
  821. vport, &lpfc_debugfs_op_nodelist);
  822. if (!vport->debug_nodelist) {
  823. lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
  824. "0409 Cant create debugfs nodelist");
  825. goto debug_failed;
  826. }
  827. debug_failed:
  828. return;
  829. #endif
  830. }
  831. inline void
  832. lpfc_debugfs_terminate(struct lpfc_vport *vport)
  833. {
  834. #ifdef CONFIG_LPFC_DEBUG_FS
  835. struct lpfc_hba *phba = vport->phba;
  836. if (vport->disc_trc) {
  837. kfree(vport->disc_trc);
  838. vport->disc_trc = NULL;
  839. }
  840. if (vport->debug_disc_trc) {
  841. debugfs_remove(vport->debug_disc_trc); /* discovery_trace */
  842. vport->debug_disc_trc = NULL;
  843. }
  844. if (vport->debug_nodelist) {
  845. debugfs_remove(vport->debug_nodelist); /* nodelist */
  846. vport->debug_nodelist = NULL;
  847. }
  848. if (vport->vport_debugfs_root) {
  849. debugfs_remove(vport->vport_debugfs_root); /* vportX */
  850. vport->vport_debugfs_root = NULL;
  851. atomic_dec(&phba->debugfs_vport_count);
  852. }
  853. if (atomic_read(&phba->debugfs_vport_count) == 0) {
  854. if (phba->debug_hbqinfo) {
  855. debugfs_remove(phba->debug_hbqinfo); /* hbqinfo */
  856. phba->debug_hbqinfo = NULL;
  857. }
  858. if (phba->debug_dumpslim) {
  859. debugfs_remove(phba->debug_dumpslim); /* dumpslim */
  860. phba->debug_dumpslim = NULL;
  861. }
  862. if (phba->slow_ring_trc) {
  863. kfree(phba->slow_ring_trc);
  864. phba->slow_ring_trc = NULL;
  865. }
  866. if (phba->debug_slow_ring_trc) {
  867. /* slow_ring_trace */
  868. debugfs_remove(phba->debug_slow_ring_trc);
  869. phba->debug_slow_ring_trc = NULL;
  870. }
  871. if (phba->hba_debugfs_root) {
  872. debugfs_remove(phba->hba_debugfs_root); /* lpfcX */
  873. phba->hba_debugfs_root = NULL;
  874. atomic_dec(&lpfc_debugfs_hba_count);
  875. }
  876. if (atomic_read(&lpfc_debugfs_hba_count) == 0) {
  877. debugfs_remove(lpfc_debugfs_root); /* lpfc */
  878. lpfc_debugfs_root = NULL;
  879. }
  880. }
  881. #endif
  882. return;
  883. }