diff options
Diffstat (limited to 'drivers/scsi/mpt2sas/mpt2sas_ctl.c')
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_ctl.c | 297 |
1 files changed, 122 insertions, 175 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.c b/drivers/scsi/mpt2sas/mpt2sas_ctl.c index 3b9a28efea82..8eb85e1a0c37 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_ctl.c +++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.c | |||
@@ -620,11 +620,10 @@ _ctl_set_task_mid(struct MPT2SAS_ADAPTER *ioc, struct mpt2_ioctl_command *karg, | |||
620 | * @ioc: per adapter object | 620 | * @ioc: per adapter object |
621 | * @karg - (struct mpt2_ioctl_command) | 621 | * @karg - (struct mpt2_ioctl_command) |
622 | * @mf - pointer to mf in user space | 622 | * @mf - pointer to mf in user space |
623 | * @state - NON_BLOCKING or BLOCKING | ||
624 | */ | 623 | */ |
625 | static long | 624 | static long |
626 | _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc, | 625 | _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc, struct mpt2_ioctl_command karg, |
627 | struct mpt2_ioctl_command karg, void __user *mf, enum block_state state) | 626 | void __user *mf) |
628 | { | 627 | { |
629 | MPI2RequestHeader_t *mpi_request = NULL, *request; | 628 | MPI2RequestHeader_t *mpi_request = NULL, *request; |
630 | MPI2DefaultReply_t *mpi_reply; | 629 | MPI2DefaultReply_t *mpi_reply; |
@@ -647,11 +646,6 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc, | |||
647 | 646 | ||
648 | issue_reset = 0; | 647 | issue_reset = 0; |
649 | 648 | ||
650 | if (state == NON_BLOCKING && !mutex_trylock(&ioc->ctl_cmds.mutex)) | ||
651 | return -EAGAIN; | ||
652 | else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex)) | ||
653 | return -ERESTARTSYS; | ||
654 | |||
655 | if (ioc->ctl_cmds.status != MPT2_CMD_NOT_USED) { | 649 | if (ioc->ctl_cmds.status != MPT2_CMD_NOT_USED) { |
656 | printk(MPT2SAS_ERR_FMT "%s: ctl_cmd in use\n", | 650 | printk(MPT2SAS_ERR_FMT "%s: ctl_cmd in use\n", |
657 | ioc->name, __func__); | 651 | ioc->name, __func__); |
@@ -1013,27 +1007,24 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc, | |||
1013 | 1007 | ||
1014 | kfree(mpi_request); | 1008 | kfree(mpi_request); |
1015 | ioc->ctl_cmds.status = MPT2_CMD_NOT_USED; | 1009 | ioc->ctl_cmds.status = MPT2_CMD_NOT_USED; |
1016 | mutex_unlock(&ioc->ctl_cmds.mutex); | ||
1017 | return ret; | 1010 | return ret; |
1018 | } | 1011 | } |
1019 | 1012 | ||
1020 | /** | 1013 | /** |
1021 | * _ctl_getiocinfo - main handler for MPT2IOCINFO opcode | 1014 | * _ctl_getiocinfo - main handler for MPT2IOCINFO opcode |
1015 | * @ioc: per adapter object | ||
1022 | * @arg - user space buffer containing ioctl content | 1016 | * @arg - user space buffer containing ioctl content |
1023 | */ | 1017 | */ |
1024 | static long | 1018 | static long |
1025 | _ctl_getiocinfo(void __user *arg) | 1019 | _ctl_getiocinfo(struct MPT2SAS_ADAPTER *ioc, void __user *arg) |
1026 | { | 1020 | { |
1027 | struct mpt2_ioctl_iocinfo karg; | 1021 | struct mpt2_ioctl_iocinfo karg; |
1028 | struct MPT2SAS_ADAPTER *ioc; | ||
1029 | 1022 | ||
1030 | if (copy_from_user(&karg, arg, sizeof(karg))) { | 1023 | if (copy_from_user(&karg, arg, sizeof(karg))) { |
1031 | printk(KERN_ERR "failure at %s:%d/%s()!\n", | 1024 | printk(KERN_ERR "failure at %s:%d/%s()!\n", |
1032 | __FILE__, __LINE__, __func__); | 1025 | __FILE__, __LINE__, __func__); |
1033 | return -EFAULT; | 1026 | return -EFAULT; |
1034 | } | 1027 | } |
1035 | if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) | ||
1036 | return -ENODEV; | ||
1037 | 1028 | ||
1038 | dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name, | 1029 | dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name, |
1039 | __func__)); | 1030 | __func__)); |
@@ -1069,21 +1060,19 @@ _ctl_getiocinfo(void __user *arg) | |||
1069 | 1060 | ||
1070 | /** | 1061 | /** |
1071 | * _ctl_eventquery - main handler for MPT2EVENTQUERY opcode | 1062 | * _ctl_eventquery - main handler for MPT2EVENTQUERY opcode |
1063 | * @ioc: per adapter object | ||
1072 | * @arg - user space buffer containing ioctl content | 1064 | * @arg - user space buffer containing ioctl content |
1073 | */ | 1065 | */ |
1074 | static long | 1066 | static long |
1075 | _ctl_eventquery(void __user *arg) | 1067 | _ctl_eventquery(struct MPT2SAS_ADAPTER *ioc, void __user *arg) |
1076 | { | 1068 | { |
1077 | struct mpt2_ioctl_eventquery karg; | 1069 | struct mpt2_ioctl_eventquery karg; |
1078 | struct MPT2SAS_ADAPTER *ioc; | ||
1079 | 1070 | ||
1080 | if (copy_from_user(&karg, arg, sizeof(karg))) { | 1071 | if (copy_from_user(&karg, arg, sizeof(karg))) { |
1081 | printk(KERN_ERR "failure at %s:%d/%s()!\n", | 1072 | printk(KERN_ERR "failure at %s:%d/%s()!\n", |
1082 | __FILE__, __LINE__, __func__); | 1073 | __FILE__, __LINE__, __func__); |
1083 | return -EFAULT; | 1074 | return -EFAULT; |
1084 | } | 1075 | } |
1085 | if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) | ||
1086 | return -ENODEV; | ||
1087 | 1076 | ||
1088 | dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name, | 1077 | dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name, |
1089 | __func__)); | 1078 | __func__)); |
@@ -1102,21 +1091,19 @@ _ctl_eventquery(void __user *arg) | |||
1102 | 1091 | ||
1103 | /** | 1092 | /** |
1104 | * _ctl_eventenable - main handler for MPT2EVENTENABLE opcode | 1093 | * _ctl_eventenable - main handler for MPT2EVENTENABLE opcode |
1094 | * @ioc: per adapter object | ||
1105 | * @arg - user space buffer containing ioctl content | 1095 | * @arg - user space buffer containing ioctl content |
1106 | */ | 1096 | */ |
1107 | static long | 1097 | static long |
1108 | _ctl_eventenable(void __user *arg) | 1098 | _ctl_eventenable(struct MPT2SAS_ADAPTER *ioc, void __user *arg) |
1109 | { | 1099 | { |
1110 | struct mpt2_ioctl_eventenable karg; | 1100 | struct mpt2_ioctl_eventenable karg; |
1111 | struct MPT2SAS_ADAPTER *ioc; | ||
1112 | 1101 | ||
1113 | if (copy_from_user(&karg, arg, sizeof(karg))) { | 1102 | if (copy_from_user(&karg, arg, sizeof(karg))) { |
1114 | printk(KERN_ERR "failure at %s:%d/%s()!\n", | 1103 | printk(KERN_ERR "failure at %s:%d/%s()!\n", |
1115 | __FILE__, __LINE__, __func__); | 1104 | __FILE__, __LINE__, __func__); |
1116 | return -EFAULT; | 1105 | return -EFAULT; |
1117 | } | 1106 | } |
1118 | if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) | ||
1119 | return -ENODEV; | ||
1120 | 1107 | ||
1121 | dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name, | 1108 | dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name, |
1122 | __func__)); | 1109 | __func__)); |
@@ -1142,13 +1129,13 @@ _ctl_eventenable(void __user *arg) | |||
1142 | 1129 | ||
1143 | /** | 1130 | /** |
1144 | * _ctl_eventreport - main handler for MPT2EVENTREPORT opcode | 1131 | * _ctl_eventreport - main handler for MPT2EVENTREPORT opcode |
1132 | * @ioc: per adapter object | ||
1145 | * @arg - user space buffer containing ioctl content | 1133 | * @arg - user space buffer containing ioctl content |
1146 | */ | 1134 | */ |
1147 | static long | 1135 | static long |
1148 | _ctl_eventreport(void __user *arg) | 1136 | _ctl_eventreport(struct MPT2SAS_ADAPTER *ioc, void __user *arg) |
1149 | { | 1137 | { |
1150 | struct mpt2_ioctl_eventreport karg; | 1138 | struct mpt2_ioctl_eventreport karg; |
1151 | struct MPT2SAS_ADAPTER *ioc; | ||
1152 | u32 number_bytes, max_events, max; | 1139 | u32 number_bytes, max_events, max; |
1153 | struct mpt2_ioctl_eventreport __user *uarg = arg; | 1140 | struct mpt2_ioctl_eventreport __user *uarg = arg; |
1154 | 1141 | ||
@@ -1157,8 +1144,6 @@ _ctl_eventreport(void __user *arg) | |||
1157 | __FILE__, __LINE__, __func__); | 1144 | __FILE__, __LINE__, __func__); |
1158 | return -EFAULT; | 1145 | return -EFAULT; |
1159 | } | 1146 | } |
1160 | if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) | ||
1161 | return -ENODEV; | ||
1162 | 1147 | ||
1163 | dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name, | 1148 | dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name, |
1164 | __func__)); | 1149 | __func__)); |
@@ -1188,13 +1173,13 @@ _ctl_eventreport(void __user *arg) | |||
1188 | 1173 | ||
1189 | /** | 1174 | /** |
1190 | * _ctl_do_reset - main handler for MPT2HARDRESET opcode | 1175 | * _ctl_do_reset - main handler for MPT2HARDRESET opcode |
1176 | * @ioc: per adapter object | ||
1191 | * @arg - user space buffer containing ioctl content | 1177 | * @arg - user space buffer containing ioctl content |
1192 | */ | 1178 | */ |
1193 | static long | 1179 | static long |
1194 | _ctl_do_reset(void __user *arg) | 1180 | _ctl_do_reset(struct MPT2SAS_ADAPTER *ioc, void __user *arg) |
1195 | { | 1181 | { |
1196 | struct mpt2_ioctl_diag_reset karg; | 1182 | struct mpt2_ioctl_diag_reset karg; |
1197 | struct MPT2SAS_ADAPTER *ioc; | ||
1198 | int retval; | 1183 | int retval; |
1199 | 1184 | ||
1200 | if (copy_from_user(&karg, arg, sizeof(karg))) { | 1185 | if (copy_from_user(&karg, arg, sizeof(karg))) { |
@@ -1202,8 +1187,6 @@ _ctl_do_reset(void __user *arg) | |||
1202 | __FILE__, __LINE__, __func__); | 1187 | __FILE__, __LINE__, __func__); |
1203 | return -EFAULT; | 1188 | return -EFAULT; |
1204 | } | 1189 | } |
1205 | if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) | ||
1206 | return -ENODEV; | ||
1207 | 1190 | ||
1208 | if (ioc->shost_recovery || ioc->pci_error_recovery || | 1191 | if (ioc->shost_recovery || ioc->pci_error_recovery || |
1209 | ioc->is_driver_loading) | 1192 | ioc->is_driver_loading) |
@@ -1292,13 +1275,13 @@ _ctl_btdh_search_raid_device(struct MPT2SAS_ADAPTER *ioc, | |||
1292 | 1275 | ||
1293 | /** | 1276 | /** |
1294 | * _ctl_btdh_mapping - main handler for MPT2BTDHMAPPING opcode | 1277 | * _ctl_btdh_mapping - main handler for MPT2BTDHMAPPING opcode |
1278 | * @ioc: per adapter object | ||
1295 | * @arg - user space buffer containing ioctl content | 1279 | * @arg - user space buffer containing ioctl content |
1296 | */ | 1280 | */ |
1297 | static long | 1281 | static long |
1298 | _ctl_btdh_mapping(void __user *arg) | 1282 | _ctl_btdh_mapping(struct MPT2SAS_ADAPTER *ioc, void __user *arg) |
1299 | { | 1283 | { |
1300 | struct mpt2_ioctl_btdh_mapping karg; | 1284 | struct mpt2_ioctl_btdh_mapping karg; |
1301 | struct MPT2SAS_ADAPTER *ioc; | ||
1302 | int rc; | 1285 | int rc; |
1303 | 1286 | ||
1304 | if (copy_from_user(&karg, arg, sizeof(karg))) { | 1287 | if (copy_from_user(&karg, arg, sizeof(karg))) { |
@@ -1306,8 +1289,6 @@ _ctl_btdh_mapping(void __user *arg) | |||
1306 | __FILE__, __LINE__, __func__); | 1289 | __FILE__, __LINE__, __func__); |
1307 | return -EFAULT; | 1290 | return -EFAULT; |
1308 | } | 1291 | } |
1309 | if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) | ||
1310 | return -ENODEV; | ||
1311 | 1292 | ||
1312 | dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, | 1293 | dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, |
1313 | __func__)); | 1294 | __func__)); |
@@ -1576,17 +1557,16 @@ mpt2sas_enable_diag_buffer(struct MPT2SAS_ADAPTER *ioc, u8 bits_to_register) | |||
1576 | 1557 | ||
1577 | /** | 1558 | /** |
1578 | * _ctl_diag_register - application register with driver | 1559 | * _ctl_diag_register - application register with driver |
1560 | * @ioc: per adapter object | ||
1579 | * @arg - user space buffer containing ioctl content | 1561 | * @arg - user space buffer containing ioctl content |
1580 | * @state - NON_BLOCKING or BLOCKING | ||
1581 | * | 1562 | * |
1582 | * This will allow the driver to setup any required buffers that will be | 1563 | * This will allow the driver to setup any required buffers that will be |
1583 | * needed by firmware to communicate with the driver. | 1564 | * needed by firmware to communicate with the driver. |
1584 | */ | 1565 | */ |
1585 | static long | 1566 | static long |
1586 | _ctl_diag_register(void __user *arg, enum block_state state) | 1567 | _ctl_diag_register(struct MPT2SAS_ADAPTER *ioc, void __user *arg) |
1587 | { | 1568 | { |
1588 | struct mpt2_diag_register karg; | 1569 | struct mpt2_diag_register karg; |
1589 | struct MPT2SAS_ADAPTER *ioc; | ||
1590 | long rc; | 1570 | long rc; |
1591 | 1571 | ||
1592 | if (copy_from_user(&karg, arg, sizeof(karg))) { | 1572 | if (copy_from_user(&karg, arg, sizeof(karg))) { |
@@ -1594,30 +1574,23 @@ _ctl_diag_register(void __user *arg, enum block_state state) | |||
1594 | __FILE__, __LINE__, __func__); | 1574 | __FILE__, __LINE__, __func__); |
1595 | return -EFAULT; | 1575 | return -EFAULT; |
1596 | } | 1576 | } |
1597 | if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) | ||
1598 | return -ENODEV; | ||
1599 | 1577 | ||
1600 | if (state == NON_BLOCKING && !mutex_trylock(&ioc->ctl_cmds.mutex)) | ||
1601 | return -EAGAIN; | ||
1602 | else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex)) | ||
1603 | return -ERESTARTSYS; | ||
1604 | rc = _ctl_diag_register_2(ioc, &karg); | 1578 | rc = _ctl_diag_register_2(ioc, &karg); |
1605 | mutex_unlock(&ioc->ctl_cmds.mutex); | ||
1606 | return rc; | 1579 | return rc; |
1607 | } | 1580 | } |
1608 | 1581 | ||
1609 | /** | 1582 | /** |
1610 | * _ctl_diag_unregister - application unregister with driver | 1583 | * _ctl_diag_unregister - application unregister with driver |
1584 | * @ioc: per adapter object | ||
1611 | * @arg - user space buffer containing ioctl content | 1585 | * @arg - user space buffer containing ioctl content |
1612 | * | 1586 | * |
1613 | * This will allow the driver to cleanup any memory allocated for diag | 1587 | * This will allow the driver to cleanup any memory allocated for diag |
1614 | * messages and to free up any resources. | 1588 | * messages and to free up any resources. |
1615 | */ | 1589 | */ |
1616 | static long | 1590 | static long |
1617 | _ctl_diag_unregister(void __user *arg) | 1591 | _ctl_diag_unregister(struct MPT2SAS_ADAPTER *ioc, void __user *arg) |
1618 | { | 1592 | { |
1619 | struct mpt2_diag_unregister karg; | 1593 | struct mpt2_diag_unregister karg; |
1620 | struct MPT2SAS_ADAPTER *ioc; | ||
1621 | void *request_data; | 1594 | void *request_data; |
1622 | dma_addr_t request_data_dma; | 1595 | dma_addr_t request_data_dma; |
1623 | u32 request_data_sz; | 1596 | u32 request_data_sz; |
@@ -1628,8 +1601,6 @@ _ctl_diag_unregister(void __user *arg) | |||
1628 | __FILE__, __LINE__, __func__); | 1601 | __FILE__, __LINE__, __func__); |
1629 | return -EFAULT; | 1602 | return -EFAULT; |
1630 | } | 1603 | } |
1631 | if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) | ||
1632 | return -ENODEV; | ||
1633 | 1604 | ||
1634 | dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, | 1605 | dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, |
1635 | __func__)); | 1606 | __func__)); |
@@ -1678,6 +1649,7 @@ _ctl_diag_unregister(void __user *arg) | |||
1678 | 1649 | ||
1679 | /** | 1650 | /** |
1680 | * _ctl_diag_query - query relevant info associated with diag buffers | 1651 | * _ctl_diag_query - query relevant info associated with diag buffers |
1652 | * @ioc: per adapter object | ||
1681 | * @arg - user space buffer containing ioctl content | 1653 | * @arg - user space buffer containing ioctl content |
1682 | * | 1654 | * |
1683 | * The application will send only buffer_type and unique_id. Driver will | 1655 | * The application will send only buffer_type and unique_id. Driver will |
@@ -1685,10 +1657,9 @@ _ctl_diag_unregister(void __user *arg) | |||
1685 | * 0x00, the driver will return info specified by Buffer Type. | 1657 | * 0x00, the driver will return info specified by Buffer Type. |
1686 | */ | 1658 | */ |
1687 | static long | 1659 | static long |
1688 | _ctl_diag_query(void __user *arg) | 1660 | _ctl_diag_query(struct MPT2SAS_ADAPTER *ioc, void __user *arg) |
1689 | { | 1661 | { |
1690 | struct mpt2_diag_query karg; | 1662 | struct mpt2_diag_query karg; |
1691 | struct MPT2SAS_ADAPTER *ioc; | ||
1692 | void *request_data; | 1663 | void *request_data; |
1693 | int i; | 1664 | int i; |
1694 | u8 buffer_type; | 1665 | u8 buffer_type; |
@@ -1698,8 +1669,6 @@ _ctl_diag_query(void __user *arg) | |||
1698 | __FILE__, __LINE__, __func__); | 1669 | __FILE__, __LINE__, __func__); |
1699 | return -EFAULT; | 1670 | return -EFAULT; |
1700 | } | 1671 | } |
1701 | if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) | ||
1702 | return -ENODEV; | ||
1703 | 1672 | ||
1704 | dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, | 1673 | dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, |
1705 | __func__)); | 1674 | __func__)); |
@@ -1866,17 +1835,15 @@ _ctl_send_release(struct MPT2SAS_ADAPTER *ioc, u8 buffer_type, u8 *issue_reset) | |||
1866 | /** | 1835 | /** |
1867 | * _ctl_diag_release - request to send Diag Release Message to firmware | 1836 | * _ctl_diag_release - request to send Diag Release Message to firmware |
1868 | * @arg - user space buffer containing ioctl content | 1837 | * @arg - user space buffer containing ioctl content |
1869 | * @state - NON_BLOCKING or BLOCKING | ||
1870 | * | 1838 | * |
1871 | * This allows ownership of the specified buffer to returned to the driver, | 1839 | * This allows ownership of the specified buffer to returned to the driver, |
1872 | * allowing an application to read the buffer without fear that firmware is | 1840 | * allowing an application to read the buffer without fear that firmware is |
1873 | * overwritting information in the buffer. | 1841 | * overwritting information in the buffer. |
1874 | */ | 1842 | */ |
1875 | static long | 1843 | static long |
1876 | _ctl_diag_release(void __user *arg, enum block_state state) | 1844 | _ctl_diag_release(struct MPT2SAS_ADAPTER *ioc, void __user *arg) |
1877 | { | 1845 | { |
1878 | struct mpt2_diag_release karg; | 1846 | struct mpt2_diag_release karg; |
1879 | struct MPT2SAS_ADAPTER *ioc; | ||
1880 | void *request_data; | 1847 | void *request_data; |
1881 | int rc; | 1848 | int rc; |
1882 | u8 buffer_type; | 1849 | u8 buffer_type; |
@@ -1887,8 +1854,6 @@ _ctl_diag_release(void __user *arg, enum block_state state) | |||
1887 | __FILE__, __LINE__, __func__); | 1854 | __FILE__, __LINE__, __func__); |
1888 | return -EFAULT; | 1855 | return -EFAULT; |
1889 | } | 1856 | } |
1890 | if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) | ||
1891 | return -ENODEV; | ||
1892 | 1857 | ||
1893 | dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, | 1858 | dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, |
1894 | __func__)); | 1859 | __func__)); |
@@ -1942,32 +1907,25 @@ _ctl_diag_release(void __user *arg, enum block_state state) | |||
1942 | return 0; | 1907 | return 0; |
1943 | } | 1908 | } |
1944 | 1909 | ||
1945 | if (state == NON_BLOCKING && !mutex_trylock(&ioc->ctl_cmds.mutex)) | ||
1946 | return -EAGAIN; | ||
1947 | else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex)) | ||
1948 | return -ERESTARTSYS; | ||
1949 | |||
1950 | rc = _ctl_send_release(ioc, buffer_type, &issue_reset); | 1910 | rc = _ctl_send_release(ioc, buffer_type, &issue_reset); |
1951 | 1911 | ||
1952 | if (issue_reset) | 1912 | if (issue_reset) |
1953 | mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, | 1913 | mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, |
1954 | FORCE_BIG_HAMMER); | 1914 | FORCE_BIG_HAMMER); |
1955 | 1915 | ||
1956 | mutex_unlock(&ioc->ctl_cmds.mutex); | ||
1957 | return rc; | 1916 | return rc; |
1958 | } | 1917 | } |
1959 | 1918 | ||
1960 | /** | 1919 | /** |
1961 | * _ctl_diag_read_buffer - request for copy of the diag buffer | 1920 | * _ctl_diag_read_buffer - request for copy of the diag buffer |
1921 | * @ioc: per adapter object | ||
1962 | * @arg - user space buffer containing ioctl content | 1922 | * @arg - user space buffer containing ioctl content |
1963 | * @state - NON_BLOCKING or BLOCKING | ||
1964 | */ | 1923 | */ |
1965 | static long | 1924 | static long |
1966 | _ctl_diag_read_buffer(void __user *arg, enum block_state state) | 1925 | _ctl_diag_read_buffer(struct MPT2SAS_ADAPTER *ioc, void __user *arg) |
1967 | { | 1926 | { |
1968 | struct mpt2_diag_read_buffer karg; | 1927 | struct mpt2_diag_read_buffer karg; |
1969 | struct mpt2_diag_read_buffer __user *uarg = arg; | 1928 | struct mpt2_diag_read_buffer __user *uarg = arg; |
1970 | struct MPT2SAS_ADAPTER *ioc; | ||
1971 | void *request_data, *diag_data; | 1929 | void *request_data, *diag_data; |
1972 | Mpi2DiagBufferPostRequest_t *mpi_request; | 1930 | Mpi2DiagBufferPostRequest_t *mpi_request; |
1973 | Mpi2DiagBufferPostReply_t *mpi_reply; | 1931 | Mpi2DiagBufferPostReply_t *mpi_reply; |
@@ -1983,8 +1941,6 @@ _ctl_diag_read_buffer(void __user *arg, enum block_state state) | |||
1983 | __FILE__, __LINE__, __func__); | 1941 | __FILE__, __LINE__, __func__); |
1984 | return -EFAULT; | 1942 | return -EFAULT; |
1985 | } | 1943 | } |
1986 | if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc) | ||
1987 | return -ENODEV; | ||
1988 | 1944 | ||
1989 | dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, | 1945 | dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, |
1990 | __func__)); | 1946 | __func__)); |
@@ -2055,10 +2011,6 @@ _ctl_diag_read_buffer(void __user *arg, enum block_state state) | |||
2055 | } | 2011 | } |
2056 | /* Get a free request frame and save the message context. | 2012 | /* Get a free request frame and save the message context. |
2057 | */ | 2013 | */ |
2058 | if (state == NON_BLOCKING && !mutex_trylock(&ioc->ctl_cmds.mutex)) | ||
2059 | return -EAGAIN; | ||
2060 | else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex)) | ||
2061 | return -ERESTARTSYS; | ||
2062 | 2014 | ||
2063 | if (ioc->ctl_cmds.status != MPT2_CMD_NOT_USED) { | 2015 | if (ioc->ctl_cmds.status != MPT2_CMD_NOT_USED) { |
2064 | printk(MPT2SAS_ERR_FMT "%s: ctl_cmd in use\n", | 2016 | printk(MPT2SAS_ERR_FMT "%s: ctl_cmd in use\n", |
@@ -2139,115 +2091,170 @@ _ctl_diag_read_buffer(void __user *arg, enum block_state state) | |||
2139 | out: | 2091 | out: |
2140 | 2092 | ||
2141 | ioc->ctl_cmds.status = MPT2_CMD_NOT_USED; | 2093 | ioc->ctl_cmds.status = MPT2_CMD_NOT_USED; |
2142 | mutex_unlock(&ioc->ctl_cmds.mutex); | ||
2143 | return rc; | 2094 | return rc; |
2144 | } | 2095 | } |
2145 | 2096 | ||
2097 | |||
2098 | #ifdef CONFIG_COMPAT | ||
2099 | /** | ||
2100 | * _ctl_compat_mpt_command - convert 32bit pointers to 64bit. | ||
2101 | * @ioc: per adapter object | ||
2102 | * @cmd - ioctl opcode | ||
2103 | * @arg - (struct mpt2_ioctl_command32) | ||
2104 | * | ||
2105 | * MPT2COMMAND32 - Handle 32bit applications running on 64bit os. | ||
2106 | */ | ||
2107 | static long | ||
2108 | _ctl_compat_mpt_command(struct MPT2SAS_ADAPTER *ioc, unsigned cmd, | ||
2109 | void __user *arg) | ||
2110 | { | ||
2111 | struct mpt2_ioctl_command32 karg32; | ||
2112 | struct mpt2_ioctl_command32 __user *uarg; | ||
2113 | struct mpt2_ioctl_command karg; | ||
2114 | |||
2115 | if (_IOC_SIZE(cmd) != sizeof(struct mpt2_ioctl_command32)) | ||
2116 | return -EINVAL; | ||
2117 | |||
2118 | uarg = (struct mpt2_ioctl_command32 __user *) arg; | ||
2119 | |||
2120 | if (copy_from_user(&karg32, (char __user *)arg, sizeof(karg32))) { | ||
2121 | printk(KERN_ERR "failure at %s:%d/%s()!\n", | ||
2122 | __FILE__, __LINE__, __func__); | ||
2123 | return -EFAULT; | ||
2124 | } | ||
2125 | |||
2126 | memset(&karg, 0, sizeof(struct mpt2_ioctl_command)); | ||
2127 | karg.hdr.ioc_number = karg32.hdr.ioc_number; | ||
2128 | karg.hdr.port_number = karg32.hdr.port_number; | ||
2129 | karg.hdr.max_data_size = karg32.hdr.max_data_size; | ||
2130 | karg.timeout = karg32.timeout; | ||
2131 | karg.max_reply_bytes = karg32.max_reply_bytes; | ||
2132 | karg.data_in_size = karg32.data_in_size; | ||
2133 | karg.data_out_size = karg32.data_out_size; | ||
2134 | karg.max_sense_bytes = karg32.max_sense_bytes; | ||
2135 | karg.data_sge_offset = karg32.data_sge_offset; | ||
2136 | karg.reply_frame_buf_ptr = compat_ptr(karg32.reply_frame_buf_ptr); | ||
2137 | karg.data_in_buf_ptr = compat_ptr(karg32.data_in_buf_ptr); | ||
2138 | karg.data_out_buf_ptr = compat_ptr(karg32.data_out_buf_ptr); | ||
2139 | karg.sense_data_ptr = compat_ptr(karg32.sense_data_ptr); | ||
2140 | return _ctl_do_mpt_command(ioc, karg, &uarg->mf); | ||
2141 | } | ||
2142 | #endif | ||
2143 | |||
2146 | /** | 2144 | /** |
2147 | * _ctl_ioctl_main - main ioctl entry point | 2145 | * _ctl_ioctl_main - main ioctl entry point |
2148 | * @file - (struct file) | 2146 | * @file - (struct file) |
2149 | * @cmd - ioctl opcode | 2147 | * @cmd - ioctl opcode |
2150 | * @arg - | 2148 | * @arg - |
2149 | * compat - handles 32 bit applications in 64bit os | ||
2151 | */ | 2150 | */ |
2152 | static long | 2151 | static long |
2153 | _ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg) | 2152 | _ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg, |
2153 | u8 compat) | ||
2154 | { | 2154 | { |
2155 | struct MPT2SAS_ADAPTER *ioc; | ||
2156 | struct mpt2_ioctl_header ioctl_header; | ||
2155 | enum block_state state; | 2157 | enum block_state state; |
2156 | long ret = -EINVAL; | 2158 | long ret = -EINVAL; |
2157 | 2159 | ||
2158 | state = (file->f_flags & O_NONBLOCK) ? NON_BLOCKING : | 2160 | /* get IOCTL header */ |
2159 | BLOCKING; | 2161 | if (copy_from_user(&ioctl_header, (char __user *)arg, |
2162 | sizeof(struct mpt2_ioctl_header))) { | ||
2163 | printk(KERN_ERR "failure at %s:%d/%s()!\n", | ||
2164 | __FILE__, __LINE__, __func__); | ||
2165 | return -EFAULT; | ||
2166 | } | ||
2167 | |||
2168 | if (_ctl_verify_adapter(ioctl_header.ioc_number, &ioc) == -1 || !ioc) | ||
2169 | return -ENODEV; | ||
2170 | if (ioc->shost_recovery || ioc->pci_error_recovery || | ||
2171 | ioc->is_driver_loading) | ||
2172 | return -EAGAIN; | ||
2173 | |||
2174 | state = (file->f_flags & O_NONBLOCK) ? NON_BLOCKING : BLOCKING; | ||
2175 | if (state == NON_BLOCKING && !mutex_trylock(&ioc->ctl_cmds.mutex)) | ||
2176 | return -EAGAIN; | ||
2177 | else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex)) | ||
2178 | return -ERESTARTSYS; | ||
2160 | 2179 | ||
2161 | switch (cmd) { | 2180 | switch (cmd) { |
2162 | case MPT2IOCINFO: | 2181 | case MPT2IOCINFO: |
2163 | if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_iocinfo)) | 2182 | if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_iocinfo)) |
2164 | ret = _ctl_getiocinfo(arg); | 2183 | ret = _ctl_getiocinfo(ioc, arg); |
2165 | break; | 2184 | break; |
2185 | #ifdef CONFIG_COMPAT | ||
2186 | case MPT2COMMAND32: | ||
2187 | #endif | ||
2166 | case MPT2COMMAND: | 2188 | case MPT2COMMAND: |
2167 | { | 2189 | { |
2168 | struct mpt2_ioctl_command karg; | ||
2169 | struct mpt2_ioctl_command __user *uarg; | 2190 | struct mpt2_ioctl_command __user *uarg; |
2170 | struct MPT2SAS_ADAPTER *ioc; | 2191 | struct mpt2_ioctl_command karg; |
2171 | 2192 | #ifdef CONFIG_COMPAT | |
2193 | if (compat) { | ||
2194 | ret = _ctl_compat_mpt_command(ioc, cmd, arg); | ||
2195 | break; | ||
2196 | } | ||
2197 | #endif | ||
2172 | if (copy_from_user(&karg, arg, sizeof(karg))) { | 2198 | if (copy_from_user(&karg, arg, sizeof(karg))) { |
2173 | printk(KERN_ERR "failure at %s:%d/%s()!\n", | 2199 | printk(KERN_ERR "failure at %s:%d/%s()!\n", |
2174 | __FILE__, __LINE__, __func__); | 2200 | __FILE__, __LINE__, __func__); |
2175 | return -EFAULT; | 2201 | ret = -EFAULT; |
2202 | break; | ||
2176 | } | 2203 | } |
2177 | 2204 | ||
2178 | if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || | ||
2179 | !ioc) | ||
2180 | return -ENODEV; | ||
2181 | |||
2182 | if (ioc->shost_recovery || ioc->pci_error_recovery || | ||
2183 | ioc->is_driver_loading) | ||
2184 | return -EAGAIN; | ||
2185 | |||
2186 | if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_command)) { | 2205 | if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_command)) { |
2187 | uarg = arg; | 2206 | uarg = arg; |
2188 | ret = _ctl_do_mpt_command(ioc, karg, &uarg->mf, state); | 2207 | ret = _ctl_do_mpt_command(ioc, karg, &uarg->mf); |
2189 | } | 2208 | } |
2190 | break; | 2209 | break; |
2191 | } | 2210 | } |
2192 | case MPT2EVENTQUERY: | 2211 | case MPT2EVENTQUERY: |
2193 | if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_eventquery)) | 2212 | if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_eventquery)) |
2194 | ret = _ctl_eventquery(arg); | 2213 | ret = _ctl_eventquery(ioc, arg); |
2195 | break; | 2214 | break; |
2196 | case MPT2EVENTENABLE: | 2215 | case MPT2EVENTENABLE: |
2197 | if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_eventenable)) | 2216 | if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_eventenable)) |
2198 | ret = _ctl_eventenable(arg); | 2217 | ret = _ctl_eventenable(ioc, arg); |
2199 | break; | 2218 | break; |
2200 | case MPT2EVENTREPORT: | 2219 | case MPT2EVENTREPORT: |
2201 | ret = _ctl_eventreport(arg); | 2220 | ret = _ctl_eventreport(ioc, arg); |
2202 | break; | 2221 | break; |
2203 | case MPT2HARDRESET: | 2222 | case MPT2HARDRESET: |
2204 | if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_diag_reset)) | 2223 | if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_diag_reset)) |
2205 | ret = _ctl_do_reset(arg); | 2224 | ret = _ctl_do_reset(ioc, arg); |
2206 | break; | 2225 | break; |
2207 | case MPT2BTDHMAPPING: | 2226 | case MPT2BTDHMAPPING: |
2208 | if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_btdh_mapping)) | 2227 | if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_btdh_mapping)) |
2209 | ret = _ctl_btdh_mapping(arg); | 2228 | ret = _ctl_btdh_mapping(ioc, arg); |
2210 | break; | 2229 | break; |
2211 | case MPT2DIAGREGISTER: | 2230 | case MPT2DIAGREGISTER: |
2212 | if (_IOC_SIZE(cmd) == sizeof(struct mpt2_diag_register)) | 2231 | if (_IOC_SIZE(cmd) == sizeof(struct mpt2_diag_register)) |
2213 | ret = _ctl_diag_register(arg, state); | 2232 | ret = _ctl_diag_register(ioc, arg); |
2214 | break; | 2233 | break; |
2215 | case MPT2DIAGUNREGISTER: | 2234 | case MPT2DIAGUNREGISTER: |
2216 | if (_IOC_SIZE(cmd) == sizeof(struct mpt2_diag_unregister)) | 2235 | if (_IOC_SIZE(cmd) == sizeof(struct mpt2_diag_unregister)) |
2217 | ret = _ctl_diag_unregister(arg); | 2236 | ret = _ctl_diag_unregister(ioc, arg); |
2218 | break; | 2237 | break; |
2219 | case MPT2DIAGQUERY: | 2238 | case MPT2DIAGQUERY: |
2220 | if (_IOC_SIZE(cmd) == sizeof(struct mpt2_diag_query)) | 2239 | if (_IOC_SIZE(cmd) == sizeof(struct mpt2_diag_query)) |
2221 | ret = _ctl_diag_query(arg); | 2240 | ret = _ctl_diag_query(ioc, arg); |
2222 | break; | 2241 | break; |
2223 | case MPT2DIAGRELEASE: | 2242 | case MPT2DIAGRELEASE: |
2224 | if (_IOC_SIZE(cmd) == sizeof(struct mpt2_diag_release)) | 2243 | if (_IOC_SIZE(cmd) == sizeof(struct mpt2_diag_release)) |
2225 | ret = _ctl_diag_release(arg, state); | 2244 | ret = _ctl_diag_release(ioc, arg); |
2226 | break; | 2245 | break; |
2227 | case MPT2DIAGREADBUFFER: | 2246 | case MPT2DIAGREADBUFFER: |
2228 | if (_IOC_SIZE(cmd) == sizeof(struct mpt2_diag_read_buffer)) | 2247 | if (_IOC_SIZE(cmd) == sizeof(struct mpt2_diag_read_buffer)) |
2229 | ret = _ctl_diag_read_buffer(arg, state); | 2248 | ret = _ctl_diag_read_buffer(ioc, arg); |
2230 | break; | 2249 | break; |
2231 | default: | 2250 | default: |
2232 | { | ||
2233 | struct mpt2_ioctl_command karg; | ||
2234 | struct MPT2SAS_ADAPTER *ioc; | ||
2235 | |||
2236 | if (copy_from_user(&karg, arg, sizeof(karg))) { | ||
2237 | printk(KERN_ERR "failure at %s:%d/%s()!\n", | ||
2238 | __FILE__, __LINE__, __func__); | ||
2239 | return -EFAULT; | ||
2240 | } | ||
2241 | |||
2242 | if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || | ||
2243 | !ioc) | ||
2244 | return -ENODEV; | ||
2245 | 2251 | ||
2246 | dctlprintk(ioc, printk(MPT2SAS_INFO_FMT | 2252 | dctlprintk(ioc, printk(MPT2SAS_INFO_FMT |
2247 | "unsupported ioctl opcode(0x%08x)\n", ioc->name, cmd)); | 2253 | "unsupported ioctl opcode(0x%08x)\n", ioc->name, cmd)); |
2248 | break; | 2254 | break; |
2249 | } | 2255 | } |
2250 | } | 2256 | |
2257 | mutex_unlock(&ioc->ctl_cmds.mutex); | ||
2251 | return ret; | 2258 | return ret; |
2252 | } | 2259 | } |
2253 | 2260 | ||
@@ -2262,66 +2269,11 @@ _ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
2262 | { | 2269 | { |
2263 | long ret; | 2270 | long ret; |
2264 | 2271 | ||
2265 | mutex_lock(&_ctl_mutex); | 2272 | ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 0); |
2266 | ret = _ctl_ioctl_main(file, cmd, (void __user *)arg); | ||
2267 | mutex_unlock(&_ctl_mutex); | ||
2268 | return ret; | 2273 | return ret; |
2269 | } | 2274 | } |
2270 | |||
2271 | #ifdef CONFIG_COMPAT | 2275 | #ifdef CONFIG_COMPAT |
2272 | /** | 2276 | /** |
2273 | * _ctl_compat_mpt_command - convert 32bit pointers to 64bit. | ||
2274 | * @file - (struct file) | ||
2275 | * @cmd - ioctl opcode | ||
2276 | * @arg - (struct mpt2_ioctl_command32) | ||
2277 | * | ||
2278 | * MPT2COMMAND32 - Handle 32bit applications running on 64bit os. | ||
2279 | */ | ||
2280 | static long | ||
2281 | _ctl_compat_mpt_command(struct file *file, unsigned cmd, unsigned long arg) | ||
2282 | { | ||
2283 | struct mpt2_ioctl_command32 karg32; | ||
2284 | struct mpt2_ioctl_command32 __user *uarg; | ||
2285 | struct mpt2_ioctl_command karg; | ||
2286 | struct MPT2SAS_ADAPTER *ioc; | ||
2287 | enum block_state state; | ||
2288 | |||
2289 | if (_IOC_SIZE(cmd) != sizeof(struct mpt2_ioctl_command32)) | ||
2290 | return -EINVAL; | ||
2291 | |||
2292 | uarg = (struct mpt2_ioctl_command32 __user *) arg; | ||
2293 | |||
2294 | if (copy_from_user(&karg32, (char __user *)arg, sizeof(karg32))) { | ||
2295 | printk(KERN_ERR "failure at %s:%d/%s()!\n", | ||
2296 | __FILE__, __LINE__, __func__); | ||
2297 | return -EFAULT; | ||
2298 | } | ||
2299 | if (_ctl_verify_adapter(karg32.hdr.ioc_number, &ioc) == -1 || !ioc) | ||
2300 | return -ENODEV; | ||
2301 | |||
2302 | if (ioc->shost_recovery || ioc->pci_error_recovery || | ||
2303 | ioc->is_driver_loading) | ||
2304 | return -EAGAIN; | ||
2305 | |||
2306 | memset(&karg, 0, sizeof(struct mpt2_ioctl_command)); | ||
2307 | karg.hdr.ioc_number = karg32.hdr.ioc_number; | ||
2308 | karg.hdr.port_number = karg32.hdr.port_number; | ||
2309 | karg.hdr.max_data_size = karg32.hdr.max_data_size; | ||
2310 | karg.timeout = karg32.timeout; | ||
2311 | karg.max_reply_bytes = karg32.max_reply_bytes; | ||
2312 | karg.data_in_size = karg32.data_in_size; | ||
2313 | karg.data_out_size = karg32.data_out_size; | ||
2314 | karg.max_sense_bytes = karg32.max_sense_bytes; | ||
2315 | karg.data_sge_offset = karg32.data_sge_offset; | ||
2316 | karg.reply_frame_buf_ptr = compat_ptr(karg32.reply_frame_buf_ptr); | ||
2317 | karg.data_in_buf_ptr = compat_ptr(karg32.data_in_buf_ptr); | ||
2318 | karg.data_out_buf_ptr = compat_ptr(karg32.data_out_buf_ptr); | ||
2319 | karg.sense_data_ptr = compat_ptr(karg32.sense_data_ptr); | ||
2320 | state = (file->f_flags & O_NONBLOCK) ? NON_BLOCKING : BLOCKING; | ||
2321 | return _ctl_do_mpt_command(ioc, karg, &uarg->mf, state); | ||
2322 | } | ||
2323 | |||
2324 | /** | ||
2325 | * _ctl_ioctl_compat - main ioctl entry point (compat) | 2277 | * _ctl_ioctl_compat - main ioctl entry point (compat) |
2326 | * @file - | 2278 | * @file - |
2327 | * @cmd - | 2279 | * @cmd - |
@@ -2334,12 +2286,7 @@ _ctl_ioctl_compat(struct file *file, unsigned cmd, unsigned long arg) | |||
2334 | { | 2286 | { |
2335 | long ret; | 2287 | long ret; |
2336 | 2288 | ||
2337 | mutex_lock(&_ctl_mutex); | 2289 | ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 1); |
2338 | if (cmd == MPT2COMMAND32) | ||
2339 | ret = _ctl_compat_mpt_command(file, cmd, arg); | ||
2340 | else | ||
2341 | ret = _ctl_ioctl_main(file, cmd, (void __user *)arg); | ||
2342 | mutex_unlock(&_ctl_mutex); | ||
2343 | return ret; | 2290 | return ret; |
2344 | } | 2291 | } |
2345 | #endif | 2292 | #endif |