lpfc_attr.c 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291
  1. /*******************************************************************
  2. * This file is part of the Emulex Linux Device Driver for *
  3. * Enterprise Fibre Channel Host Bus Adapters. *
  4. * Refer to the README file included with this package for *
  5. * driver version and adapter support. *
  6. * Copyright (C) 2004 Emulex Corporation. *
  7. * www.emulex.com *
  8. * *
  9. * This program is free software; you can redistribute it and/or *
  10. * modify it under the terms of the GNU General Public License *
  11. * as published by the Free Software Foundation; either version 2 *
  12. * of the License, or (at your option) any later version. *
  13. * *
  14. * This program is distributed in the hope that it will be useful, *
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  17. * GNU General Public License for more details, a copy of which *
  18. * can be found in the file COPYING included with this package. *
  19. *******************************************************************/
  20. /*
  21. * $Id: lpfc_attr.c 1.24 2005/04/13 11:58:55EDT sf_support Exp $
  22. */
  23. #include <linux/ctype.h>
  24. #include <linux/pci.h>
  25. #include <linux/interrupt.h>
  26. #include <scsi/scsi_device.h>
  27. #include <scsi/scsi_host.h>
  28. #include <scsi/scsi_tcq.h>
  29. #include <scsi/scsi_transport_fc.h>
  30. #include "lpfc_hw.h"
  31. #include "lpfc_sli.h"
  32. #include "lpfc_disc.h"
  33. #include "lpfc_scsi.h"
  34. #include "lpfc.h"
  35. #include "lpfc_logmsg.h"
  36. #include "lpfc_version.h"
  37. #include "lpfc_compat.h"
  38. #include "lpfc_crtn.h"
  39. static void
  40. lpfc_jedec_to_ascii(int incr, char hdw[])
  41. {
  42. int i, j;
  43. for (i = 0; i < 8; i++) {
  44. j = (incr & 0xf);
  45. if (j <= 9)
  46. hdw[7 - i] = 0x30 + j;
  47. else
  48. hdw[7 - i] = 0x61 + j - 10;
  49. incr = (incr >> 4);
  50. }
  51. hdw[8] = 0;
  52. return;
  53. }
  54. static ssize_t
  55. lpfc_drvr_version_show(struct class_device *cdev, char *buf)
  56. {
  57. return snprintf(buf, PAGE_SIZE, LPFC_MODULE_DESC "\n");
  58. }
  59. static ssize_t
  60. management_version_show(struct class_device *cdev, char *buf)
  61. {
  62. return snprintf(buf, PAGE_SIZE, DFC_API_VERSION "\n");
  63. }
  64. static ssize_t
  65. lpfc_info_show(struct class_device *cdev, char *buf)
  66. {
  67. struct Scsi_Host *host = class_to_shost(cdev);
  68. return snprintf(buf, PAGE_SIZE, "%s\n",lpfc_info(host));
  69. }
  70. static ssize_t
  71. lpfc_serialnum_show(struct class_device *cdev, char *buf)
  72. {
  73. struct Scsi_Host *host = class_to_shost(cdev);
  74. struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
  75. return snprintf(buf, PAGE_SIZE, "%s\n",phba->SerialNumber);
  76. }
  77. static ssize_t
  78. lpfc_modeldesc_show(struct class_device *cdev, char *buf)
  79. {
  80. struct Scsi_Host *host = class_to_shost(cdev);
  81. struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
  82. return snprintf(buf, PAGE_SIZE, "%s\n",phba->ModelDesc);
  83. }
  84. static ssize_t
  85. lpfc_modelname_show(struct class_device *cdev, char *buf)
  86. {
  87. struct Scsi_Host *host = class_to_shost(cdev);
  88. struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
  89. return snprintf(buf, PAGE_SIZE, "%s\n",phba->ModelName);
  90. }
  91. static ssize_t
  92. lpfc_programtype_show(struct class_device *cdev, char *buf)
  93. {
  94. struct Scsi_Host *host = class_to_shost(cdev);
  95. struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
  96. return snprintf(buf, PAGE_SIZE, "%s\n",phba->ProgramType);
  97. }
  98. static ssize_t
  99. lpfc_portnum_show(struct class_device *cdev, char *buf)
  100. {
  101. struct Scsi_Host *host = class_to_shost(cdev);
  102. struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
  103. return snprintf(buf, PAGE_SIZE, "%s\n",phba->Port);
  104. }
  105. static ssize_t
  106. lpfc_fwrev_show(struct class_device *cdev, char *buf)
  107. {
  108. struct Scsi_Host *host = class_to_shost(cdev);
  109. struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
  110. char fwrev[32];
  111. lpfc_decode_firmware_rev(phba, fwrev, 1);
  112. return snprintf(buf, PAGE_SIZE, "%s\n",fwrev);
  113. }
  114. static ssize_t
  115. lpfc_hdw_show(struct class_device *cdev, char *buf)
  116. {
  117. char hdw[9];
  118. struct Scsi_Host *host = class_to_shost(cdev);
  119. struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
  120. lpfc_vpd_t *vp = &phba->vpd;
  121. lpfc_jedec_to_ascii(vp->rev.biuRev, hdw);
  122. return snprintf(buf, PAGE_SIZE, "%s\n", hdw);
  123. }
  124. static ssize_t
  125. lpfc_option_rom_version_show(struct class_device *cdev, char *buf)
  126. {
  127. struct Scsi_Host *host = class_to_shost(cdev);
  128. struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
  129. return snprintf(buf, PAGE_SIZE, "%s\n", phba->OptionROMVersion);
  130. }
  131. static ssize_t
  132. lpfc_state_show(struct class_device *cdev, char *buf)
  133. {
  134. struct Scsi_Host *host = class_to_shost(cdev);
  135. struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
  136. int len = 0;
  137. switch (phba->hba_state) {
  138. case LPFC_INIT_START:
  139. case LPFC_INIT_MBX_CMDS:
  140. case LPFC_LINK_DOWN:
  141. len += snprintf(buf + len, PAGE_SIZE-len, "Link Down\n");
  142. break;
  143. case LPFC_LINK_UP:
  144. case LPFC_LOCAL_CFG_LINK:
  145. len += snprintf(buf + len, PAGE_SIZE-len, "Link Up\n");
  146. break;
  147. case LPFC_FLOGI:
  148. case LPFC_FABRIC_CFG_LINK:
  149. case LPFC_NS_REG:
  150. case LPFC_NS_QRY:
  151. case LPFC_BUILD_DISC_LIST:
  152. case LPFC_DISC_AUTH:
  153. case LPFC_CLEAR_LA:
  154. len += snprintf(buf + len, PAGE_SIZE-len,
  155. "Link Up - Discovery\n");
  156. break;
  157. case LPFC_HBA_READY:
  158. len += snprintf(buf + len, PAGE_SIZE-len,
  159. "Link Up - Ready:\n");
  160. if (phba->fc_topology == TOPOLOGY_LOOP) {
  161. if (phba->fc_flag & FC_PUBLIC_LOOP)
  162. len += snprintf(buf + len, PAGE_SIZE-len,
  163. " Public Loop\n");
  164. else
  165. len += snprintf(buf + len, PAGE_SIZE-len,
  166. " Private Loop\n");
  167. } else {
  168. if (phba->fc_flag & FC_FABRIC)
  169. len += snprintf(buf + len, PAGE_SIZE-len,
  170. " Fabric\n");
  171. else
  172. len += snprintf(buf + len, PAGE_SIZE-len,
  173. " Point-2-Point\n");
  174. }
  175. }
  176. return len;
  177. }
  178. static ssize_t
  179. lpfc_num_discovered_ports_show(struct class_device *cdev, char *buf)
  180. {
  181. struct Scsi_Host *host = class_to_shost(cdev);
  182. struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
  183. return snprintf(buf, PAGE_SIZE, "%d\n", phba->fc_map_cnt +
  184. phba->fc_unmap_cnt);
  185. }
  186. static ssize_t
  187. lpfc_issue_lip (struct class_device *cdev, const char *buf, size_t count)
  188. {
  189. struct Scsi_Host *host = class_to_shost(cdev);
  190. struct lpfc_hba *phba = (struct lpfc_hba *) host->hostdata[0];
  191. int val = 0;
  192. LPFC_MBOXQ_t *pmboxq;
  193. int mbxstatus = MBXERR_ERROR;
  194. if ((sscanf(buf, "%d", &val) != 1) ||
  195. (val != 1))
  196. return -EINVAL;
  197. if ((phba->fc_flag & FC_OFFLINE_MODE) ||
  198. (phba->hba_state != LPFC_HBA_READY))
  199. return -EPERM;
  200. pmboxq = mempool_alloc(phba->mbox_mem_pool,GFP_KERNEL);
  201. if (!pmboxq)
  202. return -ENOMEM;
  203. memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t));
  204. lpfc_init_link(phba, pmboxq, phba->cfg_topology, phba->cfg_link_speed);
  205. mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
  206. if (mbxstatus == MBX_TIMEOUT)
  207. pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
  208. else
  209. mempool_free( pmboxq, phba->mbox_mem_pool);
  210. if (mbxstatus == MBXERR_ERROR)
  211. return -EIO;
  212. return strlen(buf);
  213. }
  214. static ssize_t
  215. lpfc_nport_evt_cnt_show(struct class_device *cdev, char *buf)
  216. {
  217. struct Scsi_Host *host = class_to_shost(cdev);
  218. struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
  219. return snprintf(buf, PAGE_SIZE, "%d\n", phba->nport_event_cnt);
  220. }
  221. static ssize_t
  222. lpfc_board_online_show(struct class_device *cdev, char *buf)
  223. {
  224. struct Scsi_Host *host = class_to_shost(cdev);
  225. struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
  226. if (!phba) return 0;
  227. if (phba->fc_flag & FC_OFFLINE_MODE)
  228. return snprintf(buf, PAGE_SIZE, "0\n");
  229. else
  230. return snprintf(buf, PAGE_SIZE, "1\n");
  231. }
  232. static ssize_t
  233. lpfc_board_online_store(struct class_device *cdev, const char *buf,
  234. size_t count)
  235. {
  236. struct Scsi_Host *host = class_to_shost(cdev);
  237. struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
  238. struct completion online_compl;
  239. int val=0, status=0;
  240. if (sscanf(buf, "%d", &val) != 1)
  241. return 0;
  242. init_completion(&online_compl);
  243. if (val)
  244. lpfc_workq_post_event(phba, &status, &online_compl,
  245. LPFC_EVT_ONLINE);
  246. else
  247. lpfc_workq_post_event(phba, &status, &online_compl,
  248. LPFC_EVT_OFFLINE);
  249. wait_for_completion(&online_compl);
  250. if (!status)
  251. return strlen(buf);
  252. else
  253. return 0;
  254. }
  255. #define lpfc_param_show(attr) \
  256. static ssize_t \
  257. lpfc_##attr##_show(struct class_device *cdev, char *buf) \
  258. { \
  259. struct Scsi_Host *host = class_to_shost(cdev);\
  260. struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];\
  261. int val = 0;\
  262. if (phba){\
  263. val = phba->cfg_##attr;\
  264. return snprintf(buf, PAGE_SIZE, "%d\n",\
  265. phba->cfg_##attr);\
  266. }\
  267. return 0;\
  268. }
  269. #define lpfc_param_store(attr, minval, maxval) \
  270. static ssize_t \
  271. lpfc_##attr##_store(struct class_device *cdev, const char *buf, size_t count) \
  272. { \
  273. struct Scsi_Host *host = class_to_shost(cdev);\
  274. struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];\
  275. int val = 0;\
  276. if (!isdigit(buf[0]))\
  277. return -EINVAL;\
  278. if (sscanf(buf, "0x%x", &val) != 1)\
  279. if (sscanf(buf, "%d", &val) != 1)\
  280. return -EINVAL;\
  281. if (phba){\
  282. if (val >= minval && val <= maxval) {\
  283. phba->cfg_##attr = val;\
  284. return strlen(buf);\
  285. }\
  286. }\
  287. return 0;\
  288. }
  289. #define LPFC_ATTR_R_NOINIT(name, desc) \
  290. extern int lpfc_##name;\
  291. module_param(lpfc_##name, int, 0);\
  292. MODULE_PARM_DESC(lpfc_##name, desc);\
  293. lpfc_param_show(name)\
  294. static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO , lpfc_##name##_show, NULL)
  295. #define LPFC_ATTR_R(name, defval, minval, maxval, desc) \
  296. static int lpfc_##name = defval;\
  297. module_param(lpfc_##name, int, 0);\
  298. MODULE_PARM_DESC(lpfc_##name, desc);\
  299. lpfc_param_show(name)\
  300. static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO , lpfc_##name##_show, NULL)
  301. #define LPFC_ATTR_RW(name, defval, minval, maxval, desc) \
  302. static int lpfc_##name = defval;\
  303. module_param(lpfc_##name, int, 0);\
  304. MODULE_PARM_DESC(lpfc_##name, desc);\
  305. lpfc_param_show(name)\
  306. lpfc_param_store(name, minval, maxval)\
  307. static CLASS_DEVICE_ATTR(lpfc_##name, S_IRUGO | S_IWUSR,\
  308. lpfc_##name##_show, lpfc_##name##_store)
  309. static CLASS_DEVICE_ATTR(info, S_IRUGO, lpfc_info_show, NULL);
  310. static CLASS_DEVICE_ATTR(serialnum, S_IRUGO, lpfc_serialnum_show, NULL);
  311. static CLASS_DEVICE_ATTR(modeldesc, S_IRUGO, lpfc_modeldesc_show, NULL);
  312. static CLASS_DEVICE_ATTR(modelname, S_IRUGO, lpfc_modelname_show, NULL);
  313. static CLASS_DEVICE_ATTR(programtype, S_IRUGO, lpfc_programtype_show, NULL);
  314. static CLASS_DEVICE_ATTR(portnum, S_IRUGO, lpfc_portnum_show, NULL);
  315. static CLASS_DEVICE_ATTR(fwrev, S_IRUGO, lpfc_fwrev_show, NULL);
  316. static CLASS_DEVICE_ATTR(hdw, S_IRUGO, lpfc_hdw_show, NULL);
  317. static CLASS_DEVICE_ATTR(state, S_IRUGO, lpfc_state_show, NULL);
  318. static CLASS_DEVICE_ATTR(option_rom_version, S_IRUGO,
  319. lpfc_option_rom_version_show, NULL);
  320. static CLASS_DEVICE_ATTR(num_discovered_ports, S_IRUGO,
  321. lpfc_num_discovered_ports_show, NULL);
  322. static CLASS_DEVICE_ATTR(nport_evt_cnt, S_IRUGO, lpfc_nport_evt_cnt_show, NULL);
  323. static CLASS_DEVICE_ATTR(lpfc_drvr_version, S_IRUGO, lpfc_drvr_version_show,
  324. NULL);
  325. static CLASS_DEVICE_ATTR(management_version, S_IRUGO, management_version_show,
  326. NULL);
  327. static CLASS_DEVICE_ATTR(issue_lip, S_IWUSR, NULL, lpfc_issue_lip);
  328. static CLASS_DEVICE_ATTR(board_online, S_IRUGO | S_IWUSR,
  329. lpfc_board_online_show, lpfc_board_online_store);
  330. /*
  331. # lpfc_log_verbose: Only turn this flag on if you are willing to risk being
  332. # deluged with LOTS of information.
  333. # You can set a bit mask to record specific types of verbose messages:
  334. #
  335. # LOG_ELS 0x1 ELS events
  336. # LOG_DISCOVERY 0x2 Link discovery events
  337. # LOG_MBOX 0x4 Mailbox events
  338. # LOG_INIT 0x8 Initialization events
  339. # LOG_LINK_EVENT 0x10 Link events
  340. # LOG_IP 0x20 IP traffic history
  341. # LOG_FCP 0x40 FCP traffic history
  342. # LOG_NODE 0x80 Node table events
  343. # LOG_MISC 0x400 Miscellaneous events
  344. # LOG_SLI 0x800 SLI events
  345. # LOG_CHK_COND 0x1000 FCP Check condition flag
  346. # LOG_LIBDFC 0x2000 LIBDFC events
  347. # LOG_ALL_MSG 0xffff LOG all messages
  348. */
  349. LPFC_ATTR_RW(log_verbose, 0x0, 0x0, 0xffff, "Verbose logging bit-mask");
  350. /*
  351. # lun_queue_depth: This parameter is used to limit the number of outstanding
  352. # commands per FCP LUN. Value range is [1,128]. Default value is 30.
  353. */
  354. LPFC_ATTR_R(lun_queue_depth, 30, 1, 128,
  355. "Max number of FCP commands we can queue to a specific LUN");
  356. /*
  357. # Some disk devices have a "select ID" or "select Target" capability.
  358. # From a protocol standpoint "select ID" usually means select the
  359. # Fibre channel "ALPA". In the FC-AL Profile there is an "informative
  360. # annex" which contains a table that maps a "select ID" (a number
  361. # between 0 and 7F) to an ALPA. By default, for compatibility with
  362. # older drivers, the lpfc driver scans this table from low ALPA to high
  363. # ALPA.
  364. #
  365. # Turning on the scan-down variable (on = 1, off = 0) will
  366. # cause the lpfc driver to use an inverted table, effectively
  367. # scanning ALPAs from high to low. Value range is [0,1]. Default value is 1.
  368. #
  369. # (Note: This "select ID" functionality is a LOOP ONLY characteristic
  370. # and will not work across a fabric. Also this parameter will take
  371. # effect only in the case when ALPA map is not available.)
  372. */
  373. LPFC_ATTR_R(scan_down, 1, 0, 1,
  374. "Start scanning for devices from highest ALPA to lowest");
  375. /*
  376. # lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear
  377. # until the timer expires. Value range is [0,255]. Default value is 20.
  378. # NOTE: this MUST be less then the SCSI Layer command timeout - 1.
  379. */
  380. LPFC_ATTR_RW(nodev_tmo, 30, 0, 255,
  381. "Seconds driver will hold I/O waiting for a device to come back");
  382. /*
  383. # lpfc_topology: link topology for init link
  384. # 0x0 = attempt loop mode then point-to-point
  385. # 0x02 = attempt point-to-point mode only
  386. # 0x04 = attempt loop mode only
  387. # 0x06 = attempt point-to-point mode then loop
  388. # Set point-to-point mode if you want to run as an N_Port.
  389. # Set loop mode if you want to run as an NL_Port. Value range is [0,0x6].
  390. # Default value is 0.
  391. */
  392. LPFC_ATTR_R(topology, 0, 0, 6, "Select Fibre Channel topology");
  393. /*
  394. # lpfc_link_speed: Link speed selection for initializing the Fibre Channel
  395. # connection.
  396. # 0 = auto select (default)
  397. # 1 = 1 Gigabaud
  398. # 2 = 2 Gigabaud
  399. # 4 = 4 Gigabaud
  400. # Value range is [0,4]. Default value is 0.
  401. */
  402. LPFC_ATTR_R(link_speed, 0, 0, 4, "Select link speed");
  403. /*
  404. # lpfc_fcp_class: Determines FC class to use for the FCP protocol.
  405. # Value range is [2,3]. Default value is 3.
  406. */
  407. LPFC_ATTR_R(fcp_class, 3, 2, 3,
  408. "Select Fibre Channel class of service for FCP sequences");
  409. /*
  410. # lpfc_use_adisc: Use ADISC for FCP rediscovery instead of PLOGI. Value range
  411. # is [0,1]. Default value is 0.
  412. */
  413. LPFC_ATTR_RW(use_adisc, 0, 0, 1,
  414. "Use ADISC on rediscovery to authenticate FCP devices");
  415. /*
  416. # lpfc_ack0: Use ACK0, instead of ACK1 for class 2 acknowledgement. Value
  417. # range is [0,1]. Default value is 0.
  418. */
  419. LPFC_ATTR_R(ack0, 0, 0, 1, "Enable ACK0 support");
  420. /*
  421. # lpfc_cr_delay & lpfc_cr_count: Default values for I/O colaesing
  422. # cr_delay (msec) or cr_count outstanding commands. cr_delay can take
  423. # value [0,63]. cr_count can take value [0,255]. Default value of cr_delay
  424. # is 0. Default value of cr_count is 1. The cr_count feature is disabled if
  425. # cr_delay is set to 0.
  426. */
  427. static int lpfc_cr_delay = 0;
  428. module_param(lpfc_cr_delay, int , 0);
  429. MODULE_PARM_DESC(lpfc_cr_delay, "A count of milliseconds after which an "
  430. "interrupt response is generated");
  431. static int lpfc_cr_count = 1;
  432. module_param(lpfc_cr_count, int, 0);
  433. MODULE_PARM_DESC(lpfc_cr_count, "A count of I/O completions after which an "
  434. "interrupt response is generated");
  435. /*
  436. # lpfc_fdmi_on: controls FDMI support.
  437. # 0 = no FDMI support
  438. # 1 = support FDMI without attribute of hostname
  439. # 2 = support FDMI with attribute of hostname
  440. # Value range [0,2]. Default value is 0.
  441. */
  442. LPFC_ATTR_RW(fdmi_on, 0, 0, 2, "Enable FDMI support");
  443. /*
  444. # Specifies the maximum number of ELS cmds we can have outstanding (for
  445. # discovery). Value range is [1,64]. Default value = 32.
  446. */
  447. static int lpfc_discovery_threads = 32;
  448. module_param(lpfc_discovery_threads, int, 0);
  449. MODULE_PARM_DESC(lpfc_discovery_threads, "Maximum number of ELS commands "
  450. "during discovery");
  451. /*
  452. # lpfc_max_luns: maximum number of LUNs per target driver will support
  453. # Value range is [1,32768]. Default value is 256.
  454. # NOTE: The SCSI layer will scan each target for this many luns
  455. */
  456. LPFC_ATTR_R(max_luns, 256, 1, 32768,
  457. "Maximum number of LUNs per target driver will support");
  458. struct class_device_attribute *lpfc_host_attrs[] = {
  459. &class_device_attr_info,
  460. &class_device_attr_serialnum,
  461. &class_device_attr_modeldesc,
  462. &class_device_attr_modelname,
  463. &class_device_attr_programtype,
  464. &class_device_attr_portnum,
  465. &class_device_attr_fwrev,
  466. &class_device_attr_hdw,
  467. &class_device_attr_option_rom_version,
  468. &class_device_attr_state,
  469. &class_device_attr_num_discovered_ports,
  470. &class_device_attr_lpfc_drvr_version,
  471. &class_device_attr_lpfc_log_verbose,
  472. &class_device_attr_lpfc_lun_queue_depth,
  473. &class_device_attr_lpfc_nodev_tmo,
  474. &class_device_attr_lpfc_fcp_class,
  475. &class_device_attr_lpfc_use_adisc,
  476. &class_device_attr_lpfc_ack0,
  477. &class_device_attr_lpfc_topology,
  478. &class_device_attr_lpfc_scan_down,
  479. &class_device_attr_lpfc_link_speed,
  480. &class_device_attr_lpfc_fdmi_on,
  481. &class_device_attr_lpfc_max_luns,
  482. &class_device_attr_nport_evt_cnt,
  483. &class_device_attr_management_version,
  484. &class_device_attr_issue_lip,
  485. &class_device_attr_board_online,
  486. NULL,
  487. };
  488. static ssize_t
  489. sysfs_ctlreg_write(struct kobject *kobj, char *buf, loff_t off, size_t count)
  490. {
  491. size_t buf_off;
  492. struct Scsi_Host *host = class_to_shost(container_of(kobj,
  493. struct class_device, kobj));
  494. struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
  495. if ((off + count) > FF_REG_AREA_SIZE)
  496. return -ERANGE;
  497. if (count == 0) return 0;
  498. if (off % 4 || count % 4 || (unsigned long)buf % 4)
  499. return -EINVAL;
  500. spin_lock_irq(phba->host->host_lock);
  501. if (!(phba->fc_flag & FC_OFFLINE_MODE)) {
  502. spin_unlock_irq(phba->host->host_lock);
  503. return -EPERM;
  504. }
  505. for (buf_off = 0; buf_off < count; buf_off += sizeof(uint32_t))
  506. writel(*((uint32_t *)(buf + buf_off)),
  507. phba->ctrl_regs_memmap_p + off + buf_off);
  508. spin_unlock_irq(phba->host->host_lock);
  509. return count;
  510. }
  511. static ssize_t
  512. sysfs_ctlreg_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
  513. {
  514. size_t buf_off;
  515. uint32_t * tmp_ptr;
  516. struct Scsi_Host *host = class_to_shost(container_of(kobj,
  517. struct class_device, kobj));
  518. struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
  519. if (off > FF_REG_AREA_SIZE)
  520. return -ERANGE;
  521. if ((off + count) > FF_REG_AREA_SIZE)
  522. count = FF_REG_AREA_SIZE - off;
  523. if (count == 0) return 0;
  524. if (off % 4 || count % 4 || (unsigned long)buf % 4)
  525. return -EINVAL;
  526. spin_lock_irq(phba->host->host_lock);
  527. for (buf_off = 0; buf_off < count; buf_off += sizeof(uint32_t)) {
  528. tmp_ptr = (uint32_t *)(buf + buf_off);
  529. *tmp_ptr = readl(phba->ctrl_regs_memmap_p + off + buf_off);
  530. }
  531. spin_unlock_irq(phba->host->host_lock);
  532. return count;
  533. }
  534. static struct bin_attribute sysfs_ctlreg_attr = {
  535. .attr = {
  536. .name = "ctlreg",
  537. .mode = S_IRUSR | S_IWUSR,
  538. .owner = THIS_MODULE,
  539. },
  540. .size = 256,
  541. .read = sysfs_ctlreg_read,
  542. .write = sysfs_ctlreg_write,
  543. };
  544. static void
  545. sysfs_mbox_idle (struct lpfc_hba * phba)
  546. {
  547. phba->sysfs_mbox.state = SMBOX_IDLE;
  548. phba->sysfs_mbox.offset = 0;
  549. if (phba->sysfs_mbox.mbox) {
  550. mempool_free(phba->sysfs_mbox.mbox,
  551. phba->mbox_mem_pool);
  552. phba->sysfs_mbox.mbox = NULL;
  553. }
  554. }
  555. static ssize_t
  556. sysfs_mbox_write(struct kobject *kobj, char *buf, loff_t off, size_t count)
  557. {
  558. struct Scsi_Host * host =
  559. class_to_shost(container_of(kobj, struct class_device, kobj));
  560. struct lpfc_hba * phba = (struct lpfc_hba*)host->hostdata[0];
  561. struct lpfcMboxq * mbox = NULL;
  562. if ((count + off) > MAILBOX_CMD_SIZE)
  563. return -ERANGE;
  564. if (off % 4 || count % 4 || (unsigned long)buf % 4)
  565. return -EINVAL;
  566. if (count == 0)
  567. return 0;
  568. if (off == 0) {
  569. mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
  570. if (!mbox)
  571. return -ENOMEM;
  572. }
  573. spin_lock_irq(host->host_lock);
  574. if (off == 0) {
  575. if (phba->sysfs_mbox.mbox)
  576. mempool_free(mbox, phba->mbox_mem_pool);
  577. else
  578. phba->sysfs_mbox.mbox = mbox;
  579. phba->sysfs_mbox.state = SMBOX_WRITING;
  580. } else {
  581. if (phba->sysfs_mbox.state != SMBOX_WRITING ||
  582. phba->sysfs_mbox.offset != off ||
  583. phba->sysfs_mbox.mbox == NULL ) {
  584. sysfs_mbox_idle(phba);
  585. spin_unlock_irq(host->host_lock);
  586. return -EINVAL;
  587. }
  588. }
  589. memcpy((uint8_t *) & phba->sysfs_mbox.mbox->mb + off,
  590. buf, count);
  591. phba->sysfs_mbox.offset = off + count;
  592. spin_unlock_irq(host->host_lock);
  593. return count;
  594. }
  595. static ssize_t
  596. sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
  597. {
  598. struct Scsi_Host *host =
  599. class_to_shost(container_of(kobj, struct class_device,
  600. kobj));
  601. struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
  602. int rc;
  603. if (off > sizeof(MAILBOX_t))
  604. return -ERANGE;
  605. if ((count + off) > sizeof(MAILBOX_t))
  606. count = sizeof(MAILBOX_t) - off;
  607. if (off % 4 || count % 4 || (unsigned long)buf % 4)
  608. return -EINVAL;
  609. if (off && count == 0)
  610. return 0;
  611. spin_lock_irq(phba->host->host_lock);
  612. if (off == 0 &&
  613. phba->sysfs_mbox.state == SMBOX_WRITING &&
  614. phba->sysfs_mbox.offset >= 2 * sizeof(uint32_t)) {
  615. switch (phba->sysfs_mbox.mbox->mb.mbxCommand) {
  616. /* Offline only */
  617. case MBX_WRITE_NV:
  618. case MBX_INIT_LINK:
  619. case MBX_DOWN_LINK:
  620. case MBX_CONFIG_LINK:
  621. case MBX_CONFIG_RING:
  622. case MBX_RESET_RING:
  623. case MBX_UNREG_LOGIN:
  624. case MBX_CLEAR_LA:
  625. case MBX_DUMP_CONTEXT:
  626. case MBX_RUN_DIAGS:
  627. case MBX_RESTART:
  628. case MBX_FLASH_WR_ULA:
  629. case MBX_SET_MASK:
  630. case MBX_SET_SLIM:
  631. case MBX_SET_DEBUG:
  632. if (!(phba->fc_flag & FC_OFFLINE_MODE)) {
  633. printk(KERN_WARNING "mbox_read:Command 0x%x "
  634. "is illegal in on-line state\n",
  635. phba->sysfs_mbox.mbox->mb.mbxCommand);
  636. sysfs_mbox_idle(phba);
  637. spin_unlock_irq(phba->host->host_lock);
  638. return -EPERM;
  639. }
  640. case MBX_LOAD_SM:
  641. case MBX_READ_NV:
  642. case MBX_READ_CONFIG:
  643. case MBX_READ_RCONFIG:
  644. case MBX_READ_STATUS:
  645. case MBX_READ_XRI:
  646. case MBX_READ_REV:
  647. case MBX_READ_LNK_STAT:
  648. case MBX_DUMP_MEMORY:
  649. case MBX_DOWN_LOAD:
  650. case MBX_UPDATE_CFG:
  651. case MBX_LOAD_AREA:
  652. case MBX_LOAD_EXP_ROM:
  653. break;
  654. case MBX_READ_SPARM64:
  655. case MBX_READ_LA:
  656. case MBX_READ_LA64:
  657. case MBX_REG_LOGIN:
  658. case MBX_REG_LOGIN64:
  659. case MBX_CONFIG_PORT:
  660. case MBX_RUN_BIU_DIAG:
  661. printk(KERN_WARNING "mbox_read: Illegal Command 0x%x\n",
  662. phba->sysfs_mbox.mbox->mb.mbxCommand);
  663. sysfs_mbox_idle(phba);
  664. spin_unlock_irq(phba->host->host_lock);
  665. return -EPERM;
  666. default:
  667. printk(KERN_WARNING "mbox_read: Unknown Command 0x%x\n",
  668. phba->sysfs_mbox.mbox->mb.mbxCommand);
  669. sysfs_mbox_idle(phba);
  670. spin_unlock_irq(phba->host->host_lock);
  671. return -EPERM;
  672. }
  673. if ((phba->fc_flag & FC_OFFLINE_MODE) ||
  674. (!(phba->sli.sli_flag & LPFC_SLI2_ACTIVE))){
  675. spin_unlock_irq(phba->host->host_lock);
  676. rc = lpfc_sli_issue_mbox (phba,
  677. phba->sysfs_mbox.mbox,
  678. MBX_POLL);
  679. spin_lock_irq(phba->host->host_lock);
  680. } else {
  681. spin_unlock_irq(phba->host->host_lock);
  682. rc = lpfc_sli_issue_mbox_wait (phba,
  683. phba->sysfs_mbox.mbox,
  684. phba->fc_ratov * 2);
  685. spin_lock_irq(phba->host->host_lock);
  686. }
  687. if (rc != MBX_SUCCESS) {
  688. sysfs_mbox_idle(phba);
  689. spin_unlock_irq(host->host_lock);
  690. return -ENODEV;
  691. }
  692. phba->sysfs_mbox.state = SMBOX_READING;
  693. }
  694. else if (phba->sysfs_mbox.offset != off ||
  695. phba->sysfs_mbox.state != SMBOX_READING) {
  696. printk(KERN_WARNING "mbox_read: Bad State\n");
  697. sysfs_mbox_idle(phba);
  698. spin_unlock_irq(host->host_lock);
  699. return -EINVAL;
  700. }
  701. memcpy(buf, (uint8_t *) & phba->sysfs_mbox.mbox->mb + off, count);
  702. phba->sysfs_mbox.offset = off + count;
  703. if (phba->sysfs_mbox.offset == sizeof(MAILBOX_t))
  704. sysfs_mbox_idle(phba);
  705. spin_unlock_irq(phba->host->host_lock);
  706. return count;
  707. }
  708. static struct bin_attribute sysfs_mbox_attr = {
  709. .attr = {
  710. .name = "mbox",
  711. .mode = S_IRUSR | S_IWUSR,
  712. .owner = THIS_MODULE,
  713. },
  714. .size = sizeof(MAILBOX_t),
  715. .read = sysfs_mbox_read,
  716. .write = sysfs_mbox_write,
  717. };
  718. int
  719. lpfc_alloc_sysfs_attr(struct lpfc_hba *phba)
  720. {
  721. struct Scsi_Host *host = phba->host;
  722. int error;
  723. error = sysfs_create_bin_file(&host->shost_classdev.kobj,
  724. &sysfs_ctlreg_attr);
  725. if (error)
  726. goto out;
  727. error = sysfs_create_bin_file(&host->shost_classdev.kobj,
  728. &sysfs_mbox_attr);
  729. if (error)
  730. goto out_remove_ctlreg_attr;
  731. return 0;
  732. out_remove_ctlreg_attr:
  733. sysfs_remove_bin_file(&host->shost_classdev.kobj, &sysfs_ctlreg_attr);
  734. out:
  735. return error;
  736. }
  737. void
  738. lpfc_free_sysfs_attr(struct lpfc_hba *phba)
  739. {
  740. struct Scsi_Host *host = phba->host;
  741. sysfs_remove_bin_file(&host->shost_classdev.kobj, &sysfs_mbox_attr);
  742. sysfs_remove_bin_file(&host->shost_classdev.kobj, &sysfs_ctlreg_attr);
  743. }
  744. /*
  745. * Dynamic FC Host Attributes Support
  746. */
  747. static void
  748. lpfc_get_host_port_id(struct Scsi_Host *shost)
  749. {
  750. struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata[0];
  751. /* note: fc_myDID already in cpu endianness */
  752. fc_host_port_id(shost) = phba->fc_myDID;
  753. }
  754. static void
  755. lpfc_get_host_port_type(struct Scsi_Host *shost)
  756. {
  757. struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata[0];
  758. spin_lock_irq(shost->host_lock);
  759. if (phba->hba_state == LPFC_HBA_READY) {
  760. if (phba->fc_topology == TOPOLOGY_LOOP) {
  761. if (phba->fc_flag & FC_PUBLIC_LOOP)
  762. fc_host_port_type(shost) = FC_PORTTYPE_NLPORT;
  763. else
  764. fc_host_port_type(shost) = FC_PORTTYPE_LPORT;
  765. } else {
  766. if (phba->fc_flag & FC_FABRIC)
  767. fc_host_port_type(shost) = FC_PORTTYPE_NPORT;
  768. else
  769. fc_host_port_type(shost) = FC_PORTTYPE_PTP;
  770. }
  771. } else
  772. fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN;
  773. spin_unlock_irq(shost->host_lock);
  774. }
  775. static void
  776. lpfc_get_host_port_state(struct Scsi_Host *shost)
  777. {
  778. struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata[0];
  779. spin_lock_irq(shost->host_lock);
  780. if (phba->fc_flag & FC_OFFLINE_MODE)
  781. fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE;
  782. else {
  783. switch (phba->hba_state) {
  784. case LPFC_INIT_START:
  785. case LPFC_INIT_MBX_CMDS:
  786. case LPFC_LINK_DOWN:
  787. fc_host_port_state(shost) = FC_PORTSTATE_LINKDOWN;
  788. break;
  789. case LPFC_LINK_UP:
  790. case LPFC_LOCAL_CFG_LINK:
  791. case LPFC_FLOGI:
  792. case LPFC_FABRIC_CFG_LINK:
  793. case LPFC_NS_REG:
  794. case LPFC_NS_QRY:
  795. case LPFC_BUILD_DISC_LIST:
  796. case LPFC_DISC_AUTH:
  797. case LPFC_CLEAR_LA:
  798. case LPFC_HBA_READY:
  799. /* Links up, beyond this port_type reports state */
  800. fc_host_port_state(shost) = FC_PORTSTATE_ONLINE;
  801. break;
  802. case LPFC_HBA_ERROR:
  803. fc_host_port_state(shost) = FC_PORTSTATE_ERROR;
  804. break;
  805. default:
  806. fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN;
  807. break;
  808. }
  809. }
  810. spin_unlock_irq(shost->host_lock);
  811. }
  812. static void
  813. lpfc_get_host_speed(struct Scsi_Host *shost)
  814. {
  815. struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata[0];
  816. spin_lock_irq(shost->host_lock);
  817. if (phba->hba_state == LPFC_HBA_READY) {
  818. switch(phba->fc_linkspeed) {
  819. case LA_1GHZ_LINK:
  820. fc_host_speed(shost) = FC_PORTSPEED_1GBIT;
  821. break;
  822. case LA_2GHZ_LINK:
  823. fc_host_speed(shost) = FC_PORTSPEED_2GBIT;
  824. break;
  825. case LA_4GHZ_LINK:
  826. fc_host_speed(shost) = FC_PORTSPEED_4GBIT;
  827. break;
  828. default:
  829. fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
  830. break;
  831. }
  832. }
  833. spin_unlock_irq(shost->host_lock);
  834. }
  835. static void
  836. lpfc_get_host_fabric_name (struct Scsi_Host *shost)
  837. {
  838. struct lpfc_hba *phba = (struct lpfc_hba*)shost->hostdata[0];
  839. u64 nodename;
  840. spin_lock_irq(shost->host_lock);
  841. if ((phba->fc_flag & FC_FABRIC) ||
  842. ((phba->fc_topology == TOPOLOGY_LOOP) &&
  843. (phba->fc_flag & FC_PUBLIC_LOOP)))
  844. memcpy(&nodename, &phba->fc_fabparam.nodeName, sizeof(u64));
  845. else
  846. /* fabric is local port if there is no F/FL_Port */
  847. memcpy(&nodename, &phba->fc_nodename, sizeof(u64));
  848. spin_unlock_irq(shost->host_lock);
  849. fc_host_fabric_name(shost) = be64_to_cpu(nodename);
  850. }
  851. static struct fc_host_statistics *
  852. lpfc_get_stats(struct Scsi_Host *shost)
  853. {
  854. struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata[0];
  855. struct lpfc_sli *psli = &phba->sli;
  856. struct fc_host_statistics *hs =
  857. (struct fc_host_statistics *)phba->link_stats;
  858. LPFC_MBOXQ_t *pmboxq;
  859. MAILBOX_t *pmb;
  860. int rc=0;
  861. pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
  862. if (!pmboxq)
  863. return NULL;
  864. memset(pmboxq, 0, sizeof (LPFC_MBOXQ_t));
  865. pmb = &pmboxq->mb;
  866. pmb->mbxCommand = MBX_READ_STATUS;
  867. pmb->mbxOwner = OWN_HOST;
  868. pmboxq->context1 = NULL;
  869. if ((phba->fc_flag & FC_OFFLINE_MODE) ||
  870. (!(psli->sli_flag & LPFC_SLI2_ACTIVE))){
  871. rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
  872. } else
  873. rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
  874. if (rc != MBX_SUCCESS) {
  875. if (pmboxq) {
  876. if (rc == MBX_TIMEOUT)
  877. pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
  878. else
  879. mempool_free( pmboxq, phba->mbox_mem_pool);
  880. }
  881. return NULL;
  882. }
  883. hs->tx_frames = pmb->un.varRdStatus.xmitFrameCnt;
  884. hs->tx_words = (pmb->un.varRdStatus.xmitByteCnt * 256);
  885. hs->rx_frames = pmb->un.varRdStatus.rcvFrameCnt;
  886. hs->rx_words = (pmb->un.varRdStatus.rcvByteCnt * 256);
  887. memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t));
  888. pmb->mbxCommand = MBX_READ_LNK_STAT;
  889. pmb->mbxOwner = OWN_HOST;
  890. pmboxq->context1 = NULL;
  891. if ((phba->fc_flag & FC_OFFLINE_MODE) ||
  892. (!(psli->sli_flag & LPFC_SLI2_ACTIVE))) {
  893. rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
  894. } else
  895. rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2);
  896. if (rc != MBX_SUCCESS) {
  897. if (pmboxq) {
  898. if (rc == MBX_TIMEOUT)
  899. pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
  900. else
  901. mempool_free( pmboxq, phba->mbox_mem_pool);
  902. }
  903. return NULL;
  904. }
  905. hs->link_failure_count = pmb->un.varRdLnk.linkFailureCnt;
  906. hs->loss_of_sync_count = pmb->un.varRdLnk.lossSyncCnt;
  907. hs->loss_of_signal_count = pmb->un.varRdLnk.lossSignalCnt;
  908. hs->prim_seq_protocol_err_count = pmb->un.varRdLnk.primSeqErrCnt;
  909. hs->invalid_tx_word_count = pmb->un.varRdLnk.invalidXmitWord;
  910. hs->invalid_crc_count = pmb->un.varRdLnk.crcCnt;
  911. hs->error_frames = pmb->un.varRdLnk.crcCnt;
  912. if (phba->fc_topology == TOPOLOGY_LOOP) {
  913. hs->lip_count = (phba->fc_eventTag >> 1);
  914. hs->nos_count = -1;
  915. } else {
  916. hs->lip_count = -1;
  917. hs->nos_count = (phba->fc_eventTag >> 1);
  918. }
  919. hs->dumped_frames = -1;
  920. /* FIX ME */
  921. /*hs->SecondsSinceLastReset = (jiffies - lpfc_loadtime) / HZ;*/
  922. return hs;
  923. }
  924. /*
  925. * The LPFC driver treats linkdown handling as target loss events so there
  926. * are no sysfs handlers for link_down_tmo.
  927. */
  928. static void
  929. lpfc_get_starget_port_id(struct scsi_target *starget)
  930. {
  931. struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
  932. struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata[0];
  933. uint32_t did = -1;
  934. struct lpfc_nodelist *ndlp = NULL;
  935. spin_lock_irq(shost->host_lock);
  936. /* Search the mapped list for this target ID */
  937. list_for_each_entry(ndlp, &phba->fc_nlpmap_list, nlp_listp) {
  938. if (starget->id == ndlp->nlp_sid) {
  939. did = ndlp->nlp_DID;
  940. break;
  941. }
  942. }
  943. spin_unlock_irq(shost->host_lock);
  944. fc_starget_port_id(starget) = did;
  945. }
  946. static void
  947. lpfc_get_starget_node_name(struct scsi_target *starget)
  948. {
  949. struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
  950. struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata[0];
  951. uint64_t node_name = 0;
  952. struct lpfc_nodelist *ndlp = NULL;
  953. spin_lock_irq(shost->host_lock);
  954. /* Search the mapped list for this target ID */
  955. list_for_each_entry(ndlp, &phba->fc_nlpmap_list, nlp_listp) {
  956. if (starget->id == ndlp->nlp_sid) {
  957. memcpy(&node_name, &ndlp->nlp_nodename,
  958. sizeof(struct lpfc_name));
  959. break;
  960. }
  961. }
  962. spin_unlock_irq(shost->host_lock);
  963. fc_starget_node_name(starget) = be64_to_cpu(node_name);
  964. }
  965. static void
  966. lpfc_get_starget_port_name(struct scsi_target *starget)
  967. {
  968. struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
  969. struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata[0];
  970. uint64_t port_name = 0;
  971. struct lpfc_nodelist *ndlp = NULL;
  972. spin_lock_irq(shost->host_lock);
  973. /* Search the mapped list for this target ID */
  974. list_for_each_entry(ndlp, &phba->fc_nlpmap_list, nlp_listp) {
  975. if (starget->id == ndlp->nlp_sid) {
  976. memcpy(&port_name, &ndlp->nlp_portname,
  977. sizeof(struct lpfc_name));
  978. break;
  979. }
  980. }
  981. spin_unlock_irq(shost->host_lock);
  982. fc_starget_port_name(starget) = be64_to_cpu(port_name);
  983. }
  984. static void
  985. lpfc_get_rport_loss_tmo(struct fc_rport *rport)
  986. {
  987. /*
  988. * Return the driver's global value for device loss timeout plus
  989. * five seconds to allow the driver's nodev timer to run.
  990. */
  991. rport->dev_loss_tmo = lpfc_nodev_tmo + 5;
  992. }
  993. static void
  994. lpfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
  995. {
  996. /*
  997. * The driver doesn't have a per-target timeout setting. Set
  998. * this value globally. lpfc_nodev_tmo should be greater then 0.
  999. */
  1000. if (timeout)
  1001. lpfc_nodev_tmo = timeout;
  1002. else
  1003. lpfc_nodev_tmo = 1;
  1004. rport->dev_loss_tmo = lpfc_nodev_tmo + 5;
  1005. }
  1006. #define lpfc_rport_show_function(field, format_string, sz, cast) \
  1007. static ssize_t \
  1008. lpfc_show_rport_##field (struct class_device *cdev, char *buf) \
  1009. { \
  1010. struct fc_rport *rport = transport_class_to_rport(cdev); \
  1011. struct lpfc_rport_data *rdata = rport->hostdata; \
  1012. return snprintf(buf, sz, format_string, \
  1013. (rdata->target) ? cast rdata->target->field : 0); \
  1014. }
  1015. #define lpfc_rport_rd_attr(field, format_string, sz) \
  1016. lpfc_rport_show_function(field, format_string, sz, ) \
  1017. static FC_RPORT_ATTR(field, S_IRUGO, lpfc_show_rport_##field, NULL)
  1018. struct fc_function_template lpfc_transport_functions = {
  1019. /* fixed attributes the driver supports */
  1020. .show_host_node_name = 1,
  1021. .show_host_port_name = 1,
  1022. .show_host_supported_classes = 1,
  1023. .show_host_supported_fc4s = 1,
  1024. .show_host_symbolic_name = 1,
  1025. .show_host_supported_speeds = 1,
  1026. .show_host_maxframe_size = 1,
  1027. /* dynamic attributes the driver supports */
  1028. .get_host_port_id = lpfc_get_host_port_id,
  1029. .show_host_port_id = 1,
  1030. .get_host_port_type = lpfc_get_host_port_type,
  1031. .show_host_port_type = 1,
  1032. .get_host_port_state = lpfc_get_host_port_state,
  1033. .show_host_port_state = 1,
  1034. /* active_fc4s is shown but doesn't change (thus no get function) */
  1035. .show_host_active_fc4s = 1,
  1036. .get_host_speed = lpfc_get_host_speed,
  1037. .show_host_speed = 1,
  1038. .get_host_fabric_name = lpfc_get_host_fabric_name,
  1039. .show_host_fabric_name = 1,
  1040. /*
  1041. * The LPFC driver treats linkdown handling as target loss events
  1042. * so there are no sysfs handlers for link_down_tmo.
  1043. */
  1044. .get_fc_host_stats = lpfc_get_stats,
  1045. /* the LPFC driver doesn't support resetting stats yet */
  1046. .dd_fcrport_size = sizeof(struct lpfc_rport_data),
  1047. .show_rport_maxframe_size = 1,
  1048. .show_rport_supported_classes = 1,
  1049. .get_rport_dev_loss_tmo = lpfc_get_rport_loss_tmo,
  1050. .set_rport_dev_loss_tmo = lpfc_set_rport_loss_tmo,
  1051. .show_rport_dev_loss_tmo = 1,
  1052. .get_starget_port_id = lpfc_get_starget_port_id,
  1053. .show_starget_port_id = 1,
  1054. .get_starget_node_name = lpfc_get_starget_node_name,
  1055. .show_starget_node_name = 1,
  1056. .get_starget_port_name = lpfc_get_starget_port_name,
  1057. .show_starget_port_name = 1,
  1058. };
  1059. void
  1060. lpfc_get_cfgparam(struct lpfc_hba *phba)
  1061. {
  1062. phba->cfg_log_verbose = lpfc_log_verbose;
  1063. phba->cfg_cr_delay = lpfc_cr_delay;
  1064. phba->cfg_cr_count = lpfc_cr_count;
  1065. phba->cfg_lun_queue_depth = lpfc_lun_queue_depth;
  1066. phba->cfg_fcp_class = lpfc_fcp_class;
  1067. phba->cfg_use_adisc = lpfc_use_adisc;
  1068. phba->cfg_ack0 = lpfc_ack0;
  1069. phba->cfg_topology = lpfc_topology;
  1070. phba->cfg_scan_down = lpfc_scan_down;
  1071. phba->cfg_nodev_tmo = lpfc_nodev_tmo;
  1072. phba->cfg_link_speed = lpfc_link_speed;
  1073. phba->cfg_fdmi_on = lpfc_fdmi_on;
  1074. phba->cfg_discovery_threads = lpfc_discovery_threads;
  1075. phba->cfg_max_luns = lpfc_max_luns;
  1076. /*
  1077. * The total number of segments is the configuration value plus 2
  1078. * since the IOCB need a command and response bde.
  1079. */
  1080. phba->cfg_sg_seg_cnt = LPFC_SG_SEG_CNT + 2;
  1081. /*
  1082. * Since the sg_tablesize is module parameter, the sg_dma_buf_size
  1083. * used to create the sg_dma_buf_pool must be dynamically calculated
  1084. */
  1085. phba->cfg_sg_dma_buf_size = sizeof(struct fcp_cmnd) +
  1086. sizeof(struct fcp_rsp) +
  1087. (phba->cfg_sg_seg_cnt * sizeof(struct ulp_bde64));
  1088. switch (phba->pcidev->device) {
  1089. case PCI_DEVICE_ID_LP101:
  1090. case PCI_DEVICE_ID_BSMB:
  1091. case PCI_DEVICE_ID_ZSMB:
  1092. phba->cfg_hba_queue_depth = LPFC_LP101_HBA_Q_DEPTH;
  1093. break;
  1094. case PCI_DEVICE_ID_RFLY:
  1095. case PCI_DEVICE_ID_PFLY:
  1096. case PCI_DEVICE_ID_BMID:
  1097. case PCI_DEVICE_ID_ZMID:
  1098. case PCI_DEVICE_ID_TFLY:
  1099. phba->cfg_hba_queue_depth = LPFC_LC_HBA_Q_DEPTH;
  1100. break;
  1101. default:
  1102. phba->cfg_hba_queue_depth = LPFC_DFT_HBA_Q_DEPTH;
  1103. }
  1104. return;
  1105. }