diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_base.c | 13 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_base.h | 3 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_ctl.c | 125 |
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; | |||
77 | module_param(msix_disable, int, 0); | 77 | module_param(msix_disable, int, 0); |
78 | MODULE_PARM_DESC(msix_disable, " disable msix routed interrupts (default=0)"); | 78 | MODULE_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 | */ | ||
86 | static int diag_buffer_enable; | ||
87 | module_param(diag_buffer_enable, int, 0); | ||
88 | MODULE_PARM_DESC(diag_buffer_enable, " enable diag buffer at driver load " | ||
89 | "time (TRACE=1/SNAP=2/default=0)"); | ||
90 | |||
80 | int mpt2sas_fwfault_debug; | 91 | int mpt2sas_fwfault_debug; |
81 | MODULE_PARM_DESC(mpt2sas_fwfault_debug, " enable detection of firmware fault " | 92 | MODULE_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, | |||
886 | void mpt2sas_ctl_add_to_event_log(struct MPT2SAS_ADAPTER *ioc, | 886 | void mpt2sas_ctl_add_to_event_log(struct MPT2SAS_ADAPTER *ioc, |
887 | Mpi2EventNotificationReply_t *mpi_reply); | 887 | Mpi2EventNotificationReply_t *mpi_reply); |
888 | 888 | ||
889 | void mpt2sas_enable_diag_buffer(struct MPT2SAS_ADAPTER *ioc, | ||
890 | u8 bits_to_regsiter); | ||
891 | |||
889 | /* transport shared API */ | 892 | /* transport shared API */ |
890 | u8 mpt2sas_transport_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, | 893 | u8 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 | */ |
1266 | static long | 1264 | static 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 | */ | ||
1437 | void | ||
1438 | mpt2sas_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 | */ | ||
1473 | static 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 | } |