aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2011-02-16 12:40:06 -0500
committerJames Bottomley <James.Bottomley@suse.de>2011-02-18 16:36:33 -0500
commit2a622bfbe1d95664ecd4bc1cfe6dacf4788dfc10 (patch)
tree25d1bb419a3036612fe4967309804a2ec4c6a195 /drivers/scsi/lpfc
parentab56dc2e1d32556971e0729b3a6c37e0ff3104a6 (diff)
[SCSI] lpfc 8.3.21: Debugfs additions
- Add the driver debugfs framework for supporting debugfs read and write operations, and iDiag command structure. - Add read and write to SLI4 device PCI config space registers. - Add the driver support of debugfs PCI config space register bits set/clear methods to the provided bitmask. - Add iDiag driver support for SLI4 device queue diagnostic. Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com> Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r--drivers/scsi/lpfc/lpfc.h6
-rw-r--r--drivers/scsi/lpfc/lpfc_debugfs.c954
-rw-r--r--drivers/scsi/lpfc/lpfc_debugfs.h60
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c5
-rw-r--r--drivers/scsi/lpfc/lpfc_sli4.h2
5 files changed, 972 insertions, 55 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index f41722e8652a..b64c6da870d3 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -1,7 +1,7 @@
1/******************************************************************* 1/*******************************************************************
2 * This file is part of the Emulex Linux Device Driver for * 2 * This file is part of the Emulex Linux Device Driver for *
3 * Fibre Channel Host Bus Adapters. * 3 * Fibre Channel Host Bus Adapters. *
4 * Copyright (C) 2004-2010 Emulex. All rights reserved. * 4 * Copyright (C) 2004-2011 Emulex. All rights reserved. *
5 * EMULEX and SLI are trademarks of Emulex. * 5 * EMULEX and SLI are trademarks of Emulex. *
6 * www.emulex.com * 6 * www.emulex.com *
7 * Portions Copyright (C) 2004-2005 Christoph Hellwig * 7 * Portions Copyright (C) 2004-2005 Christoph Hellwig *
@@ -799,6 +799,10 @@ struct lpfc_hba {
799 struct dentry *debug_slow_ring_trc; 799 struct dentry *debug_slow_ring_trc;
800 struct lpfc_debugfs_trc *slow_ring_trc; 800 struct lpfc_debugfs_trc *slow_ring_trc;
801 atomic_t slow_ring_trc_cnt; 801 atomic_t slow_ring_trc_cnt;
802 /* iDiag debugfs sub-directory */
803 struct dentry *idiag_root;
804 struct dentry *idiag_pci_cfg;
805 struct dentry *idiag_que_info;
802#endif 806#endif
803 807
804 /* Used for deferred freeing of ELS data buffers */ 808 /* Used for deferred freeing of ELS data buffers */
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
index 3c8c91a7609c..a753581509d6 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
@@ -1,7 +1,7 @@
1/******************************************************************* 1/*******************************************************************
2 * This file is part of the Emulex Linux Device Driver for * 2 * This file is part of the Emulex Linux Device Driver for *
3 * Fibre Channel Host Bus Adapters. * 3 * Fibre Channel Host Bus Adapters. *
4 * Copyright (C) 2007-2009 Emulex. All rights reserved. * 4 * Copyright (C) 2007-2011 Emulex. All rights reserved. *
5 * EMULEX and SLI are trademarks of Emulex. * 5 * EMULEX and SLI are trademarks of Emulex. *
6 * www.emulex.com * 6 * www.emulex.com *
7 * * 7 * *
@@ -57,8 +57,8 @@
57 * # mount -t debugfs none /sys/kernel/debug 57 * # mount -t debugfs none /sys/kernel/debug
58 * 58 *
59 * The lpfc debugfs directory hierarchy is: 59 * The lpfc debugfs directory hierarchy is:
60 * lpfc/lpfcX/vportY 60 * /sys/kernel/debug/lpfc/fnX/vportY
61 * where X is the lpfc hba unique_id 61 * where X is the lpfc hba function unique_id
62 * where Y is the vport VPI on that hba 62 * where Y is the vport VPI on that hba
63 * 63 *
64 * Debugging services available per vport: 64 * Debugging services available per vport:
@@ -104,30 +104,12 @@ MODULE_PARM_DESC(lpfc_debugfs_mask_disc_trc,
104 104
105#include <linux/debugfs.h> 105#include <linux/debugfs.h>
106 106
107/* size of output line, for discovery_trace and slow_ring_trace */
108#define LPFC_DEBUG_TRC_ENTRY_SIZE 100
109
110/* nodelist output buffer size */
111#define LPFC_NODELIST_SIZE 8192
112#define LPFC_NODELIST_ENTRY_SIZE 120
113
114/* dumpHBASlim output buffer size */
115#define LPFC_DUMPHBASLIM_SIZE 4096
116
117/* dumpHostSlim output buffer size */
118#define LPFC_DUMPHOSTSLIM_SIZE 4096
119
120/* hbqinfo output buffer size */
121#define LPFC_HBQINFO_SIZE 8192
122
123struct lpfc_debug {
124 char *buffer;
125 int len;
126};
127
128static atomic_t lpfc_debugfs_seq_trc_cnt = ATOMIC_INIT(0); 107static atomic_t lpfc_debugfs_seq_trc_cnt = ATOMIC_INIT(0);
129static unsigned long lpfc_debugfs_start_time = 0L; 108static unsigned long lpfc_debugfs_start_time = 0L;
130 109
110/* iDiag */
111static struct lpfc_idiag idiag;
112
131/** 113/**
132 * lpfc_debugfs_disc_trc_data - Dump discovery logging to a buffer 114 * lpfc_debugfs_disc_trc_data - Dump discovery logging to a buffer
133 * @vport: The vport to gather the log info from. 115 * @vport: The vport to gather the log info from.
@@ -996,8 +978,6 @@ lpfc_debugfs_dumpDataDif_write(struct file *file, const char __user *buf,
996 return nbytes; 978 return nbytes;
997} 979}
998 980
999
1000
1001/** 981/**
1002 * lpfc_debugfs_nodelist_open - Open the nodelist debugfs file 982 * lpfc_debugfs_nodelist_open - Open the nodelist debugfs file
1003 * @inode: The inode pointer that contains a vport pointer. 983 * @inode: The inode pointer that contains a vport pointer.
@@ -1099,6 +1079,7 @@ lpfc_debugfs_read(struct file *file, char __user *buf,
1099 size_t nbytes, loff_t *ppos) 1079 size_t nbytes, loff_t *ppos)
1100{ 1080{
1101 struct lpfc_debug *debug = file->private_data; 1081 struct lpfc_debug *debug = file->private_data;
1082
1102 return simple_read_from_buffer(buf, nbytes, ppos, debug->buffer, 1083 return simple_read_from_buffer(buf, nbytes, ppos, debug->buffer,
1103 debug->len); 1084 debug->len);
1104} 1085}
@@ -1137,6 +1118,776 @@ lpfc_debugfs_dumpDataDif_release(struct inode *inode, struct file *file)
1137 return 0; 1118 return 0;
1138} 1119}
1139 1120
1121/*
1122 * iDiag debugfs file access methods
1123 */
1124
1125/*
1126 * iDiag PCI config space register access methods:
1127 *
1128 * The PCI config space register accessees of read, write, read-modify-write
1129 * for set bits, and read-modify-write for clear bits to SLI4 PCI functions
1130 * are provided. In the proper SLI4 PCI function's debugfs iDiag directory,
1131 *
1132 * /sys/kernel/debug/lpfc/fn<#>/iDiag
1133 *
1134 * the access is through the debugfs entry pciCfg:
1135 *
1136 * 1. For PCI config space register read access, there are two read methods:
1137 * A) read a single PCI config space register in the size of a byte
1138 * (8 bits), a word (16 bits), or a dword (32 bits); or B) browse through
1139 * the 4K extended PCI config space.
1140 *
1141 * A) Read a single PCI config space register consists of two steps:
1142 *
1143 * Step-1: Set up PCI config space register read command, the command
1144 * syntax is,
1145 *
1146 * echo 1 <where> <count> > pciCfg
1147 *
1148 * where, 1 is the iDiag command for PCI config space read, <where> is the
1149 * offset from the beginning of the device's PCI config space to read from,
1150 * and <count> is the size of PCI config space register data to read back,
1151 * it will be 1 for reading a byte (8 bits), 2 for reading a word (16 bits
1152 * or 2 bytes), or 4 for reading a dword (32 bits or 4 bytes).
1153 *
1154 * Setp-2: Perform the debugfs read operation to execute the idiag command
1155 * set up in Step-1,
1156 *
1157 * cat pciCfg
1158 *
1159 * Examples:
1160 * To read PCI device's vendor-id and device-id from PCI config space,
1161 *
1162 * echo 1 0 4 > pciCfg
1163 * cat pciCfg
1164 *
1165 * To read PCI device's currnt command from config space,
1166 *
1167 * echo 1 4 2 > pciCfg
1168 * cat pciCfg
1169 *
1170 * B) Browse through the entire 4K extended PCI config space also consists
1171 * of two steps:
1172 *
1173 * Step-1: Set up PCI config space register browsing command, the command
1174 * syntax is,
1175 *
1176 * echo 1 0 4096 > pciCfg
1177 *
1178 * where, 1 is the iDiag command for PCI config space read, 0 must be used
1179 * as the offset for PCI config space register browse, and 4096 must be
1180 * used as the count for PCI config space register browse.
1181 *
1182 * Step-2: Repeately issue the debugfs read operation to browse through
1183 * the entire PCI config space registers:
1184 *
1185 * cat pciCfg
1186 * cat pciCfg
1187 * cat pciCfg
1188 * ...
1189 *
1190 * When browsing to the end of the 4K PCI config space, the browse method
1191 * shall wrap around to start reading from beginning again, and again...
1192 *
1193 * 2. For PCI config space register write access, it supports a single PCI
1194 * config space register write in the size of a byte (8 bits), a word
1195 * (16 bits), or a dword (32 bits). The command syntax is,
1196 *
1197 * echo 2 <where> <count> <value> > pciCfg
1198 *
1199 * where, 2 is the iDiag command for PCI config space write, <where> is
1200 * the offset from the beginning of the device's PCI config space to write
1201 * into, <count> is the size of data to write into the PCI config space,
1202 * it will be 1 for writing a byte (8 bits), 2 for writing a word (16 bits
1203 * or 2 bytes), or 4 for writing a dword (32 bits or 4 bytes), and <value>
1204 * is the data to be written into the PCI config space register at the
1205 * offset.
1206 *
1207 * Examples:
1208 * To disable PCI device's interrupt assertion,
1209 *
1210 * 1) Read in device's PCI config space register command field <cmd>:
1211 *
1212 * echo 1 4 2 > pciCfg
1213 * cat pciCfg
1214 *
1215 * 2) Set bit 10 (Interrupt Disable bit) in the <cmd>:
1216 *
1217 * <cmd> = <cmd> | (1 < 10)
1218 *
1219 * 3) Write the modified command back:
1220 *
1221 * echo 2 4 2 <cmd> > pciCfg
1222 *
1223 * 3. For PCI config space register set bits access, it supports a single PCI
1224 * config space register set bits in the size of a byte (8 bits), a word
1225 * (16 bits), or a dword (32 bits). The command syntax is,
1226 *
1227 * echo 3 <where> <count> <bitmask> > pciCfg
1228 *
1229 * where, 3 is the iDiag command for PCI config space set bits, <where> is
1230 * the offset from the beginning of the device's PCI config space to set
1231 * bits into, <count> is the size of the bitmask to set into the PCI config
1232 * space, it will be 1 for setting a byte (8 bits), 2 for setting a word
1233 * (16 bits or 2 bytes), or 4 for setting a dword (32 bits or 4 bytes), and
1234 * <bitmask> is the bitmask, indicating the bits to be set into the PCI
1235 * config space register at the offset. The logic performed to the content
1236 * of the PCI config space register, regval, is,
1237 *
1238 * regval |= <bitmask>
1239 *
1240 * 4. For PCI config space register clear bits access, it supports a single
1241 * PCI config space register clear bits in the size of a byte (8 bits),
1242 * a word (16 bits), or a dword (32 bits). The command syntax is,
1243 *
1244 * echo 4 <where> <count> <bitmask> > pciCfg
1245 *
1246 * where, 4 is the iDiag command for PCI config space clear bits, <where>
1247 * is the offset from the beginning of the device's PCI config space to
1248 * clear bits from, <count> is the size of the bitmask to set into the PCI
1249 * config space, it will be 1 for setting a byte (8 bits), 2 for setting
1250 * a word(16 bits or 2 bytes), or 4 for setting a dword (32 bits or 4
1251 * bytes), and <bitmask> is the bitmask, indicating the bits to be cleared
1252 * from the PCI config space register at the offset. the logic performed
1253 * to the content of the PCI config space register, regval, is,
1254 *
1255 * regval &= ~<bitmask>
1256 *
1257 * Note, for all single register read, write, set bits, or clear bits access,
1258 * the offset (<where>) must be aligned with the size of the data:
1259 *
1260 * For data size of byte (8 bits), the offset must be aligned to the byte
1261 * boundary; for data size of word (16 bits), the offset must be aligned
1262 * to the word boundary; while for data size of dword (32 bits), the offset
1263 * must be aligned to the dword boundary. Otherwise, the interface will
1264 * return the error:
1265 *
1266 * "-bash: echo: write error: Invalid argument".
1267 *
1268 * For example:
1269 *
1270 * echo 1 2 4 > pciCfg
1271 * -bash: echo: write error: Invalid argument
1272 *
1273 * Note also, all of the numbers in the command fields for all read, write,
1274 * set bits, and clear bits PCI config space register command fields can be
1275 * either decimal or hex.
1276 *
1277 * For example,
1278 * echo 1 0 4096 > pciCfg
1279 *
1280 * will be the same as
1281 * echo 1 0 0x1000 > pciCfg
1282 *
1283 * And,
1284 * echo 2 155 1 10 > pciCfg
1285 *
1286 * will be
1287 * echo 2 0x9b 1 0xa > pciCfg
1288 */
1289
1290/**
1291 * lpfc_idiag_cmd_get - Get and parse idiag debugfs comands from user space
1292 * @buf: The pointer to the user space buffer.
1293 * @nbytes: The number of bytes in the user space buffer.
1294 * @idiag_cmd: pointer to the idiag command struct.
1295 *
1296 * This routine reads data from debugfs user space buffer and parses the
1297 * buffer for getting the idiag command and arguments. The while space in
1298 * between the set of data is used as the parsing separator.
1299 *
1300 * This routine returns 0 when successful, it returns proper error code
1301 * back to the user space in error conditions.
1302 */
1303static int lpfc_idiag_cmd_get(const char __user *buf, size_t nbytes,
1304 struct lpfc_idiag_cmd *idiag_cmd)
1305{
1306 char mybuf[64];
1307 char *pbuf, *step_str;
1308 int bsize, i;
1309
1310 /* Protect copy from user */
1311 if (!access_ok(VERIFY_READ, buf, nbytes))
1312 return -EFAULT;
1313
1314 memset(mybuf, 0, sizeof(mybuf));
1315 memset(idiag_cmd, 0, sizeof(*idiag_cmd));
1316 bsize = min(nbytes, (sizeof(mybuf)-1));
1317
1318 if (copy_from_user(mybuf, buf, bsize))
1319 return -EFAULT;
1320 pbuf = &mybuf[0];
1321 step_str = strsep(&pbuf, "\t ");
1322
1323 /* The opcode must present */
1324 if (!step_str)
1325 return -EINVAL;
1326
1327 idiag_cmd->opcode = simple_strtol(step_str, NULL, 0);
1328 if (idiag_cmd->opcode == 0)
1329 return -EINVAL;
1330
1331 for (i = 0; i < LPFC_IDIAG_CMD_DATA_SIZE; i++) {
1332 step_str = strsep(&pbuf, "\t ");
1333 if (!step_str)
1334 return 0;
1335 idiag_cmd->data[i] = simple_strtol(step_str, NULL, 0);
1336 }
1337 return 0;
1338}
1339
1340/**
1341 * lpfc_idiag_open - idiag open debugfs
1342 * @inode: The inode pointer that contains a pointer to phba.
1343 * @file: The file pointer to attach the file operation.
1344 *
1345 * Description:
1346 * This routine is the entry point for the debugfs open file operation. It
1347 * gets the reference to phba from the i_private field in @inode, it then
1348 * allocates buffer for the file operation, performs the necessary PCI config
1349 * space read into the allocated buffer according to the idiag user command
1350 * setup, and then returns a pointer to buffer in the private_data field in
1351 * @file.
1352 *
1353 * Returns:
1354 * This function returns zero if successful. On error it will return an
1355 * negative error value.
1356 **/
1357static int
1358lpfc_idiag_open(struct inode *inode, struct file *file)
1359{
1360 struct lpfc_debug *debug;
1361
1362 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
1363 if (!debug)
1364 return -ENOMEM;
1365
1366 debug->i_private = inode->i_private;
1367 debug->buffer = NULL;
1368 file->private_data = debug;
1369
1370 return 0;
1371}
1372
1373/**
1374 * lpfc_idiag_release - Release idiag access file operation
1375 * @inode: The inode pointer that contains a vport pointer. (unused)
1376 * @file: The file pointer that contains the buffer to release.
1377 *
1378 * Description:
1379 * This routine is the generic release routine for the idiag access file
1380 * operation, it frees the buffer that was allocated when the debugfs file
1381 * was opened.
1382 *
1383 * Returns:
1384 * This function returns zero.
1385 **/
1386static int
1387lpfc_idiag_release(struct inode *inode, struct file *file)
1388{
1389 struct lpfc_debug *debug = file->private_data;
1390
1391 /* Free the buffers to the file operation */
1392 kfree(debug->buffer);
1393 kfree(debug);
1394
1395 return 0;
1396}
1397
1398/**
1399 * lpfc_idiag_cmd_release - Release idiag cmd access file operation
1400 * @inode: The inode pointer that contains a vport pointer. (unused)
1401 * @file: The file pointer that contains the buffer to release.
1402 *
1403 * Description:
1404 * This routine frees the buffer that was allocated when the debugfs file
1405 * was opened. It also reset the fields in the idiag command struct in the
1406 * case the command is not continuous browsing of the data structure.
1407 *
1408 * Returns:
1409 * This function returns zero.
1410 **/
1411static int
1412lpfc_idiag_cmd_release(struct inode *inode, struct file *file)
1413{
1414 struct lpfc_debug *debug = file->private_data;
1415
1416 /* Read PCI config register, if not read all, clear command fields */
1417 if ((debug->op == LPFC_IDIAG_OP_RD) &&
1418 (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_RD))
1419 if ((idiag.cmd.data[1] == sizeof(uint8_t)) ||
1420 (idiag.cmd.data[1] == sizeof(uint16_t)) ||
1421 (idiag.cmd.data[1] == sizeof(uint32_t)))
1422 memset(&idiag, 0, sizeof(idiag));
1423
1424 /* Write PCI config register, clear command fields */
1425 if ((debug->op == LPFC_IDIAG_OP_WR) &&
1426 (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_WR))
1427 memset(&idiag, 0, sizeof(idiag));
1428
1429 /* Free the buffers to the file operation */
1430 kfree(debug->buffer);
1431 kfree(debug);
1432
1433 return 0;
1434}
1435
1436/**
1437 * lpfc_idiag_pcicfg_read - idiag debugfs read pcicfg
1438 * @file: The file pointer to read from.
1439 * @buf: The buffer to copy the data to.
1440 * @nbytes: The number of bytes to read.
1441 * @ppos: The position in the file to start reading from.
1442 *
1443 * Description:
1444 * This routine reads data from the @phba pci config space according to the
1445 * idiag command, and copies to user @buf. Depending on the PCI config space
1446 * read command setup, it does either a single register read of a byte
1447 * (8 bits), a word (16 bits), or a dword (32 bits) or browsing through all
1448 * registers from the 4K extended PCI config space.
1449 *
1450 * Returns:
1451 * This function returns the amount of data that was read (this could be less
1452 * than @nbytes if the end of the file was reached) or a negative error value.
1453 **/
1454static ssize_t
1455lpfc_idiag_pcicfg_read(struct file *file, char __user *buf, size_t nbytes,
1456 loff_t *ppos)
1457{
1458 struct lpfc_debug *debug = file->private_data;
1459 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
1460 int offset_label, offset, len = 0, index = LPFC_PCI_CFG_RD_SIZE;
1461 int where, count;
1462 char *pbuffer;
1463 struct pci_dev *pdev;
1464 uint32_t u32val;
1465 uint16_t u16val;
1466 uint8_t u8val;
1467
1468 pdev = phba->pcidev;
1469 if (!pdev)
1470 return 0;
1471
1472 /* This is a user read operation */
1473 debug->op = LPFC_IDIAG_OP_RD;
1474
1475 if (!debug->buffer)
1476 debug->buffer = kmalloc(LPFC_PCI_CFG_SIZE, GFP_KERNEL);
1477 if (!debug->buffer)
1478 return 0;
1479 pbuffer = debug->buffer;
1480
1481 if (*ppos)
1482 return 0;
1483
1484 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_RD) {
1485 where = idiag.cmd.data[0];
1486 count = idiag.cmd.data[1];
1487 } else
1488 return 0;
1489
1490 /* Read single PCI config space register */
1491 switch (count) {
1492 case SIZE_U8: /* byte (8 bits) */
1493 pci_read_config_byte(pdev, where, &u8val);
1494 len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
1495 "%03x: %02x\n", where, u8val);
1496 break;
1497 case SIZE_U16: /* word (16 bits) */
1498 pci_read_config_word(pdev, where, &u16val);
1499 len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
1500 "%03x: %04x\n", where, u16val);
1501 break;
1502 case SIZE_U32: /* double word (32 bits) */
1503 pci_read_config_dword(pdev, where, &u32val);
1504 len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
1505 "%03x: %08x\n", where, u32val);
1506 break;
1507 case LPFC_PCI_CFG_SIZE: /* browse all */
1508 goto pcicfg_browse;
1509 break;
1510 default:
1511 /* illegal count */
1512 len = 0;
1513 break;
1514 }
1515 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
1516
1517pcicfg_browse:
1518
1519 /* Browse all PCI config space registers */
1520 offset_label = idiag.offset.last_rd;
1521 offset = offset_label;
1522
1523 /* Read PCI config space */
1524 len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
1525 "%03x: ", offset_label);
1526 while (index > 0) {
1527 pci_read_config_dword(pdev, offset, &u32val);
1528 len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
1529 "%08x ", u32val);
1530 offset += sizeof(uint32_t);
1531 index -= sizeof(uint32_t);
1532 if (!index)
1533 len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
1534 "\n");
1535 else if (!(index % (8 * sizeof(uint32_t)))) {
1536 offset_label += (8 * sizeof(uint32_t));
1537 len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
1538 "\n%03x: ", offset_label);
1539 }
1540 }
1541
1542 /* Set up the offset for next portion of pci cfg read */
1543 idiag.offset.last_rd += LPFC_PCI_CFG_RD_SIZE;
1544 if (idiag.offset.last_rd >= LPFC_PCI_CFG_SIZE)
1545 idiag.offset.last_rd = 0;
1546
1547 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
1548}
1549
1550/**
1551 * lpfc_idiag_pcicfg_write - Syntax check and set up idiag pcicfg commands
1552 * @file: The file pointer to read from.
1553 * @buf: The buffer to copy the user data from.
1554 * @nbytes: The number of bytes to get.
1555 * @ppos: The position in the file to start reading from.
1556 *
1557 * This routine get the debugfs idiag command struct from user space and
1558 * then perform the syntax check for PCI config space read or write command
1559 * accordingly. In the case of PCI config space read command, it sets up
1560 * the command in the idiag command struct for the debugfs read operation.
1561 * In the case of PCI config space write operation, it executes the write
1562 * operation into the PCI config space accordingly.
1563 *
1564 * It returns the @nbytges passing in from debugfs user space when successful.
1565 * In case of error conditions, it returns proper error code back to the user
1566 * space.
1567 */
1568static ssize_t
1569lpfc_idiag_pcicfg_write(struct file *file, const char __user *buf,
1570 size_t nbytes, loff_t *ppos)
1571{
1572 struct lpfc_debug *debug = file->private_data;
1573 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
1574 uint32_t where, value, count;
1575 uint32_t u32val;
1576 uint16_t u16val;
1577 uint8_t u8val;
1578 struct pci_dev *pdev;
1579 int rc;
1580
1581 pdev = phba->pcidev;
1582 if (!pdev)
1583 return -EFAULT;
1584
1585 /* This is a user write operation */
1586 debug->op = LPFC_IDIAG_OP_WR;
1587
1588 rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
1589 if (rc)
1590 return rc;
1591
1592 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_RD) {
1593 /* Read command from PCI config space, set up command fields */
1594 where = idiag.cmd.data[0];
1595 count = idiag.cmd.data[1];
1596 if (count == LPFC_PCI_CFG_SIZE) {
1597 if (where != 0)
1598 goto error_out;
1599 } else if ((count != sizeof(uint8_t)) &&
1600 (count != sizeof(uint16_t)) &&
1601 (count != sizeof(uint32_t)))
1602 goto error_out;
1603 if (count == sizeof(uint8_t)) {
1604 if (where > LPFC_PCI_CFG_SIZE - sizeof(uint8_t))
1605 goto error_out;
1606 if (where % sizeof(uint8_t))
1607 goto error_out;
1608 }
1609 if (count == sizeof(uint16_t)) {
1610 if (where > LPFC_PCI_CFG_SIZE - sizeof(uint16_t))
1611 goto error_out;
1612 if (where % sizeof(uint16_t))
1613 goto error_out;
1614 }
1615 if (count == sizeof(uint32_t)) {
1616 if (where > LPFC_PCI_CFG_SIZE - sizeof(uint32_t))
1617 goto error_out;
1618 if (where % sizeof(uint32_t))
1619 goto error_out;
1620 }
1621 } else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_WR ||
1622 idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_ST ||
1623 idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_CL) {
1624 /* Write command to PCI config space, read-modify-write */
1625 where = idiag.cmd.data[0];
1626 count = idiag.cmd.data[1];
1627 value = idiag.cmd.data[2];
1628 /* Sanity checks */
1629 if ((count != sizeof(uint8_t)) &&
1630 (count != sizeof(uint16_t)) &&
1631 (count != sizeof(uint32_t)))
1632 goto error_out;
1633 if (count == sizeof(uint8_t)) {
1634 if (where > LPFC_PCI_CFG_SIZE - sizeof(uint8_t))
1635 goto error_out;
1636 if (where % sizeof(uint8_t))
1637 goto error_out;
1638 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_WR)
1639 pci_write_config_byte(pdev, where,
1640 (uint8_t)value);
1641 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_ST) {
1642 rc = pci_read_config_byte(pdev, where, &u8val);
1643 if (!rc) {
1644 u8val |= (uint8_t)value;
1645 pci_write_config_byte(pdev, where,
1646 u8val);
1647 }
1648 }
1649 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_CL) {
1650 rc = pci_read_config_byte(pdev, where, &u8val);
1651 if (!rc) {
1652 u8val &= (uint8_t)(~value);
1653 pci_write_config_byte(pdev, where,
1654 u8val);
1655 }
1656 }
1657 }
1658 if (count == sizeof(uint16_t)) {
1659 if (where > LPFC_PCI_CFG_SIZE - sizeof(uint16_t))
1660 goto error_out;
1661 if (where % sizeof(uint16_t))
1662 goto error_out;
1663 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_WR)
1664 pci_write_config_word(pdev, where,
1665 (uint16_t)value);
1666 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_ST) {
1667 rc = pci_read_config_word(pdev, where, &u16val);
1668 if (!rc) {
1669 u16val |= (uint16_t)value;
1670 pci_write_config_word(pdev, where,
1671 u16val);
1672 }
1673 }
1674 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_CL) {
1675 rc = pci_read_config_word(pdev, where, &u16val);
1676 if (!rc) {
1677 u16val &= (uint16_t)(~value);
1678 pci_write_config_word(pdev, where,
1679 u16val);
1680 }
1681 }
1682 }
1683 if (count == sizeof(uint32_t)) {
1684 if (where > LPFC_PCI_CFG_SIZE - sizeof(uint32_t))
1685 goto error_out;
1686 if (where % sizeof(uint32_t))
1687 goto error_out;
1688 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_WR)
1689 pci_write_config_dword(pdev, where, value);
1690 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_ST) {
1691 rc = pci_read_config_dword(pdev, where,
1692 &u32val);
1693 if (!rc) {
1694 u32val |= value;
1695 pci_write_config_dword(pdev, where,
1696 u32val);
1697 }
1698 }
1699 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_CL) {
1700 rc = pci_read_config_dword(pdev, where,
1701 &u32val);
1702 if (!rc) {
1703 u32val &= ~value;
1704 pci_write_config_dword(pdev, where,
1705 u32val);
1706 }
1707 }
1708 }
1709 } else
1710 /* All other opecodes are illegal for now */
1711 goto error_out;
1712
1713 return nbytes;
1714error_out:
1715 memset(&idiag, 0, sizeof(idiag));
1716 return -EINVAL;
1717}
1718
1719/**
1720 * lpfc_idiag_queinfo_read - idiag debugfs read queue information
1721 * @file: The file pointer to read from.
1722 * @buf: The buffer to copy the data to.
1723 * @nbytes: The number of bytes to read.
1724 * @ppos: The position in the file to start reading from.
1725 *
1726 * Description:
1727 * This routine reads data from the @phba SLI4 PCI function queue information,
1728 * and copies to user @buf.
1729 *
1730 * Returns:
1731 * This function returns the amount of data that was read (this could be less
1732 * than @nbytes if the end of the file was reached) or a negative error value.
1733 **/
1734static ssize_t
1735lpfc_idiag_queinfo_read(struct file *file, char __user *buf, size_t nbytes,
1736 loff_t *ppos)
1737{
1738 struct lpfc_debug *debug = file->private_data;
1739 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
1740 int len = 0, fcp_qidx;
1741 char *pbuffer;
1742
1743 if (!debug->buffer)
1744 debug->buffer = kmalloc(LPFC_QUE_INFO_GET_BUF_SIZE, GFP_KERNEL);
1745 if (!debug->buffer)
1746 return 0;
1747 pbuffer = debug->buffer;
1748
1749 if (*ppos)
1750 return 0;
1751
1752 /* Get slow-path event queue information */
1753 len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
1754 "Slow-path EQ information:\n");
1755 len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
1756 "\tID [%02d], EQE-COUNT [%04d], "
1757 "HOST-INDEX [%04x], PORT-INDEX [%04x]\n\n",
1758 phba->sli4_hba.sp_eq->queue_id,
1759 phba->sli4_hba.sp_eq->entry_count,
1760 phba->sli4_hba.sp_eq->host_index,
1761 phba->sli4_hba.sp_eq->hba_index);
1762
1763 /* Get fast-path event queue information */
1764 len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
1765 "Fast-path EQ information:\n");
1766 for (fcp_qidx = 0; fcp_qidx < phba->cfg_fcp_eq_count; fcp_qidx++) {
1767 len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
1768 "\tID [%02d], EQE-COUNT [%04d], "
1769 "HOST-INDEX [%04x], PORT-INDEX [%04x]\n",
1770 phba->sli4_hba.fp_eq[fcp_qidx]->queue_id,
1771 phba->sli4_hba.fp_eq[fcp_qidx]->entry_count,
1772 phba->sli4_hba.fp_eq[fcp_qidx]->host_index,
1773 phba->sli4_hba.fp_eq[fcp_qidx]->hba_index);
1774 }
1775 len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
1776
1777 /* Get mailbox complete queue information */
1778 len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
1779 "Mailbox CQ information:\n");
1780 len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
1781 "\t\tAssociated EQ-ID [%02d]:\n",
1782 phba->sli4_hba.mbx_cq->assoc_qid);
1783 len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
1784 "\tID [%02d], CQE-COUNT [%04d], "
1785 "HOST-INDEX [%04x], PORT-INDEX [%04x]\n\n",
1786 phba->sli4_hba.mbx_cq->queue_id,
1787 phba->sli4_hba.mbx_cq->entry_count,
1788 phba->sli4_hba.mbx_cq->host_index,
1789 phba->sli4_hba.mbx_cq->hba_index);
1790
1791 /* Get slow-path complete queue information */
1792 len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
1793 "Slow-path CQ information:\n");
1794 len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
1795 "\t\tAssociated EQ-ID [%02d]:\n",
1796 phba->sli4_hba.els_cq->assoc_qid);
1797 len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
1798 "\tID [%02d], CQE-COUNT [%04d], "
1799 "HOST-INDEX [%04x], PORT-INDEX [%04x]\n\n",
1800 phba->sli4_hba.els_cq->queue_id,
1801 phba->sli4_hba.els_cq->entry_count,
1802 phba->sli4_hba.els_cq->host_index,
1803 phba->sli4_hba.els_cq->hba_index);
1804
1805 /* Get fast-path complete queue information */
1806 len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
1807 "Fast-path CQ information:\n");
1808 for (fcp_qidx = 0; fcp_qidx < phba->cfg_fcp_eq_count; fcp_qidx++) {
1809 len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
1810 "\t\tAssociated EQ-ID [%02d]:\n",
1811 phba->sli4_hba.fcp_cq[fcp_qidx]->assoc_qid);
1812 len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
1813 "\tID [%02d], EQE-COUNT [%04d], "
1814 "HOST-INDEX [%04x], PORT-INDEX [%04x]\n",
1815 phba->sli4_hba.fcp_cq[fcp_qidx]->queue_id,
1816 phba->sli4_hba.fcp_cq[fcp_qidx]->entry_count,
1817 phba->sli4_hba.fcp_cq[fcp_qidx]->host_index,
1818 phba->sli4_hba.fcp_cq[fcp_qidx]->hba_index);
1819 }
1820 len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
1821
1822 /* Get mailbox queue information */
1823 len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
1824 "Mailbox MQ information:\n");
1825 len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
1826 "\t\tAssociated CQ-ID [%02d]:\n",
1827 phba->sli4_hba.mbx_wq->assoc_qid);
1828 len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
1829 "\tID [%02d], MQE-COUNT [%04d], "
1830 "HOST-INDEX [%04x], PORT-INDEX [%04x]\n\n",
1831 phba->sli4_hba.mbx_wq->queue_id,
1832 phba->sli4_hba.mbx_wq->entry_count,
1833 phba->sli4_hba.mbx_wq->host_index,
1834 phba->sli4_hba.mbx_wq->hba_index);
1835
1836 /* Get slow-path work queue information */
1837 len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
1838 "Slow-path WQ information:\n");
1839 len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
1840 "\t\tAssociated CQ-ID [%02d]:\n",
1841 phba->sli4_hba.els_wq->assoc_qid);
1842 len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
1843 "\tID [%02d], WQE-COUNT [%04d], "
1844 "HOST-INDEX [%04x], PORT-INDEX [%04x]\n\n",
1845 phba->sli4_hba.els_wq->queue_id,
1846 phba->sli4_hba.els_wq->entry_count,
1847 phba->sli4_hba.els_wq->host_index,
1848 phba->sli4_hba.els_wq->hba_index);
1849
1850 /* Get fast-path work queue information */
1851 len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
1852 "Fast-path WQ information:\n");
1853 for (fcp_qidx = 0; fcp_qidx < phba->cfg_fcp_wq_count; fcp_qidx++) {
1854 len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
1855 "\t\tAssociated CQ-ID [%02d]:\n",
1856 phba->sli4_hba.fcp_wq[fcp_qidx]->assoc_qid);
1857 len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
1858 "\tID [%02d], WQE-COUNT [%04d], "
1859 "HOST-INDEX [%04x], PORT-INDEX [%04x]\n",
1860 phba->sli4_hba.fcp_wq[fcp_qidx]->queue_id,
1861 phba->sli4_hba.fcp_wq[fcp_qidx]->entry_count,
1862 phba->sli4_hba.fcp_wq[fcp_qidx]->host_index,
1863 phba->sli4_hba.fcp_wq[fcp_qidx]->hba_index);
1864 }
1865 len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
1866
1867 /* Get receive queue information */
1868 len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
1869 "Slow-path RQ information:\n");
1870 len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
1871 "\t\tAssociated CQ-ID [%02d]:\n",
1872 phba->sli4_hba.hdr_rq->assoc_qid);
1873 len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
1874 "\tID [%02d], RHQE-COUNT [%04d], "
1875 "HOST-INDEX [%04x], PORT-INDEX [%04x]\n",
1876 phba->sli4_hba.hdr_rq->queue_id,
1877 phba->sli4_hba.hdr_rq->entry_count,
1878 phba->sli4_hba.hdr_rq->host_index,
1879 phba->sli4_hba.hdr_rq->hba_index);
1880 len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
1881 "\tID [%02d], RDQE-COUNT [%04d], "
1882 "HOST-INDEX [%04x], PORT-INDEX [%04x]\n",
1883 phba->sli4_hba.dat_rq->queue_id,
1884 phba->sli4_hba.dat_rq->entry_count,
1885 phba->sli4_hba.dat_rq->host_index,
1886 phba->sli4_hba.dat_rq->hba_index);
1887
1888 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
1889}
1890
1140#undef lpfc_debugfs_op_disc_trc 1891#undef lpfc_debugfs_op_disc_trc
1141static const struct file_operations lpfc_debugfs_op_disc_trc = { 1892static const struct file_operations lpfc_debugfs_op_disc_trc = {
1142 .owner = THIS_MODULE, 1893 .owner = THIS_MODULE,
@@ -1213,6 +1964,28 @@ static const struct file_operations lpfc_debugfs_op_slow_ring_trc = {
1213 1964
1214static struct dentry *lpfc_debugfs_root = NULL; 1965static struct dentry *lpfc_debugfs_root = NULL;
1215static atomic_t lpfc_debugfs_hba_count; 1966static atomic_t lpfc_debugfs_hba_count;
1967
1968/*
1969 * File operations for the iDiag debugfs
1970 */
1971#undef lpfc_idiag_op_pciCfg
1972static const struct file_operations lpfc_idiag_op_pciCfg = {
1973 .owner = THIS_MODULE,
1974 .open = lpfc_idiag_open,
1975 .llseek = lpfc_debugfs_lseek,
1976 .read = lpfc_idiag_pcicfg_read,
1977 .write = lpfc_idiag_pcicfg_write,
1978 .release = lpfc_idiag_cmd_release,
1979};
1980
1981#undef lpfc_idiag_op_queInfo
1982static const struct file_operations lpfc_idiag_op_queInfo = {
1983 .owner = THIS_MODULE,
1984 .open = lpfc_idiag_open,
1985 .read = lpfc_idiag_queinfo_read,
1986 .release = lpfc_idiag_release,
1987};
1988
1216#endif 1989#endif
1217 1990
1218/** 1991/**
@@ -1249,8 +2022,8 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
1249 if (!lpfc_debugfs_start_time) 2022 if (!lpfc_debugfs_start_time)
1250 lpfc_debugfs_start_time = jiffies; 2023 lpfc_debugfs_start_time = jiffies;
1251 2024
1252 /* Setup lpfcX directory for specific HBA */ 2025 /* Setup funcX directory for specific HBA PCI function */
1253 snprintf(name, sizeof(name), "lpfc%d", phba->brd_no); 2026 snprintf(name, sizeof(name), "fn%d", phba->brd_no);
1254 if (!phba->hba_debugfs_root) { 2027 if (!phba->hba_debugfs_root) {
1255 phba->hba_debugfs_root = 2028 phba->hba_debugfs_root =
1256 debugfs_create_dir(name, lpfc_debugfs_root); 2029 debugfs_create_dir(name, lpfc_debugfs_root);
@@ -1275,28 +2048,38 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
1275 } 2048 }
1276 2049
1277 /* Setup dumpHBASlim */ 2050 /* Setup dumpHBASlim */
1278 snprintf(name, sizeof(name), "dumpHBASlim"); 2051 if (phba->sli_rev < LPFC_SLI_REV4) {
1279 phba->debug_dumpHBASlim = 2052 snprintf(name, sizeof(name), "dumpHBASlim");
1280 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, 2053 phba->debug_dumpHBASlim =
1281 phba->hba_debugfs_root, 2054 debugfs_create_file(name,
1282 phba, &lpfc_debugfs_op_dumpHBASlim); 2055 S_IFREG|S_IRUGO|S_IWUSR,
1283 if (!phba->debug_dumpHBASlim) { 2056 phba->hba_debugfs_root,
1284 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, 2057 phba, &lpfc_debugfs_op_dumpHBASlim);
1285 "0413 Cannot create debugfs dumpHBASlim\n"); 2058 if (!phba->debug_dumpHBASlim) {
1286 goto debug_failed; 2059 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
1287 } 2060 "0413 Cannot create debugfs "
2061 "dumpHBASlim\n");
2062 goto debug_failed;
2063 }
2064 } else
2065 phba->debug_dumpHBASlim = NULL;
1288 2066
1289 /* Setup dumpHostSlim */ 2067 /* Setup dumpHostSlim */
1290 snprintf(name, sizeof(name), "dumpHostSlim"); 2068 if (phba->sli_rev < LPFC_SLI_REV4) {
1291 phba->debug_dumpHostSlim = 2069 snprintf(name, sizeof(name), "dumpHostSlim");
1292 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, 2070 phba->debug_dumpHostSlim =
1293 phba->hba_debugfs_root, 2071 debugfs_create_file(name,
1294 phba, &lpfc_debugfs_op_dumpHostSlim); 2072 S_IFREG|S_IRUGO|S_IWUSR,
1295 if (!phba->debug_dumpHostSlim) { 2073 phba->hba_debugfs_root,
1296 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, 2074 phba, &lpfc_debugfs_op_dumpHostSlim);
1297 "0414 Cannot create debugfs dumpHostSlim\n"); 2075 if (!phba->debug_dumpHostSlim) {
1298 goto debug_failed; 2076 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
1299 } 2077 "0414 Cannot create debugfs "
2078 "dumpHostSlim\n");
2079 goto debug_failed;
2080 }
2081 } else
2082 phba->debug_dumpHBASlim = NULL;
1300 2083
1301 /* Setup dumpData */ 2084 /* Setup dumpData */
1302 snprintf(name, sizeof(name), "dumpData"); 2085 snprintf(name, sizeof(name), "dumpData");
@@ -1322,8 +2105,6 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
1322 goto debug_failed; 2105 goto debug_failed;
1323 } 2106 }
1324 2107
1325
1326
1327 /* Setup slow ring trace */ 2108 /* Setup slow ring trace */
1328 if (lpfc_debugfs_max_slow_ring_trc) { 2109 if (lpfc_debugfs_max_slow_ring_trc) {
1329 num = lpfc_debugfs_max_slow_ring_trc - 1; 2110 num = lpfc_debugfs_max_slow_ring_trc - 1;
@@ -1342,7 +2123,6 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
1342 } 2123 }
1343 } 2124 }
1344 2125
1345
1346 snprintf(name, sizeof(name), "slow_ring_trace"); 2126 snprintf(name, sizeof(name), "slow_ring_trace");
1347 phba->debug_slow_ring_trc = 2127 phba->debug_slow_ring_trc =
1348 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, 2128 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
@@ -1434,6 +2214,53 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
1434 "0409 Cant create debugfs nodelist\n"); 2214 "0409 Cant create debugfs nodelist\n");
1435 goto debug_failed; 2215 goto debug_failed;
1436 } 2216 }
2217
2218 /*
2219 * iDiag debugfs root entry points for SLI4 device only
2220 */
2221 if (phba->sli_rev < LPFC_SLI_REV4)
2222 goto debug_failed;
2223
2224 snprintf(name, sizeof(name), "iDiag");
2225 if (!phba->idiag_root) {
2226 phba->idiag_root =
2227 debugfs_create_dir(name, phba->hba_debugfs_root);
2228 if (!phba->idiag_root) {
2229 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
2230 "2922 Can't create idiag debugfs\n");
2231 goto debug_failed;
2232 }
2233 /* Initialize iDiag data structure */
2234 memset(&idiag, 0, sizeof(idiag));
2235 }
2236
2237 /* iDiag read PCI config space */
2238 snprintf(name, sizeof(name), "pciCfg");
2239 if (!phba->idiag_pci_cfg) {
2240 phba->idiag_pci_cfg =
2241 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
2242 phba->idiag_root, phba, &lpfc_idiag_op_pciCfg);
2243 if (!phba->idiag_pci_cfg) {
2244 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
2245 "2923 Can't create idiag debugfs\n");
2246 goto debug_failed;
2247 }
2248 idiag.offset.last_rd = 0;
2249 }
2250
2251 /* iDiag get PCI function queue information */
2252 snprintf(name, sizeof(name), "queInfo");
2253 if (!phba->idiag_que_info) {
2254 phba->idiag_que_info =
2255 debugfs_create_file(name, S_IFREG|S_IRUGO,
2256 phba->idiag_root, phba, &lpfc_idiag_op_queInfo);
2257 if (!phba->idiag_que_info) {
2258 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
2259 "2924 Can't create idiag debugfs\n");
2260 goto debug_failed;
2261 }
2262 }
2263
1437debug_failed: 2264debug_failed:
1438 return; 2265 return;
1439#endif 2266#endif
@@ -1508,8 +2335,31 @@ lpfc_debugfs_terminate(struct lpfc_vport *vport)
1508 phba->debug_slow_ring_trc = NULL; 2335 phba->debug_slow_ring_trc = NULL;
1509 } 2336 }
1510 2337
2338 /*
2339 * iDiag release
2340 */
2341 if (phba->sli_rev == LPFC_SLI_REV4) {
2342 if (phba->idiag_que_info) {
2343 /* iDiag queInfo */
2344 debugfs_remove(phba->idiag_que_info);
2345 phba->idiag_que_info = NULL;
2346 }
2347 if (phba->idiag_pci_cfg) {
2348 /* iDiag pciCfg */
2349 debugfs_remove(phba->idiag_pci_cfg);
2350 phba->idiag_pci_cfg = NULL;
2351 }
2352
2353 /* Finally remove the iDiag debugfs root */
2354 if (phba->idiag_root) {
2355 /* iDiag root */
2356 debugfs_remove(phba->idiag_root);
2357 phba->idiag_root = NULL;
2358 }
2359 }
2360
1511 if (phba->hba_debugfs_root) { 2361 if (phba->hba_debugfs_root) {
1512 debugfs_remove(phba->hba_debugfs_root); /* lpfcX */ 2362 debugfs_remove(phba->hba_debugfs_root); /* fnX */
1513 phba->hba_debugfs_root = NULL; 2363 phba->hba_debugfs_root = NULL;
1514 atomic_dec(&lpfc_debugfs_hba_count); 2364 atomic_dec(&lpfc_debugfs_hba_count);
1515 } 2365 }
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.h b/drivers/scsi/lpfc/lpfc_debugfs.h
index 03c7313a1012..91b9a9427cda 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.h
+++ b/drivers/scsi/lpfc/lpfc_debugfs.h
@@ -1,7 +1,7 @@
1/******************************************************************* 1/*******************************************************************
2 * This file is part of the Emulex Linux Device Driver for * 2 * This file is part of the Emulex Linux Device Driver for *
3 * Fibre Channel Host Bus Adapters. * 3 * Fibre Channel Host Bus Adapters. *
4 * Copyright (C) 2007 Emulex. All rights reserved. * 4 * Copyright (C) 2007-2011 Emulex. All rights reserved. *
5 * EMULEX and SLI are trademarks of Emulex. * 5 * EMULEX and SLI are trademarks of Emulex. *
6 * www.emulex.com * 6 * www.emulex.com *
7 * * 7 * *
@@ -22,6 +22,44 @@
22#define _H_LPFC_DEBUG_FS 22#define _H_LPFC_DEBUG_FS
23 23
24#ifdef CONFIG_SCSI_LPFC_DEBUG_FS 24#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
25
26/* size of output line, for discovery_trace and slow_ring_trace */
27#define LPFC_DEBUG_TRC_ENTRY_SIZE 100
28
29/* nodelist output buffer size */
30#define LPFC_NODELIST_SIZE 8192
31#define LPFC_NODELIST_ENTRY_SIZE 120
32
33/* dumpHBASlim output buffer size */
34#define LPFC_DUMPHBASLIM_SIZE 4096
35
36/* dumpHostSlim output buffer size */
37#define LPFC_DUMPHOSTSLIM_SIZE 4096
38
39/* hbqinfo output buffer size */
40#define LPFC_HBQINFO_SIZE 8192
41
42/* rdPciConf output buffer size */
43#define LPFC_PCI_CFG_SIZE 4096
44#define LPFC_PCI_CFG_RD_BUF_SIZE (LPFC_PCI_CFG_SIZE/2)
45#define LPFC_PCI_CFG_RD_SIZE (LPFC_PCI_CFG_SIZE/4)
46
47/* queue info output buffer size */
48#define LPFC_QUE_INFO_GET_BUF_SIZE 2048
49
50#define SIZE_U8 sizeof(uint8_t)
51#define SIZE_U16 sizeof(uint16_t)
52#define SIZE_U32 sizeof(uint32_t)
53
54struct lpfc_debug {
55 char *i_private;
56 char op;
57#define LPFC_IDIAG_OP_RD 1
58#define LPFC_IDIAG_OP_WR 2
59 char *buffer;
60 int len;
61};
62
25struct lpfc_debugfs_trc { 63struct lpfc_debugfs_trc {
26 char *fmt; 64 char *fmt;
27 uint32_t data1; 65 uint32_t data1;
@@ -30,6 +68,26 @@ struct lpfc_debugfs_trc {
30 uint32_t seq_cnt; 68 uint32_t seq_cnt;
31 unsigned long jif; 69 unsigned long jif;
32}; 70};
71
72struct lpfc_idiag_offset {
73 uint32_t last_rd;
74};
75
76#define LPFC_IDIAG_CMD_DATA_SIZE 4
77struct lpfc_idiag_cmd {
78 uint32_t opcode;
79#define LPFC_IDIAG_CMD_PCICFG_RD 0x00000001
80#define LPFC_IDIAG_CMD_PCICFG_WR 0x00000002
81#define LPFC_IDIAG_CMD_PCICFG_ST 0x00000003
82#define LPFC_IDIAG_CMD_PCICFG_CL 0x00000004
83 uint32_t data[LPFC_IDIAG_CMD_DATA_SIZE];
84};
85
86struct lpfc_idiag {
87 uint32_t active;
88 struct lpfc_idiag_cmd cmd;
89 struct lpfc_idiag_offset offset;
90};
33#endif 91#endif
34 92
35/* Mask for discovery_trace */ 93/* Mask for discovery_trace */
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index b85c40e3bf55..2ee0374a9908 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -10471,6 +10471,7 @@ lpfc_cq_create(struct lpfc_hba *phba, struct lpfc_queue *cq,
10471 cq->type = type; 10471 cq->type = type;
10472 cq->subtype = subtype; 10472 cq->subtype = subtype;
10473 cq->queue_id = bf_get(lpfc_mbx_cq_create_q_id, &cq_create->u.response); 10473 cq->queue_id = bf_get(lpfc_mbx_cq_create_q_id, &cq_create->u.response);
10474 cq->assoc_qid = eq->queue_id;
10474 cq->host_index = 0; 10475 cq->host_index = 0;
10475 cq->hba_index = 0; 10476 cq->hba_index = 0;
10476 10477
@@ -10665,6 +10666,7 @@ lpfc_mq_create(struct lpfc_hba *phba, struct lpfc_queue *mq,
10665 goto out; 10666 goto out;
10666 } 10667 }
10667 mq->type = LPFC_MQ; 10668 mq->type = LPFC_MQ;
10669 mq->assoc_qid = cq->queue_id;
10668 mq->subtype = subtype; 10670 mq->subtype = subtype;
10669 mq->host_index = 0; 10671 mq->host_index = 0;
10670 mq->hba_index = 0; 10672 mq->hba_index = 0;
@@ -10752,6 +10754,7 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq,
10752 goto out; 10754 goto out;
10753 } 10755 }
10754 wq->type = LPFC_WQ; 10756 wq->type = LPFC_WQ;
10757 wq->assoc_qid = cq->queue_id;
10755 wq->subtype = subtype; 10758 wq->subtype = subtype;
10756 wq->host_index = 0; 10759 wq->host_index = 0;
10757 wq->hba_index = 0; 10760 wq->hba_index = 0;
@@ -10869,6 +10872,7 @@ lpfc_rq_create(struct lpfc_hba *phba, struct lpfc_queue *hrq,
10869 goto out; 10872 goto out;
10870 } 10873 }
10871 hrq->type = LPFC_HRQ; 10874 hrq->type = LPFC_HRQ;
10875 hrq->assoc_qid = cq->queue_id;
10872 hrq->subtype = subtype; 10876 hrq->subtype = subtype;
10873 hrq->host_index = 0; 10877 hrq->host_index = 0;
10874 hrq->hba_index = 0; 10878 hrq->hba_index = 0;
@@ -10929,6 +10933,7 @@ lpfc_rq_create(struct lpfc_hba *phba, struct lpfc_queue *hrq,
10929 goto out; 10933 goto out;
10930 } 10934 }
10931 drq->type = LPFC_DRQ; 10935 drq->type = LPFC_DRQ;
10936 drq->assoc_qid = cq->queue_id;
10932 drq->subtype = subtype; 10937 drq->subtype = subtype;
10933 drq->host_index = 0; 10938 drq->host_index = 0;
10934 drq->hba_index = 0; 10939 drq->hba_index = 0;
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h
index 435a09d331ee..595056b89608 100644
--- a/drivers/scsi/lpfc/lpfc_sli4.h
+++ b/drivers/scsi/lpfc/lpfc_sli4.h
@@ -125,9 +125,9 @@ struct lpfc_queue {
125 uint32_t entry_count; /* Number of entries to support on the queue */ 125 uint32_t entry_count; /* Number of entries to support on the queue */
126 uint32_t entry_size; /* Size of each queue entry. */ 126 uint32_t entry_size; /* Size of each queue entry. */
127 uint32_t queue_id; /* Queue ID assigned by the hardware */ 127 uint32_t queue_id; /* Queue ID assigned by the hardware */
128 uint32_t assoc_qid; /* Queue ID associated with, for CQ/WQ/MQ */
128 struct list_head page_list; 129 struct list_head page_list;
129 uint32_t page_count; /* Number of pages allocated for this queue */ 130 uint32_t page_count; /* Number of pages allocated for this queue */
130
131 uint32_t host_index; /* The host's index for putting or getting */ 131 uint32_t host_index; /* The host's index for putting or getting */
132 uint32_t hba_index; /* The last known hba index for get or put */ 132 uint32_t hba_index; /* The last known hba index for get or put */
133 union sli4_qe qe[1]; /* array to index entries (must be last) */ 133 union sli4_qe qe[1]; /* array to index entries (must be last) */