diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-09-11 22:00:42 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-09-11 22:00:42 -0400 |
commit | 05c78081d2d8eaf04bf60946fcc53380febf3376 (patch) | |
tree | 0ba735378eb44380c916c075e4fe17d74f3889c5 | |
parent | 8e78b7dc93c580c050435b0f88991c26e02166bc (diff) | |
parent | ac64a2ce509104a746321a4f9646b6750cf281eb (diff) |
Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending
Pull SCSI target updates from Nicholas Bellinger:
"Here are the outstanding target-pending updates for v4.3-rc1.
Mostly bug-fixes and minor changes this round. The fallout from the
big v4.2-rc1 RCU conversion have (thus far) been minimal.
The highlights this round include:
- Move sense handling routines into scsi_common code (Sagi)
- Return ABORTED_COMMAND sense key for PI errors (Sagi)
- Add tpg_enabled_sendtargets attribute for disabled iscsi-target
discovery (David)
- Shrink target struct se_cmd by rearranging fields (Roland)
- Drop iSCSI use of mutex around max_cmd_sn increment (Roland)
- Replace iSCSI __kernel_sockaddr_storage with sockaddr_storage (Andy +
Chris)
- Honor fabric max_data_sg_nents I/O transfer limit (Arun + Himanshu +
nab)
- Fix EXTENDED_COPY >= v4.1 regression OOPsen (Alex + nab)"
* 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: (37 commits)
target: use stringify.h instead of own definition
target/user: Fix UFLAG_UNKNOWN_OP handling
target: Remove no-op conditional
target/user: Remove unused variable
target: Fix max_cmd_sn increment w/o cmdsn mutex regressions
target: Attach EXTENDED_COPY local I/O descriptors to xcopy_pt_sess
target/qla2xxx: Honor max_data_sg_nents I/O transfer limit
target/iscsi: Replace __kernel_sockaddr_storage with sockaddr_storage
target/iscsi: Replace conn->login_ip with login_sockaddr
target/iscsi: Keep local_ip as the actual sockaddr
target/iscsi: Fix np_ip bracket issue by removing np_ip
target: Drop iSCSI use of mutex around max_cmd_sn increment
qla2xxx: Update tcm_qla2xxx module description to 24xx+
iscsi-target: Add tpg_enabled_sendtargets for disabled discovery
drivers: target: Drop unlikely before IS_ERR(_OR_NULL)
target: check DPO/FUA usage for COMPARE AND WRITE
target: Shrink struct se_cmd by rearranging fields
target: Remove cmd->se_ordered_id (unused except debug log lines)
target: add support for START_STOP_UNIT SCSI opcode
target: improve unsupported opcode message
...
38 files changed, 675 insertions, 633 deletions
diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c index dc439a40da3f..403bd29443b8 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.c +++ b/drivers/infiniband/ulp/isert/ib_isert.c | |||
@@ -3095,7 +3095,7 @@ out: | |||
3095 | 3095 | ||
3096 | static int | 3096 | static int |
3097 | isert_setup_np(struct iscsi_np *np, | 3097 | isert_setup_np(struct iscsi_np *np, |
3098 | struct __kernel_sockaddr_storage *ksockaddr) | 3098 | struct sockaddr_storage *ksockaddr) |
3099 | { | 3099 | { |
3100 | struct isert_np *isert_np; | 3100 | struct isert_np *isert_np; |
3101 | struct rdma_cm_id *isert_lid; | 3101 | struct rdma_cm_id *isert_lid; |
@@ -3117,7 +3117,7 @@ isert_setup_np(struct iscsi_np *np, | |||
3117 | * in iscsi_target_configfs.c code.. | 3117 | * in iscsi_target_configfs.c code.. |
3118 | */ | 3118 | */ |
3119 | memcpy(&np->np_sockaddr, ksockaddr, | 3119 | memcpy(&np->np_sockaddr, ksockaddr, |
3120 | sizeof(struct __kernel_sockaddr_storage)); | 3120 | sizeof(struct sockaddr_storage)); |
3121 | 3121 | ||
3122 | isert_lid = isert_setup_id(isert_np); | 3122 | isert_lid = isert_setup_id(isert_np); |
3123 | if (IS_ERR(isert_lid)) { | 3123 | if (IS_ERR(isert_lid)) { |
@@ -3199,32 +3199,11 @@ isert_set_conn_info(struct iscsi_np *np, struct iscsi_conn *conn, | |||
3199 | { | 3199 | { |
3200 | struct rdma_cm_id *cm_id = isert_conn->cm_id; | 3200 | struct rdma_cm_id *cm_id = isert_conn->cm_id; |
3201 | struct rdma_route *cm_route = &cm_id->route; | 3201 | struct rdma_route *cm_route = &cm_id->route; |
3202 | struct sockaddr_in *sock_in; | ||
3203 | struct sockaddr_in6 *sock_in6; | ||
3204 | 3202 | ||
3205 | conn->login_family = np->np_sockaddr.ss_family; | 3203 | conn->login_family = np->np_sockaddr.ss_family; |
3206 | 3204 | ||
3207 | if (np->np_sockaddr.ss_family == AF_INET6) { | 3205 | conn->login_sockaddr = cm_route->addr.dst_addr; |
3208 | sock_in6 = (struct sockaddr_in6 *)&cm_route->addr.dst_addr; | 3206 | conn->local_sockaddr = cm_route->addr.src_addr; |
3209 | snprintf(conn->login_ip, sizeof(conn->login_ip), "%pI6c", | ||
3210 | &sock_in6->sin6_addr.in6_u); | ||
3211 | conn->login_port = ntohs(sock_in6->sin6_port); | ||
3212 | |||
3213 | sock_in6 = (struct sockaddr_in6 *)&cm_route->addr.src_addr; | ||
3214 | snprintf(conn->local_ip, sizeof(conn->local_ip), "%pI6c", | ||
3215 | &sock_in6->sin6_addr.in6_u); | ||
3216 | conn->local_port = ntohs(sock_in6->sin6_port); | ||
3217 | } else { | ||
3218 | sock_in = (struct sockaddr_in *)&cm_route->addr.dst_addr; | ||
3219 | sprintf(conn->login_ip, "%pI4", | ||
3220 | &sock_in->sin_addr.s_addr); | ||
3221 | conn->login_port = ntohs(sock_in->sin_port); | ||
3222 | |||
3223 | sock_in = (struct sockaddr_in *)&cm_route->addr.src_addr; | ||
3224 | sprintf(conn->local_ip, "%pI4", | ||
3225 | &sock_in->sin_addr.s_addr); | ||
3226 | conn->local_port = ntohs(sock_in->sin_port); | ||
3227 | } | ||
3228 | } | 3207 | } |
3229 | 3208 | ||
3230 | static int | 3209 | static int |
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 98d9bb6ff725..33c74d3436c9 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c | |||
@@ -853,12 +853,9 @@ static void iscsi_scsi_cmd_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr, | |||
853 | SAM_STAT_CHECK_CONDITION; | 853 | SAM_STAT_CHECK_CONDITION; |
854 | scsi_build_sense_buffer(1, sc->sense_buffer, | 854 | scsi_build_sense_buffer(1, sc->sense_buffer, |
855 | ILLEGAL_REQUEST, 0x10, ascq); | 855 | ILLEGAL_REQUEST, 0x10, ascq); |
856 | sc->sense_buffer[7] = 0xc; /* Additional sense length */ | 856 | scsi_set_sense_information(sc->sense_buffer, |
857 | sc->sense_buffer[8] = 0; /* Information desc type */ | 857 | SCSI_SENSE_BUFFERSIZE, |
858 | sc->sense_buffer[9] = 0xa; /* Additional desc length */ | 858 | sector); |
859 | sc->sense_buffer[10] = 0x80; /* Validity bit */ | ||
860 | |||
861 | put_unaligned_be64(sector, &sc->sense_buffer[12]); | ||
862 | goto out; | 859 | goto out; |
863 | } | 860 | } |
864 | } | 861 | } |
diff --git a/drivers/scsi/qla2xxx/Kconfig b/drivers/scsi/qla2xxx/Kconfig index 33f60c92e20e..a0f732b138e4 100644 --- a/drivers/scsi/qla2xxx/Kconfig +++ b/drivers/scsi/qla2xxx/Kconfig | |||
@@ -32,10 +32,10 @@ config SCSI_QLA_FC | |||
32 | They are also included in the linux-firmware tree as well. | 32 | They are also included in the linux-firmware tree as well. |
33 | 33 | ||
34 | config TCM_QLA2XXX | 34 | config TCM_QLA2XXX |
35 | tristate "TCM_QLA2XXX fabric module for Qlogic 2xxx series target mode HBAs" | 35 | tristate "TCM_QLA2XXX fabric module for QLogic 24xx+ series target mode HBAs" |
36 | depends on SCSI_QLA_FC && TARGET_CORE | 36 | depends on SCSI_QLA_FC && TARGET_CORE |
37 | depends on LIBFC | 37 | depends on LIBFC |
38 | select BTREE | 38 | select BTREE |
39 | default n | 39 | default n |
40 | ---help--- | 40 | ---help--- |
41 | Say Y here to enable the TCM_QLA2XXX fabric module for Qlogic 2xxx series target mode HBAs | 41 | Say Y here to enable the TCM_QLA2XXX fabric module for QLogic 24xx+ series target mode HBAs |
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index 7ed7bae6172b..ac65cb7b4886 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c | |||
@@ -1359,9 +1359,7 @@ static void tcm_qla2xxx_free_session(struct qla_tgt_sess *sess) | |||
1359 | struct qla_hw_data *ha = tgt->ha; | 1359 | struct qla_hw_data *ha = tgt->ha; |
1360 | scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); | 1360 | scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); |
1361 | struct se_session *se_sess; | 1361 | struct se_session *se_sess; |
1362 | struct se_node_acl *se_nacl; | ||
1363 | struct tcm_qla2xxx_lport *lport; | 1362 | struct tcm_qla2xxx_lport *lport; |
1364 | struct tcm_qla2xxx_nacl *nacl; | ||
1365 | 1363 | ||
1366 | BUG_ON(in_interrupt()); | 1364 | BUG_ON(in_interrupt()); |
1367 | 1365 | ||
@@ -1371,8 +1369,6 @@ static void tcm_qla2xxx_free_session(struct qla_tgt_sess *sess) | |||
1371 | dump_stack(); | 1369 | dump_stack(); |
1372 | return; | 1370 | return; |
1373 | } | 1371 | } |
1374 | se_nacl = se_sess->se_node_acl; | ||
1375 | nacl = container_of(se_nacl, struct tcm_qla2xxx_nacl, se_node_acl); | ||
1376 | 1372 | ||
1377 | lport = vha->vha_tgt.target_lport_ptr; | 1373 | lport = vha->vha_tgt.target_lport_ptr; |
1378 | if (!lport) { | 1374 | if (!lport) { |
@@ -1680,7 +1676,6 @@ static int tcm_qla2xxx_lport_register_npiv_cb(struct scsi_qla_host *base_vha, | |||
1680 | (struct tcm_qla2xxx_lport *)target_lport_ptr; | 1676 | (struct tcm_qla2xxx_lport *)target_lport_ptr; |
1681 | struct tcm_qla2xxx_lport *base_lport = | 1677 | struct tcm_qla2xxx_lport *base_lport = |
1682 | (struct tcm_qla2xxx_lport *)base_vha->vha_tgt.target_lport_ptr; | 1678 | (struct tcm_qla2xxx_lport *)base_vha->vha_tgt.target_lport_ptr; |
1683 | struct tcm_qla2xxx_tpg *base_tpg; | ||
1684 | struct fc_vport_identifiers vport_id; | 1679 | struct fc_vport_identifiers vport_id; |
1685 | 1680 | ||
1686 | if (!qla_tgt_mode_enabled(base_vha)) { | 1681 | if (!qla_tgt_mode_enabled(base_vha)) { |
@@ -1693,7 +1688,6 @@ static int tcm_qla2xxx_lport_register_npiv_cb(struct scsi_qla_host *base_vha, | |||
1693 | pr_err("qla2xxx base_lport or tpg_1 not available\n"); | 1688 | pr_err("qla2xxx base_lport or tpg_1 not available\n"); |
1694 | return -EPERM; | 1689 | return -EPERM; |
1695 | } | 1690 | } |
1696 | base_tpg = base_lport->tpg_1; | ||
1697 | 1691 | ||
1698 | memset(&vport_id, 0, sizeof(vport_id)); | 1692 | memset(&vport_id, 0, sizeof(vport_id)); |
1699 | vport_id.port_name = npiv_wwpn; | 1693 | vport_id.port_name = npiv_wwpn; |
@@ -1810,6 +1804,11 @@ static const struct target_core_fabric_ops tcm_qla2xxx_ops = { | |||
1810 | .module = THIS_MODULE, | 1804 | .module = THIS_MODULE, |
1811 | .name = "qla2xxx", | 1805 | .name = "qla2xxx", |
1812 | .node_acl_size = sizeof(struct tcm_qla2xxx_nacl), | 1806 | .node_acl_size = sizeof(struct tcm_qla2xxx_nacl), |
1807 | /* | ||
1808 | * XXX: Limit assumes single page per scatter-gather-list entry. | ||
1809 | * Current maximum is ~4.9 MB per se_cmd->t_data_sg with PAGE_SIZE=4096 | ||
1810 | */ | ||
1811 | .max_data_sg_nents = 1200, | ||
1813 | .get_fabric_name = tcm_qla2xxx_get_fabric_name, | 1812 | .get_fabric_name = tcm_qla2xxx_get_fabric_name, |
1814 | .tpg_get_wwn = tcm_qla2xxx_get_fabric_wwn, | 1813 | .tpg_get_wwn = tcm_qla2xxx_get_fabric_wwn, |
1815 | .tpg_get_tag = tcm_qla2xxx_get_tag, | 1814 | .tpg_get_tag = tcm_qla2xxx_get_tag, |
@@ -1958,7 +1957,7 @@ static void __exit tcm_qla2xxx_exit(void) | |||
1958 | tcm_qla2xxx_deregister_configfs(); | 1957 | tcm_qla2xxx_deregister_configfs(); |
1959 | } | 1958 | } |
1960 | 1959 | ||
1961 | MODULE_DESCRIPTION("TCM QLA2XXX series NPIV enabled fabric driver"); | 1960 | MODULE_DESCRIPTION("TCM QLA24XX+ series NPIV enabled fabric driver"); |
1962 | MODULE_LICENSE("GPL"); | 1961 | MODULE_LICENSE("GPL"); |
1963 | module_init(tcm_qla2xxx_init); | 1962 | module_init(tcm_qla2xxx_init); |
1964 | module_exit(tcm_qla2xxx_exit); | 1963 | module_exit(tcm_qla2xxx_exit); |
diff --git a/drivers/scsi/scsi_common.c b/drivers/scsi/scsi_common.c index 2ff092252b76..c126966130ab 100644 --- a/drivers/scsi/scsi_common.c +++ b/drivers/scsi/scsi_common.c | |||
@@ -5,6 +5,8 @@ | |||
5 | #include <linux/bug.h> | 5 | #include <linux/bug.h> |
6 | #include <linux/kernel.h> | 6 | #include <linux/kernel.h> |
7 | #include <linux/string.h> | 7 | #include <linux/string.h> |
8 | #include <linux/errno.h> | ||
9 | #include <asm/unaligned.h> | ||
8 | #include <scsi/scsi_common.h> | 10 | #include <scsi/scsi_common.h> |
9 | 11 | ||
10 | /* NB: These are exposed through /proc/scsi/scsi and form part of the ABI. | 12 | /* NB: These are exposed through /proc/scsi/scsi and form part of the ABI. |
@@ -176,3 +178,110 @@ bool scsi_normalize_sense(const u8 *sense_buffer, int sb_len, | |||
176 | return true; | 178 | return true; |
177 | } | 179 | } |
178 | EXPORT_SYMBOL(scsi_normalize_sense); | 180 | EXPORT_SYMBOL(scsi_normalize_sense); |
181 | |||
182 | /** | ||
183 | * scsi_sense_desc_find - search for a given descriptor type in descriptor sense data format. | ||
184 | * @sense_buffer: byte array of descriptor format sense data | ||
185 | * @sb_len: number of valid bytes in sense_buffer | ||
186 | * @desc_type: value of descriptor type to find | ||
187 | * (e.g. 0 -> information) | ||
188 | * | ||
189 | * Notes: | ||
190 | * only valid when sense data is in descriptor format | ||
191 | * | ||
192 | * Return value: | ||
193 | * pointer to start of (first) descriptor if found else NULL | ||
194 | */ | ||
195 | const u8 * scsi_sense_desc_find(const u8 * sense_buffer, int sb_len, | ||
196 | int desc_type) | ||
197 | { | ||
198 | int add_sen_len, add_len, desc_len, k; | ||
199 | const u8 * descp; | ||
200 | |||
201 | if ((sb_len < 8) || (0 == (add_sen_len = sense_buffer[7]))) | ||
202 | return NULL; | ||
203 | if ((sense_buffer[0] < 0x72) || (sense_buffer[0] > 0x73)) | ||
204 | return NULL; | ||
205 | add_sen_len = (add_sen_len < (sb_len - 8)) ? | ||
206 | add_sen_len : (sb_len - 8); | ||
207 | descp = &sense_buffer[8]; | ||
208 | for (desc_len = 0, k = 0; k < add_sen_len; k += desc_len) { | ||
209 | descp += desc_len; | ||
210 | add_len = (k < (add_sen_len - 1)) ? descp[1]: -1; | ||
211 | desc_len = add_len + 2; | ||
212 | if (descp[0] == desc_type) | ||
213 | return descp; | ||
214 | if (add_len < 0) // short descriptor ?? | ||
215 | break; | ||
216 | } | ||
217 | return NULL; | ||
218 | } | ||
219 | EXPORT_SYMBOL(scsi_sense_desc_find); | ||
220 | |||
221 | /** | ||
222 | * scsi_build_sense_buffer - build sense data in a buffer | ||
223 | * @desc: Sense format (non zero == descriptor format, | ||
224 | * 0 == fixed format) | ||
225 | * @buf: Where to build sense data | ||
226 | * @key: Sense key | ||
227 | * @asc: Additional sense code | ||
228 | * @ascq: Additional sense code qualifier | ||
229 | * | ||
230 | **/ | ||
231 | void scsi_build_sense_buffer(int desc, u8 *buf, u8 key, u8 asc, u8 ascq) | ||
232 | { | ||
233 | if (desc) { | ||
234 | buf[0] = 0x72; /* descriptor, current */ | ||
235 | buf[1] = key; | ||
236 | buf[2] = asc; | ||
237 | buf[3] = ascq; | ||
238 | buf[7] = 0; | ||
239 | } else { | ||
240 | buf[0] = 0x70; /* fixed, current */ | ||
241 | buf[2] = key; | ||
242 | buf[7] = 0xa; | ||
243 | buf[12] = asc; | ||
244 | buf[13] = ascq; | ||
245 | } | ||
246 | } | ||
247 | EXPORT_SYMBOL(scsi_build_sense_buffer); | ||
248 | |||
249 | /** | ||
250 | * scsi_set_sense_information - set the information field in a | ||
251 | * formatted sense data buffer | ||
252 | * @buf: Where to build sense data | ||
253 | * @buf_len: buffer length | ||
254 | * @info: 64-bit information value to be set | ||
255 | * | ||
256 | * Return value: | ||
257 | * 0 on success or EINVAL for invalid sense buffer length | ||
258 | **/ | ||
259 | int scsi_set_sense_information(u8 *buf, int buf_len, u64 info) | ||
260 | { | ||
261 | if ((buf[0] & 0x7f) == 0x72) { | ||
262 | u8 *ucp, len; | ||
263 | |||
264 | len = buf[7]; | ||
265 | ucp = (char *)scsi_sense_desc_find(buf, len + 8, 0); | ||
266 | if (!ucp) { | ||
267 | buf[7] = len + 0xc; | ||
268 | ucp = buf + 8 + len; | ||
269 | } | ||
270 | |||
271 | if (buf_len < len + 0xc) | ||
272 | /* Not enough room for info */ | ||
273 | return -EINVAL; | ||
274 | |||
275 | ucp[0] = 0; | ||
276 | ucp[1] = 0xa; | ||
277 | ucp[2] = 0x80; /* Valid bit */ | ||
278 | ucp[3] = 0; | ||
279 | put_unaligned_be64(info, &ucp[4]); | ||
280 | } else if ((buf[0] & 0x7f) == 0x70) { | ||
281 | buf[0] |= 0x80; | ||
282 | put_unaligned_be64(info, &buf[3]); | ||
283 | } | ||
284 | |||
285 | return 0; | ||
286 | } | ||
287 | EXPORT_SYMBOL(scsi_set_sense_information); | ||
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index b616a6bef44a..66a96cd98b97 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <scsi/scsi_device.h> | 33 | #include <scsi/scsi_device.h> |
34 | #include <scsi/scsi_driver.h> | 34 | #include <scsi/scsi_driver.h> |
35 | #include <scsi/scsi_eh.h> | 35 | #include <scsi/scsi_eh.h> |
36 | #include <scsi/scsi_common.h> | ||
36 | #include <scsi/scsi_transport.h> | 37 | #include <scsi/scsi_transport.h> |
37 | #include <scsi/scsi_host.h> | 38 | #include <scsi/scsi_host.h> |
38 | #include <scsi/scsi_ioctl.h> | 39 | #include <scsi/scsi_ioctl.h> |
@@ -2425,45 +2426,6 @@ bool scsi_command_normalize_sense(const struct scsi_cmnd *cmd, | |||
2425 | EXPORT_SYMBOL(scsi_command_normalize_sense); | 2426 | EXPORT_SYMBOL(scsi_command_normalize_sense); |
2426 | 2427 | ||
2427 | /** | 2428 | /** |
2428 | * scsi_sense_desc_find - search for a given descriptor type in descriptor sense data format. | ||
2429 | * @sense_buffer: byte array of descriptor format sense data | ||
2430 | * @sb_len: number of valid bytes in sense_buffer | ||
2431 | * @desc_type: value of descriptor type to find | ||
2432 | * (e.g. 0 -> information) | ||
2433 | * | ||
2434 | * Notes: | ||
2435 | * only valid when sense data is in descriptor format | ||
2436 | * | ||
2437 | * Return value: | ||
2438 | * pointer to start of (first) descriptor if found else NULL | ||
2439 | */ | ||
2440 | const u8 * scsi_sense_desc_find(const u8 * sense_buffer, int sb_len, | ||
2441 | int desc_type) | ||
2442 | { | ||
2443 | int add_sen_len, add_len, desc_len, k; | ||
2444 | const u8 * descp; | ||
2445 | |||
2446 | if ((sb_len < 8) || (0 == (add_sen_len = sense_buffer[7]))) | ||
2447 | return NULL; | ||
2448 | if ((sense_buffer[0] < 0x72) || (sense_buffer[0] > 0x73)) | ||
2449 | return NULL; | ||
2450 | add_sen_len = (add_sen_len < (sb_len - 8)) ? | ||
2451 | add_sen_len : (sb_len - 8); | ||
2452 | descp = &sense_buffer[8]; | ||
2453 | for (desc_len = 0, k = 0; k < add_sen_len; k += desc_len) { | ||
2454 | descp += desc_len; | ||
2455 | add_len = (k < (add_sen_len - 1)) ? descp[1]: -1; | ||
2456 | desc_len = add_len + 2; | ||
2457 | if (descp[0] == desc_type) | ||
2458 | return descp; | ||
2459 | if (add_len < 0) // short descriptor ?? | ||
2460 | break; | ||
2461 | } | ||
2462 | return NULL; | ||
2463 | } | ||
2464 | EXPORT_SYMBOL(scsi_sense_desc_find); | ||
2465 | |||
2466 | /** | ||
2467 | * scsi_get_sense_info_fld - get information field from sense data (either fixed or descriptor format) | 2429 | * scsi_get_sense_info_fld - get information field from sense data (either fixed or descriptor format) |
2468 | * @sense_buffer: byte array of sense data | 2430 | * @sense_buffer: byte array of sense data |
2469 | * @sb_len: number of valid bytes in sense_buffer | 2431 | * @sb_len: number of valid bytes in sense_buffer |
@@ -2512,31 +2474,3 @@ int scsi_get_sense_info_fld(const u8 * sense_buffer, int sb_len, | |||
2512 | } | 2474 | } |
2513 | } | 2475 | } |
2514 | EXPORT_SYMBOL(scsi_get_sense_info_fld); | 2476 | EXPORT_SYMBOL(scsi_get_sense_info_fld); |
2515 | |||
2516 | /** | ||
2517 | * scsi_build_sense_buffer - build sense data in a buffer | ||
2518 | * @desc: Sense format (non zero == descriptor format, | ||
2519 | * 0 == fixed format) | ||
2520 | * @buf: Where to build sense data | ||
2521 | * @key: Sense key | ||
2522 | * @asc: Additional sense code | ||
2523 | * @ascq: Additional sense code qualifier | ||
2524 | * | ||
2525 | **/ | ||
2526 | void scsi_build_sense_buffer(int desc, u8 *buf, u8 key, u8 asc, u8 ascq) | ||
2527 | { | ||
2528 | if (desc) { | ||
2529 | buf[0] = 0x72; /* descriptor, current */ | ||
2530 | buf[1] = key; | ||
2531 | buf[2] = asc; | ||
2532 | buf[3] = ascq; | ||
2533 | buf[7] = 0; | ||
2534 | } else { | ||
2535 | buf[0] = 0x70; /* fixed, current */ | ||
2536 | buf[2] = key; | ||
2537 | buf[7] = 0xa; | ||
2538 | buf[12] = asc; | ||
2539 | buf[13] = ascq; | ||
2540 | } | ||
2541 | } | ||
2542 | EXPORT_SYMBOL(scsi_build_sense_buffer); | ||
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index fd092909a457..342a07c58d89 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c | |||
@@ -269,14 +269,14 @@ int iscsit_deaccess_np(struct iscsi_np *np, struct iscsi_portal_group *tpg, | |||
269 | } | 269 | } |
270 | 270 | ||
271 | bool iscsit_check_np_match( | 271 | bool iscsit_check_np_match( |
272 | struct __kernel_sockaddr_storage *sockaddr, | 272 | struct sockaddr_storage *sockaddr, |
273 | struct iscsi_np *np, | 273 | struct iscsi_np *np, |
274 | int network_transport) | 274 | int network_transport) |
275 | { | 275 | { |
276 | struct sockaddr_in *sock_in, *sock_in_e; | 276 | struct sockaddr_in *sock_in, *sock_in_e; |
277 | struct sockaddr_in6 *sock_in6, *sock_in6_e; | 277 | struct sockaddr_in6 *sock_in6, *sock_in6_e; |
278 | bool ip_match = false; | 278 | bool ip_match = false; |
279 | u16 port; | 279 | u16 port, port_e; |
280 | 280 | ||
281 | if (sockaddr->ss_family == AF_INET6) { | 281 | if (sockaddr->ss_family == AF_INET6) { |
282 | sock_in6 = (struct sockaddr_in6 *)sockaddr; | 282 | sock_in6 = (struct sockaddr_in6 *)sockaddr; |
@@ -288,6 +288,7 @@ bool iscsit_check_np_match( | |||
288 | ip_match = true; | 288 | ip_match = true; |
289 | 289 | ||
290 | port = ntohs(sock_in6->sin6_port); | 290 | port = ntohs(sock_in6->sin6_port); |
291 | port_e = ntohs(sock_in6_e->sin6_port); | ||
291 | } else { | 292 | } else { |
292 | sock_in = (struct sockaddr_in *)sockaddr; | 293 | sock_in = (struct sockaddr_in *)sockaddr; |
293 | sock_in_e = (struct sockaddr_in *)&np->np_sockaddr; | 294 | sock_in_e = (struct sockaddr_in *)&np->np_sockaddr; |
@@ -296,9 +297,10 @@ bool iscsit_check_np_match( | |||
296 | ip_match = true; | 297 | ip_match = true; |
297 | 298 | ||
298 | port = ntohs(sock_in->sin_port); | 299 | port = ntohs(sock_in->sin_port); |
300 | port_e = ntohs(sock_in_e->sin_port); | ||
299 | } | 301 | } |
300 | 302 | ||
301 | if (ip_match && (np->np_port == port) && | 303 | if (ip_match && (port_e == port) && |
302 | (np->np_network_transport == network_transport)) | 304 | (np->np_network_transport == network_transport)) |
303 | return true; | 305 | return true; |
304 | 306 | ||
@@ -309,7 +311,7 @@ bool iscsit_check_np_match( | |||
309 | * Called with mutex np_lock held | 311 | * Called with mutex np_lock held |
310 | */ | 312 | */ |
311 | static struct iscsi_np *iscsit_get_np( | 313 | static struct iscsi_np *iscsit_get_np( |
312 | struct __kernel_sockaddr_storage *sockaddr, | 314 | struct sockaddr_storage *sockaddr, |
313 | int network_transport) | 315 | int network_transport) |
314 | { | 316 | { |
315 | struct iscsi_np *np; | 317 | struct iscsi_np *np; |
@@ -340,12 +342,9 @@ static struct iscsi_np *iscsit_get_np( | |||
340 | } | 342 | } |
341 | 343 | ||
342 | struct iscsi_np *iscsit_add_np( | 344 | struct iscsi_np *iscsit_add_np( |
343 | struct __kernel_sockaddr_storage *sockaddr, | 345 | struct sockaddr_storage *sockaddr, |
344 | char *ip_str, | ||
345 | int network_transport) | 346 | int network_transport) |
346 | { | 347 | { |
347 | struct sockaddr_in *sock_in; | ||
348 | struct sockaddr_in6 *sock_in6; | ||
349 | struct iscsi_np *np; | 348 | struct iscsi_np *np; |
350 | int ret; | 349 | int ret; |
351 | 350 | ||
@@ -368,16 +367,6 @@ struct iscsi_np *iscsit_add_np( | |||
368 | } | 367 | } |
369 | 368 | ||
370 | np->np_flags |= NPF_IP_NETWORK; | 369 | np->np_flags |= NPF_IP_NETWORK; |
371 | if (sockaddr->ss_family == AF_INET6) { | ||
372 | sock_in6 = (struct sockaddr_in6 *)sockaddr; | ||
373 | snprintf(np->np_ip, IPV6_ADDRESS_SPACE, "%s", ip_str); | ||
374 | np->np_port = ntohs(sock_in6->sin6_port); | ||
375 | } else { | ||
376 | sock_in = (struct sockaddr_in *)sockaddr; | ||
377 | sprintf(np->np_ip, "%s", ip_str); | ||
378 | np->np_port = ntohs(sock_in->sin_port); | ||
379 | } | ||
380 | |||
381 | np->np_network_transport = network_transport; | 370 | np->np_network_transport = network_transport; |
382 | spin_lock_init(&np->np_thread_lock); | 371 | spin_lock_init(&np->np_thread_lock); |
383 | init_completion(&np->np_restart_comp); | 372 | init_completion(&np->np_restart_comp); |
@@ -411,8 +400,8 @@ struct iscsi_np *iscsit_add_np( | |||
411 | list_add_tail(&np->np_list, &g_np_list); | 400 | list_add_tail(&np->np_list, &g_np_list); |
412 | mutex_unlock(&np_lock); | 401 | mutex_unlock(&np_lock); |
413 | 402 | ||
414 | pr_debug("CORE[0] - Added Network Portal: %s:%hu on %s\n", | 403 | pr_debug("CORE[0] - Added Network Portal: %pISpc on %s\n", |
415 | np->np_ip, np->np_port, np->np_transport->name); | 404 | &np->np_sockaddr, np->np_transport->name); |
416 | 405 | ||
417 | return np; | 406 | return np; |
418 | } | 407 | } |
@@ -481,8 +470,8 @@ int iscsit_del_np(struct iscsi_np *np) | |||
481 | list_del(&np->np_list); | 470 | list_del(&np->np_list); |
482 | mutex_unlock(&np_lock); | 471 | mutex_unlock(&np_lock); |
483 | 472 | ||
484 | pr_debug("CORE[0] - Removed Network Portal: %s:%hu on %s\n", | 473 | pr_debug("CORE[0] - Removed Network Portal: %pISpc on %s\n", |
485 | np->np_ip, np->np_port, np->np_transport->name); | 474 | &np->np_sockaddr, np->np_transport->name); |
486 | 475 | ||
487 | iscsit_put_transport(np->np_transport); | 476 | iscsit_put_transport(np->np_transport); |
488 | kfree(np); | 477 | kfree(np); |
@@ -1209,7 +1198,6 @@ static u32 iscsit_do_crypto_hash_sg( | |||
1209 | u8 *pad_bytes) | 1198 | u8 *pad_bytes) |
1210 | { | 1199 | { |
1211 | u32 data_crc; | 1200 | u32 data_crc; |
1212 | u32 i; | ||
1213 | struct scatterlist *sg; | 1201 | struct scatterlist *sg; |
1214 | unsigned int page_off; | 1202 | unsigned int page_off; |
1215 | 1203 | ||
@@ -1218,15 +1206,15 @@ static u32 iscsit_do_crypto_hash_sg( | |||
1218 | sg = cmd->first_data_sg; | 1206 | sg = cmd->first_data_sg; |
1219 | page_off = cmd->first_data_sg_off; | 1207 | page_off = cmd->first_data_sg_off; |
1220 | 1208 | ||
1221 | i = 0; | ||
1222 | while (data_length) { | 1209 | while (data_length) { |
1223 | u32 cur_len = min_t(u32, data_length, (sg[i].length - page_off)); | 1210 | u32 cur_len = min_t(u32, data_length, (sg->length - page_off)); |
1224 | 1211 | ||
1225 | crypto_hash_update(hash, &sg[i], cur_len); | 1212 | crypto_hash_update(hash, sg, cur_len); |
1226 | 1213 | ||
1227 | data_length -= cur_len; | 1214 | data_length -= cur_len; |
1228 | page_off = 0; | 1215 | page_off = 0; |
1229 | i++; | 1216 | /* iscsit_map_iovec has already checked for invalid sg pointers */ |
1217 | sg = sg_next(sg); | ||
1230 | } | 1218 | } |
1231 | 1219 | ||
1232 | if (padding) { | 1220 | if (padding) { |
@@ -2556,7 +2544,7 @@ static int iscsit_send_conn_drop_async_message( | |||
2556 | cmd->stat_sn = conn->stat_sn++; | 2544 | cmd->stat_sn = conn->stat_sn++; |
2557 | hdr->statsn = cpu_to_be32(cmd->stat_sn); | 2545 | hdr->statsn = cpu_to_be32(cmd->stat_sn); |
2558 | hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); | 2546 | hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); |
2559 | hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn); | 2547 | hdr->max_cmdsn = cpu_to_be32((u32) atomic_read(&conn->sess->max_cmd_sn)); |
2560 | hdr->async_event = ISCSI_ASYNC_MSG_DROPPING_CONNECTION; | 2548 | hdr->async_event = ISCSI_ASYNC_MSG_DROPPING_CONNECTION; |
2561 | hdr->param1 = cpu_to_be16(cmd->logout_cid); | 2549 | hdr->param1 = cpu_to_be16(cmd->logout_cid); |
2562 | hdr->param2 = cpu_to_be16(conn->sess->sess_ops->DefaultTime2Wait); | 2550 | hdr->param2 = cpu_to_be16(conn->sess->sess_ops->DefaultTime2Wait); |
@@ -2628,7 +2616,7 @@ iscsit_build_datain_pdu(struct iscsi_cmd *cmd, struct iscsi_conn *conn, | |||
2628 | hdr->statsn = cpu_to_be32(0xFFFFFFFF); | 2616 | hdr->statsn = cpu_to_be32(0xFFFFFFFF); |
2629 | 2617 | ||
2630 | hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); | 2618 | hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); |
2631 | hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn); | 2619 | hdr->max_cmdsn = cpu_to_be32((u32) atomic_read(&conn->sess->max_cmd_sn)); |
2632 | hdr->datasn = cpu_to_be32(datain->data_sn); | 2620 | hdr->datasn = cpu_to_be32(datain->data_sn); |
2633 | hdr->offset = cpu_to_be32(datain->offset); | 2621 | hdr->offset = cpu_to_be32(datain->offset); |
2634 | 2622 | ||
@@ -2839,7 +2827,7 @@ iscsit_build_logout_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn, | |||
2839 | 2827 | ||
2840 | iscsit_increment_maxcmdsn(cmd, conn->sess); | 2828 | iscsit_increment_maxcmdsn(cmd, conn->sess); |
2841 | hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); | 2829 | hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); |
2842 | hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn); | 2830 | hdr->max_cmdsn = cpu_to_be32((u32) atomic_read(&conn->sess->max_cmd_sn)); |
2843 | 2831 | ||
2844 | pr_debug("Built Logout Response ITT: 0x%08x StatSN:" | 2832 | pr_debug("Built Logout Response ITT: 0x%08x StatSN:" |
2845 | " 0x%08x Response: 0x%02x CID: %hu on CID: %hu\n", | 2833 | " 0x%08x Response: 0x%02x CID: %hu on CID: %hu\n", |
@@ -2902,7 +2890,7 @@ iscsit_build_nopin_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn, | |||
2902 | iscsit_increment_maxcmdsn(cmd, conn->sess); | 2890 | iscsit_increment_maxcmdsn(cmd, conn->sess); |
2903 | 2891 | ||
2904 | hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); | 2892 | hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); |
2905 | hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn); | 2893 | hdr->max_cmdsn = cpu_to_be32((u32) atomic_read(&conn->sess->max_cmd_sn)); |
2906 | 2894 | ||
2907 | pr_debug("Built NOPIN %s Response ITT: 0x%08x, TTT: 0x%08x," | 2895 | pr_debug("Built NOPIN %s Response ITT: 0x%08x, TTT: 0x%08x," |
2908 | " StatSN: 0x%08x, Length %u\n", (nopout_response) ? | 2896 | " StatSN: 0x%08x, Length %u\n", (nopout_response) ? |
@@ -3049,7 +3037,7 @@ static int iscsit_send_r2t( | |||
3049 | hdr->ttt = cpu_to_be32(r2t->targ_xfer_tag); | 3037 | hdr->ttt = cpu_to_be32(r2t->targ_xfer_tag); |
3050 | hdr->statsn = cpu_to_be32(conn->stat_sn); | 3038 | hdr->statsn = cpu_to_be32(conn->stat_sn); |
3051 | hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); | 3039 | hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); |
3052 | hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn); | 3040 | hdr->max_cmdsn = cpu_to_be32((u32) atomic_read(&conn->sess->max_cmd_sn)); |
3053 | hdr->r2tsn = cpu_to_be32(r2t->r2t_sn); | 3041 | hdr->r2tsn = cpu_to_be32(r2t->r2t_sn); |
3054 | hdr->data_offset = cpu_to_be32(r2t->offset); | 3042 | hdr->data_offset = cpu_to_be32(r2t->offset); |
3055 | hdr->data_length = cpu_to_be32(r2t->xfer_len); | 3043 | hdr->data_length = cpu_to_be32(r2t->xfer_len); |
@@ -3202,7 +3190,7 @@ void iscsit_build_rsp_pdu(struct iscsi_cmd *cmd, struct iscsi_conn *conn, | |||
3202 | 3190 | ||
3203 | iscsit_increment_maxcmdsn(cmd, conn->sess); | 3191 | iscsit_increment_maxcmdsn(cmd, conn->sess); |
3204 | hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); | 3192 | hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); |
3205 | hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn); | 3193 | hdr->max_cmdsn = cpu_to_be32((u32) atomic_read(&conn->sess->max_cmd_sn)); |
3206 | 3194 | ||
3207 | pr_debug("Built SCSI Response, ITT: 0x%08x, StatSN: 0x%08x," | 3195 | pr_debug("Built SCSI Response, ITT: 0x%08x, StatSN: 0x%08x," |
3208 | " Response: 0x%02x, SAM Status: 0x%02x, CID: %hu\n", | 3196 | " Response: 0x%02x, SAM Status: 0x%02x, CID: %hu\n", |
@@ -3321,7 +3309,7 @@ iscsit_build_task_mgt_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn, | |||
3321 | 3309 | ||
3322 | iscsit_increment_maxcmdsn(cmd, conn->sess); | 3310 | iscsit_increment_maxcmdsn(cmd, conn->sess); |
3323 | hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); | 3311 | hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); |
3324 | hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn); | 3312 | hdr->max_cmdsn = cpu_to_be32((u32) atomic_read(&conn->sess->max_cmd_sn)); |
3325 | 3313 | ||
3326 | pr_debug("Built Task Management Response ITT: 0x%08x," | 3314 | pr_debug("Built Task Management Response ITT: 0x%08x," |
3327 | " StatSN: 0x%08x, Response: 0x%02x, CID: %hu\n", | 3315 | " StatSN: 0x%08x, Response: 0x%02x, CID: %hu\n", |
@@ -3399,6 +3387,7 @@ iscsit_build_sendtargets_response(struct iscsi_cmd *cmd, | |||
3399 | int target_name_printed; | 3387 | int target_name_printed; |
3400 | unsigned char buf[ISCSI_IQN_LEN+12]; /* iqn + "TargetName=" + \0 */ | 3388 | unsigned char buf[ISCSI_IQN_LEN+12]; /* iqn + "TargetName=" + \0 */ |
3401 | unsigned char *text_in = cmd->text_in_ptr, *text_ptr = NULL; | 3389 | unsigned char *text_in = cmd->text_in_ptr, *text_ptr = NULL; |
3390 | bool active; | ||
3402 | 3391 | ||
3403 | buffer_len = min(conn->conn_ops->MaxRecvDataSegmentLength, | 3392 | buffer_len = min(conn->conn_ops->MaxRecvDataSegmentLength, |
3404 | SENDTARGETS_BUF_LIMIT); | 3393 | SENDTARGETS_BUF_LIMIT); |
@@ -3452,19 +3441,18 @@ iscsit_build_sendtargets_response(struct iscsi_cmd *cmd, | |||
3452 | } | 3441 | } |
3453 | 3442 | ||
3454 | spin_lock(&tpg->tpg_state_lock); | 3443 | spin_lock(&tpg->tpg_state_lock); |
3455 | if ((tpg->tpg_state == TPG_STATE_FREE) || | 3444 | active = (tpg->tpg_state == TPG_STATE_ACTIVE); |
3456 | (tpg->tpg_state == TPG_STATE_INACTIVE)) { | ||
3457 | spin_unlock(&tpg->tpg_state_lock); | ||
3458 | continue; | ||
3459 | } | ||
3460 | spin_unlock(&tpg->tpg_state_lock); | 3445 | spin_unlock(&tpg->tpg_state_lock); |
3461 | 3446 | ||
3447 | if (!active && tpg->tpg_attrib.tpg_enabled_sendtargets) | ||
3448 | continue; | ||
3449 | |||
3462 | spin_lock(&tpg->tpg_np_lock); | 3450 | spin_lock(&tpg->tpg_np_lock); |
3463 | list_for_each_entry(tpg_np, &tpg->tpg_gnp_list, | 3451 | list_for_each_entry(tpg_np, &tpg->tpg_gnp_list, |
3464 | tpg_np_list) { | 3452 | tpg_np_list) { |
3465 | struct iscsi_np *np = tpg_np->tpg_np; | 3453 | struct iscsi_np *np = tpg_np->tpg_np; |
3466 | bool inaddr_any = iscsit_check_inaddr_any(np); | 3454 | bool inaddr_any = iscsit_check_inaddr_any(np); |
3467 | char *fmt_str; | 3455 | struct sockaddr_storage *sockaddr; |
3468 | 3456 | ||
3469 | if (np->np_network_transport != network_transport) | 3457 | if (np->np_network_transport != network_transport) |
3470 | continue; | 3458 | continue; |
@@ -3492,15 +3480,15 @@ iscsit_build_sendtargets_response(struct iscsi_cmd *cmd, | |||
3492 | } | 3480 | } |
3493 | } | 3481 | } |
3494 | 3482 | ||
3495 | if (np->np_sockaddr.ss_family == AF_INET6) | 3483 | if (inaddr_any) |
3496 | fmt_str = "TargetAddress=[%s]:%hu,%hu"; | 3484 | sockaddr = &conn->local_sockaddr; |
3497 | else | 3485 | else |
3498 | fmt_str = "TargetAddress=%s:%hu,%hu"; | 3486 | sockaddr = &np->np_sockaddr; |
3499 | 3487 | ||
3500 | len = sprintf(buf, fmt_str, | 3488 | len = sprintf(buf, "TargetAddress=" |
3501 | inaddr_any ? conn->local_ip : np->np_ip, | 3489 | "%pISpc,%hu", |
3502 | np->np_port, | 3490 | sockaddr, |
3503 | tpg->tpgt); | 3491 | tpg->tpgt); |
3504 | len += 1; | 3492 | len += 1; |
3505 | 3493 | ||
3506 | if ((len + payload_len) > buffer_len) { | 3494 | if ((len + payload_len) > buffer_len) { |
@@ -3576,7 +3564,7 @@ iscsit_build_text_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn, | |||
3576 | */ | 3564 | */ |
3577 | cmd->maxcmdsn_inc = 0; | 3565 | cmd->maxcmdsn_inc = 0; |
3578 | hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); | 3566 | hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); |
3579 | hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn); | 3567 | hdr->max_cmdsn = cpu_to_be32((u32) atomic_read(&conn->sess->max_cmd_sn)); |
3580 | 3568 | ||
3581 | pr_debug("Built Text Response: ITT: 0x%08x, TTT: 0x%08x, StatSN: 0x%08x," | 3569 | pr_debug("Built Text Response: ITT: 0x%08x, TTT: 0x%08x, StatSN: 0x%08x," |
3582 | " Length: %u, CID: %hu F: %d C: %d\n", cmd->init_task_tag, | 3570 | " Length: %u, CID: %hu F: %d C: %d\n", cmd->init_task_tag, |
@@ -3654,7 +3642,7 @@ iscsit_build_reject(struct iscsi_cmd *cmd, struct iscsi_conn *conn, | |||
3654 | cmd->stat_sn = conn->stat_sn++; | 3642 | cmd->stat_sn = conn->stat_sn++; |
3655 | hdr->statsn = cpu_to_be32(cmd->stat_sn); | 3643 | hdr->statsn = cpu_to_be32(cmd->stat_sn); |
3656 | hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); | 3644 | hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); |
3657 | hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn); | 3645 | hdr->max_cmdsn = cpu_to_be32((u32) atomic_read(&conn->sess->max_cmd_sn)); |
3658 | 3646 | ||
3659 | } | 3647 | } |
3660 | EXPORT_SYMBOL(iscsit_build_reject); | 3648 | EXPORT_SYMBOL(iscsit_build_reject); |
diff --git a/drivers/target/iscsi/iscsi_target.h b/drivers/target/iscsi/iscsi_target.h index 7d0f9c00d9c2..4cf2c0f2ba2f 100644 --- a/drivers/target/iscsi/iscsi_target.h +++ b/drivers/target/iscsi/iscsi_target.h | |||
@@ -10,10 +10,10 @@ extern int iscsit_access_np(struct iscsi_np *, struct iscsi_portal_group *); | |||
10 | extern void iscsit_login_kref_put(struct kref *); | 10 | extern void iscsit_login_kref_put(struct kref *); |
11 | extern int iscsit_deaccess_np(struct iscsi_np *, struct iscsi_portal_group *, | 11 | extern int iscsit_deaccess_np(struct iscsi_np *, struct iscsi_portal_group *, |
12 | struct iscsi_tpg_np *); | 12 | struct iscsi_tpg_np *); |
13 | extern bool iscsit_check_np_match(struct __kernel_sockaddr_storage *, | 13 | extern bool iscsit_check_np_match(struct sockaddr_storage *, |
14 | struct iscsi_np *, int); | 14 | struct iscsi_np *, int); |
15 | extern struct iscsi_np *iscsit_add_np(struct __kernel_sockaddr_storage *, | 15 | extern struct iscsi_np *iscsit_add_np(struct sockaddr_storage *, |
16 | char *, int); | 16 | int); |
17 | extern int iscsit_reset_np_thread(struct iscsi_np *, struct iscsi_tpg_np *, | 17 | extern int iscsit_reset_np_thread(struct iscsi_np *, struct iscsi_tpg_np *, |
18 | struct iscsi_portal_group *, bool); | 18 | struct iscsi_portal_group *, bool); |
19 | extern int iscsit_del_np(struct iscsi_np *); | 19 | extern int iscsit_del_np(struct iscsi_np *); |
diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c index c1898c84b3d2..c7461d770d3a 100644 --- a/drivers/target/iscsi/iscsi_target_configfs.c +++ b/drivers/target/iscsi/iscsi_target_configfs.c | |||
@@ -99,7 +99,7 @@ static ssize_t lio_target_np_store_sctp( | |||
99 | * Use existing np->np_sockaddr for SCTP network portal reference | 99 | * Use existing np->np_sockaddr for SCTP network portal reference |
100 | */ | 100 | */ |
101 | tpg_np_sctp = iscsit_tpg_add_network_portal(tpg, &np->np_sockaddr, | 101 | tpg_np_sctp = iscsit_tpg_add_network_portal(tpg, &np->np_sockaddr, |
102 | np->np_ip, tpg_np, ISCSI_SCTP_TCP); | 102 | tpg_np, ISCSI_SCTP_TCP); |
103 | if (!tpg_np_sctp || IS_ERR(tpg_np_sctp)) | 103 | if (!tpg_np_sctp || IS_ERR(tpg_np_sctp)) |
104 | goto out; | 104 | goto out; |
105 | } else { | 105 | } else { |
@@ -177,7 +177,7 @@ static ssize_t lio_target_np_store_iser( | |||
177 | } | 177 | } |
178 | 178 | ||
179 | tpg_np_iser = iscsit_tpg_add_network_portal(tpg, &np->np_sockaddr, | 179 | tpg_np_iser = iscsit_tpg_add_network_portal(tpg, &np->np_sockaddr, |
180 | np->np_ip, tpg_np, ISCSI_INFINIBAND); | 180 | tpg_np, ISCSI_INFINIBAND); |
181 | if (IS_ERR(tpg_np_iser)) { | 181 | if (IS_ERR(tpg_np_iser)) { |
182 | rc = PTR_ERR(tpg_np_iser); | 182 | rc = PTR_ERR(tpg_np_iser); |
183 | goto out; | 183 | goto out; |
@@ -220,7 +220,7 @@ static struct se_tpg_np *lio_target_call_addnptotpg( | |||
220 | struct iscsi_portal_group *tpg; | 220 | struct iscsi_portal_group *tpg; |
221 | struct iscsi_tpg_np *tpg_np; | 221 | struct iscsi_tpg_np *tpg_np; |
222 | char *str, *str2, *ip_str, *port_str; | 222 | char *str, *str2, *ip_str, *port_str; |
223 | struct __kernel_sockaddr_storage sockaddr; | 223 | struct sockaddr_storage sockaddr; |
224 | struct sockaddr_in *sock_in; | 224 | struct sockaddr_in *sock_in; |
225 | struct sockaddr_in6 *sock_in6; | 225 | struct sockaddr_in6 *sock_in6; |
226 | unsigned long port; | 226 | unsigned long port; |
@@ -235,7 +235,7 @@ static struct se_tpg_np *lio_target_call_addnptotpg( | |||
235 | memset(buf, 0, MAX_PORTAL_LEN + 1); | 235 | memset(buf, 0, MAX_PORTAL_LEN + 1); |
236 | snprintf(buf, MAX_PORTAL_LEN + 1, "%s", name); | 236 | snprintf(buf, MAX_PORTAL_LEN + 1, "%s", name); |
237 | 237 | ||
238 | memset(&sockaddr, 0, sizeof(struct __kernel_sockaddr_storage)); | 238 | memset(&sockaddr, 0, sizeof(struct sockaddr_storage)); |
239 | 239 | ||
240 | str = strstr(buf, "["); | 240 | str = strstr(buf, "["); |
241 | if (str) { | 241 | if (str) { |
@@ -248,8 +248,8 @@ static struct se_tpg_np *lio_target_call_addnptotpg( | |||
248 | return ERR_PTR(-EINVAL); | 248 | return ERR_PTR(-EINVAL); |
249 | } | 249 | } |
250 | str++; /* Skip over leading "[" */ | 250 | str++; /* Skip over leading "[" */ |
251 | *str2 = '\0'; /* Terminate the IPv6 address */ | 251 | *str2 = '\0'; /* Terminate the unbracketed IPv6 address */ |
252 | str2++; /* Skip over the "]" */ | 252 | str2++; /* Skip over the \0 */ |
253 | port_str = strstr(str2, ":"); | 253 | port_str = strstr(str2, ":"); |
254 | if (!port_str) { | 254 | if (!port_str) { |
255 | pr_err("Unable to locate \":port\"" | 255 | pr_err("Unable to locate \":port\"" |
@@ -267,7 +267,7 @@ static struct se_tpg_np *lio_target_call_addnptotpg( | |||
267 | sock_in6 = (struct sockaddr_in6 *)&sockaddr; | 267 | sock_in6 = (struct sockaddr_in6 *)&sockaddr; |
268 | sock_in6->sin6_family = AF_INET6; | 268 | sock_in6->sin6_family = AF_INET6; |
269 | sock_in6->sin6_port = htons((unsigned short)port); | 269 | sock_in6->sin6_port = htons((unsigned short)port); |
270 | ret = in6_pton(str, IPV6_ADDRESS_SPACE, | 270 | ret = in6_pton(str, -1, |
271 | (void *)&sock_in6->sin6_addr.in6_u, -1, &end); | 271 | (void *)&sock_in6->sin6_addr.in6_u, -1, &end); |
272 | if (ret <= 0) { | 272 | if (ret <= 0) { |
273 | pr_err("in6_pton returned: %d\n", ret); | 273 | pr_err("in6_pton returned: %d\n", ret); |
@@ -316,7 +316,7 @@ static struct se_tpg_np *lio_target_call_addnptotpg( | |||
316 | * sys/kernel/config/iscsi/$IQN/$TPG/np/$IP:$PORT/ | 316 | * sys/kernel/config/iscsi/$IQN/$TPG/np/$IP:$PORT/ |
317 | * | 317 | * |
318 | */ | 318 | */ |
319 | tpg_np = iscsit_tpg_add_network_portal(tpg, &sockaddr, str, NULL, | 319 | tpg_np = iscsit_tpg_add_network_portal(tpg, &sockaddr, NULL, |
320 | ISCSI_TCP); | 320 | ISCSI_TCP); |
321 | if (IS_ERR(tpg_np)) { | 321 | if (IS_ERR(tpg_np)) { |
322 | iscsit_put_tpg(tpg); | 322 | iscsit_put_tpg(tpg); |
@@ -344,8 +344,8 @@ static void lio_target_call_delnpfromtpg( | |||
344 | 344 | ||
345 | se_tpg = &tpg->tpg_se_tpg; | 345 | se_tpg = &tpg->tpg_se_tpg; |
346 | pr_debug("LIO_Target_ConfigFS: DEREGISTER -> %s TPGT: %hu" | 346 | pr_debug("LIO_Target_ConfigFS: DEREGISTER -> %s TPGT: %hu" |
347 | " PORTAL: %s:%hu\n", config_item_name(&se_tpg->se_tpg_wwn->wwn_group.cg_item), | 347 | " PORTAL: %pISpc\n", config_item_name(&se_tpg->se_tpg_wwn->wwn_group.cg_item), |
348 | tpg->tpgt, tpg_np->tpg_np->np_ip, tpg_np->tpg_np->np_port); | 348 | tpg->tpgt, &tpg_np->tpg_np->np_sockaddr); |
349 | 349 | ||
350 | ret = iscsit_tpg_del_network_portal(tpg, tpg_np); | 350 | ret = iscsit_tpg_del_network_portal(tpg, tpg_np); |
351 | if (ret < 0) | 351 | if (ret < 0) |
@@ -656,6 +656,7 @@ static ssize_t lio_target_nacl_show_info( | |||
656 | struct iscsi_conn *conn; | 656 | struct iscsi_conn *conn; |
657 | struct se_session *se_sess; | 657 | struct se_session *se_sess; |
658 | ssize_t rb = 0; | 658 | ssize_t rb = 0; |
659 | u32 max_cmd_sn; | ||
659 | 660 | ||
660 | spin_lock_bh(&se_nacl->nacl_sess_lock); | 661 | spin_lock_bh(&se_nacl->nacl_sess_lock); |
661 | se_sess = se_nacl->nacl_sess; | 662 | se_sess = se_nacl->nacl_sess; |
@@ -703,11 +704,12 @@ static ssize_t lio_target_nacl_show_info( | |||
703 | " Values]-----------------------\n"); | 704 | " Values]-----------------------\n"); |
704 | rb += sprintf(page+rb, " CmdSN/WR : CmdSN/WC : ExpCmdSN" | 705 | rb += sprintf(page+rb, " CmdSN/WR : CmdSN/WC : ExpCmdSN" |
705 | " : MaxCmdSN : ITT : TTT\n"); | 706 | " : MaxCmdSN : ITT : TTT\n"); |
707 | max_cmd_sn = (u32) atomic_read(&sess->max_cmd_sn); | ||
706 | rb += sprintf(page+rb, " 0x%08x 0x%08x 0x%08x 0x%08x" | 708 | rb += sprintf(page+rb, " 0x%08x 0x%08x 0x%08x 0x%08x" |
707 | " 0x%08x 0x%08x\n", | 709 | " 0x%08x 0x%08x\n", |
708 | sess->cmdsn_window, | 710 | sess->cmdsn_window, |
709 | (sess->max_cmd_sn - sess->exp_cmd_sn) + 1, | 711 | (max_cmd_sn - sess->exp_cmd_sn) + 1, |
710 | sess->exp_cmd_sn, sess->max_cmd_sn, | 712 | sess->exp_cmd_sn, max_cmd_sn, |
711 | sess->init_task_tag, sess->targ_xfer_tag); | 713 | sess->init_task_tag, sess->targ_xfer_tag); |
712 | rb += sprintf(page+rb, "----------------------[iSCSI" | 714 | rb += sprintf(page+rb, "----------------------[iSCSI" |
713 | " Connections]-------------------------\n"); | 715 | " Connections]-------------------------\n"); |
@@ -751,7 +753,7 @@ static ssize_t lio_target_nacl_show_info( | |||
751 | break; | 753 | break; |
752 | } | 754 | } |
753 | 755 | ||
754 | rb += sprintf(page+rb, " Address %s %s", conn->login_ip, | 756 | rb += sprintf(page+rb, " Address %pISc %s", &conn->login_sockaddr, |
755 | (conn->network_transport == ISCSI_TCP) ? | 757 | (conn->network_transport == ISCSI_TCP) ? |
756 | "TCP" : "SCTP"); | 758 | "TCP" : "SCTP"); |
757 | rb += sprintf(page+rb, " StatSN: 0x%08x\n", | 759 | rb += sprintf(page+rb, " StatSN: 0x%08x\n", |
@@ -1010,6 +1012,11 @@ TPG_ATTR(t10_pi, S_IRUGO | S_IWUSR); | |||
1010 | */ | 1012 | */ |
1011 | DEF_TPG_ATTRIB(fabric_prot_type); | 1013 | DEF_TPG_ATTRIB(fabric_prot_type); |
1012 | TPG_ATTR(fabric_prot_type, S_IRUGO | S_IWUSR); | 1014 | TPG_ATTR(fabric_prot_type, S_IRUGO | S_IWUSR); |
1015 | /* | ||
1016 | * Define iscsi_tpg_attrib_s_tpg_enabled_sendtargets | ||
1017 | */ | ||
1018 | DEF_TPG_ATTRIB(tpg_enabled_sendtargets); | ||
1019 | TPG_ATTR(tpg_enabled_sendtargets, S_IRUGO | S_IWUSR); | ||
1013 | 1020 | ||
1014 | static struct configfs_attribute *lio_target_tpg_attrib_attrs[] = { | 1021 | static struct configfs_attribute *lio_target_tpg_attrib_attrs[] = { |
1015 | &iscsi_tpg_attrib_authentication.attr, | 1022 | &iscsi_tpg_attrib_authentication.attr, |
@@ -1024,6 +1031,7 @@ static struct configfs_attribute *lio_target_tpg_attrib_attrs[] = { | |||
1024 | &iscsi_tpg_attrib_default_erl.attr, | 1031 | &iscsi_tpg_attrib_default_erl.attr, |
1025 | &iscsi_tpg_attrib_t10_pi.attr, | 1032 | &iscsi_tpg_attrib_t10_pi.attr, |
1026 | &iscsi_tpg_attrib_fabric_prot_type.attr, | 1033 | &iscsi_tpg_attrib_fabric_prot_type.attr, |
1034 | &iscsi_tpg_attrib_tpg_enabled_sendtargets.attr, | ||
1027 | NULL, | 1035 | NULL, |
1028 | }; | 1036 | }; |
1029 | 1037 | ||
diff --git a/drivers/target/iscsi/iscsi_target_device.c b/drivers/target/iscsi/iscsi_target_device.c index 5fabcd3d623f..0382fa24b53b 100644 --- a/drivers/target/iscsi/iscsi_target_device.c +++ b/drivers/target/iscsi/iscsi_target_device.c | |||
@@ -47,19 +47,19 @@ void iscsit_determine_maxcmdsn(struct iscsi_session *sess) | |||
47 | * core_set_queue_depth_for_node(). | 47 | * core_set_queue_depth_for_node(). |
48 | */ | 48 | */ |
49 | sess->cmdsn_window = se_nacl->queue_depth; | 49 | sess->cmdsn_window = se_nacl->queue_depth; |
50 | sess->max_cmd_sn = (sess->max_cmd_sn + se_nacl->queue_depth) - 1; | 50 | atomic_add(se_nacl->queue_depth - 1, &sess->max_cmd_sn); |
51 | } | 51 | } |
52 | 52 | ||
53 | void iscsit_increment_maxcmdsn(struct iscsi_cmd *cmd, struct iscsi_session *sess) | 53 | void iscsit_increment_maxcmdsn(struct iscsi_cmd *cmd, struct iscsi_session *sess) |
54 | { | 54 | { |
55 | u32 max_cmd_sn; | ||
56 | |||
55 | if (cmd->immediate_cmd || cmd->maxcmdsn_inc) | 57 | if (cmd->immediate_cmd || cmd->maxcmdsn_inc) |
56 | return; | 58 | return; |
57 | 59 | ||
58 | cmd->maxcmdsn_inc = 1; | 60 | cmd->maxcmdsn_inc = 1; |
59 | 61 | ||
60 | mutex_lock(&sess->cmdsn_mutex); | 62 | max_cmd_sn = atomic_inc_return(&sess->max_cmd_sn); |
61 | sess->max_cmd_sn += 1; | 63 | pr_debug("Updated MaxCmdSN to 0x%08x\n", max_cmd_sn); |
62 | pr_debug("Updated MaxCmdSN to 0x%08x\n", sess->max_cmd_sn); | ||
63 | mutex_unlock(&sess->cmdsn_mutex); | ||
64 | } | 64 | } |
65 | EXPORT_SYMBOL(iscsit_increment_maxcmdsn); | 65 | EXPORT_SYMBOL(iscsit_increment_maxcmdsn); |
diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index 7e8f65e5448f..96e78c823d13 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c | |||
@@ -331,7 +331,7 @@ static int iscsi_login_zero_tsih_s1( | |||
331 | * The FFP CmdSN window values will be allocated from the TPG's | 331 | * The FFP CmdSN window values will be allocated from the TPG's |
332 | * Initiator Node's ACL once the login has been successfully completed. | 332 | * Initiator Node's ACL once the login has been successfully completed. |
333 | */ | 333 | */ |
334 | sess->max_cmd_sn = be32_to_cpu(pdu->cmdsn); | 334 | atomic_set(&sess->max_cmd_sn, be32_to_cpu(pdu->cmdsn)); |
335 | 335 | ||
336 | sess->sess_ops = kzalloc(sizeof(struct iscsi_sess_ops), GFP_KERNEL); | 336 | sess->sess_ops = kzalloc(sizeof(struct iscsi_sess_ops), GFP_KERNEL); |
337 | if (!sess->sess_ops) { | 337 | if (!sess->sess_ops) { |
@@ -729,9 +729,9 @@ void iscsi_post_login_handler( | |||
729 | stop_timer = 1; | 729 | stop_timer = 1; |
730 | } | 730 | } |
731 | 731 | ||
732 | pr_debug("iSCSI Login successful on CID: %hu from %s to" | 732 | pr_debug("iSCSI Login successful on CID: %hu from %pISpc to" |
733 | " %s:%hu,%hu\n", conn->cid, conn->login_ip, | 733 | " %pISpc,%hu\n", conn->cid, &conn->login_sockaddr, |
734 | conn->local_ip, conn->local_port, tpg->tpgt); | 734 | &conn->local_sockaddr, tpg->tpgt); |
735 | 735 | ||
736 | list_add_tail(&conn->conn_list, &sess->sess_conn_list); | 736 | list_add_tail(&conn->conn_list, &sess->sess_conn_list); |
737 | atomic_inc(&sess->nconn); | 737 | atomic_inc(&sess->nconn); |
@@ -776,8 +776,8 @@ void iscsi_post_login_handler( | |||
776 | pr_debug("Moving to TARG_SESS_STATE_LOGGED_IN.\n"); | 776 | pr_debug("Moving to TARG_SESS_STATE_LOGGED_IN.\n"); |
777 | sess->session_state = TARG_SESS_STATE_LOGGED_IN; | 777 | sess->session_state = TARG_SESS_STATE_LOGGED_IN; |
778 | 778 | ||
779 | pr_debug("iSCSI Login successful on CID: %hu from %s to %s:%hu,%hu\n", | 779 | pr_debug("iSCSI Login successful on CID: %hu from %pISpc to %pISpc,%hu\n", |
780 | conn->cid, conn->login_ip, conn->local_ip, conn->local_port, | 780 | conn->cid, &conn->login_sockaddr, &conn->local_sockaddr, |
781 | tpg->tpgt); | 781 | tpg->tpgt); |
782 | 782 | ||
783 | spin_lock_bh(&sess->conn_lock); | 783 | spin_lock_bh(&sess->conn_lock); |
@@ -823,8 +823,8 @@ static void iscsi_handle_login_thread_timeout(unsigned long data) | |||
823 | struct iscsi_np *np = (struct iscsi_np *) data; | 823 | struct iscsi_np *np = (struct iscsi_np *) data; |
824 | 824 | ||
825 | spin_lock_bh(&np->np_thread_lock); | 825 | spin_lock_bh(&np->np_thread_lock); |
826 | pr_err("iSCSI Login timeout on Network Portal %s:%hu\n", | 826 | pr_err("iSCSI Login timeout on Network Portal %pISpc\n", |
827 | np->np_ip, np->np_port); | 827 | &np->np_sockaddr); |
828 | 828 | ||
829 | if (np->np_login_timer_flags & ISCSI_TF_STOP) { | 829 | if (np->np_login_timer_flags & ISCSI_TF_STOP) { |
830 | spin_unlock_bh(&np->np_thread_lock); | 830 | spin_unlock_bh(&np->np_thread_lock); |
@@ -877,7 +877,7 @@ static void iscsi_stop_login_thread_timer(struct iscsi_np *np) | |||
877 | 877 | ||
878 | int iscsit_setup_np( | 878 | int iscsit_setup_np( |
879 | struct iscsi_np *np, | 879 | struct iscsi_np *np, |
880 | struct __kernel_sockaddr_storage *sockaddr) | 880 | struct sockaddr_storage *sockaddr) |
881 | { | 881 | { |
882 | struct socket *sock = NULL; | 882 | struct socket *sock = NULL; |
883 | int backlog = ISCSIT_TCP_BACKLOG, ret, opt = 0, len; | 883 | int backlog = ISCSIT_TCP_BACKLOG, ret, opt = 0, len; |
@@ -916,7 +916,7 @@ int iscsit_setup_np( | |||
916 | * in iscsi_target_configfs.c code.. | 916 | * in iscsi_target_configfs.c code.. |
917 | */ | 917 | */ |
918 | memcpy(&np->np_sockaddr, sockaddr, | 918 | memcpy(&np->np_sockaddr, sockaddr, |
919 | sizeof(struct __kernel_sockaddr_storage)); | 919 | sizeof(struct sockaddr_storage)); |
920 | 920 | ||
921 | if (sockaddr->ss_family == AF_INET6) | 921 | if (sockaddr->ss_family == AF_INET6) |
922 | len = sizeof(struct sockaddr_in6); | 922 | len = sizeof(struct sockaddr_in6); |
@@ -975,7 +975,7 @@ fail: | |||
975 | 975 | ||
976 | int iscsi_target_setup_login_socket( | 976 | int iscsi_target_setup_login_socket( |
977 | struct iscsi_np *np, | 977 | struct iscsi_np *np, |
978 | struct __kernel_sockaddr_storage *sockaddr) | 978 | struct sockaddr_storage *sockaddr) |
979 | { | 979 | { |
980 | struct iscsit_transport *t; | 980 | struct iscsit_transport *t; |
981 | int rc; | 981 | int rc; |
@@ -1015,44 +1015,42 @@ int iscsit_accept_np(struct iscsi_np *np, struct iscsi_conn *conn) | |||
1015 | rc = conn->sock->ops->getname(conn->sock, | 1015 | rc = conn->sock->ops->getname(conn->sock, |
1016 | (struct sockaddr *)&sock_in6, &err, 1); | 1016 | (struct sockaddr *)&sock_in6, &err, 1); |
1017 | if (!rc) { | 1017 | if (!rc) { |
1018 | if (!ipv6_addr_v4mapped(&sock_in6.sin6_addr)) | 1018 | if (!ipv6_addr_v4mapped(&sock_in6.sin6_addr)) { |
1019 | snprintf(conn->login_ip, sizeof(conn->login_ip), "[%pI6c]", | 1019 | memcpy(&conn->login_sockaddr, &sock_in6, sizeof(sock_in6)); |
1020 | &sock_in6.sin6_addr.in6_u); | 1020 | } else { |
1021 | else | 1021 | /* Pretend to be an ipv4 socket */ |
1022 | snprintf(conn->login_ip, sizeof(conn->login_ip), "%pI4", | 1022 | sock_in.sin_family = AF_INET; |
1023 | &sock_in6.sin6_addr.s6_addr32[3]); | 1023 | sock_in.sin_port = sock_in6.sin6_port; |
1024 | conn->login_port = ntohs(sock_in6.sin6_port); | 1024 | memcpy(&sock_in.sin_addr, &sock_in6.sin6_addr.s6_addr32[3], 4); |
1025 | memcpy(&conn->login_sockaddr, &sock_in, sizeof(sock_in)); | ||
1026 | } | ||
1025 | } | 1027 | } |
1026 | 1028 | ||
1027 | rc = conn->sock->ops->getname(conn->sock, | 1029 | rc = conn->sock->ops->getname(conn->sock, |
1028 | (struct sockaddr *)&sock_in6, &err, 0); | 1030 | (struct sockaddr *)&sock_in6, &err, 0); |
1029 | if (!rc) { | 1031 | if (!rc) { |
1030 | if (!ipv6_addr_v4mapped(&sock_in6.sin6_addr)) | 1032 | if (!ipv6_addr_v4mapped(&sock_in6.sin6_addr)) { |
1031 | snprintf(conn->local_ip, sizeof(conn->local_ip), "[%pI6c]", | 1033 | memcpy(&conn->local_sockaddr, &sock_in6, sizeof(sock_in6)); |
1032 | &sock_in6.sin6_addr.in6_u); | 1034 | } else { |
1033 | else | 1035 | /* Pretend to be an ipv4 socket */ |
1034 | snprintf(conn->local_ip, sizeof(conn->local_ip), "%pI4", | 1036 | sock_in.sin_family = AF_INET; |
1035 | &sock_in6.sin6_addr.s6_addr32[3]); | 1037 | sock_in.sin_port = sock_in6.sin6_port; |
1036 | conn->local_port = ntohs(sock_in6.sin6_port); | 1038 | memcpy(&sock_in.sin_addr, &sock_in6.sin6_addr.s6_addr32[3], 4); |
1039 | memcpy(&conn->local_sockaddr, &sock_in, sizeof(sock_in)); | ||
1040 | } | ||
1037 | } | 1041 | } |
1038 | } else { | 1042 | } else { |
1039 | memset(&sock_in, 0, sizeof(struct sockaddr_in)); | 1043 | memset(&sock_in, 0, sizeof(struct sockaddr_in)); |
1040 | 1044 | ||
1041 | rc = conn->sock->ops->getname(conn->sock, | 1045 | rc = conn->sock->ops->getname(conn->sock, |
1042 | (struct sockaddr *)&sock_in, &err, 1); | 1046 | (struct sockaddr *)&sock_in, &err, 1); |
1043 | if (!rc) { | 1047 | if (!rc) |
1044 | sprintf(conn->login_ip, "%pI4", | 1048 | memcpy(&conn->login_sockaddr, &sock_in, sizeof(sock_in)); |
1045 | &sock_in.sin_addr.s_addr); | ||
1046 | conn->login_port = ntohs(sock_in.sin_port); | ||
1047 | } | ||
1048 | 1049 | ||
1049 | rc = conn->sock->ops->getname(conn->sock, | 1050 | rc = conn->sock->ops->getname(conn->sock, |
1050 | (struct sockaddr *)&sock_in, &err, 0); | 1051 | (struct sockaddr *)&sock_in, &err, 0); |
1051 | if (!rc) { | 1052 | if (!rc) |
1052 | sprintf(conn->local_ip, "%pI4", | 1053 | memcpy(&conn->local_sockaddr, &sock_in, sizeof(sock_in)); |
1053 | &sock_in.sin_addr.s_addr); | ||
1054 | conn->local_port = ntohs(sock_in.sin_port); | ||
1055 | } | ||
1056 | } | 1054 | } |
1057 | 1055 | ||
1058 | return 0; | 1056 | return 0; |
@@ -1302,8 +1300,8 @@ static int __iscsi_target_login_thread(struct iscsi_np *np) | |||
1302 | spin_lock_bh(&np->np_thread_lock); | 1300 | spin_lock_bh(&np->np_thread_lock); |
1303 | if (np->np_thread_state != ISCSI_NP_THREAD_ACTIVE) { | 1301 | if (np->np_thread_state != ISCSI_NP_THREAD_ACTIVE) { |
1304 | spin_unlock_bh(&np->np_thread_lock); | 1302 | spin_unlock_bh(&np->np_thread_lock); |
1305 | pr_err("iSCSI Network Portal on %s:%hu currently not" | 1303 | pr_err("iSCSI Network Portal on %pISpc currently not" |
1306 | " active.\n", np->np_ip, np->np_port); | 1304 | " active.\n", &np->np_sockaddr); |
1307 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, | 1305 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, |
1308 | ISCSI_LOGIN_STATUS_SVC_UNAVAILABLE); | 1306 | ISCSI_LOGIN_STATUS_SVC_UNAVAILABLE); |
1309 | goto new_sess_out; | 1307 | goto new_sess_out; |
@@ -1312,9 +1310,9 @@ static int __iscsi_target_login_thread(struct iscsi_np *np) | |||
1312 | 1310 | ||
1313 | conn->network_transport = np->np_network_transport; | 1311 | conn->network_transport = np->np_network_transport; |
1314 | 1312 | ||
1315 | pr_debug("Received iSCSI login request from %s on %s Network" | 1313 | pr_debug("Received iSCSI login request from %pISpc on %s Network" |
1316 | " Portal %s:%hu\n", conn->login_ip, np->np_transport->name, | 1314 | " Portal %pISpc\n", &conn->login_sockaddr, np->np_transport->name, |
1317 | conn->local_ip, conn->local_port); | 1315 | &conn->local_sockaddr); |
1318 | 1316 | ||
1319 | pr_debug("Moving to TARG_CONN_STATE_IN_LOGIN.\n"); | 1317 | pr_debug("Moving to TARG_CONN_STATE_IN_LOGIN.\n"); |
1320 | conn->conn_state = TARG_CONN_STATE_IN_LOGIN; | 1318 | conn->conn_state = TARG_CONN_STATE_IN_LOGIN; |
diff --git a/drivers/target/iscsi/iscsi_target_login.h b/drivers/target/iscsi/iscsi_target_login.h index 57aa0d0fd820..b597aa2c61a1 100644 --- a/drivers/target/iscsi/iscsi_target_login.h +++ b/drivers/target/iscsi/iscsi_target_login.h | |||
@@ -5,9 +5,9 @@ extern int iscsi_login_setup_crypto(struct iscsi_conn *); | |||
5 | extern int iscsi_check_for_session_reinstatement(struct iscsi_conn *); | 5 | extern int iscsi_check_for_session_reinstatement(struct iscsi_conn *); |
6 | extern int iscsi_login_post_auth_non_zero_tsih(struct iscsi_conn *, u16, u32); | 6 | extern int iscsi_login_post_auth_non_zero_tsih(struct iscsi_conn *, u16, u32); |
7 | extern int iscsit_setup_np(struct iscsi_np *, | 7 | extern int iscsit_setup_np(struct iscsi_np *, |
8 | struct __kernel_sockaddr_storage *); | 8 | struct sockaddr_storage *); |
9 | extern int iscsi_target_setup_login_socket(struct iscsi_np *, | 9 | extern int iscsi_target_setup_login_socket(struct iscsi_np *, |
10 | struct __kernel_sockaddr_storage *); | 10 | struct sockaddr_storage *); |
11 | extern int iscsit_accept_np(struct iscsi_np *, struct iscsi_conn *); | 11 | extern int iscsit_accept_np(struct iscsi_np *, struct iscsi_conn *); |
12 | extern int iscsit_get_login_rx(struct iscsi_conn *, struct iscsi_login *); | 12 | extern int iscsit_get_login_rx(struct iscsi_conn *, struct iscsi_login *); |
13 | extern int iscsit_put_login_tx(struct iscsi_conn *, struct iscsi_login *, u32); | 13 | extern int iscsit_put_login_tx(struct iscsi_conn *, struct iscsi_login *, u32); |
diff --git a/drivers/target/iscsi/iscsi_target_nego.c b/drivers/target/iscsi/iscsi_target_nego.c index f9cde9141836..5c964c09c89f 100644 --- a/drivers/target/iscsi/iscsi_target_nego.c +++ b/drivers/target/iscsi/iscsi_target_nego.c | |||
@@ -341,7 +341,6 @@ static int iscsi_target_check_first_request( | |||
341 | static int iscsi_target_do_tx_login_io(struct iscsi_conn *conn, struct iscsi_login *login) | 341 | static int iscsi_target_do_tx_login_io(struct iscsi_conn *conn, struct iscsi_login *login) |
342 | { | 342 | { |
343 | u32 padding = 0; | 343 | u32 padding = 0; |
344 | struct iscsi_session *sess = conn->sess; | ||
345 | struct iscsi_login_rsp *login_rsp; | 344 | struct iscsi_login_rsp *login_rsp; |
346 | 345 | ||
347 | login_rsp = (struct iscsi_login_rsp *) login->rsp; | 346 | login_rsp = (struct iscsi_login_rsp *) login->rsp; |
@@ -353,7 +352,7 @@ static int iscsi_target_do_tx_login_io(struct iscsi_conn *conn, struct iscsi_log | |||
353 | login_rsp->itt = login->init_task_tag; | 352 | login_rsp->itt = login->init_task_tag; |
354 | login_rsp->statsn = cpu_to_be32(conn->stat_sn++); | 353 | login_rsp->statsn = cpu_to_be32(conn->stat_sn++); |
355 | login_rsp->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); | 354 | login_rsp->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); |
356 | login_rsp->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn); | 355 | login_rsp->max_cmdsn = cpu_to_be32((u32) atomic_read(&conn->sess->max_cmd_sn)); |
357 | 356 | ||
358 | pr_debug("Sending Login Response, Flags: 0x%02x, ITT: 0x%08x," | 357 | pr_debug("Sending Login Response, Flags: 0x%02x, ITT: 0x%08x," |
359 | " ExpCmdSN; 0x%08x, MaxCmdSN: 0x%08x, StatSN: 0x%08x, Length:" | 358 | " ExpCmdSN; 0x%08x, MaxCmdSN: 0x%08x, StatSN: 0x%08x, Length:" |
@@ -382,10 +381,6 @@ static int iscsi_target_do_tx_login_io(struct iscsi_conn *conn, struct iscsi_log | |||
382 | goto err; | 381 | goto err; |
383 | 382 | ||
384 | login->rsp_length = 0; | 383 | login->rsp_length = 0; |
385 | mutex_lock(&sess->cmdsn_mutex); | ||
386 | login_rsp->exp_cmdsn = cpu_to_be32(sess->exp_cmd_sn); | ||
387 | login_rsp->max_cmdsn = cpu_to_be32(sess->max_cmd_sn); | ||
388 | mutex_unlock(&sess->cmdsn_mutex); | ||
389 | 384 | ||
390 | return 0; | 385 | return 0; |
391 | 386 | ||
diff --git a/drivers/target/iscsi/iscsi_target_stat.c b/drivers/target/iscsi/iscsi_target_stat.c index 5e1349a3b143..9dd94ff0b62c 100644 --- a/drivers/target/iscsi/iscsi_target_stat.c +++ b/drivers/target/iscsi/iscsi_target_stat.c | |||
@@ -430,7 +430,7 @@ static ssize_t iscsi_stat_tgt_attr_show_attr_fail_intr_addr( | |||
430 | int ret; | 430 | int ret; |
431 | 431 | ||
432 | spin_lock(&lstat->lock); | 432 | spin_lock(&lstat->lock); |
433 | ret = snprintf(page, PAGE_SIZE, "%s\n", lstat->last_intr_fail_ip_addr); | 433 | ret = snprintf(page, PAGE_SIZE, "%pISc\n", &lstat->last_intr_fail_sockaddr); |
434 | spin_unlock(&lstat->lock); | 434 | spin_unlock(&lstat->lock); |
435 | 435 | ||
436 | return ret; | 436 | return ret; |
diff --git a/drivers/target/iscsi/iscsi_target_tmr.c b/drivers/target/iscsi/iscsi_target_tmr.c index cf59c397007b..11320df939f7 100644 --- a/drivers/target/iscsi/iscsi_target_tmr.c +++ b/drivers/target/iscsi/iscsi_target_tmr.c | |||
@@ -50,7 +50,7 @@ u8 iscsit_tmr_abort_task( | |||
50 | pr_err("Unable to locate RefTaskTag: 0x%08x on CID:" | 50 | pr_err("Unable to locate RefTaskTag: 0x%08x on CID:" |
51 | " %hu.\n", hdr->rtt, conn->cid); | 51 | " %hu.\n", hdr->rtt, conn->cid); |
52 | return (iscsi_sna_gte(be32_to_cpu(hdr->refcmdsn), conn->sess->exp_cmd_sn) && | 52 | return (iscsi_sna_gte(be32_to_cpu(hdr->refcmdsn), conn->sess->exp_cmd_sn) && |
53 | iscsi_sna_lte(be32_to_cpu(hdr->refcmdsn), conn->sess->max_cmd_sn)) ? | 53 | iscsi_sna_lte(be32_to_cpu(hdr->refcmdsn), (u32) atomic_read(&conn->sess->max_cmd_sn))) ? |
54 | ISCSI_TMF_RSP_COMPLETE : ISCSI_TMF_RSP_NO_TASK; | 54 | ISCSI_TMF_RSP_COMPLETE : ISCSI_TMF_RSP_NO_TASK; |
55 | } | 55 | } |
56 | if (ref_cmd->cmd_sn != be32_to_cpu(hdr->refcmdsn)) { | 56 | if (ref_cmd->cmd_sn != be32_to_cpu(hdr->refcmdsn)) { |
diff --git a/drivers/target/iscsi/iscsi_target_tpg.c b/drivers/target/iscsi/iscsi_target_tpg.c index 968068ffcb1c..23c95cd14167 100644 --- a/drivers/target/iscsi/iscsi_target_tpg.c +++ b/drivers/target/iscsi/iscsi_target_tpg.c | |||
@@ -226,6 +226,7 @@ static void iscsit_set_default_tpg_attribs(struct iscsi_portal_group *tpg) | |||
226 | a->default_erl = TA_DEFAULT_ERL; | 226 | a->default_erl = TA_DEFAULT_ERL; |
227 | a->t10_pi = TA_DEFAULT_T10_PI; | 227 | a->t10_pi = TA_DEFAULT_T10_PI; |
228 | a->fabric_prot_type = TA_DEFAULT_FABRIC_PROT_TYPE; | 228 | a->fabric_prot_type = TA_DEFAULT_FABRIC_PROT_TYPE; |
229 | a->tpg_enabled_sendtargets = TA_DEFAULT_TPG_ENABLED_SENDTARGETS; | ||
229 | } | 230 | } |
230 | 231 | ||
231 | int iscsit_tpg_add_portal_group(struct iscsi_tiqn *tiqn, struct iscsi_portal_group *tpg) | 232 | int iscsit_tpg_add_portal_group(struct iscsi_tiqn *tiqn, struct iscsi_portal_group *tpg) |
@@ -430,7 +431,7 @@ struct iscsi_tpg_np *iscsit_tpg_locate_child_np( | |||
430 | 431 | ||
431 | static bool iscsit_tpg_check_network_portal( | 432 | static bool iscsit_tpg_check_network_portal( |
432 | struct iscsi_tiqn *tiqn, | 433 | struct iscsi_tiqn *tiqn, |
433 | struct __kernel_sockaddr_storage *sockaddr, | 434 | struct sockaddr_storage *sockaddr, |
434 | int network_transport) | 435 | int network_transport) |
435 | { | 436 | { |
436 | struct iscsi_portal_group *tpg; | 437 | struct iscsi_portal_group *tpg; |
@@ -459,8 +460,7 @@ static bool iscsit_tpg_check_network_portal( | |||
459 | 460 | ||
460 | struct iscsi_tpg_np *iscsit_tpg_add_network_portal( | 461 | struct iscsi_tpg_np *iscsit_tpg_add_network_portal( |
461 | struct iscsi_portal_group *tpg, | 462 | struct iscsi_portal_group *tpg, |
462 | struct __kernel_sockaddr_storage *sockaddr, | 463 | struct sockaddr_storage *sockaddr, |
463 | char *ip_str, | ||
464 | struct iscsi_tpg_np *tpg_np_parent, | 464 | struct iscsi_tpg_np *tpg_np_parent, |
465 | int network_transport) | 465 | int network_transport) |
466 | { | 466 | { |
@@ -470,8 +470,8 @@ struct iscsi_tpg_np *iscsit_tpg_add_network_portal( | |||
470 | if (!tpg_np_parent) { | 470 | if (!tpg_np_parent) { |
471 | if (iscsit_tpg_check_network_portal(tpg->tpg_tiqn, sockaddr, | 471 | if (iscsit_tpg_check_network_portal(tpg->tpg_tiqn, sockaddr, |
472 | network_transport)) { | 472 | network_transport)) { |
473 | pr_err("Network Portal: %s already exists on a" | 473 | pr_err("Network Portal: %pISc already exists on a" |
474 | " different TPG on %s\n", ip_str, | 474 | " different TPG on %s\n", sockaddr, |
475 | tpg->tpg_tiqn->tiqn); | 475 | tpg->tpg_tiqn->tiqn); |
476 | return ERR_PTR(-EEXIST); | 476 | return ERR_PTR(-EEXIST); |
477 | } | 477 | } |
@@ -484,7 +484,7 @@ struct iscsi_tpg_np *iscsit_tpg_add_network_portal( | |||
484 | return ERR_PTR(-ENOMEM); | 484 | return ERR_PTR(-ENOMEM); |
485 | } | 485 | } |
486 | 486 | ||
487 | np = iscsit_add_np(sockaddr, ip_str, network_transport); | 487 | np = iscsit_add_np(sockaddr, network_transport); |
488 | if (IS_ERR(np)) { | 488 | if (IS_ERR(np)) { |
489 | kfree(tpg_np); | 489 | kfree(tpg_np); |
490 | return ERR_CAST(np); | 490 | return ERR_CAST(np); |
@@ -514,8 +514,8 @@ struct iscsi_tpg_np *iscsit_tpg_add_network_portal( | |||
514 | spin_unlock(&tpg_np_parent->tpg_np_parent_lock); | 514 | spin_unlock(&tpg_np_parent->tpg_np_parent_lock); |
515 | } | 515 | } |
516 | 516 | ||
517 | pr_debug("CORE[%s] - Added Network Portal: %s:%hu,%hu on %s\n", | 517 | pr_debug("CORE[%s] - Added Network Portal: %pISpc,%hu on %s\n", |
518 | tpg->tpg_tiqn->tiqn, np->np_ip, np->np_port, tpg->tpgt, | 518 | tpg->tpg_tiqn->tiqn, &np->np_sockaddr, tpg->tpgt, |
519 | np->np_transport->name); | 519 | np->np_transport->name); |
520 | 520 | ||
521 | return tpg_np; | 521 | return tpg_np; |
@@ -528,8 +528,8 @@ static int iscsit_tpg_release_np( | |||
528 | { | 528 | { |
529 | iscsit_clear_tpg_np_login_thread(tpg_np, tpg, true); | 529 | iscsit_clear_tpg_np_login_thread(tpg_np, tpg, true); |
530 | 530 | ||
531 | pr_debug("CORE[%s] - Removed Network Portal: %s:%hu,%hu on %s\n", | 531 | pr_debug("CORE[%s] - Removed Network Portal: %pISpc,%hu on %s\n", |
532 | tpg->tpg_tiqn->tiqn, np->np_ip, np->np_port, tpg->tpgt, | 532 | tpg->tpg_tiqn->tiqn, &np->np_sockaddr, tpg->tpgt, |
533 | np->np_transport->name); | 533 | np->np_transport->name); |
534 | 534 | ||
535 | tpg_np->tpg_np = NULL; | 535 | tpg_np->tpg_np = NULL; |
@@ -892,3 +892,21 @@ int iscsit_ta_fabric_prot_type( | |||
892 | 892 | ||
893 | return 0; | 893 | return 0; |
894 | } | 894 | } |
895 | |||
896 | int iscsit_ta_tpg_enabled_sendtargets( | ||
897 | struct iscsi_portal_group *tpg, | ||
898 | u32 flag) | ||
899 | { | ||
900 | struct iscsi_tpg_attrib *a = &tpg->tpg_attrib; | ||
901 | |||
902 | if ((flag != 0) && (flag != 1)) { | ||
903 | pr_err("Illegal value %d\n", flag); | ||
904 | return -EINVAL; | ||
905 | } | ||
906 | |||
907 | a->tpg_enabled_sendtargets = flag; | ||
908 | pr_debug("iSCSI_TPG[%hu] - TPG enabled bit required for SendTargets:" | ||
909 | " %s\n", tpg->tpgt, (a->tpg_enabled_sendtargets) ? "ON" : "OFF"); | ||
910 | |||
911 | return 0; | ||
912 | } | ||
diff --git a/drivers/target/iscsi/iscsi_target_tpg.h b/drivers/target/iscsi/iscsi_target_tpg.h index 95ff5bdecd71..9db32bd24cd4 100644 --- a/drivers/target/iscsi/iscsi_target_tpg.h +++ b/drivers/target/iscsi/iscsi_target_tpg.h | |||
@@ -22,7 +22,7 @@ extern struct iscsi_node_attrib *iscsit_tpg_get_node_attrib(struct iscsi_session | |||
22 | extern void iscsit_tpg_del_external_nps(struct iscsi_tpg_np *); | 22 | extern void iscsit_tpg_del_external_nps(struct iscsi_tpg_np *); |
23 | extern struct iscsi_tpg_np *iscsit_tpg_locate_child_np(struct iscsi_tpg_np *, int); | 23 | extern struct iscsi_tpg_np *iscsit_tpg_locate_child_np(struct iscsi_tpg_np *, int); |
24 | extern struct iscsi_tpg_np *iscsit_tpg_add_network_portal(struct iscsi_portal_group *, | 24 | extern struct iscsi_tpg_np *iscsit_tpg_add_network_portal(struct iscsi_portal_group *, |
25 | struct __kernel_sockaddr_storage *, char *, struct iscsi_tpg_np *, | 25 | struct sockaddr_storage *, struct iscsi_tpg_np *, |
26 | int); | 26 | int); |
27 | extern int iscsit_tpg_del_network_portal(struct iscsi_portal_group *, | 27 | extern int iscsit_tpg_del_network_portal(struct iscsi_portal_group *, |
28 | struct iscsi_tpg_np *); | 28 | struct iscsi_tpg_np *); |
@@ -40,5 +40,6 @@ extern int iscsit_ta_demo_mode_discovery(struct iscsi_portal_group *, u32); | |||
40 | extern int iscsit_ta_default_erl(struct iscsi_portal_group *, u32); | 40 | extern int iscsit_ta_default_erl(struct iscsi_portal_group *, u32); |
41 | extern int iscsit_ta_t10_pi(struct iscsi_portal_group *, u32); | 41 | extern int iscsit_ta_t10_pi(struct iscsi_portal_group *, u32); |
42 | extern int iscsit_ta_fabric_prot_type(struct iscsi_portal_group *, u32); | 42 | extern int iscsit_ta_fabric_prot_type(struct iscsi_portal_group *, u32); |
43 | extern int iscsit_ta_tpg_enabled_sendtargets(struct iscsi_portal_group *, u32); | ||
43 | 44 | ||
44 | #endif /* ISCSI_TARGET_TPG_H */ | 45 | #endif /* ISCSI_TARGET_TPG_H */ |
diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c index a2bff0702eb2..428b0d9e3dba 100644 --- a/drivers/target/iscsi/iscsi_target_util.c +++ b/drivers/target/iscsi/iscsi_target_util.c | |||
@@ -233,6 +233,7 @@ struct iscsi_r2t *iscsit_get_holder_for_r2tsn( | |||
233 | 233 | ||
234 | static inline int iscsit_check_received_cmdsn(struct iscsi_session *sess, u32 cmdsn) | 234 | static inline int iscsit_check_received_cmdsn(struct iscsi_session *sess, u32 cmdsn) |
235 | { | 235 | { |
236 | u32 max_cmdsn; | ||
236 | int ret; | 237 | int ret; |
237 | 238 | ||
238 | /* | 239 | /* |
@@ -241,10 +242,10 @@ static inline int iscsit_check_received_cmdsn(struct iscsi_session *sess, u32 cm | |||
241 | * or order CmdSNs due to multiple connection sessions and/or | 242 | * or order CmdSNs due to multiple connection sessions and/or |
242 | * CRC failures. | 243 | * CRC failures. |
243 | */ | 244 | */ |
244 | if (iscsi_sna_gt(cmdsn, sess->max_cmd_sn)) { | 245 | max_cmdsn = atomic_read(&sess->max_cmd_sn); |
246 | if (iscsi_sna_gt(cmdsn, max_cmdsn)) { | ||
245 | pr_err("Received CmdSN: 0x%08x is greater than" | 247 | pr_err("Received CmdSN: 0x%08x is greater than" |
246 | " MaxCmdSN: 0x%08x, ignoring.\n", cmdsn, | 248 | " MaxCmdSN: 0x%08x, ignoring.\n", cmdsn, max_cmdsn); |
247 | sess->max_cmd_sn); | ||
248 | ret = CMDSN_MAXCMDSN_OVERRUN; | 249 | ret = CMDSN_MAXCMDSN_OVERRUN; |
249 | 250 | ||
250 | } else if (cmdsn == sess->exp_cmd_sn) { | 251 | } else if (cmdsn == sess->exp_cmd_sn) { |
@@ -1371,6 +1372,33 @@ int tx_data( | |||
1371 | return iscsit_do_tx_data(conn, &c); | 1372 | return iscsit_do_tx_data(conn, &c); |
1372 | } | 1373 | } |
1373 | 1374 | ||
1375 | static bool sockaddr_equal(struct sockaddr_storage *x, struct sockaddr_storage *y) | ||
1376 | { | ||
1377 | switch (x->ss_family) { | ||
1378 | case AF_INET: { | ||
1379 | struct sockaddr_in *sinx = (struct sockaddr_in *)x; | ||
1380 | struct sockaddr_in *siny = (struct sockaddr_in *)y; | ||
1381 | if (sinx->sin_addr.s_addr != siny->sin_addr.s_addr) | ||
1382 | return false; | ||
1383 | if (sinx->sin_port != siny->sin_port) | ||
1384 | return false; | ||
1385 | break; | ||
1386 | } | ||
1387 | case AF_INET6: { | ||
1388 | struct sockaddr_in6 *sinx = (struct sockaddr_in6 *)x; | ||
1389 | struct sockaddr_in6 *siny = (struct sockaddr_in6 *)y; | ||
1390 | if (!ipv6_addr_equal(&sinx->sin6_addr, &siny->sin6_addr)) | ||
1391 | return false; | ||
1392 | if (sinx->sin6_port != siny->sin6_port) | ||
1393 | return false; | ||
1394 | break; | ||
1395 | } | ||
1396 | default: | ||
1397 | return false; | ||
1398 | } | ||
1399 | return true; | ||
1400 | } | ||
1401 | |||
1374 | void iscsit_collect_login_stats( | 1402 | void iscsit_collect_login_stats( |
1375 | struct iscsi_conn *conn, | 1403 | struct iscsi_conn *conn, |
1376 | u8 status_class, | 1404 | u8 status_class, |
@@ -1387,7 +1415,7 @@ void iscsit_collect_login_stats( | |||
1387 | ls = &tiqn->login_stats; | 1415 | ls = &tiqn->login_stats; |
1388 | 1416 | ||
1389 | spin_lock(&ls->lock); | 1417 | spin_lock(&ls->lock); |
1390 | if (!strcmp(conn->login_ip, ls->last_intr_fail_ip_addr) && | 1418 | if (sockaddr_equal(&conn->login_sockaddr, &ls->last_intr_fail_sockaddr) && |
1391 | ((get_jiffies_64() - ls->last_fail_time) < 10)) { | 1419 | ((get_jiffies_64() - ls->last_fail_time) < 10)) { |
1392 | /* We already have the failure info for this login */ | 1420 | /* We already have the failure info for this login */ |
1393 | spin_unlock(&ls->lock); | 1421 | spin_unlock(&ls->lock); |
@@ -1427,8 +1455,7 @@ void iscsit_collect_login_stats( | |||
1427 | 1455 | ||
1428 | ls->last_intr_fail_ip_family = conn->login_family; | 1456 | ls->last_intr_fail_ip_family = conn->login_family; |
1429 | 1457 | ||
1430 | snprintf(ls->last_intr_fail_ip_addr, IPV6_ADDRESS_SPACE, | 1458 | ls->last_intr_fail_sockaddr = conn->login_sockaddr; |
1431 | "%s", conn->login_ip); | ||
1432 | ls->last_fail_time = get_jiffies_64(); | 1459 | ls->last_fail_time = get_jiffies_64(); |
1433 | } | 1460 | } |
1434 | 1461 | ||
diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index a556bdebd775..5bc85ffed720 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c | |||
@@ -526,7 +526,7 @@ static inline struct tcm_loop_tpg *tl_tpg(struct se_portal_group *se_tpg) | |||
526 | static char *tcm_loop_get_endpoint_wwn(struct se_portal_group *se_tpg) | 526 | static char *tcm_loop_get_endpoint_wwn(struct se_portal_group *se_tpg) |
527 | { | 527 | { |
528 | /* | 528 | /* |
529 | * Return the passed NAA identifier for the SAS Target Port | 529 | * Return the passed NAA identifier for the Target Port |
530 | */ | 530 | */ |
531 | return &tl_tpg(se_tpg)->tl_hba->tl_wwn_address[0]; | 531 | return &tl_tpg(se_tpg)->tl_hba->tl_wwn_address[0]; |
532 | } | 532 | } |
@@ -845,7 +845,7 @@ static int tcm_loop_make_nexus( | |||
845 | transport_free_session(tl_nexus->se_sess); | 845 | transport_free_session(tl_nexus->se_sess); |
846 | goto out; | 846 | goto out; |
847 | } | 847 | } |
848 | /* Now, register the SAS I_T Nexus as active. */ | 848 | /* Now, register the I_T Nexus as active. */ |
849 | transport_register_session(se_tpg, tl_nexus->se_sess->se_node_acl, | 849 | transport_register_session(se_tpg, tl_nexus->se_sess->se_node_acl, |
850 | tl_nexus->se_sess, tl_nexus); | 850 | tl_nexus->se_sess, tl_nexus); |
851 | tl_tpg->tl_nexus = tl_nexus; | 851 | tl_tpg->tl_nexus = tl_nexus; |
@@ -884,7 +884,7 @@ static int tcm_loop_drop_nexus( | |||
884 | " %s Initiator Port: %s\n", tcm_loop_dump_proto_id(tpg->tl_hba), | 884 | " %s Initiator Port: %s\n", tcm_loop_dump_proto_id(tpg->tl_hba), |
885 | tl_nexus->se_sess->se_node_acl->initiatorname); | 885 | tl_nexus->se_sess->se_node_acl->initiatorname); |
886 | /* | 886 | /* |
887 | * Release the SCSI I_T Nexus to the emulated SAS Target Port | 887 | * Release the SCSI I_T Nexus to the emulated Target Port |
888 | */ | 888 | */ |
889 | transport_deregister_session(tl_nexus->se_sess); | 889 | transport_deregister_session(tl_nexus->se_sess); |
890 | tpg->tl_nexus = NULL; | 890 | tpg->tl_nexus = NULL; |
@@ -1034,6 +1034,11 @@ static ssize_t tcm_loop_tpg_store_transport_status( | |||
1034 | } | 1034 | } |
1035 | if (!strncmp(page, "offline", 7)) { | 1035 | if (!strncmp(page, "offline", 7)) { |
1036 | tl_tpg->tl_transport_status = TCM_TRANSPORT_OFFLINE; | 1036 | tl_tpg->tl_transport_status = TCM_TRANSPORT_OFFLINE; |
1037 | if (tl_tpg->tl_nexus) { | ||
1038 | struct se_session *tl_sess = tl_tpg->tl_nexus->se_sess; | ||
1039 | |||
1040 | core_allocate_nexus_loss_ua(tl_sess->se_node_acl); | ||
1041 | } | ||
1037 | return count; | 1042 | return count; |
1038 | } | 1043 | } |
1039 | return -EINVAL; | 1044 | return -EINVAL; |
@@ -1077,7 +1082,7 @@ static struct se_portal_group *tcm_loop_make_naa_tpg( | |||
1077 | tl_tpg->tl_hba = tl_hba; | 1082 | tl_tpg->tl_hba = tl_hba; |
1078 | tl_tpg->tl_tpgt = tpgt; | 1083 | tl_tpg->tl_tpgt = tpgt; |
1079 | /* | 1084 | /* |
1080 | * Register the tl_tpg as a emulated SAS TCM Target Endpoint | 1085 | * Register the tl_tpg as a emulated TCM Target Endpoint |
1081 | */ | 1086 | */ |
1082 | ret = core_tpg_register(wwn, &tl_tpg->tl_se_tpg, tl_hba->tl_proto_id); | 1087 | ret = core_tpg_register(wwn, &tl_tpg->tl_se_tpg, tl_hba->tl_proto_id); |
1083 | if (ret < 0) | 1088 | if (ret < 0) |
@@ -1102,11 +1107,11 @@ static void tcm_loop_drop_naa_tpg( | |||
1102 | tl_hba = tl_tpg->tl_hba; | 1107 | tl_hba = tl_tpg->tl_hba; |
1103 | tpgt = tl_tpg->tl_tpgt; | 1108 | tpgt = tl_tpg->tl_tpgt; |
1104 | /* | 1109 | /* |
1105 | * Release the I_T Nexus for the Virtual SAS link if present | 1110 | * Release the I_T Nexus for the Virtual target link if present |
1106 | */ | 1111 | */ |
1107 | tcm_loop_drop_nexus(tl_tpg); | 1112 | tcm_loop_drop_nexus(tl_tpg); |
1108 | /* | 1113 | /* |
1109 | * Deregister the tl_tpg as a emulated SAS TCM Target Endpoint | 1114 | * Deregister the tl_tpg as a emulated TCM Target Endpoint |
1110 | */ | 1115 | */ |
1111 | core_tpg_deregister(se_tpg); | 1116 | core_tpg_deregister(se_tpg); |
1112 | 1117 | ||
@@ -1199,8 +1204,9 @@ static void tcm_loop_drop_scsi_hba( | |||
1199 | struct tcm_loop_hba, tl_hba_wwn); | 1204 | struct tcm_loop_hba, tl_hba_wwn); |
1200 | 1205 | ||
1201 | pr_debug("TCM_Loop_ConfigFS: Deallocating emulated Target" | 1206 | pr_debug("TCM_Loop_ConfigFS: Deallocating emulated Target" |
1202 | " SAS Address: %s at Linux/SCSI Host ID: %d\n", | 1207 | " %s Address: %s at Linux/SCSI Host ID: %d\n", |
1203 | tl_hba->tl_wwn_address, tl_hba->sh->host_no); | 1208 | tcm_loop_dump_proto_id(tl_hba), tl_hba->tl_wwn_address, |
1209 | tl_hba->sh->host_no); | ||
1204 | /* | 1210 | /* |
1205 | * Call device_unregister() on the original tl_hba->dev. | 1211 | * Call device_unregister() on the original tl_hba->dev. |
1206 | * tcm_loop_fabric_scsi.c:tcm_loop_release_adapter() will | 1212 | * tcm_loop_fabric_scsi.c:tcm_loop_release_adapter() will |
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 09e682b1c549..dcc424ac35d4 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c | |||
@@ -620,8 +620,6 @@ struct se_lun_acl *core_dev_init_initiator_node_lun_acl( | |||
620 | 620 | ||
621 | lacl->mapped_lun = mapped_lun; | 621 | lacl->mapped_lun = mapped_lun; |
622 | lacl->se_lun_nacl = nacl; | 622 | lacl->se_lun_nacl = nacl; |
623 | snprintf(lacl->initiatorname, TRANSPORT_IQN_LEN, "%s", | ||
624 | nacl->initiatorname); | ||
625 | 623 | ||
626 | return lacl; | 624 | return lacl; |
627 | } | 625 | } |
@@ -656,7 +654,7 @@ int core_dev_add_initiator_node_lun_acl( | |||
656 | " InitiatorNode: %s\n", tpg->se_tpg_tfo->get_fabric_name(), | 654 | " InitiatorNode: %s\n", tpg->se_tpg_tfo->get_fabric_name(), |
657 | tpg->se_tpg_tfo->tpg_get_tag(tpg), lun->unpacked_lun, lacl->mapped_lun, | 655 | tpg->se_tpg_tfo->tpg_get_tag(tpg), lun->unpacked_lun, lacl->mapped_lun, |
658 | (lun_access & TRANSPORT_LUNFLAGS_READ_WRITE) ? "RW" : "RO", | 656 | (lun_access & TRANSPORT_LUNFLAGS_READ_WRITE) ? "RW" : "RO", |
659 | lacl->initiatorname); | 657 | nacl->initiatorname); |
660 | /* | 658 | /* |
661 | * Check to see if there are any existing persistent reservation APTPL | 659 | * Check to see if there are any existing persistent reservation APTPL |
662 | * pre-registrations that need to be enabled for this LUN ACL.. | 660 | * pre-registrations that need to be enabled for this LUN ACL.. |
@@ -688,7 +686,7 @@ int core_dev_del_initiator_node_lun_acl( | |||
688 | " InitiatorNode: %s Mapped LUN: %llu\n", | 686 | " InitiatorNode: %s Mapped LUN: %llu\n", |
689 | tpg->se_tpg_tfo->get_fabric_name(), | 687 | tpg->se_tpg_tfo->get_fabric_name(), |
690 | tpg->se_tpg_tfo->tpg_get_tag(tpg), lun->unpacked_lun, | 688 | tpg->se_tpg_tfo->tpg_get_tag(tpg), lun->unpacked_lun, |
691 | lacl->initiatorname, lacl->mapped_lun); | 689 | nacl->initiatorname, lacl->mapped_lun); |
692 | 690 | ||
693 | return 0; | 691 | return 0; |
694 | } | 692 | } |
@@ -701,7 +699,7 @@ void core_dev_free_initiator_node_lun_acl( | |||
701 | " Mapped LUN: %llu\n", tpg->se_tpg_tfo->get_fabric_name(), | 699 | " Mapped LUN: %llu\n", tpg->se_tpg_tfo->get_fabric_name(), |
702 | tpg->se_tpg_tfo->tpg_get_tag(tpg), | 700 | tpg->se_tpg_tfo->tpg_get_tag(tpg), |
703 | tpg->se_tpg_tfo->get_fabric_name(), | 701 | tpg->se_tpg_tfo->get_fabric_name(), |
704 | lacl->initiatorname, lacl->mapped_lun); | 702 | lacl->se_lun_nacl->initiatorname, lacl->mapped_lun); |
705 | 703 | ||
706 | kfree(lacl); | 704 | kfree(lacl); |
707 | } | 705 | } |
@@ -754,7 +752,7 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name) | |||
754 | dev->dev_link_magic = SE_DEV_LINK_MAGIC; | 752 | dev->dev_link_magic = SE_DEV_LINK_MAGIC; |
755 | dev->se_hba = hba; | 753 | dev->se_hba = hba; |
756 | dev->transport = hba->backend->ops; | 754 | dev->transport = hba->backend->ops; |
757 | dev->prot_length = sizeof(struct se_dif_v1_tuple); | 755 | dev->prot_length = sizeof(struct t10_pi_tuple); |
758 | dev->hba_index = hba->hba_index; | 756 | dev->hba_index = hba->hba_index; |
759 | 757 | ||
760 | INIT_LIST_HEAD(&dev->dev_list); | 758 | INIT_LIST_HEAD(&dev->dev_list); |
@@ -771,7 +769,6 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name) | |||
771 | spin_lock_init(&dev->se_tmr_lock); | 769 | spin_lock_init(&dev->se_tmr_lock); |
772 | spin_lock_init(&dev->qf_cmd_lock); | 770 | spin_lock_init(&dev->qf_cmd_lock); |
773 | sema_init(&dev->caw_sem, 1); | 771 | sema_init(&dev->caw_sem, 1); |
774 | atomic_set(&dev->dev_ordered_id, 0); | ||
775 | INIT_LIST_HEAD(&dev->t10_wwn.t10_vpd_list); | 772 | INIT_LIST_HEAD(&dev->t10_wwn.t10_vpd_list); |
776 | spin_lock_init(&dev->t10_wwn.t10_vpd_lock); | 773 | spin_lock_init(&dev->t10_wwn.t10_vpd_lock); |
777 | INIT_LIST_HEAD(&dev->t10_pr.registration_list); | 774 | INIT_LIST_HEAD(&dev->t10_pr.registration_list); |
diff --git a/drivers/target/target_core_fabric_configfs.c b/drivers/target/target_core_fabric_configfs.c index 48a36989c1a6..be42429468e2 100644 --- a/drivers/target/target_core_fabric_configfs.c +++ b/drivers/target/target_core_fabric_configfs.c | |||
@@ -203,7 +203,7 @@ static ssize_t target_fabric_mappedlun_store_write_protect( | |||
203 | pr_debug("%s_ConfigFS: Changed Initiator ACL: %s" | 203 | pr_debug("%s_ConfigFS: Changed Initiator ACL: %s" |
204 | " Mapped LUN: %llu Write Protect bit to %s\n", | 204 | " Mapped LUN: %llu Write Protect bit to %s\n", |
205 | se_tpg->se_tpg_tfo->get_fabric_name(), | 205 | se_tpg->se_tpg_tfo->get_fabric_name(), |
206 | lacl->initiatorname, lacl->mapped_lun, (op) ? "ON" : "OFF"); | 206 | se_nacl->initiatorname, lacl->mapped_lun, (op) ? "ON" : "OFF"); |
207 | 207 | ||
208 | return count; | 208 | return count; |
209 | 209 | ||
diff --git a/drivers/target/target_core_hba.c b/drivers/target/target_core_hba.c index be9cefc07407..9522960c7fdd 100644 --- a/drivers/target/target_core_hba.c +++ b/drivers/target/target_core_hba.c | |||
@@ -184,3 +184,8 @@ core_delete_hba(struct se_hba *hba) | |||
184 | kfree(hba); | 184 | kfree(hba); |
185 | return 0; | 185 | return 0; |
186 | } | 186 | } |
187 | |||
188 | bool target_sense_desc_format(struct se_device *dev) | ||
189 | { | ||
190 | return dev->transport->get_blocks(dev) > U32_MAX; | ||
191 | } | ||
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index e318ddbe15da..0b4b2a67d9f9 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c | |||
@@ -154,6 +154,38 @@ sbc_emulate_readcapacity_16(struct se_cmd *cmd) | |||
154 | return 0; | 154 | return 0; |
155 | } | 155 | } |
156 | 156 | ||
157 | static sense_reason_t | ||
158 | sbc_emulate_startstop(struct se_cmd *cmd) | ||
159 | { | ||
160 | unsigned char *cdb = cmd->t_task_cdb; | ||
161 | |||
162 | /* | ||
163 | * See sbc3r36 section 5.25 | ||
164 | * Immediate bit should be set since there is nothing to complete | ||
165 | * POWER CONDITION MODIFIER 0h | ||
166 | */ | ||
167 | if (!(cdb[1] & 1) || cdb[2] || cdb[3]) | ||
168 | return TCM_INVALID_CDB_FIELD; | ||
169 | |||
170 | /* | ||
171 | * See sbc3r36 section 5.25 | ||
172 | * POWER CONDITION 0h START_VALID - process START and LOEJ | ||
173 | */ | ||
174 | if (cdb[4] >> 4 & 0xf) | ||
175 | return TCM_INVALID_CDB_FIELD; | ||
176 | |||
177 | /* | ||
178 | * See sbc3r36 section 5.25 | ||
179 | * LOEJ 0h - nothing to load or unload | ||
180 | * START 1h - we are ready | ||
181 | */ | ||
182 | if (!(cdb[4] & 1) || (cdb[4] & 2) || (cdb[4] & 4)) | ||
183 | return TCM_INVALID_CDB_FIELD; | ||
184 | |||
185 | target_complete_cmd(cmd, SAM_STAT_GOOD); | ||
186 | return 0; | ||
187 | } | ||
188 | |||
157 | sector_t sbc_get_write_same_sectors(struct se_cmd *cmd) | 189 | sector_t sbc_get_write_same_sectors(struct se_cmd *cmd) |
158 | { | 190 | { |
159 | u32 num_blocks; | 191 | u32 num_blocks; |
@@ -960,6 +992,9 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) | |||
960 | " than 1\n", sectors); | 992 | " than 1\n", sectors); |
961 | return TCM_INVALID_CDB_FIELD; | 993 | return TCM_INVALID_CDB_FIELD; |
962 | } | 994 | } |
995 | if (sbc_check_dpofua(dev, cmd, cdb)) | ||
996 | return TCM_INVALID_CDB_FIELD; | ||
997 | |||
963 | /* | 998 | /* |
964 | * Double size because we have two buffers, note that | 999 | * Double size because we have two buffers, note that |
965 | * zero is not an error.. | 1000 | * zero is not an error.. |
@@ -1069,6 +1104,10 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) | |||
1069 | size = 0; | 1104 | size = 0; |
1070 | cmd->execute_cmd = sbc_emulate_noop; | 1105 | cmd->execute_cmd = sbc_emulate_noop; |
1071 | break; | 1106 | break; |
1107 | case START_STOP: | ||
1108 | size = 0; | ||
1109 | cmd->execute_cmd = sbc_emulate_startstop; | ||
1110 | break; | ||
1072 | default: | 1111 | default: |
1073 | ret = spc_parse_cdb(cmd, &size); | 1112 | ret = spc_parse_cdb(cmd, &size); |
1074 | if (ret) | 1113 | if (ret) |
@@ -1191,7 +1230,7 @@ void | |||
1191 | sbc_dif_generate(struct se_cmd *cmd) | 1230 | sbc_dif_generate(struct se_cmd *cmd) |
1192 | { | 1231 | { |
1193 | struct se_device *dev = cmd->se_dev; | 1232 | struct se_device *dev = cmd->se_dev; |
1194 | struct se_dif_v1_tuple *sdt; | 1233 | struct t10_pi_tuple *sdt; |
1195 | struct scatterlist *dsg = cmd->t_data_sg, *psg; | 1234 | struct scatterlist *dsg = cmd->t_data_sg, *psg; |
1196 | sector_t sector = cmd->t_task_lba; | 1235 | sector_t sector = cmd->t_task_lba; |
1197 | void *daddr, *paddr; | 1236 | void *daddr, *paddr; |
@@ -1203,7 +1242,7 @@ sbc_dif_generate(struct se_cmd *cmd) | |||
1203 | daddr = kmap_atomic(sg_page(dsg)) + dsg->offset; | 1242 | daddr = kmap_atomic(sg_page(dsg)) + dsg->offset; |
1204 | 1243 | ||
1205 | for (j = 0; j < psg->length; | 1244 | for (j = 0; j < psg->length; |
1206 | j += sizeof(struct se_dif_v1_tuple)) { | 1245 | j += sizeof(*sdt)) { |
1207 | __u16 crc; | 1246 | __u16 crc; |
1208 | unsigned int avail; | 1247 | unsigned int avail; |
1209 | 1248 | ||
@@ -1256,7 +1295,7 @@ sbc_dif_generate(struct se_cmd *cmd) | |||
1256 | } | 1295 | } |
1257 | 1296 | ||
1258 | static sense_reason_t | 1297 | static sense_reason_t |
1259 | sbc_dif_v1_verify(struct se_cmd *cmd, struct se_dif_v1_tuple *sdt, | 1298 | sbc_dif_v1_verify(struct se_cmd *cmd, struct t10_pi_tuple *sdt, |
1260 | __u16 crc, sector_t sector, unsigned int ei_lba) | 1299 | __u16 crc, sector_t sector, unsigned int ei_lba) |
1261 | { | 1300 | { |
1262 | __be16 csum; | 1301 | __be16 csum; |
@@ -1346,7 +1385,7 @@ sbc_dif_verify(struct se_cmd *cmd, sector_t start, unsigned int sectors, | |||
1346 | unsigned int ei_lba, struct scatterlist *psg, int psg_off) | 1385 | unsigned int ei_lba, struct scatterlist *psg, int psg_off) |
1347 | { | 1386 | { |
1348 | struct se_device *dev = cmd->se_dev; | 1387 | struct se_device *dev = cmd->se_dev; |
1349 | struct se_dif_v1_tuple *sdt; | 1388 | struct t10_pi_tuple *sdt; |
1350 | struct scatterlist *dsg = cmd->t_data_sg; | 1389 | struct scatterlist *dsg = cmd->t_data_sg; |
1351 | sector_t sector = start; | 1390 | sector_t sector = start; |
1352 | void *daddr, *paddr; | 1391 | void *daddr, *paddr; |
@@ -1361,7 +1400,7 @@ sbc_dif_verify(struct se_cmd *cmd, sector_t start, unsigned int sectors, | |||
1361 | 1400 | ||
1362 | for (i = psg_off; i < psg->length && | 1401 | for (i = psg_off; i < psg->length && |
1363 | sector < start + sectors; | 1402 | sector < start + sectors; |
1364 | i += sizeof(struct se_dif_v1_tuple)) { | 1403 | i += sizeof(*sdt)) { |
1365 | __u16 crc; | 1404 | __u16 crc; |
1366 | unsigned int avail; | 1405 | unsigned int avail; |
1367 | 1406 | ||
diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c index f87d4cef6d39..9413e1a949e5 100644 --- a/drivers/target/target_core_spc.c +++ b/drivers/target/target_core_spc.c | |||
@@ -484,8 +484,8 @@ static sense_reason_t | |||
484 | spc_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf) | 484 | spc_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf) |
485 | { | 485 | { |
486 | struct se_device *dev = cmd->se_dev; | 486 | struct se_device *dev = cmd->se_dev; |
487 | int have_tp = 0; | 487 | u32 mtl = 0; |
488 | int opt, min; | 488 | int have_tp = 0, opt, min; |
489 | 489 | ||
490 | /* | 490 | /* |
491 | * Following spc3r22 section 6.5.3 Block Limits VPD page, when | 491 | * Following spc3r22 section 6.5.3 Block Limits VPD page, when |
@@ -516,8 +516,15 @@ spc_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf) | |||
516 | 516 | ||
517 | /* | 517 | /* |
518 | * Set MAXIMUM TRANSFER LENGTH | 518 | * Set MAXIMUM TRANSFER LENGTH |
519 | * | ||
520 | * XXX: Currently assumes single PAGE_SIZE per scatterlist for fabrics | ||
521 | * enforcing maximum HW scatter-gather-list entry limit | ||
519 | */ | 522 | */ |
520 | put_unaligned_be32(dev->dev_attrib.hw_max_sectors, &buf[8]); | 523 | if (cmd->se_tfo->max_data_sg_nents) { |
524 | mtl = (cmd->se_tfo->max_data_sg_nents * PAGE_SIZE) / | ||
525 | dev->dev_attrib.block_size; | ||
526 | } | ||
527 | put_unaligned_be32(min_not_zero(mtl, dev->dev_attrib.hw_max_sectors), &buf[8]); | ||
521 | 528 | ||
522 | /* | 529 | /* |
523 | * Set OPTIMAL TRANSFER LENGTH | 530 | * Set OPTIMAL TRANSFER LENGTH |
@@ -768,7 +775,12 @@ static int spc_modesense_control(struct se_cmd *cmd, u8 pc, u8 *p) | |||
768 | if (pc == 1) | 775 | if (pc == 1) |
769 | goto out; | 776 | goto out; |
770 | 777 | ||
771 | p[2] = 2; | 778 | /* GLTSD: No implicit save of log parameters */ |
779 | p[2] = (1 << 1); | ||
780 | if (target_sense_desc_format(dev)) | ||
781 | /* D_SENSE: Descriptor format sense data for 64bit sectors */ | ||
782 | p[2] |= (1 << 2); | ||
783 | |||
772 | /* | 784 | /* |
773 | * From spc4r23, 7.4.7 Control mode page | 785 | * From spc4r23, 7.4.7 Control mode page |
774 | * | 786 | * |
@@ -1151,6 +1163,7 @@ static sense_reason_t spc_emulate_request_sense(struct se_cmd *cmd) | |||
1151 | unsigned char *rbuf; | 1163 | unsigned char *rbuf; |
1152 | u8 ua_asc = 0, ua_ascq = 0; | 1164 | u8 ua_asc = 0, ua_ascq = 0; |
1153 | unsigned char buf[SE_SENSE_BUF]; | 1165 | unsigned char buf[SE_SENSE_BUF]; |
1166 | bool desc_format = target_sense_desc_format(cmd->se_dev); | ||
1154 | 1167 | ||
1155 | memset(buf, 0, SE_SENSE_BUF); | 1168 | memset(buf, 0, SE_SENSE_BUF); |
1156 | 1169 | ||
@@ -1164,32 +1177,11 @@ static sense_reason_t spc_emulate_request_sense(struct se_cmd *cmd) | |||
1164 | if (!rbuf) | 1177 | if (!rbuf) |
1165 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 1178 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
1166 | 1179 | ||
1167 | if (!core_scsi3_ua_clear_for_request_sense(cmd, &ua_asc, &ua_ascq)) { | 1180 | if (!core_scsi3_ua_clear_for_request_sense(cmd, &ua_asc, &ua_ascq)) |
1168 | /* | 1181 | scsi_build_sense_buffer(desc_format, buf, UNIT_ATTENTION, |
1169 | * CURRENT ERROR, UNIT ATTENTION | 1182 | ua_asc, ua_ascq); |
1170 | */ | 1183 | else |
1171 | buf[0] = 0x70; | 1184 | scsi_build_sense_buffer(desc_format, buf, NO_SENSE, 0x0, 0x0); |
1172 | buf[SPC_SENSE_KEY_OFFSET] = UNIT_ATTENTION; | ||
1173 | |||
1174 | /* | ||
1175 | * The Additional Sense Code (ASC) from the UNIT ATTENTION | ||
1176 | */ | ||
1177 | buf[SPC_ASC_KEY_OFFSET] = ua_asc; | ||
1178 | buf[SPC_ASCQ_KEY_OFFSET] = ua_ascq; | ||
1179 | buf[7] = 0x0A; | ||
1180 | } else { | ||
1181 | /* | ||
1182 | * CURRENT ERROR, NO SENSE | ||
1183 | */ | ||
1184 | buf[0] = 0x70; | ||
1185 | buf[SPC_SENSE_KEY_OFFSET] = NO_SENSE; | ||
1186 | |||
1187 | /* | ||
1188 | * NO ADDITIONAL SENSE INFORMATION | ||
1189 | */ | ||
1190 | buf[SPC_ASC_KEY_OFFSET] = 0x00; | ||
1191 | buf[7] = 0x0A; | ||
1192 | } | ||
1193 | 1185 | ||
1194 | memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); | 1186 | memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); |
1195 | transport_kunmap_data_sg(cmd); | 1187 | transport_kunmap_data_sg(cmd); |
@@ -1418,9 +1410,6 @@ spc_parse_cdb(struct se_cmd *cmd, unsigned int *size) | |||
1418 | } | 1410 | } |
1419 | break; | 1411 | break; |
1420 | default: | 1412 | default: |
1421 | pr_warn("TARGET_CORE[%s]: Unsupported SCSI Opcode" | ||
1422 | " 0x%02x, sending CHECK_CONDITION.\n", | ||
1423 | cmd->se_tfo->get_fabric_name(), cdb[0]); | ||
1424 | return TCM_UNSUPPORTED_SCSI_OPCODE; | 1413 | return TCM_UNSUPPORTED_SCSI_OPCODE; |
1425 | } | 1414 | } |
1426 | 1415 | ||
diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c index babde4ad841f..2d0381dd105c 100644 --- a/drivers/target/target_core_tpg.c +++ b/drivers/target/target_core_tpg.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include "target_core_internal.h" | 41 | #include "target_core_internal.h" |
42 | #include "target_core_alua.h" | 42 | #include "target_core_alua.h" |
43 | #include "target_core_pr.h" | 43 | #include "target_core_pr.h" |
44 | #include "target_core_ua.h" | ||
44 | 45 | ||
45 | extern struct se_device *g_lun0_dev; | 46 | extern struct se_device *g_lun0_dev; |
46 | 47 | ||
@@ -83,6 +84,22 @@ struct se_node_acl *core_tpg_get_initiator_node_acl( | |||
83 | } | 84 | } |
84 | EXPORT_SYMBOL(core_tpg_get_initiator_node_acl); | 85 | EXPORT_SYMBOL(core_tpg_get_initiator_node_acl); |
85 | 86 | ||
87 | void core_allocate_nexus_loss_ua( | ||
88 | struct se_node_acl *nacl) | ||
89 | { | ||
90 | struct se_dev_entry *deve; | ||
91 | |||
92 | if (!nacl) | ||
93 | return; | ||
94 | |||
95 | rcu_read_lock(); | ||
96 | hlist_for_each_entry_rcu(deve, &nacl->lun_entry_hlist, link) | ||
97 | core_scsi3_ua_allocate(deve, 0x29, | ||
98 | ASCQ_29H_NEXUS_LOSS_OCCURRED); | ||
99 | rcu_read_unlock(); | ||
100 | } | ||
101 | EXPORT_SYMBOL(core_allocate_nexus_loss_ua); | ||
102 | |||
86 | /* core_tpg_add_node_to_devs(): | 103 | /* core_tpg_add_node_to_devs(): |
87 | * | 104 | * |
88 | * | 105 | * |
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index ce8574b7220c..5bacc7b5ed6d 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <net/sock.h> | 39 | #include <net/sock.h> |
40 | #include <net/tcp.h> | 40 | #include <net/tcp.h> |
41 | #include <scsi/scsi_proto.h> | 41 | #include <scsi/scsi_proto.h> |
42 | #include <scsi/scsi_common.h> | ||
42 | 43 | ||
43 | #include <target/target_core_base.h> | 44 | #include <target/target_core_base.h> |
44 | #include <target/target_core_backend.h> | 45 | #include <target/target_core_backend.h> |
@@ -1074,6 +1075,55 @@ transport_set_vpd_ident(struct t10_vpd *vpd, unsigned char *page_83) | |||
1074 | } | 1075 | } |
1075 | EXPORT_SYMBOL(transport_set_vpd_ident); | 1076 | EXPORT_SYMBOL(transport_set_vpd_ident); |
1076 | 1077 | ||
1078 | static sense_reason_t | ||
1079 | target_check_max_data_sg_nents(struct se_cmd *cmd, struct se_device *dev, | ||
1080 | unsigned int size) | ||
1081 | { | ||
1082 | u32 mtl; | ||
1083 | |||
1084 | if (!cmd->se_tfo->max_data_sg_nents) | ||
1085 | return TCM_NO_SENSE; | ||
1086 | /* | ||
1087 | * Check if fabric enforced maximum SGL entries per I/O descriptor | ||
1088 | * exceeds se_cmd->data_length. If true, set SCF_UNDERFLOW_BIT + | ||
1089 | * residual_count and reduce original cmd->data_length to maximum | ||
1090 | * length based on single PAGE_SIZE entry scatter-lists. | ||
1091 | */ | ||
1092 | mtl = (cmd->se_tfo->max_data_sg_nents * PAGE_SIZE); | ||
1093 | if (cmd->data_length > mtl) { | ||
1094 | /* | ||
1095 | * If an existing CDB overflow is present, calculate new residual | ||
1096 | * based on CDB size minus fabric maximum transfer length. | ||
1097 | * | ||
1098 | * If an existing CDB underflow is present, calculate new residual | ||
1099 | * based on original cmd->data_length minus fabric maximum transfer | ||
1100 | * length. | ||
1101 | * | ||
1102 | * Otherwise, set the underflow residual based on cmd->data_length | ||
1103 | * minus fabric maximum transfer length. | ||
1104 | */ | ||
1105 | if (cmd->se_cmd_flags & SCF_OVERFLOW_BIT) { | ||
1106 | cmd->residual_count = (size - mtl); | ||
1107 | } else if (cmd->se_cmd_flags & SCF_UNDERFLOW_BIT) { | ||
1108 | u32 orig_dl = size + cmd->residual_count; | ||
1109 | cmd->residual_count = (orig_dl - mtl); | ||
1110 | } else { | ||
1111 | cmd->se_cmd_flags |= SCF_UNDERFLOW_BIT; | ||
1112 | cmd->residual_count = (cmd->data_length - mtl); | ||
1113 | } | ||
1114 | cmd->data_length = mtl; | ||
1115 | /* | ||
1116 | * Reset sbc_check_prot() calculated protection payload | ||
1117 | * length based upon the new smaller MTL. | ||
1118 | */ | ||
1119 | if (cmd->prot_length) { | ||
1120 | u32 sectors = (mtl / dev->dev_attrib.block_size); | ||
1121 | cmd->prot_length = dev->prot_length * sectors; | ||
1122 | } | ||
1123 | } | ||
1124 | return TCM_NO_SENSE; | ||
1125 | } | ||
1126 | |||
1077 | sense_reason_t | 1127 | sense_reason_t |
1078 | target_cmd_size_check(struct se_cmd *cmd, unsigned int size) | 1128 | target_cmd_size_check(struct se_cmd *cmd, unsigned int size) |
1079 | { | 1129 | { |
@@ -1087,9 +1137,9 @@ target_cmd_size_check(struct se_cmd *cmd, unsigned int size) | |||
1087 | " 0x%02x\n", cmd->se_tfo->get_fabric_name(), | 1137 | " 0x%02x\n", cmd->se_tfo->get_fabric_name(), |
1088 | cmd->data_length, size, cmd->t_task_cdb[0]); | 1138 | cmd->data_length, size, cmd->t_task_cdb[0]); |
1089 | 1139 | ||
1090 | if (cmd->data_direction == DMA_TO_DEVICE) { | 1140 | if (cmd->data_direction == DMA_TO_DEVICE && |
1091 | pr_err("Rejecting underflow/overflow" | 1141 | cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) { |
1092 | " WRITE data\n"); | 1142 | pr_err("Rejecting underflow/overflow WRITE data\n"); |
1093 | return TCM_INVALID_CDB_FIELD; | 1143 | return TCM_INVALID_CDB_FIELD; |
1094 | } | 1144 | } |
1095 | /* | 1145 | /* |
@@ -1119,7 +1169,7 @@ target_cmd_size_check(struct se_cmd *cmd, unsigned int size) | |||
1119 | } | 1169 | } |
1120 | } | 1170 | } |
1121 | 1171 | ||
1122 | return 0; | 1172 | return target_check_max_data_sg_nents(cmd, dev, size); |
1123 | 1173 | ||
1124 | } | 1174 | } |
1125 | 1175 | ||
@@ -1177,14 +1227,7 @@ transport_check_alloc_task_attr(struct se_cmd *cmd) | |||
1177 | " emulation is not supported\n"); | 1227 | " emulation is not supported\n"); |
1178 | return TCM_INVALID_CDB_FIELD; | 1228 | return TCM_INVALID_CDB_FIELD; |
1179 | } | 1229 | } |
1180 | /* | 1230 | |
1181 | * Used to determine when ORDERED commands should go from | ||
1182 | * Dormant to Active status. | ||
1183 | */ | ||
1184 | cmd->se_ordered_id = atomic_inc_return(&dev->dev_ordered_id); | ||
1185 | pr_debug("Allocated se_ordered_id: %u for Task Attr: 0x%02x on %s\n", | ||
1186 | cmd->se_ordered_id, cmd->sam_task_attr, | ||
1187 | dev->transport->name); | ||
1188 | return 0; | 1231 | return 0; |
1189 | } | 1232 | } |
1190 | 1233 | ||
@@ -1246,6 +1289,11 @@ target_setup_cmd_from_cdb(struct se_cmd *cmd, unsigned char *cdb) | |||
1246 | } | 1289 | } |
1247 | 1290 | ||
1248 | ret = dev->transport->parse_cdb(cmd); | 1291 | ret = dev->transport->parse_cdb(cmd); |
1292 | if (ret == TCM_UNSUPPORTED_SCSI_OPCODE) | ||
1293 | pr_warn_ratelimited("%s/%s: Unsupported SCSI Opcode 0x%02x, sending CHECK_CONDITION.\n", | ||
1294 | cmd->se_tfo->get_fabric_name(), | ||
1295 | cmd->se_sess->se_node_acl->initiatorname, | ||
1296 | cmd->t_task_cdb[0]); | ||
1249 | if (ret) | 1297 | if (ret) |
1250 | return ret; | 1298 | return ret; |
1251 | 1299 | ||
@@ -1693,8 +1741,7 @@ void transport_generic_request_failure(struct se_cmd *cmd, | |||
1693 | 1741 | ||
1694 | check_stop: | 1742 | check_stop: |
1695 | transport_lun_remove_cmd(cmd); | 1743 | transport_lun_remove_cmd(cmd); |
1696 | if (!transport_cmd_check_stop_to_fabric(cmd)) | 1744 | transport_cmd_check_stop_to_fabric(cmd); |
1697 | ; | ||
1698 | return; | 1745 | return; |
1699 | 1746 | ||
1700 | queue_full: | 1747 | queue_full: |
@@ -1767,16 +1814,14 @@ static bool target_handle_task_attr(struct se_cmd *cmd) | |||
1767 | */ | 1814 | */ |
1768 | switch (cmd->sam_task_attr) { | 1815 | switch (cmd->sam_task_attr) { |
1769 | case TCM_HEAD_TAG: | 1816 | case TCM_HEAD_TAG: |
1770 | pr_debug("Added HEAD_OF_QUEUE for CDB: 0x%02x, " | 1817 | pr_debug("Added HEAD_OF_QUEUE for CDB: 0x%02x\n", |
1771 | "se_ordered_id: %u\n", | 1818 | cmd->t_task_cdb[0]); |
1772 | cmd->t_task_cdb[0], cmd->se_ordered_id); | ||
1773 | return false; | 1819 | return false; |
1774 | case TCM_ORDERED_TAG: | 1820 | case TCM_ORDERED_TAG: |
1775 | atomic_inc_mb(&dev->dev_ordered_sync); | 1821 | atomic_inc_mb(&dev->dev_ordered_sync); |
1776 | 1822 | ||
1777 | pr_debug("Added ORDERED for CDB: 0x%02x to ordered list, " | 1823 | pr_debug("Added ORDERED for CDB: 0x%02x to ordered list\n", |
1778 | " se_ordered_id: %u\n", | 1824 | cmd->t_task_cdb[0]); |
1779 | cmd->t_task_cdb[0], cmd->se_ordered_id); | ||
1780 | 1825 | ||
1781 | /* | 1826 | /* |
1782 | * Execute an ORDERED command if no other older commands | 1827 | * Execute an ORDERED command if no other older commands |
@@ -1800,10 +1845,8 @@ static bool target_handle_task_attr(struct se_cmd *cmd) | |||
1800 | list_add_tail(&cmd->se_delayed_node, &dev->delayed_cmd_list); | 1845 | list_add_tail(&cmd->se_delayed_node, &dev->delayed_cmd_list); |
1801 | spin_unlock(&dev->delayed_cmd_lock); | 1846 | spin_unlock(&dev->delayed_cmd_lock); |
1802 | 1847 | ||
1803 | pr_debug("Added CDB: 0x%02x Task Attr: 0x%02x to" | 1848 | pr_debug("Added CDB: 0x%02x Task Attr: 0x%02x to delayed CMD listn", |
1804 | " delayed CMD list, se_ordered_id: %u\n", | 1849 | cmd->t_task_cdb[0], cmd->sam_task_attr); |
1805 | cmd->t_task_cdb[0], cmd->sam_task_attr, | ||
1806 | cmd->se_ordered_id); | ||
1807 | return true; | 1850 | return true; |
1808 | } | 1851 | } |
1809 | 1852 | ||
@@ -1888,20 +1931,18 @@ static void transport_complete_task_attr(struct se_cmd *cmd) | |||
1888 | if (cmd->sam_task_attr == TCM_SIMPLE_TAG) { | 1931 | if (cmd->sam_task_attr == TCM_SIMPLE_TAG) { |
1889 | atomic_dec_mb(&dev->simple_cmds); | 1932 | atomic_dec_mb(&dev->simple_cmds); |
1890 | dev->dev_cur_ordered_id++; | 1933 | dev->dev_cur_ordered_id++; |
1891 | pr_debug("Incremented dev->dev_cur_ordered_id: %u for" | 1934 | pr_debug("Incremented dev->dev_cur_ordered_id: %u for SIMPLE\n", |
1892 | " SIMPLE: %u\n", dev->dev_cur_ordered_id, | 1935 | dev->dev_cur_ordered_id); |
1893 | cmd->se_ordered_id); | ||
1894 | } else if (cmd->sam_task_attr == TCM_HEAD_TAG) { | 1936 | } else if (cmd->sam_task_attr == TCM_HEAD_TAG) { |
1895 | dev->dev_cur_ordered_id++; | 1937 | dev->dev_cur_ordered_id++; |
1896 | pr_debug("Incremented dev_cur_ordered_id: %u for" | 1938 | pr_debug("Incremented dev_cur_ordered_id: %u for HEAD_OF_QUEUE\n", |
1897 | " HEAD_OF_QUEUE: %u\n", dev->dev_cur_ordered_id, | 1939 | dev->dev_cur_ordered_id); |
1898 | cmd->se_ordered_id); | ||
1899 | } else if (cmd->sam_task_attr == TCM_ORDERED_TAG) { | 1940 | } else if (cmd->sam_task_attr == TCM_ORDERED_TAG) { |
1900 | atomic_dec_mb(&dev->dev_ordered_sync); | 1941 | atomic_dec_mb(&dev->dev_ordered_sync); |
1901 | 1942 | ||
1902 | dev->dev_cur_ordered_id++; | 1943 | dev->dev_cur_ordered_id++; |
1903 | pr_debug("Incremented dev_cur_ordered_id: %u for ORDERED:" | 1944 | pr_debug("Incremented dev_cur_ordered_id: %u for ORDERED\n", |
1904 | " %u\n", dev->dev_cur_ordered_id, cmd->se_ordered_id); | 1945 | dev->dev_cur_ordered_id); |
1905 | } | 1946 | } |
1906 | 1947 | ||
1907 | target_restart_delayed_cmds(dev); | 1948 | target_restart_delayed_cmds(dev); |
@@ -2615,37 +2656,159 @@ bool transport_wait_for_tasks(struct se_cmd *cmd) | |||
2615 | } | 2656 | } |
2616 | EXPORT_SYMBOL(transport_wait_for_tasks); | 2657 | EXPORT_SYMBOL(transport_wait_for_tasks); |
2617 | 2658 | ||
2618 | static int transport_get_sense_codes( | 2659 | struct sense_info { |
2619 | struct se_cmd *cmd, | 2660 | u8 key; |
2620 | u8 *asc, | 2661 | u8 asc; |
2621 | u8 *ascq) | 2662 | u8 ascq; |
2663 | bool add_sector_info; | ||
2664 | }; | ||
2665 | |||
2666 | static const struct sense_info sense_info_table[] = { | ||
2667 | [TCM_NO_SENSE] = { | ||
2668 | .key = NOT_READY | ||
2669 | }, | ||
2670 | [TCM_NON_EXISTENT_LUN] = { | ||
2671 | .key = ILLEGAL_REQUEST, | ||
2672 | .asc = 0x25 /* LOGICAL UNIT NOT SUPPORTED */ | ||
2673 | }, | ||
2674 | [TCM_UNSUPPORTED_SCSI_OPCODE] = { | ||
2675 | .key = ILLEGAL_REQUEST, | ||
2676 | .asc = 0x20, /* INVALID COMMAND OPERATION CODE */ | ||
2677 | }, | ||
2678 | [TCM_SECTOR_COUNT_TOO_MANY] = { | ||
2679 | .key = ILLEGAL_REQUEST, | ||
2680 | .asc = 0x20, /* INVALID COMMAND OPERATION CODE */ | ||
2681 | }, | ||
2682 | [TCM_UNKNOWN_MODE_PAGE] = { | ||
2683 | .key = ILLEGAL_REQUEST, | ||
2684 | .asc = 0x24, /* INVALID FIELD IN CDB */ | ||
2685 | }, | ||
2686 | [TCM_CHECK_CONDITION_ABORT_CMD] = { | ||
2687 | .key = ABORTED_COMMAND, | ||
2688 | .asc = 0x29, /* BUS DEVICE RESET FUNCTION OCCURRED */ | ||
2689 | .ascq = 0x03, | ||
2690 | }, | ||
2691 | [TCM_INCORRECT_AMOUNT_OF_DATA] = { | ||
2692 | .key = ABORTED_COMMAND, | ||
2693 | .asc = 0x0c, /* WRITE ERROR */ | ||
2694 | .ascq = 0x0d, /* NOT ENOUGH UNSOLICITED DATA */ | ||
2695 | }, | ||
2696 | [TCM_INVALID_CDB_FIELD] = { | ||
2697 | .key = ILLEGAL_REQUEST, | ||
2698 | .asc = 0x24, /* INVALID FIELD IN CDB */ | ||
2699 | }, | ||
2700 | [TCM_INVALID_PARAMETER_LIST] = { | ||
2701 | .key = ILLEGAL_REQUEST, | ||
2702 | .asc = 0x26, /* INVALID FIELD IN PARAMETER LIST */ | ||
2703 | }, | ||
2704 | [TCM_PARAMETER_LIST_LENGTH_ERROR] = { | ||
2705 | .key = ILLEGAL_REQUEST, | ||
2706 | .asc = 0x1a, /* PARAMETER LIST LENGTH ERROR */ | ||
2707 | }, | ||
2708 | [TCM_UNEXPECTED_UNSOLICITED_DATA] = { | ||
2709 | .key = ILLEGAL_REQUEST, | ||
2710 | .asc = 0x0c, /* WRITE ERROR */ | ||
2711 | .ascq = 0x0c, /* UNEXPECTED_UNSOLICITED_DATA */ | ||
2712 | }, | ||
2713 | [TCM_SERVICE_CRC_ERROR] = { | ||
2714 | .key = ABORTED_COMMAND, | ||
2715 | .asc = 0x47, /* PROTOCOL SERVICE CRC ERROR */ | ||
2716 | .ascq = 0x05, /* N/A */ | ||
2717 | }, | ||
2718 | [TCM_SNACK_REJECTED] = { | ||
2719 | .key = ABORTED_COMMAND, | ||
2720 | .asc = 0x11, /* READ ERROR */ | ||
2721 | .ascq = 0x13, /* FAILED RETRANSMISSION REQUEST */ | ||
2722 | }, | ||
2723 | [TCM_WRITE_PROTECTED] = { | ||
2724 | .key = DATA_PROTECT, | ||
2725 | .asc = 0x27, /* WRITE PROTECTED */ | ||
2726 | }, | ||
2727 | [TCM_ADDRESS_OUT_OF_RANGE] = { | ||
2728 | .key = ILLEGAL_REQUEST, | ||
2729 | .asc = 0x21, /* LOGICAL BLOCK ADDRESS OUT OF RANGE */ | ||
2730 | }, | ||
2731 | [TCM_CHECK_CONDITION_UNIT_ATTENTION] = { | ||
2732 | .key = UNIT_ATTENTION, | ||
2733 | }, | ||
2734 | [TCM_CHECK_CONDITION_NOT_READY] = { | ||
2735 | .key = NOT_READY, | ||
2736 | }, | ||
2737 | [TCM_MISCOMPARE_VERIFY] = { | ||
2738 | .key = MISCOMPARE, | ||
2739 | .asc = 0x1d, /* MISCOMPARE DURING VERIFY OPERATION */ | ||
2740 | .ascq = 0x00, | ||
2741 | }, | ||
2742 | [TCM_LOGICAL_BLOCK_GUARD_CHECK_FAILED] = { | ||
2743 | .key = ABORTED_COMMAND, | ||
2744 | .asc = 0x10, | ||
2745 | .ascq = 0x01, /* LOGICAL BLOCK GUARD CHECK FAILED */ | ||
2746 | .add_sector_info = true, | ||
2747 | }, | ||
2748 | [TCM_LOGICAL_BLOCK_APP_TAG_CHECK_FAILED] = { | ||
2749 | .key = ABORTED_COMMAND, | ||
2750 | .asc = 0x10, | ||
2751 | .ascq = 0x02, /* LOGICAL BLOCK APPLICATION TAG CHECK FAILED */ | ||
2752 | .add_sector_info = true, | ||
2753 | }, | ||
2754 | [TCM_LOGICAL_BLOCK_REF_TAG_CHECK_FAILED] = { | ||
2755 | .key = ABORTED_COMMAND, | ||
2756 | .asc = 0x10, | ||
2757 | .ascq = 0x03, /* LOGICAL BLOCK REFERENCE TAG CHECK FAILED */ | ||
2758 | .add_sector_info = true, | ||
2759 | }, | ||
2760 | [TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE] = { | ||
2761 | /* | ||
2762 | * Returning ILLEGAL REQUEST would cause immediate IO errors on | ||
2763 | * Solaris initiators. Returning NOT READY instead means the | ||
2764 | * operations will be retried a finite number of times and we | ||
2765 | * can survive intermittent errors. | ||
2766 | */ | ||
2767 | .key = NOT_READY, | ||
2768 | .asc = 0x08, /* LOGICAL UNIT COMMUNICATION FAILURE */ | ||
2769 | }, | ||
2770 | }; | ||
2771 | |||
2772 | static int translate_sense_reason(struct se_cmd *cmd, sense_reason_t reason) | ||
2622 | { | 2773 | { |
2623 | *asc = cmd->scsi_asc; | 2774 | const struct sense_info *si; |
2624 | *ascq = cmd->scsi_ascq; | 2775 | u8 *buffer = cmd->sense_buffer; |
2776 | int r = (__force int)reason; | ||
2777 | u8 asc, ascq; | ||
2778 | bool desc_format = target_sense_desc_format(cmd->se_dev); | ||
2625 | 2779 | ||
2626 | return 0; | 2780 | if (r < ARRAY_SIZE(sense_info_table) && sense_info_table[r].key) |
2627 | } | 2781 | si = &sense_info_table[r]; |
2782 | else | ||
2783 | si = &sense_info_table[(__force int) | ||
2784 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE]; | ||
2628 | 2785 | ||
2629 | static | 2786 | if (reason == TCM_CHECK_CONDITION_UNIT_ATTENTION) { |
2630 | void transport_err_sector_info(unsigned char *buffer, sector_t bad_sector) | 2787 | core_scsi3_ua_for_check_condition(cmd, &asc, &ascq); |
2631 | { | 2788 | WARN_ON_ONCE(asc == 0); |
2632 | /* Place failed LBA in sense data information descriptor 0. */ | 2789 | } else if (si->asc == 0) { |
2633 | buffer[SPC_ADD_SENSE_LEN_OFFSET] = 0xc; | 2790 | WARN_ON_ONCE(cmd->scsi_asc == 0); |
2634 | buffer[SPC_DESC_TYPE_OFFSET] = 0; /* Information */ | 2791 | asc = cmd->scsi_asc; |
2635 | buffer[SPC_ADDITIONAL_DESC_LEN_OFFSET] = 0xa; | 2792 | ascq = cmd->scsi_ascq; |
2636 | buffer[SPC_VALIDITY_OFFSET] = 0x80; | 2793 | } else { |
2794 | asc = si->asc; | ||
2795 | ascq = si->ascq; | ||
2796 | } | ||
2797 | |||
2798 | scsi_build_sense_buffer(desc_format, buffer, si->key, asc, ascq); | ||
2799 | if (si->add_sector_info) | ||
2800 | return scsi_set_sense_information(buffer, | ||
2801 | cmd->scsi_sense_length, | ||
2802 | cmd->bad_sector); | ||
2637 | 2803 | ||
2638 | /* Descriptor Information: failing sector */ | 2804 | return 0; |
2639 | put_unaligned_be64(bad_sector, &buffer[12]); | ||
2640 | } | 2805 | } |
2641 | 2806 | ||
2642 | int | 2807 | int |
2643 | transport_send_check_condition_and_sense(struct se_cmd *cmd, | 2808 | transport_send_check_condition_and_sense(struct se_cmd *cmd, |
2644 | sense_reason_t reason, int from_transport) | 2809 | sense_reason_t reason, int from_transport) |
2645 | { | 2810 | { |
2646 | unsigned char *buffer = cmd->sense_buffer; | ||
2647 | unsigned long flags; | 2811 | unsigned long flags; |
2648 | u8 asc = 0, ascq = 0; | ||
2649 | 2812 | ||
2650 | spin_lock_irqsave(&cmd->t_state_lock, flags); | 2813 | spin_lock_irqsave(&cmd->t_state_lock, flags); |
2651 | if (cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION) { | 2814 | if (cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION) { |
@@ -2655,243 +2818,17 @@ transport_send_check_condition_and_sense(struct se_cmd *cmd, | |||
2655 | cmd->se_cmd_flags |= SCF_SENT_CHECK_CONDITION; | 2818 | cmd->se_cmd_flags |= SCF_SENT_CHECK_CONDITION; |
2656 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | 2819 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); |
2657 | 2820 | ||
2658 | if (!reason && from_transport) | 2821 | if (!from_transport) { |
2659 | goto after_reason; | 2822 | int rc; |
2660 | 2823 | ||
2661 | if (!from_transport) | ||
2662 | cmd->se_cmd_flags |= SCF_EMULATED_TASK_SENSE; | 2824 | cmd->se_cmd_flags |= SCF_EMULATED_TASK_SENSE; |
2663 | 2825 | cmd->scsi_status = SAM_STAT_CHECK_CONDITION; | |
2664 | /* | 2826 | cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER; |
2665 | * Actual SENSE DATA, see SPC-3 7.23.2 SPC_SENSE_KEY_OFFSET uses | 2827 | rc = translate_sense_reason(cmd, reason); |
2666 | * SENSE KEY values from include/scsi/scsi.h | 2828 | if (rc) |
2667 | */ | 2829 | return rc; |
2668 | switch (reason) { | ||
2669 | case TCM_NO_SENSE: | ||
2670 | /* CURRENT ERROR */ | ||
2671 | buffer[0] = 0x70; | ||
2672 | buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; | ||
2673 | /* Not Ready */ | ||
2674 | buffer[SPC_SENSE_KEY_OFFSET] = NOT_READY; | ||
2675 | /* NO ADDITIONAL SENSE INFORMATION */ | ||
2676 | buffer[SPC_ASC_KEY_OFFSET] = 0; | ||
2677 | buffer[SPC_ASCQ_KEY_OFFSET] = 0; | ||
2678 | break; | ||
2679 | case TCM_NON_EXISTENT_LUN: | ||
2680 | /* CURRENT ERROR */ | ||
2681 | buffer[0] = 0x70; | ||
2682 | buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; | ||
2683 | /* ILLEGAL REQUEST */ | ||
2684 | buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; | ||
2685 | /* LOGICAL UNIT NOT SUPPORTED */ | ||
2686 | buffer[SPC_ASC_KEY_OFFSET] = 0x25; | ||
2687 | break; | ||
2688 | case TCM_UNSUPPORTED_SCSI_OPCODE: | ||
2689 | case TCM_SECTOR_COUNT_TOO_MANY: | ||
2690 | /* CURRENT ERROR */ | ||
2691 | buffer[0] = 0x70; | ||
2692 | buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; | ||
2693 | /* ILLEGAL REQUEST */ | ||
2694 | buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; | ||
2695 | /* INVALID COMMAND OPERATION CODE */ | ||
2696 | buffer[SPC_ASC_KEY_OFFSET] = 0x20; | ||
2697 | break; | ||
2698 | case TCM_UNKNOWN_MODE_PAGE: | ||
2699 | /* CURRENT ERROR */ | ||
2700 | buffer[0] = 0x70; | ||
2701 | buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; | ||
2702 | /* ILLEGAL REQUEST */ | ||
2703 | buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; | ||
2704 | /* INVALID FIELD IN CDB */ | ||
2705 | buffer[SPC_ASC_KEY_OFFSET] = 0x24; | ||
2706 | break; | ||
2707 | case TCM_CHECK_CONDITION_ABORT_CMD: | ||
2708 | /* CURRENT ERROR */ | ||
2709 | buffer[0] = 0x70; | ||
2710 | buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; | ||
2711 | /* ABORTED COMMAND */ | ||
2712 | buffer[SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND; | ||
2713 | /* BUS DEVICE RESET FUNCTION OCCURRED */ | ||
2714 | buffer[SPC_ASC_KEY_OFFSET] = 0x29; | ||
2715 | buffer[SPC_ASCQ_KEY_OFFSET] = 0x03; | ||
2716 | break; | ||
2717 | case TCM_INCORRECT_AMOUNT_OF_DATA: | ||
2718 | /* CURRENT ERROR */ | ||
2719 | buffer[0] = 0x70; | ||
2720 | buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; | ||
2721 | /* ABORTED COMMAND */ | ||
2722 | buffer[SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND; | ||
2723 | /* WRITE ERROR */ | ||
2724 | buffer[SPC_ASC_KEY_OFFSET] = 0x0c; | ||
2725 | /* NOT ENOUGH UNSOLICITED DATA */ | ||
2726 | buffer[SPC_ASCQ_KEY_OFFSET] = 0x0d; | ||
2727 | break; | ||
2728 | case TCM_INVALID_CDB_FIELD: | ||
2729 | /* CURRENT ERROR */ | ||
2730 | buffer[0] = 0x70; | ||
2731 | buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; | ||
2732 | /* ILLEGAL REQUEST */ | ||
2733 | buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; | ||
2734 | /* INVALID FIELD IN CDB */ | ||
2735 | buffer[SPC_ASC_KEY_OFFSET] = 0x24; | ||
2736 | break; | ||
2737 | case TCM_INVALID_PARAMETER_LIST: | ||
2738 | /* CURRENT ERROR */ | ||
2739 | buffer[0] = 0x70; | ||
2740 | buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; | ||
2741 | /* ILLEGAL REQUEST */ | ||
2742 | buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; | ||
2743 | /* INVALID FIELD IN PARAMETER LIST */ | ||
2744 | buffer[SPC_ASC_KEY_OFFSET] = 0x26; | ||
2745 | break; | ||
2746 | case TCM_PARAMETER_LIST_LENGTH_ERROR: | ||
2747 | /* CURRENT ERROR */ | ||
2748 | buffer[0] = 0x70; | ||
2749 | buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; | ||
2750 | /* ILLEGAL REQUEST */ | ||
2751 | buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; | ||
2752 | /* PARAMETER LIST LENGTH ERROR */ | ||
2753 | buffer[SPC_ASC_KEY_OFFSET] = 0x1a; | ||
2754 | break; | ||
2755 | case TCM_UNEXPECTED_UNSOLICITED_DATA: | ||
2756 | /* CURRENT ERROR */ | ||
2757 | buffer[0] = 0x70; | ||
2758 | buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; | ||
2759 | /* ABORTED COMMAND */ | ||
2760 | buffer[SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND; | ||
2761 | /* WRITE ERROR */ | ||
2762 | buffer[SPC_ASC_KEY_OFFSET] = 0x0c; | ||
2763 | /* UNEXPECTED_UNSOLICITED_DATA */ | ||
2764 | buffer[SPC_ASCQ_KEY_OFFSET] = 0x0c; | ||
2765 | break; | ||
2766 | case TCM_SERVICE_CRC_ERROR: | ||
2767 | /* CURRENT ERROR */ | ||
2768 | buffer[0] = 0x70; | ||
2769 | buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; | ||
2770 | /* ABORTED COMMAND */ | ||
2771 | buffer[SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND; | ||
2772 | /* PROTOCOL SERVICE CRC ERROR */ | ||
2773 | buffer[SPC_ASC_KEY_OFFSET] = 0x47; | ||
2774 | /* N/A */ | ||
2775 | buffer[SPC_ASCQ_KEY_OFFSET] = 0x05; | ||
2776 | break; | ||
2777 | case TCM_SNACK_REJECTED: | ||
2778 | /* CURRENT ERROR */ | ||
2779 | buffer[0] = 0x70; | ||
2780 | buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; | ||
2781 | /* ABORTED COMMAND */ | ||
2782 | buffer[SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND; | ||
2783 | /* READ ERROR */ | ||
2784 | buffer[SPC_ASC_KEY_OFFSET] = 0x11; | ||
2785 | /* FAILED RETRANSMISSION REQUEST */ | ||
2786 | buffer[SPC_ASCQ_KEY_OFFSET] = 0x13; | ||
2787 | break; | ||
2788 | case TCM_WRITE_PROTECTED: | ||
2789 | /* CURRENT ERROR */ | ||
2790 | buffer[0] = 0x70; | ||
2791 | buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; | ||
2792 | /* DATA PROTECT */ | ||
2793 | buffer[SPC_SENSE_KEY_OFFSET] = DATA_PROTECT; | ||
2794 | /* WRITE PROTECTED */ | ||
2795 | buffer[SPC_ASC_KEY_OFFSET] = 0x27; | ||
2796 | break; | ||
2797 | case TCM_ADDRESS_OUT_OF_RANGE: | ||
2798 | /* CURRENT ERROR */ | ||
2799 | buffer[0] = 0x70; | ||
2800 | buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; | ||
2801 | /* ILLEGAL REQUEST */ | ||
2802 | buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; | ||
2803 | /* LOGICAL BLOCK ADDRESS OUT OF RANGE */ | ||
2804 | buffer[SPC_ASC_KEY_OFFSET] = 0x21; | ||
2805 | break; | ||
2806 | case TCM_CHECK_CONDITION_UNIT_ATTENTION: | ||
2807 | /* CURRENT ERROR */ | ||
2808 | buffer[0] = 0x70; | ||
2809 | buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; | ||
2810 | /* UNIT ATTENTION */ | ||
2811 | buffer[SPC_SENSE_KEY_OFFSET] = UNIT_ATTENTION; | ||
2812 | core_scsi3_ua_for_check_condition(cmd, &asc, &ascq); | ||
2813 | buffer[SPC_ASC_KEY_OFFSET] = asc; | ||
2814 | buffer[SPC_ASCQ_KEY_OFFSET] = ascq; | ||
2815 | break; | ||
2816 | case TCM_CHECK_CONDITION_NOT_READY: | ||
2817 | /* CURRENT ERROR */ | ||
2818 | buffer[0] = 0x70; | ||
2819 | buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; | ||
2820 | /* Not Ready */ | ||
2821 | buffer[SPC_SENSE_KEY_OFFSET] = NOT_READY; | ||
2822 | transport_get_sense_codes(cmd, &asc, &ascq); | ||
2823 | buffer[SPC_ASC_KEY_OFFSET] = asc; | ||
2824 | buffer[SPC_ASCQ_KEY_OFFSET] = ascq; | ||
2825 | break; | ||
2826 | case TCM_MISCOMPARE_VERIFY: | ||
2827 | /* CURRENT ERROR */ | ||
2828 | buffer[0] = 0x70; | ||
2829 | buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; | ||
2830 | buffer[SPC_SENSE_KEY_OFFSET] = MISCOMPARE; | ||
2831 | /* MISCOMPARE DURING VERIFY OPERATION */ | ||
2832 | buffer[SPC_ASC_KEY_OFFSET] = 0x1d; | ||
2833 | buffer[SPC_ASCQ_KEY_OFFSET] = 0x00; | ||
2834 | break; | ||
2835 | case TCM_LOGICAL_BLOCK_GUARD_CHECK_FAILED: | ||
2836 | /* CURRENT ERROR */ | ||
2837 | buffer[0] = 0x70; | ||
2838 | buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; | ||
2839 | /* ILLEGAL REQUEST */ | ||
2840 | buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; | ||
2841 | /* LOGICAL BLOCK GUARD CHECK FAILED */ | ||
2842 | buffer[SPC_ASC_KEY_OFFSET] = 0x10; | ||
2843 | buffer[SPC_ASCQ_KEY_OFFSET] = 0x01; | ||
2844 | transport_err_sector_info(buffer, cmd->bad_sector); | ||
2845 | break; | ||
2846 | case TCM_LOGICAL_BLOCK_APP_TAG_CHECK_FAILED: | ||
2847 | /* CURRENT ERROR */ | ||
2848 | buffer[0] = 0x70; | ||
2849 | buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; | ||
2850 | /* ILLEGAL REQUEST */ | ||
2851 | buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; | ||
2852 | /* LOGICAL BLOCK APPLICATION TAG CHECK FAILED */ | ||
2853 | buffer[SPC_ASC_KEY_OFFSET] = 0x10; | ||
2854 | buffer[SPC_ASCQ_KEY_OFFSET] = 0x02; | ||
2855 | transport_err_sector_info(buffer, cmd->bad_sector); | ||
2856 | break; | ||
2857 | case TCM_LOGICAL_BLOCK_REF_TAG_CHECK_FAILED: | ||
2858 | /* CURRENT ERROR */ | ||
2859 | buffer[0] = 0x70; | ||
2860 | buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; | ||
2861 | /* ILLEGAL REQUEST */ | ||
2862 | buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST; | ||
2863 | /* LOGICAL BLOCK REFERENCE TAG CHECK FAILED */ | ||
2864 | buffer[SPC_ASC_KEY_OFFSET] = 0x10; | ||
2865 | buffer[SPC_ASCQ_KEY_OFFSET] = 0x03; | ||
2866 | transport_err_sector_info(buffer, cmd->bad_sector); | ||
2867 | break; | ||
2868 | case TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE: | ||
2869 | default: | ||
2870 | /* CURRENT ERROR */ | ||
2871 | buffer[0] = 0x70; | ||
2872 | buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10; | ||
2873 | /* | ||
2874 | * Returning ILLEGAL REQUEST would cause immediate IO errors on | ||
2875 | * Solaris initiators. Returning NOT READY instead means the | ||
2876 | * operations will be retried a finite number of times and we | ||
2877 | * can survive intermittent errors. | ||
2878 | */ | ||
2879 | buffer[SPC_SENSE_KEY_OFFSET] = NOT_READY; | ||
2880 | /* LOGICAL UNIT COMMUNICATION FAILURE */ | ||
2881 | buffer[SPC_ASC_KEY_OFFSET] = 0x08; | ||
2882 | break; | ||
2883 | } | 2830 | } |
2884 | /* | ||
2885 | * This code uses linux/include/scsi/scsi.h SAM status codes! | ||
2886 | */ | ||
2887 | cmd->scsi_status = SAM_STAT_CHECK_CONDITION; | ||
2888 | /* | ||
2889 | * Automatically padded, this value is encoded in the fabric's | ||
2890 | * data_length response PDU containing the SCSI defined sense data. | ||
2891 | */ | ||
2892 | cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER; | ||
2893 | 2831 | ||
2894 | after_reason: | ||
2895 | trace_target_cmd_complete(cmd); | 2832 | trace_target_cmd_complete(cmd); |
2896 | return cmd->se_tfo->queue_status(cmd); | 2833 | return cmd->se_tfo->queue_status(cmd); |
2897 | } | 2834 | } |
diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c index c448ef421ce7..937cebf76633 100644 --- a/drivers/target/target_core_user.c +++ b/drivers/target/target_core_user.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/parser.h> | 25 | #include <linux/parser.h> |
26 | #include <linux/vmalloc.h> | 26 | #include <linux/vmalloc.h> |
27 | #include <linux/uio_driver.h> | 27 | #include <linux/uio_driver.h> |
28 | #include <linux/stringify.h> | ||
28 | #include <net/genetlink.h> | 29 | #include <net/genetlink.h> |
29 | #include <scsi/scsi_common.h> | 30 | #include <scsi/scsi_common.h> |
30 | #include <scsi/scsi_proto.h> | 31 | #include <scsi/scsi_proto.h> |
@@ -538,14 +539,8 @@ static void tcmu_handle_completion(struct tcmu_cmd *cmd, struct tcmu_cmd_entry * | |||
538 | UPDATE_HEAD(udev->data_tail, cmd->data_length, udev->data_size); | 539 | UPDATE_HEAD(udev->data_tail, cmd->data_length, udev->data_size); |
539 | pr_warn("TCMU: Userspace set UNKNOWN_OP flag on se_cmd %p\n", | 540 | pr_warn("TCMU: Userspace set UNKNOWN_OP flag on se_cmd %p\n", |
540 | cmd->se_cmd); | 541 | cmd->se_cmd); |
541 | transport_generic_request_failure(cmd->se_cmd, | 542 | entry->rsp.scsi_status = SAM_STAT_CHECK_CONDITION; |
542 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE); | 543 | } else if (entry->rsp.scsi_status == SAM_STAT_CHECK_CONDITION) { |
543 | cmd->se_cmd = NULL; | ||
544 | kmem_cache_free(tcmu_cmd_cache, cmd); | ||
545 | return; | ||
546 | } | ||
547 | |||
548 | if (entry->rsp.scsi_status == SAM_STAT_CHECK_CONDITION) { | ||
549 | memcpy(se_cmd->sense_buffer, entry->rsp.sense_buffer, | 544 | memcpy(se_cmd->sense_buffer, entry->rsp.sense_buffer, |
550 | se_cmd->scsi_sense_length); | 545 | se_cmd->scsi_sense_length); |
551 | 546 | ||
@@ -577,7 +572,6 @@ static void tcmu_handle_completion(struct tcmu_cmd *cmd, struct tcmu_cmd_entry * | |||
577 | static unsigned int tcmu_handle_completions(struct tcmu_dev *udev) | 572 | static unsigned int tcmu_handle_completions(struct tcmu_dev *udev) |
578 | { | 573 | { |
579 | struct tcmu_mailbox *mb; | 574 | struct tcmu_mailbox *mb; |
580 | LIST_HEAD(cpl_cmds); | ||
581 | unsigned long flags; | 575 | unsigned long flags; |
582 | int handled = 0; | 576 | int handled = 0; |
583 | 577 | ||
@@ -905,7 +899,7 @@ static int tcmu_configure_device(struct se_device *dev) | |||
905 | WARN_ON(!PAGE_ALIGNED(udev->data_off)); | 899 | WARN_ON(!PAGE_ALIGNED(udev->data_off)); |
906 | WARN_ON(udev->data_size % PAGE_SIZE); | 900 | WARN_ON(udev->data_size % PAGE_SIZE); |
907 | 901 | ||
908 | info->version = xstr(TCMU_MAILBOX_VERSION); | 902 | info->version = __stringify(TCMU_MAILBOX_VERSION); |
909 | 903 | ||
910 | info->mem[0].name = "tcm-user command & data buffer"; | 904 | info->mem[0].name = "tcm-user command & data buffer"; |
911 | info->mem[0].addr = (phys_addr_t) udev->mb_addr; | 905 | info->mem[0].addr = (phys_addr_t) udev->mb_addr; |
diff --git a/drivers/target/target_core_xcopy.c b/drivers/target/target_core_xcopy.c index 4515f52546f8..47fe94ee10b8 100644 --- a/drivers/target/target_core_xcopy.c +++ b/drivers/target/target_core_xcopy.c | |||
@@ -450,6 +450,8 @@ int target_xcopy_setup_pt(void) | |||
450 | memset(&xcopy_pt_sess, 0, sizeof(struct se_session)); | 450 | memset(&xcopy_pt_sess, 0, sizeof(struct se_session)); |
451 | INIT_LIST_HEAD(&xcopy_pt_sess.sess_list); | 451 | INIT_LIST_HEAD(&xcopy_pt_sess.sess_list); |
452 | INIT_LIST_HEAD(&xcopy_pt_sess.sess_acl_list); | 452 | INIT_LIST_HEAD(&xcopy_pt_sess.sess_acl_list); |
453 | INIT_LIST_HEAD(&xcopy_pt_sess.sess_cmd_list); | ||
454 | spin_lock_init(&xcopy_pt_sess.sess_cmd_lock); | ||
453 | 455 | ||
454 | xcopy_pt_nacl.se_tpg = &xcopy_pt_tpg; | 456 | xcopy_pt_nacl.se_tpg = &xcopy_pt_tpg; |
455 | xcopy_pt_nacl.nacl_sess = &xcopy_pt_sess; | 457 | xcopy_pt_nacl.nacl_sess = &xcopy_pt_sess; |
@@ -644,7 +646,7 @@ static int target_xcopy_read_source( | |||
644 | pr_debug("XCOPY: Built READ_16: LBA: %llu Sectors: %u Length: %u\n", | 646 | pr_debug("XCOPY: Built READ_16: LBA: %llu Sectors: %u Length: %u\n", |
645 | (unsigned long long)src_lba, src_sectors, length); | 647 | (unsigned long long)src_lba, src_sectors, length); |
646 | 648 | ||
647 | transport_init_se_cmd(se_cmd, &xcopy_pt_tfo, NULL, length, | 649 | transport_init_se_cmd(se_cmd, &xcopy_pt_tfo, &xcopy_pt_sess, length, |
648 | DMA_FROM_DEVICE, 0, &xpt_cmd->sense_buffer[0]); | 650 | DMA_FROM_DEVICE, 0, &xpt_cmd->sense_buffer[0]); |
649 | xop->src_pt_cmd = xpt_cmd; | 651 | xop->src_pt_cmd = xpt_cmd; |
650 | 652 | ||
@@ -704,7 +706,7 @@ static int target_xcopy_write_destination( | |||
704 | pr_debug("XCOPY: Built WRITE_16: LBA: %llu Sectors: %u Length: %u\n", | 706 | pr_debug("XCOPY: Built WRITE_16: LBA: %llu Sectors: %u Length: %u\n", |
705 | (unsigned long long)dst_lba, dst_sectors, length); | 707 | (unsigned long long)dst_lba, dst_sectors, length); |
706 | 708 | ||
707 | transport_init_se_cmd(se_cmd, &xcopy_pt_tfo, NULL, length, | 709 | transport_init_se_cmd(se_cmd, &xcopy_pt_tfo, &xcopy_pt_sess, length, |
708 | DMA_TO_DEVICE, 0, &xpt_cmd->sense_buffer[0]); | 710 | DMA_TO_DEVICE, 0, &xpt_cmd->sense_buffer[0]); |
709 | xop->dst_pt_cmd = xpt_cmd; | 711 | xop->dst_pt_cmd = xpt_cmd; |
710 | 712 | ||
diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c index 68031723e5be..aa3caca8bace 100644 --- a/drivers/target/tcm_fc/tfc_cmd.c +++ b/drivers/target/tcm_fc/tfc_cmd.c | |||
@@ -255,7 +255,7 @@ static void ft_recv_seq(struct fc_seq *sp, struct fc_frame *fp, void *arg) | |||
255 | struct ft_cmd *cmd = arg; | 255 | struct ft_cmd *cmd = arg; |
256 | struct fc_frame_header *fh; | 256 | struct fc_frame_header *fh; |
257 | 257 | ||
258 | if (unlikely(IS_ERR(fp))) { | 258 | if (IS_ERR(fp)) { |
259 | /* XXX need to find cmd if queued */ | 259 | /* XXX need to find cmd if queued */ |
260 | cmd->seq = NULL; | 260 | cmd->seq = NULL; |
261 | cmd->aborted = true; | 261 | cmd->aborted = true; |
diff --git a/include/scsi/scsi_common.h b/include/scsi/scsi_common.h index 676b03b78e57..11571b2a831e 100644 --- a/include/scsi/scsi_common.h +++ b/include/scsi/scsi_common.h | |||
@@ -61,4 +61,9 @@ static inline bool scsi_sense_valid(const struct scsi_sense_hdr *sshdr) | |||
61 | extern bool scsi_normalize_sense(const u8 *sense_buffer, int sb_len, | 61 | extern bool scsi_normalize_sense(const u8 *sense_buffer, int sb_len, |
62 | struct scsi_sense_hdr *sshdr); | 62 | struct scsi_sense_hdr *sshdr); |
63 | 63 | ||
64 | extern void scsi_build_sense_buffer(int desc, u8 *buf, u8 key, u8 asc, u8 ascq); | ||
65 | int scsi_set_sense_information(u8 *buf, int buf_len, u64 info); | ||
66 | extern const u8 * scsi_sense_desc_find(const u8 * sense_buffer, int sb_len, | ||
67 | int desc_type); | ||
68 | |||
64 | #endif /* _SCSI_COMMON_H_ */ | 69 | #endif /* _SCSI_COMMON_H_ */ |
diff --git a/include/scsi/scsi_eh.h b/include/scsi/scsi_eh.h index 8d1d7fa67ec4..dbb8c640e26f 100644 --- a/include/scsi/scsi_eh.h +++ b/include/scsi/scsi_eh.h | |||
@@ -4,6 +4,7 @@ | |||
4 | #include <linux/scatterlist.h> | 4 | #include <linux/scatterlist.h> |
5 | 5 | ||
6 | #include <scsi/scsi_cmnd.h> | 6 | #include <scsi/scsi_cmnd.h> |
7 | #include <scsi/scsi_common.h> | ||
7 | struct scsi_device; | 8 | struct scsi_device; |
8 | struct Scsi_Host; | 9 | struct Scsi_Host; |
9 | 10 | ||
@@ -21,14 +22,9 @@ static inline bool scsi_sense_is_deferred(const struct scsi_sense_hdr *sshdr) | |||
21 | return ((sshdr->response_code >= 0x70) && (sshdr->response_code & 1)); | 22 | return ((sshdr->response_code >= 0x70) && (sshdr->response_code & 1)); |
22 | } | 23 | } |
23 | 24 | ||
24 | extern const u8 * scsi_sense_desc_find(const u8 * sense_buffer, int sb_len, | ||
25 | int desc_type); | ||
26 | |||
27 | extern int scsi_get_sense_info_fld(const u8 * sense_buffer, int sb_len, | 25 | extern int scsi_get_sense_info_fld(const u8 * sense_buffer, int sb_len, |
28 | u64 * info_out); | 26 | u64 * info_out); |
29 | 27 | ||
30 | extern void scsi_build_sense_buffer(int desc, u8 *buf, u8 key, u8 asc, u8 ascq); | ||
31 | |||
32 | extern int scsi_ioctl_reset(struct scsi_device *, int __user *); | 28 | extern int scsi_ioctl_reset(struct scsi_device *, int __user *); |
33 | 29 | ||
34 | struct scsi_eh_save { | 30 | struct scsi_eh_save { |
diff --git a/include/target/iscsi/iscsi_target_core.h b/include/target/iscsi/iscsi_target_core.h index 0aedbb2c10e0..373d3342002b 100644 --- a/include/target/iscsi/iscsi_target_core.h +++ b/include/target/iscsi/iscsi_target_core.h | |||
@@ -62,6 +62,8 @@ | |||
62 | /* T10 protection information disabled by default */ | 62 | /* T10 protection information disabled by default */ |
63 | #define TA_DEFAULT_T10_PI 0 | 63 | #define TA_DEFAULT_T10_PI 0 |
64 | #define TA_DEFAULT_FABRIC_PROT_TYPE 0 | 64 | #define TA_DEFAULT_FABRIC_PROT_TYPE 0 |
65 | /* TPG status needs to be enabled to return sendtargets discovery endpoint info */ | ||
66 | #define TA_DEFAULT_TPG_ENABLED_SENDTARGETS 1 | ||
65 | 67 | ||
66 | #define ISCSI_IOV_DATA_BUFFER 5 | 68 | #define ISCSI_IOV_DATA_BUFFER 5 |
67 | 69 | ||
@@ -517,7 +519,6 @@ struct iscsi_conn { | |||
517 | u16 cid; | 519 | u16 cid; |
518 | /* Remote TCP Port */ | 520 | /* Remote TCP Port */ |
519 | u16 login_port; | 521 | u16 login_port; |
520 | u16 local_port; | ||
521 | int net_size; | 522 | int net_size; |
522 | int login_family; | 523 | int login_family; |
523 | u32 auth_id; | 524 | u32 auth_id; |
@@ -527,9 +528,8 @@ struct iscsi_conn { | |||
527 | u32 exp_statsn; | 528 | u32 exp_statsn; |
528 | /* Per connection status sequence number */ | 529 | /* Per connection status sequence number */ |
529 | u32 stat_sn; | 530 | u32 stat_sn; |
530 | #define IPV6_ADDRESS_SPACE 48 | 531 | struct sockaddr_storage login_sockaddr; |
531 | unsigned char login_ip[IPV6_ADDRESS_SPACE]; | 532 | struct sockaddr_storage local_sockaddr; |
532 | unsigned char local_ip[IPV6_ADDRESS_SPACE]; | ||
533 | int conn_usage_count; | 533 | int conn_usage_count; |
534 | int conn_waiting_on_uc; | 534 | int conn_waiting_on_uc; |
535 | atomic_t check_immediate_queue; | 535 | atomic_t check_immediate_queue; |
@@ -636,7 +636,7 @@ struct iscsi_session { | |||
636 | /* session wide counter: expected command sequence number */ | 636 | /* session wide counter: expected command sequence number */ |
637 | u32 exp_cmd_sn; | 637 | u32 exp_cmd_sn; |
638 | /* session wide counter: maximum allowed command sequence number */ | 638 | /* session wide counter: maximum allowed command sequence number */ |
639 | u32 max_cmd_sn; | 639 | atomic_t max_cmd_sn; |
640 | struct list_head sess_ooo_cmdsn_list; | 640 | struct list_head sess_ooo_cmdsn_list; |
641 | 641 | ||
642 | /* LIO specific session ID */ | 642 | /* LIO specific session ID */ |
@@ -764,6 +764,7 @@ struct iscsi_tpg_attrib { | |||
764 | u32 default_erl; | 764 | u32 default_erl; |
765 | u8 t10_pi; | 765 | u8 t10_pi; |
766 | u32 fabric_prot_type; | 766 | u32 fabric_prot_type; |
767 | u32 tpg_enabled_sendtargets; | ||
767 | struct iscsi_portal_group *tpg; | 768 | struct iscsi_portal_group *tpg; |
768 | }; | 769 | }; |
769 | 770 | ||
@@ -776,12 +777,10 @@ struct iscsi_np { | |||
776 | enum iscsi_timer_flags_table np_login_timer_flags; | 777 | enum iscsi_timer_flags_table np_login_timer_flags; |
777 | u32 np_exports; | 778 | u32 np_exports; |
778 | enum np_flags_table np_flags; | 779 | enum np_flags_table np_flags; |
779 | unsigned char np_ip[IPV6_ADDRESS_SPACE]; | ||
780 | u16 np_port; | ||
781 | spinlock_t np_thread_lock; | 780 | spinlock_t np_thread_lock; |
782 | struct completion np_restart_comp; | 781 | struct completion np_restart_comp; |
783 | struct socket *np_socket; | 782 | struct socket *np_socket; |
784 | struct __kernel_sockaddr_storage np_sockaddr; | 783 | struct sockaddr_storage np_sockaddr; |
785 | struct task_struct *np_thread; | 784 | struct task_struct *np_thread; |
786 | struct timer_list np_login_timer; | 785 | struct timer_list np_login_timer; |
787 | void *np_context; | 786 | void *np_context; |
diff --git a/include/target/iscsi/iscsi_target_stat.h b/include/target/iscsi/iscsi_target_stat.h index 3ff76b4faad3..e615bb485d0b 100644 --- a/include/target/iscsi/iscsi_target_stat.h +++ b/include/target/iscsi/iscsi_target_stat.h | |||
@@ -50,7 +50,7 @@ struct iscsi_login_stats { | |||
50 | u64 last_fail_time; /* time stamp (jiffies) */ | 50 | u64 last_fail_time; /* time stamp (jiffies) */ |
51 | u32 last_fail_type; | 51 | u32 last_fail_type; |
52 | int last_intr_fail_ip_family; | 52 | int last_intr_fail_ip_family; |
53 | unsigned char last_intr_fail_ip_addr[IPV6_ADDRESS_SPACE]; | 53 | struct sockaddr_storage last_intr_fail_sockaddr; |
54 | char last_intr_fail_name[224]; | 54 | char last_intr_fail_name[224]; |
55 | } ____cacheline_aligned; | 55 | } ____cacheline_aligned; |
56 | 56 | ||
diff --git a/include/target/iscsi/iscsi_transport.h b/include/target/iscsi/iscsi_transport.h index e6bb166f12c2..90e37faa2ede 100644 --- a/include/target/iscsi/iscsi_transport.h +++ b/include/target/iscsi/iscsi_transport.h | |||
@@ -9,7 +9,7 @@ struct iscsit_transport { | |||
9 | int priv_size; | 9 | int priv_size; |
10 | struct module *owner; | 10 | struct module *owner; |
11 | struct list_head t_node; | 11 | struct list_head t_node; |
12 | int (*iscsit_setup_np)(struct iscsi_np *, struct __kernel_sockaddr_storage *); | 12 | int (*iscsit_setup_np)(struct iscsi_np *, struct sockaddr_storage *); |
13 | int (*iscsit_accept_np)(struct iscsi_np *, struct iscsi_conn *); | 13 | int (*iscsit_accept_np)(struct iscsi_np *, struct iscsi_conn *); |
14 | void (*iscsit_free_np)(struct iscsi_np *); | 14 | void (*iscsit_free_np)(struct iscsi_np *); |
15 | void (*iscsit_wait_conn)(struct iscsi_conn *); | 15 | void (*iscsit_wait_conn)(struct iscsi_conn *); |
diff --git a/include/target/target_core_backend.h b/include/target/target_core_backend.h index 1e5c8f949bae..56cf8e485ef2 100644 --- a/include/target/target_core_backend.h +++ b/include/target/target_core_backend.h | |||
@@ -93,4 +93,6 @@ bool target_lun_is_rdonly(struct se_cmd *); | |||
93 | sense_reason_t passthrough_parse_cdb(struct se_cmd *cmd, | 93 | sense_reason_t passthrough_parse_cdb(struct se_cmd *cmd, |
94 | sense_reason_t (*exec_cmd)(struct se_cmd *cmd)); | 94 | sense_reason_t (*exec_cmd)(struct se_cmd *cmd)); |
95 | 95 | ||
96 | bool target_sense_desc_format(struct se_device *dev); | ||
97 | |||
96 | #endif /* TARGET_CORE_BACKEND_H */ | 98 | #endif /* TARGET_CORE_BACKEND_H */ |
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index 17ae2d6a4891..ac9bf1c0e42d 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h | |||
@@ -6,6 +6,7 @@ | |||
6 | #include <linux/dma-mapping.h> | 6 | #include <linux/dma-mapping.h> |
7 | #include <linux/blkdev.h> | 7 | #include <linux/blkdev.h> |
8 | #include <linux/percpu_ida.h> | 8 | #include <linux/percpu_ida.h> |
9 | #include <linux/t10-pi.h> | ||
9 | #include <net/sock.h> | 10 | #include <net/sock.h> |
10 | #include <net/tcp.h> | 11 | #include <net/tcp.h> |
11 | 12 | ||
@@ -426,12 +427,6 @@ enum target_core_dif_check { | |||
426 | TARGET_DIF_CHECK_REFTAG = 0x1 << 2, | 427 | TARGET_DIF_CHECK_REFTAG = 0x1 << 2, |
427 | }; | 428 | }; |
428 | 429 | ||
429 | struct se_dif_v1_tuple { | ||
430 | __be16 guard_tag; | ||
431 | __be16 app_tag; | ||
432 | __be32 ref_tag; | ||
433 | }; | ||
434 | |||
435 | /* for sam_task_attr */ | 430 | /* for sam_task_attr */ |
436 | #define TCM_SIMPLE_TAG 0x20 | 431 | #define TCM_SIMPLE_TAG 0x20 |
437 | #define TCM_HEAD_TAG 0x21 | 432 | #define TCM_HEAD_TAG 0x21 |
@@ -444,6 +439,9 @@ struct se_cmd { | |||
444 | u8 scsi_asc; | 439 | u8 scsi_asc; |
445 | u8 scsi_ascq; | 440 | u8 scsi_ascq; |
446 | u16 scsi_sense_length; | 441 | u16 scsi_sense_length; |
442 | unsigned cmd_wait_set:1; | ||
443 | unsigned unknown_data_length:1; | ||
444 | bool state_active:1; | ||
447 | u64 tag; /* SAM command identifier aka task tag */ | 445 | u64 tag; /* SAM command identifier aka task tag */ |
448 | /* Delay for ALUA Active/NonOptimized state access in milliseconds */ | 446 | /* Delay for ALUA Active/NonOptimized state access in milliseconds */ |
449 | int alua_nonop_delay; | 447 | int alua_nonop_delay; |
@@ -455,11 +453,8 @@ struct se_cmd { | |||
455 | unsigned int map_tag; | 453 | unsigned int map_tag; |
456 | /* Transport protocol dependent state, see transport_state_table */ | 454 | /* Transport protocol dependent state, see transport_state_table */ |
457 | enum transport_state_table t_state; | 455 | enum transport_state_table t_state; |
458 | unsigned cmd_wait_set:1; | ||
459 | unsigned unknown_data_length:1; | ||
460 | /* See se_cmd_flags_table */ | 456 | /* See se_cmd_flags_table */ |
461 | u32 se_cmd_flags; | 457 | u32 se_cmd_flags; |
462 | u32 se_ordered_id; | ||
463 | /* Total size in bytes associated with command */ | 458 | /* Total size in bytes associated with command */ |
464 | u32 data_length; | 459 | u32 data_length; |
465 | u32 residual_count; | 460 | u32 residual_count; |
@@ -477,7 +472,6 @@ struct se_cmd { | |||
477 | struct se_tmr_req *se_tmr_req; | 472 | struct se_tmr_req *se_tmr_req; |
478 | struct list_head se_cmd_list; | 473 | struct list_head se_cmd_list; |
479 | struct completion cmd_wait_comp; | 474 | struct completion cmd_wait_comp; |
480 | struct kref cmd_kref; | ||
481 | const struct target_core_fabric_ops *se_tfo; | 475 | const struct target_core_fabric_ops *se_tfo; |
482 | sense_reason_t (*execute_cmd)(struct se_cmd *); | 476 | sense_reason_t (*execute_cmd)(struct se_cmd *); |
483 | sense_reason_t (*transport_complete_callback)(struct se_cmd *, bool); | 477 | sense_reason_t (*transport_complete_callback)(struct se_cmd *, bool); |
@@ -497,6 +491,7 @@ struct se_cmd { | |||
497 | #define CMD_T_REQUEST_STOP (1 << 8) | 491 | #define CMD_T_REQUEST_STOP (1 << 8) |
498 | #define CMD_T_BUSY (1 << 9) | 492 | #define CMD_T_BUSY (1 << 9) |
499 | spinlock_t t_state_lock; | 493 | spinlock_t t_state_lock; |
494 | struct kref cmd_kref; | ||
500 | struct completion t_transport_stop_comp; | 495 | struct completion t_transport_stop_comp; |
501 | 496 | ||
502 | struct work_struct work; | 497 | struct work_struct work; |
@@ -509,8 +504,10 @@ struct se_cmd { | |||
509 | struct scatterlist *t_bidi_data_sg; | 504 | struct scatterlist *t_bidi_data_sg; |
510 | unsigned int t_bidi_data_nents; | 505 | unsigned int t_bidi_data_nents; |
511 | 506 | ||
507 | /* Used for lun->lun_ref counting */ | ||
508 | int lun_ref_active; | ||
509 | |||
512 | struct list_head state_list; | 510 | struct list_head state_list; |
513 | bool state_active; | ||
514 | 511 | ||
515 | /* old task stop completion, consider merging with some of the above */ | 512 | /* old task stop completion, consider merging with some of the above */ |
516 | struct completion task_stop_comp; | 513 | struct completion task_stop_comp; |
@@ -518,20 +515,17 @@ struct se_cmd { | |||
518 | /* backend private data */ | 515 | /* backend private data */ |
519 | void *priv; | 516 | void *priv; |
520 | 517 | ||
521 | /* Used for lun->lun_ref counting */ | ||
522 | int lun_ref_active; | ||
523 | |||
524 | /* DIF related members */ | 518 | /* DIF related members */ |
525 | enum target_prot_op prot_op; | 519 | enum target_prot_op prot_op; |
526 | enum target_prot_type prot_type; | 520 | enum target_prot_type prot_type; |
527 | u8 prot_checks; | 521 | u8 prot_checks; |
522 | bool prot_pto; | ||
528 | u32 prot_length; | 523 | u32 prot_length; |
529 | u32 reftag_seed; | 524 | u32 reftag_seed; |
530 | struct scatterlist *t_prot_sg; | 525 | struct scatterlist *t_prot_sg; |
531 | unsigned int t_prot_nents; | 526 | unsigned int t_prot_nents; |
532 | sense_reason_t pi_err; | 527 | sense_reason_t pi_err; |
533 | sector_t bad_sector; | 528 | sector_t bad_sector; |
534 | bool prot_pto; | ||
535 | }; | 529 | }; |
536 | 530 | ||
537 | struct se_ua { | 531 | struct se_ua { |
@@ -598,7 +592,6 @@ struct se_ml_stat_grps { | |||
598 | }; | 592 | }; |
599 | 593 | ||
600 | struct se_lun_acl { | 594 | struct se_lun_acl { |
601 | char initiatorname[TRANSPORT_IQN_LEN]; | ||
602 | u64 mapped_lun; | 595 | u64 mapped_lun; |
603 | struct se_node_acl *se_lun_nacl; | 596 | struct se_node_acl *se_lun_nacl; |
604 | struct se_lun *se_lun; | 597 | struct se_lun *se_lun; |
@@ -685,7 +678,6 @@ struct se_lun { | |||
685 | #define SE_LUN_LINK_MAGIC 0xffff7771 | 678 | #define SE_LUN_LINK_MAGIC 0xffff7771 |
686 | u32 lun_link_magic; | 679 | u32 lun_link_magic; |
687 | u32 lun_access; | 680 | u32 lun_access; |
688 | u32 lun_flags; | ||
689 | u32 lun_index; | 681 | u32 lun_index; |
690 | 682 | ||
691 | /* RELATIVE TARGET PORT IDENTIFER */ | 683 | /* RELATIVE TARGET PORT IDENTIFER */ |
@@ -751,7 +743,6 @@ struct se_device { | |||
751 | atomic_long_t write_bytes; | 743 | atomic_long_t write_bytes; |
752 | /* Active commands on this virtual SE device */ | 744 | /* Active commands on this virtual SE device */ |
753 | atomic_t simple_cmds; | 745 | atomic_t simple_cmds; |
754 | atomic_t dev_ordered_id; | ||
755 | atomic_t dev_ordered_sync; | 746 | atomic_t dev_ordered_sync; |
756 | atomic_t dev_qf_count; | 747 | atomic_t dev_qf_count; |
757 | u32 export_count; | 748 | u32 export_count; |
diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h index 18afef91b447..7fb2557a760e 100644 --- a/include/target/target_core_fabric.h +++ b/include/target/target_core_fabric.h | |||
@@ -5,6 +5,19 @@ struct target_core_fabric_ops { | |||
5 | struct module *module; | 5 | struct module *module; |
6 | const char *name; | 6 | const char *name; |
7 | size_t node_acl_size; | 7 | size_t node_acl_size; |
8 | /* | ||
9 | * Limits number of scatterlist entries per SCF_SCSI_DATA_CDB payload. | ||
10 | * Setting this value tells target-core to enforce this limit, and | ||
11 | * report as INQUIRY EVPD=b0 MAXIMUM TRANSFER LENGTH. | ||
12 | * | ||
13 | * target-core will currently reset se_cmd->data_length to this | ||
14 | * maximum size, and set UNDERFLOW residual count if length exceeds | ||
15 | * this limit. | ||
16 | * | ||
17 | * XXX: Not all initiator hosts honor this block-limit EVPD | ||
18 | * XXX: Currently assumes single PAGE_SIZE per scatterlist entry | ||
19 | */ | ||
20 | u32 max_data_sg_nents; | ||
8 | char *(*get_fabric_name)(void); | 21 | char *(*get_fabric_name)(void); |
9 | char *(*tpg_get_wwn)(struct se_portal_group *); | 22 | char *(*tpg_get_wwn)(struct se_portal_group *); |
10 | u16 (*tpg_get_tag)(struct se_portal_group *); | 23 | u16 (*tpg_get_tag)(struct se_portal_group *); |
@@ -152,6 +165,7 @@ int transport_generic_handle_tmr(struct se_cmd *); | |||
152 | void transport_generic_request_failure(struct se_cmd *, sense_reason_t); | 165 | void transport_generic_request_failure(struct se_cmd *, sense_reason_t); |
153 | void __target_execute_cmd(struct se_cmd *); | 166 | void __target_execute_cmd(struct se_cmd *); |
154 | int transport_lookup_tmr_lun(struct se_cmd *, u64); | 167 | int transport_lookup_tmr_lun(struct se_cmd *, u64); |
168 | void core_allocate_nexus_loss_ua(struct se_node_acl *acl); | ||
155 | 169 | ||
156 | struct se_node_acl *core_tpg_get_initiator_node_acl(struct se_portal_group *tpg, | 170 | struct se_node_acl *core_tpg_get_initiator_node_acl(struct se_portal_group *tpg, |
157 | unsigned char *); | 171 | unsigned char *); |
diff --git a/include/uapi/linux/target_core_user.h b/include/uapi/linux/target_core_user.h index b67f99d3c520..95c6521d8a95 100644 --- a/include/uapi/linux/target_core_user.h +++ b/include/uapi/linux/target_core_user.h | |||
@@ -42,10 +42,6 @@ | |||
42 | #define TCMU_MAILBOX_VERSION 2 | 42 | #define TCMU_MAILBOX_VERSION 2 |
43 | #define ALIGN_SIZE 64 /* Should be enough for most CPUs */ | 43 | #define ALIGN_SIZE 64 /* Should be enough for most CPUs */ |
44 | 44 | ||
45 | /* See https://gcc.gnu.org/onlinedocs/cpp/Stringification.html */ | ||
46 | #define xstr(s) str(s) | ||
47 | #define str(s) #s | ||
48 | |||
49 | struct tcmu_mailbox { | 45 | struct tcmu_mailbox { |
50 | __u16 version; | 46 | __u16 version; |
51 | __u16 flags; | 47 | __u16 flags; |