aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/mpt2sas
diff options
context:
space:
mode:
authorKashyap, Desai <kashyap.desai@lsi.com>2009-09-23 07:58:09 -0400
committerJames Bottomley <James.Bottomley@suse.de>2009-10-29 13:03:11 -0400
commit32e0eb569df09a8cb790cf370ee498721d88e5c6 (patch)
tree719dcb9b7f3f2131217889ba038f6a7a669423ad /drivers/scsi/mpt2sas
parentcef7a12cd1e0647ce2b566a76bbf4cd132b9118d (diff)
[SCSI] mpt2sas: Added command line option diag_buffer_enable.
Added command line option diag_buffer_enable. When the command line option is set, the driver will automatically post diag buffers at driver load time. The command line option diag_buffer_enable is bitwise, so it's possible to enable both and/or snapshot + trace buffers. For trace, the driver will allocate 1MB buffer, whereas for snapshot its 2MB. The purpose for this is so the enduser doesn't have to manually use an application to setup diag buffers for debugging firmware related issues. Here is some examples trace: # insmod mpt2sas.ko diag_buffer_enable=1 snapshot: # insmod mpt2sas.ko diag_buffer_enable=2 both trace and snapshot: # insmod mpt2sas.ko diag_buffer_enable=3 Signed-off-by: Kashyap Desai <kashyap.desai@lsi.com> Signed-off-by: Eric Moore <Eric.moore@lsi.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/mpt2sas')
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.c13
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.h3
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_ctl.c125
3 files changed, 104 insertions, 37 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c
index ec3f57732e97..1d2374b5a0a1 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.c
@@ -77,6 +77,17 @@ static int msix_disable = -1;
77module_param(msix_disable, int, 0); 77module_param(msix_disable, int, 0);
78MODULE_PARM_DESC(msix_disable, " disable msix routed interrupts (default=0)"); 78MODULE_PARM_DESC(msix_disable, " disable msix routed interrupts (default=0)");
79 79
80/* diag_buffer_enable is bitwise
81 * bit 0 set = MPI2_DIAG_BUF_TYPE_TRACE(1)
82 * bit 1 set = MPI2_DIAG_BUF_TYPE_SNAPSHOT(2)
83 *
84 * Either bit can be set, or both
85 */
86static int diag_buffer_enable;
87module_param(diag_buffer_enable, int, 0);
88MODULE_PARM_DESC(diag_buffer_enable, " enable diag buffer at driver load "
89 "time (TRACE=1/SNAP=2/default=0)");
90
80int mpt2sas_fwfault_debug; 91int mpt2sas_fwfault_debug;
81MODULE_PARM_DESC(mpt2sas_fwfault_debug, " enable detection of firmware fault " 92MODULE_PARM_DESC(mpt2sas_fwfault_debug, " enable detection of firmware fault "
82 "and halt firmware - (default=0)"); 93 "and halt firmware - (default=0)");
@@ -3588,6 +3599,8 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
3588 goto out_free_resources; 3599 goto out_free_resources;
3589 3600
3590 mpt2sas_base_start_watchdog(ioc); 3601 mpt2sas_base_start_watchdog(ioc);
3602 if (diag_buffer_enable != 0)
3603 mpt2sas_enable_diag_buffer(ioc, diag_buffer_enable);
3591 return 0; 3604 return 0;
3592 3605
3593 out_free_resources: 3606 out_free_resources:
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h
index 0c75c0e137f7..879fd70fd683 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.h
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.h
@@ -886,6 +886,9 @@ u8 mpt2sas_ctl_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
886void mpt2sas_ctl_add_to_event_log(struct MPT2SAS_ADAPTER *ioc, 886void mpt2sas_ctl_add_to_event_log(struct MPT2SAS_ADAPTER *ioc,
887 Mpi2EventNotificationReply_t *mpi_reply); 887 Mpi2EventNotificationReply_t *mpi_reply);
888 888
889void mpt2sas_enable_diag_buffer(struct MPT2SAS_ADAPTER *ioc,
890 u8 bits_to_regsiter);
891
889/* transport shared API */ 892/* transport shared API */
890u8 mpt2sas_transport_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, 893u8 mpt2sas_transport_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
891 u32 reply); 894 u32 reply);
diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.c b/drivers/scsi/mpt2sas/mpt2sas_ctl.c
index 6901a6706ede..99a332d76f51 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_ctl.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.c
@@ -1256,18 +1256,15 @@ _ctl_diag_capability(struct MPT2SAS_ADAPTER *ioc, u8 buffer_type)
1256} 1256}
1257 1257
1258/** 1258/**
1259 * _ctl_diag_register - application register with driver 1259 * _ctl_diag_register_2 - wrapper for registering diag buffer support
1260 * @arg - user space buffer containing ioctl content 1260 * @ioc: per adapter object
1261 * @state - NON_BLOCKING or BLOCKING 1261 * @diag_register: the diag_register struct passed in from user space
1262 * 1262 *
1263 * This will allow the driver to setup any required buffers that will be
1264 * needed by firmware to communicate with the driver.
1265 */ 1263 */
1266static long 1264static long
1267_ctl_diag_register(void __user *arg, enum block_state state) 1265_ctl_diag_register_2(struct MPT2SAS_ADAPTER *ioc,
1266 struct mpt2_diag_register *diag_register)
1268{ 1267{
1269 struct mpt2_diag_register karg;
1270 struct MPT2SAS_ADAPTER *ioc;
1271 int rc, i; 1268 int rc, i;
1272 void *request_data = NULL; 1269 void *request_data = NULL;
1273 dma_addr_t request_data_dma; 1270 dma_addr_t request_data_dma;
@@ -1280,18 +1277,17 @@ _ctl_diag_register(void __user *arg, enum block_state state)
1280 u16 ioc_status; 1277 u16 ioc_status;
1281 u8 issue_reset = 0; 1278 u8 issue_reset = 0;
1282 1279
1283 if (copy_from_user(&karg, arg, sizeof(karg))) {
1284 printk(KERN_ERR "failure at %s:%d/%s()!\n",
1285 __FILE__, __LINE__, __func__);
1286 return -EFAULT;
1287 }
1288 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
1289 return -ENODEV;
1290
1291 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, 1280 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
1292 __func__)); 1281 __func__));
1293 1282
1294 buffer_type = karg.buffer_type; 1283 if (ioc->ctl_cmds.status != MPT2_CMD_NOT_USED) {
1284 printk(MPT2SAS_ERR_FMT "%s: ctl_cmd in use\n",
1285 ioc->name, __func__);
1286 rc = -EAGAIN;
1287 goto out;
1288 }
1289
1290 buffer_type = diag_register->buffer_type;
1295 if (!_ctl_diag_capability(ioc, buffer_type)) { 1291 if (!_ctl_diag_capability(ioc, buffer_type)) {
1296 printk(MPT2SAS_ERR_FMT "%s: doesn't have capability for " 1292 printk(MPT2SAS_ERR_FMT "%s: doesn't have capability for "
1297 "buffer_type(0x%02x)\n", ioc->name, __func__, buffer_type); 1293 "buffer_type(0x%02x)\n", ioc->name, __func__, buffer_type);
@@ -1306,24 +1302,12 @@ _ctl_diag_register(void __user *arg, enum block_state state)
1306 return -EINVAL; 1302 return -EINVAL;
1307 } 1303 }
1308 1304
1309 if (karg.requested_buffer_size % 4) { 1305 if (diag_register->requested_buffer_size % 4) {
1310 printk(MPT2SAS_ERR_FMT "%s: the requested_buffer_size " 1306 printk(MPT2SAS_ERR_FMT "%s: the requested_buffer_size "
1311 "is not 4 byte aligned\n", ioc->name, __func__); 1307 "is not 4 byte aligned\n", ioc->name, __func__);
1312 return -EINVAL; 1308 return -EINVAL;
1313 } 1309 }
1314 1310
1315 if (state == NON_BLOCKING && !mutex_trylock(&ioc->ctl_cmds.mutex))
1316 return -EAGAIN;
1317 else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex))
1318 return -ERESTARTSYS;
1319
1320 if (ioc->ctl_cmds.status != MPT2_CMD_NOT_USED) {
1321 printk(MPT2SAS_ERR_FMT "%s: ctl_cmd in use\n",
1322 ioc->name, __func__);
1323 rc = -EAGAIN;
1324 goto out;
1325 }
1326
1327 smid = mpt2sas_base_get_smid(ioc, ioc->ctl_cb_idx); 1311 smid = mpt2sas_base_get_smid(ioc, ioc->ctl_cb_idx);
1328 if (!smid) { 1312 if (!smid) {
1329 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n", 1313 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
@@ -1339,12 +1323,12 @@ _ctl_diag_register(void __user *arg, enum block_state state)
1339 ioc->ctl_cmds.smid = smid; 1323 ioc->ctl_cmds.smid = smid;
1340 1324
1341 request_data = ioc->diag_buffer[buffer_type]; 1325 request_data = ioc->diag_buffer[buffer_type];
1342 request_data_sz = karg.requested_buffer_size; 1326 request_data_sz = diag_register->requested_buffer_size;
1343 ioc->unique_id[buffer_type] = karg.unique_id; 1327 ioc->unique_id[buffer_type] = diag_register->unique_id;
1344 ioc->diag_buffer_status[buffer_type] = 0; 1328 ioc->diag_buffer_status[buffer_type] = 0;
1345 memcpy(ioc->product_specific[buffer_type], karg.product_specific, 1329 memcpy(ioc->product_specific[buffer_type],
1346 MPT2_PRODUCT_SPECIFIC_DWORDS); 1330 diag_register->product_specific, MPT2_PRODUCT_SPECIFIC_DWORDS);
1347 ioc->diagnostic_flags[buffer_type] = karg.diagnostic_flags; 1331 ioc->diagnostic_flags[buffer_type] = diag_register->diagnostic_flags;
1348 1332
1349 if (request_data) { 1333 if (request_data) {
1350 request_data_dma = ioc->diag_buffer_dma[buffer_type]; 1334 request_data_dma = ioc->diag_buffer_dma[buffer_type];
@@ -1374,8 +1358,8 @@ _ctl_diag_register(void __user *arg, enum block_state state)
1374 } 1358 }
1375 1359
1376 mpi_request->Function = MPI2_FUNCTION_DIAG_BUFFER_POST; 1360 mpi_request->Function = MPI2_FUNCTION_DIAG_BUFFER_POST;
1377 mpi_request->BufferType = karg.buffer_type; 1361 mpi_request->BufferType = diag_register->buffer_type;
1378 mpi_request->Flags = cpu_to_le32(karg.diagnostic_flags); 1362 mpi_request->Flags = cpu_to_le32(diag_register->diagnostic_flags);
1379 mpi_request->BufferAddress = cpu_to_le64(request_data_dma); 1363 mpi_request->BufferAddress = cpu_to_le64(request_data_dma);
1380 mpi_request->BufferLength = cpu_to_le32(request_data_sz); 1364 mpi_request->BufferLength = cpu_to_le32(request_data_sz);
1381 mpi_request->VF_ID = 0; /* TODO */ 1365 mpi_request->VF_ID = 0; /* TODO */
@@ -1439,6 +1423,73 @@ _ctl_diag_register(void __user *arg, enum block_state state)
1439 request_data, request_data_dma); 1423 request_data, request_data_dma);
1440 1424
1441 ioc->ctl_cmds.status = MPT2_CMD_NOT_USED; 1425 ioc->ctl_cmds.status = MPT2_CMD_NOT_USED;
1426 return rc;
1427}
1428
1429/**
1430 * mpt2sas_enable_diag_buffer - enabling diag_buffers support driver load time
1431 * @ioc: per adapter object
1432 * @bits_to_register: bitwise field where trace is bit 0, and snapshot is bit 1
1433 *
1434 * This is called when command line option diag_buffer_enable is enabled
1435 * at driver load time.
1436 */
1437void
1438mpt2sas_enable_diag_buffer(struct MPT2SAS_ADAPTER *ioc, u8 bits_to_register)
1439{
1440 struct mpt2_diag_register diag_register;
1441
1442 memset(&diag_register, 0, sizeof(struct mpt2_diag_register));
1443
1444 if (bits_to_register & 1) {
1445 printk(MPT2SAS_INFO_FMT "registering trace buffer support\n",
1446 ioc->name);
1447 diag_register.buffer_type = MPI2_DIAG_BUF_TYPE_TRACE;
1448 /* register for 1MB buffers */
1449 diag_register.requested_buffer_size = (1024 * 1024);
1450 diag_register.unique_id = 0x7075900;
1451 _ctl_diag_register_2(ioc, &diag_register);
1452 }
1453
1454 if (bits_to_register & 2) {
1455 printk(MPT2SAS_INFO_FMT "registering snapshot buffer support\n",
1456 ioc->name);
1457 diag_register.buffer_type = MPI2_DIAG_BUF_TYPE_SNAPSHOT;
1458 /* register for 2MB buffers */
1459 diag_register.requested_buffer_size = 2 * (1024 * 1024);
1460 diag_register.unique_id = 0x7075901;
1461 _ctl_diag_register_2(ioc, &diag_register);
1462 }
1463}
1464
1465/**
1466 * _ctl_diag_register - application register with driver
1467 * @arg - user space buffer containing ioctl content
1468 * @state - NON_BLOCKING or BLOCKING
1469 *
1470 * This will allow the driver to setup any required buffers that will be
1471 * needed by firmware to communicate with the driver.
1472 */
1473static long
1474_ctl_diag_register(void __user *arg, enum block_state state)
1475{
1476 struct mpt2_diag_register karg;
1477 struct MPT2SAS_ADAPTER *ioc;
1478 long rc;
1479
1480 if (copy_from_user(&karg, arg, sizeof(karg))) {
1481 printk(KERN_ERR "failure at %s:%d/%s()!\n",
1482 __FILE__, __LINE__, __func__);
1483 return -EFAULT;
1484 }
1485 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
1486 return -ENODEV;
1487
1488 if (state == NON_BLOCKING && !mutex_trylock(&ioc->ctl_cmds.mutex))
1489 return -EAGAIN;
1490 else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex))
1491 return -ERESTARTSYS;
1492 rc = _ctl_diag_register_2(ioc, &karg);
1442 mutex_unlock(&ioc->ctl_cmds.mutex); 1493 mutex_unlock(&ioc->ctl_cmds.mutex);
1443 return rc; 1494 return rc;
1444} 1495}