aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/mpt2sas/mpt2sas_ctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/mpt2sas/mpt2sas_ctl.c')
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_ctl.c197
1 files changed, 150 insertions, 47 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.c b/drivers/scsi/mpt2sas/mpt2sas_ctl.c
index 57d724633906..84a124f8e21f 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_ctl.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.c
@@ -740,7 +740,7 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
740 Mpi2SCSIIORequest_t *scsiio_request = 740 Mpi2SCSIIORequest_t *scsiio_request =
741 (Mpi2SCSIIORequest_t *)mpi_request; 741 (Mpi2SCSIIORequest_t *)mpi_request;
742 scsiio_request->SenseBufferLowAddress = 742 scsiio_request->SenseBufferLowAddress =
743 (u32)mpt2sas_base_get_sense_buffer_dma(ioc, smid); 743 mpt2sas_base_get_sense_buffer_dma(ioc, smid);
744 priv_sense = mpt2sas_base_get_sense_buffer(ioc, smid); 744 priv_sense = mpt2sas_base_get_sense_buffer(ioc, smid);
745 memset(priv_sense, 0, SCSI_SENSE_BUFFERSIZE); 745 memset(priv_sense, 0, SCSI_SENSE_BUFFERSIZE);
746 mpt2sas_base_put_smid_scsi_io(ioc, smid, 746 mpt2sas_base_put_smid_scsi_io(ioc, smid,
@@ -848,8 +848,9 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
848 printk(MPT2SAS_DEBUG_FMT "TASK_MGMT: " 848 printk(MPT2SAS_DEBUG_FMT "TASK_MGMT: "
849 "IOCStatus(0x%04x), IOCLogInfo(0x%08x), " 849 "IOCStatus(0x%04x), IOCLogInfo(0x%08x), "
850 "TerminationCount(0x%08x)\n", ioc->name, 850 "TerminationCount(0x%08x)\n", ioc->name,
851 tm_reply->IOCStatus, tm_reply->IOCLogInfo, 851 le16_to_cpu(tm_reply->IOCStatus),
852 tm_reply->TerminationCount); 852 le32_to_cpu(tm_reply->IOCLogInfo),
853 le32_to_cpu(tm_reply->TerminationCount));
853 } 854 }
854#endif 855#endif
855 /* copy out xdata to user */ 856 /* copy out xdata to user */
@@ -896,6 +897,7 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
896 printk(MPT2SAS_INFO_FMT "issue target reset: handle " 897 printk(MPT2SAS_INFO_FMT "issue target reset: handle "
897 "= (0x%04x)\n", ioc->name, 898 "= (0x%04x)\n", ioc->name,
898 mpi_request->FunctionDependent1); 899 mpi_request->FunctionDependent1);
900 mpt2sas_halt_firmware(ioc);
899 mutex_lock(&ioc->tm_cmds.mutex); 901 mutex_lock(&ioc->tm_cmds.mutex);
900 mpt2sas_scsih_issue_tm(ioc, 902 mpt2sas_scsih_issue_tm(ioc,
901 mpi_request->FunctionDependent1, 0, 903 mpi_request->FunctionDependent1, 0,
@@ -1229,7 +1231,7 @@ _ctl_btdh_mapping(void __user *arg)
1229/** 1231/**
1230 * _ctl_diag_capability - return diag buffer capability 1232 * _ctl_diag_capability - return diag buffer capability
1231 * @ioc: per adapter object 1233 * @ioc: per adapter object
1232 * @buffer_type: specifies either TRACE or SNAPSHOT 1234 * @buffer_type: specifies either TRACE, SNAPSHOT, or EXTENDED
1233 * 1235 *
1234 * returns 1 when diag buffer support is enabled in firmware 1236 * returns 1 when diag buffer support is enabled in firmware
1235 */ 1237 */
@@ -1249,24 +1251,25 @@ _ctl_diag_capability(struct MPT2SAS_ADAPTER *ioc, u8 buffer_type)
1249 MPI2_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER) 1251 MPI2_IOCFACTS_CAPABILITY_SNAPSHOT_BUFFER)
1250 rc = 1; 1252 rc = 1;
1251 break; 1253 break;
1254 case MPI2_DIAG_BUF_TYPE_EXTENDED:
1255 if (ioc->facts.IOCCapabilities &
1256 MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER)
1257 rc = 1;
1252 } 1258 }
1253 1259
1254 return rc; 1260 return rc;
1255} 1261}
1256 1262
1257/** 1263/**
1258 * _ctl_diag_register - application register with driver 1264 * _ctl_diag_register_2 - wrapper for registering diag buffer support
1259 * @arg - user space buffer containing ioctl content 1265 * @ioc: per adapter object
1260 * @state - NON_BLOCKING or BLOCKING 1266 * @diag_register: the diag_register struct passed in from user space
1261 * 1267 *
1262 * This will allow the driver to setup any required buffers that will be
1263 * needed by firmware to communicate with the driver.
1264 */ 1268 */
1265static long 1269static long
1266_ctl_diag_register(void __user *arg, enum block_state state) 1270_ctl_diag_register_2(struct MPT2SAS_ADAPTER *ioc,
1271 struct mpt2_diag_register *diag_register)
1267{ 1272{
1268 struct mpt2_diag_register karg;
1269 struct MPT2SAS_ADAPTER *ioc;
1270 int rc, i; 1273 int rc, i;
1271 void *request_data = NULL; 1274 void *request_data = NULL;
1272 dma_addr_t request_data_dma; 1275 dma_addr_t request_data_dma;
@@ -1279,18 +1282,17 @@ _ctl_diag_register(void __user *arg, enum block_state state)
1279 u16 ioc_status; 1282 u16 ioc_status;
1280 u8 issue_reset = 0; 1283 u8 issue_reset = 0;
1281 1284
1282 if (copy_from_user(&karg, arg, sizeof(karg))) {
1283 printk(KERN_ERR "failure at %s:%d/%s()!\n",
1284 __FILE__, __LINE__, __func__);
1285 return -EFAULT;
1286 }
1287 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
1288 return -ENODEV;
1289
1290 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, 1285 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
1291 __func__)); 1286 __func__));
1292 1287
1293 buffer_type = karg.buffer_type; 1288 if (ioc->ctl_cmds.status != MPT2_CMD_NOT_USED) {
1289 printk(MPT2SAS_ERR_FMT "%s: ctl_cmd in use\n",
1290 ioc->name, __func__);
1291 rc = -EAGAIN;
1292 goto out;
1293 }
1294
1295 buffer_type = diag_register->buffer_type;
1294 if (!_ctl_diag_capability(ioc, buffer_type)) { 1296 if (!_ctl_diag_capability(ioc, buffer_type)) {
1295 printk(MPT2SAS_ERR_FMT "%s: doesn't have capability for " 1297 printk(MPT2SAS_ERR_FMT "%s: doesn't have capability for "
1296 "buffer_type(0x%02x)\n", ioc->name, __func__, buffer_type); 1298 "buffer_type(0x%02x)\n", ioc->name, __func__, buffer_type);
@@ -1305,24 +1307,12 @@ _ctl_diag_register(void __user *arg, enum block_state state)
1305 return -EINVAL; 1307 return -EINVAL;
1306 } 1308 }
1307 1309
1308 if (karg.requested_buffer_size % 4) { 1310 if (diag_register->requested_buffer_size % 4) {
1309 printk(MPT2SAS_ERR_FMT "%s: the requested_buffer_size " 1311 printk(MPT2SAS_ERR_FMT "%s: the requested_buffer_size "
1310 "is not 4 byte aligned\n", ioc->name, __func__); 1312 "is not 4 byte aligned\n", ioc->name, __func__);
1311 return -EINVAL; 1313 return -EINVAL;
1312 } 1314 }
1313 1315
1314 if (state == NON_BLOCKING && !mutex_trylock(&ioc->ctl_cmds.mutex))
1315 return -EAGAIN;
1316 else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex))
1317 return -ERESTARTSYS;
1318
1319 if (ioc->ctl_cmds.status != MPT2_CMD_NOT_USED) {
1320 printk(MPT2SAS_ERR_FMT "%s: ctl_cmd in use\n",
1321 ioc->name, __func__);
1322 rc = -EAGAIN;
1323 goto out;
1324 }
1325
1326 smid = mpt2sas_base_get_smid(ioc, ioc->ctl_cb_idx); 1316 smid = mpt2sas_base_get_smid(ioc, ioc->ctl_cb_idx);
1327 if (!smid) { 1317 if (!smid) {
1328 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n", 1318 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
@@ -1338,12 +1328,12 @@ _ctl_diag_register(void __user *arg, enum block_state state)
1338 ioc->ctl_cmds.smid = smid; 1328 ioc->ctl_cmds.smid = smid;
1339 1329
1340 request_data = ioc->diag_buffer[buffer_type]; 1330 request_data = ioc->diag_buffer[buffer_type];
1341 request_data_sz = karg.requested_buffer_size; 1331 request_data_sz = diag_register->requested_buffer_size;
1342 ioc->unique_id[buffer_type] = karg.unique_id; 1332 ioc->unique_id[buffer_type] = diag_register->unique_id;
1343 ioc->diag_buffer_status[buffer_type] = 0; 1333 ioc->diag_buffer_status[buffer_type] = 0;
1344 memcpy(ioc->product_specific[buffer_type], karg.product_specific, 1334 memcpy(ioc->product_specific[buffer_type],
1345 MPT2_PRODUCT_SPECIFIC_DWORDS); 1335 diag_register->product_specific, MPT2_PRODUCT_SPECIFIC_DWORDS);
1346 ioc->diagnostic_flags[buffer_type] = karg.diagnostic_flags; 1336 ioc->diagnostic_flags[buffer_type] = diag_register->diagnostic_flags;
1347 1337
1348 if (request_data) { 1338 if (request_data) {
1349 request_data_dma = ioc->diag_buffer_dma[buffer_type]; 1339 request_data_dma = ioc->diag_buffer_dma[buffer_type];
@@ -1373,8 +1363,8 @@ _ctl_diag_register(void __user *arg, enum block_state state)
1373 } 1363 }
1374 1364
1375 mpi_request->Function = MPI2_FUNCTION_DIAG_BUFFER_POST; 1365 mpi_request->Function = MPI2_FUNCTION_DIAG_BUFFER_POST;
1376 mpi_request->BufferType = karg.buffer_type; 1366 mpi_request->BufferType = diag_register->buffer_type;
1377 mpi_request->Flags = cpu_to_le32(karg.diagnostic_flags); 1367 mpi_request->Flags = cpu_to_le32(diag_register->diagnostic_flags);
1378 mpi_request->BufferAddress = cpu_to_le64(request_data_dma); 1368 mpi_request->BufferAddress = cpu_to_le64(request_data_dma);
1379 mpi_request->BufferLength = cpu_to_le32(request_data_sz); 1369 mpi_request->BufferLength = cpu_to_le32(request_data_sz);
1380 mpi_request->VF_ID = 0; /* TODO */ 1370 mpi_request->VF_ID = 0; /* TODO */
@@ -1422,7 +1412,7 @@ _ctl_diag_register(void __user *arg, enum block_state state)
1422 } else { 1412 } else {
1423 printk(MPT2SAS_DEBUG_FMT "%s: ioc_status(0x%04x) " 1413 printk(MPT2SAS_DEBUG_FMT "%s: ioc_status(0x%04x) "
1424 "log_info(0x%08x)\n", ioc->name, __func__, 1414 "log_info(0x%08x)\n", ioc->name, __func__,
1425 ioc_status, mpi_reply->IOCLogInfo); 1415 ioc_status, le32_to_cpu(mpi_reply->IOCLogInfo));
1426 rc = -EFAULT; 1416 rc = -EFAULT;
1427 } 1417 }
1428 1418
@@ -1438,6 +1428,83 @@ _ctl_diag_register(void __user *arg, enum block_state state)
1438 request_data, request_data_dma); 1428 request_data, request_data_dma);
1439 1429
1440 ioc->ctl_cmds.status = MPT2_CMD_NOT_USED; 1430 ioc->ctl_cmds.status = MPT2_CMD_NOT_USED;
1431 return rc;
1432}
1433
1434/**
1435 * mpt2sas_enable_diag_buffer - enabling diag_buffers support driver load time
1436 * @ioc: per adapter object
1437 * @bits_to_register: bitwise field where trace is bit 0, and snapshot is bit 1
1438 *
1439 * This is called when command line option diag_buffer_enable is enabled
1440 * at driver load time.
1441 */
1442void
1443mpt2sas_enable_diag_buffer(struct MPT2SAS_ADAPTER *ioc, u8 bits_to_register)
1444{
1445 struct mpt2_diag_register diag_register;
1446
1447 memset(&diag_register, 0, sizeof(struct mpt2_diag_register));
1448
1449 if (bits_to_register & 1) {
1450 printk(MPT2SAS_INFO_FMT "registering trace buffer support\n",
1451 ioc->name);
1452 diag_register.buffer_type = MPI2_DIAG_BUF_TYPE_TRACE;
1453 /* register for 1MB buffers */
1454 diag_register.requested_buffer_size = (1024 * 1024);
1455 diag_register.unique_id = 0x7075900;
1456 _ctl_diag_register_2(ioc, &diag_register);
1457 }
1458
1459 if (bits_to_register & 2) {
1460 printk(MPT2SAS_INFO_FMT "registering snapshot buffer support\n",
1461 ioc->name);
1462 diag_register.buffer_type = MPI2_DIAG_BUF_TYPE_SNAPSHOT;
1463 /* register for 2MB buffers */
1464 diag_register.requested_buffer_size = 2 * (1024 * 1024);
1465 diag_register.unique_id = 0x7075901;
1466 _ctl_diag_register_2(ioc, &diag_register);
1467 }
1468
1469 if (bits_to_register & 4) {
1470 printk(MPT2SAS_INFO_FMT "registering extended buffer support\n",
1471 ioc->name);
1472 diag_register.buffer_type = MPI2_DIAG_BUF_TYPE_EXTENDED;
1473 /* register for 2MB buffers */
1474 diag_register.requested_buffer_size = 2 * (1024 * 1024);
1475 diag_register.unique_id = 0x7075901;
1476 _ctl_diag_register_2(ioc, &diag_register);
1477 }
1478}
1479
1480/**
1481 * _ctl_diag_register - application register with driver
1482 * @arg - user space buffer containing ioctl content
1483 * @state - NON_BLOCKING or BLOCKING
1484 *
1485 * This will allow the driver to setup any required buffers that will be
1486 * needed by firmware to communicate with the driver.
1487 */
1488static long
1489_ctl_diag_register(void __user *arg, enum block_state state)
1490{
1491 struct mpt2_diag_register karg;
1492 struct MPT2SAS_ADAPTER *ioc;
1493 long rc;
1494
1495 if (copy_from_user(&karg, arg, sizeof(karg))) {
1496 printk(KERN_ERR "failure at %s:%d/%s()!\n",
1497 __FILE__, __LINE__, __func__);
1498 return -EFAULT;
1499 }
1500 if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
1501 return -ENODEV;
1502
1503 if (state == NON_BLOCKING && !mutex_trylock(&ioc->ctl_cmds.mutex))
1504 return -EAGAIN;
1505 else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex))
1506 return -ERESTARTSYS;
1507 rc = _ctl_diag_register_2(ioc, &karg);
1441 mutex_unlock(&ioc->ctl_cmds.mutex); 1508 mutex_unlock(&ioc->ctl_cmds.mutex);
1442 return rc; 1509 return rc;
1443} 1510}
@@ -1600,7 +1667,7 @@ _ctl_diag_query(void __user *arg)
1600/** 1667/**
1601 * _ctl_send_release - Diag Release Message 1668 * _ctl_send_release - Diag Release Message
1602 * @ioc: per adapter object 1669 * @ioc: per adapter object
1603 * @buffer_type - specifies either TRACE or SNAPSHOT 1670 * @buffer_type - specifies either TRACE, SNAPSHOT, or EXTENDED
1604 * @issue_reset - specifies whether host reset is required. 1671 * @issue_reset - specifies whether host reset is required.
1605 * 1672 *
1606 */ 1673 */
@@ -1690,7 +1757,7 @@ _ctl_send_release(struct MPT2SAS_ADAPTER *ioc, u8 buffer_type, u8 *issue_reset)
1690 } else { 1757 } else {
1691 printk(MPT2SAS_DEBUG_FMT "%s: ioc_status(0x%04x) " 1758 printk(MPT2SAS_DEBUG_FMT "%s: ioc_status(0x%04x) "
1692 "log_info(0x%08x)\n", ioc->name, __func__, 1759 "log_info(0x%08x)\n", ioc->name, __func__,
1693 ioc_status, mpi_reply->IOCLogInfo); 1760 ioc_status, le32_to_cpu(mpi_reply->IOCLogInfo));
1694 rc = -EFAULT; 1761 rc = -EFAULT;
1695 } 1762 }
1696 1763
@@ -1951,7 +2018,7 @@ _ctl_diag_read_buffer(void __user *arg, enum block_state state)
1951 } else { 2018 } else {
1952 printk(MPT2SAS_DEBUG_FMT "%s: ioc_status(0x%04x) " 2019 printk(MPT2SAS_DEBUG_FMT "%s: ioc_status(0x%04x) "
1953 "log_info(0x%08x)\n", ioc->name, __func__, 2020 "log_info(0x%08x)\n", ioc->name, __func__,
1954 ioc_status, mpi_reply->IOCLogInfo); 2021 ioc_status, le32_to_cpu(mpi_reply->IOCLogInfo));
1955 rc = -EFAULT; 2022 rc = -EFAULT;
1956 } 2023 }
1957 2024
@@ -2474,6 +2541,43 @@ _ctl_logging_level_store(struct device *cdev, struct device_attribute *attr,
2474static DEVICE_ATTR(logging_level, S_IRUGO | S_IWUSR, 2541static DEVICE_ATTR(logging_level, S_IRUGO | S_IWUSR,
2475 _ctl_logging_level_show, _ctl_logging_level_store); 2542 _ctl_logging_level_show, _ctl_logging_level_store);
2476 2543
2544/* device attributes */
2545/*
2546 * _ctl_fwfault_debug_show - show/store fwfault_debug
2547 * @cdev - pointer to embedded class device
2548 * @buf - the buffer returned
2549 *
2550 * mpt2sas_fwfault_debug is command line option
2551 * A sysfs 'read/write' shost attribute.
2552 */
2553static ssize_t
2554_ctl_fwfault_debug_show(struct device *cdev,
2555 struct device_attribute *attr, char *buf)
2556{
2557 struct Scsi_Host *shost = class_to_shost(cdev);
2558 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
2559
2560 return snprintf(buf, PAGE_SIZE, "%d\n", ioc->fwfault_debug);
2561}
2562static ssize_t
2563_ctl_fwfault_debug_store(struct device *cdev,
2564 struct device_attribute *attr, const char *buf, size_t count)
2565{
2566 struct Scsi_Host *shost = class_to_shost(cdev);
2567 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
2568 int val = 0;
2569
2570 if (sscanf(buf, "%d", &val) != 1)
2571 return -EINVAL;
2572
2573 ioc->fwfault_debug = val;
2574 printk(MPT2SAS_INFO_FMT "fwfault_debug=%d\n", ioc->name,
2575 ioc->fwfault_debug);
2576 return strlen(buf);
2577}
2578static DEVICE_ATTR(fwfault_debug, S_IRUGO | S_IWUSR,
2579 _ctl_fwfault_debug_show, _ctl_fwfault_debug_store);
2580
2477struct device_attribute *mpt2sas_host_attrs[] = { 2581struct device_attribute *mpt2sas_host_attrs[] = {
2478 &dev_attr_version_fw, 2582 &dev_attr_version_fw,
2479 &dev_attr_version_bios, 2583 &dev_attr_version_bios,
@@ -2487,13 +2591,12 @@ struct device_attribute *mpt2sas_host_attrs[] = {
2487 &dev_attr_io_delay, 2591 &dev_attr_io_delay,
2488 &dev_attr_device_delay, 2592 &dev_attr_device_delay,
2489 &dev_attr_logging_level, 2593 &dev_attr_logging_level,
2594 &dev_attr_fwfault_debug,
2490 &dev_attr_fw_queue_depth, 2595 &dev_attr_fw_queue_depth,
2491 &dev_attr_host_sas_address, 2596 &dev_attr_host_sas_address,
2492 NULL, 2597 NULL,
2493}; 2598};
2494 2599
2495/* device attributes */
2496
2497/** 2600/**
2498 * _ctl_device_sas_address_show - sas address 2601 * _ctl_device_sas_address_show - sas address
2499 * @cdev - pointer to embedded class device 2602 * @cdev - pointer to embedded class device