diff options
author | Christoph Hellwig <hch@infradead.org> | 2012-05-20 11:59:10 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2012-07-16 20:25:55 -0400 |
commit | cb4f4d3c7398a709b48d397e0520ee2509a953a4 (patch) | |
tree | 044ed92284a78cc2f0cb9fc69ca13bece0bd676c /drivers | |
parent | 1765fe5edcb83f53fc67edeb559fcf4bc82c6460 (diff) |
target: move unrelated code out of transport_generic_cmd_sequencer
Move all code not related to cdb parsing from transport_generic_cmd_sequencer
into target_setup_cmd_from_cdb.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/target/target_core_transport.c | 143 |
1 files changed, 66 insertions, 77 deletions
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 634d0f31a28c..bb19223faa46 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
@@ -1418,6 +1418,10 @@ int target_setup_cmd_from_cdb( | |||
1418 | struct se_cmd *cmd, | 1418 | struct se_cmd *cmd, |
1419 | unsigned char *cdb) | 1419 | unsigned char *cdb) |
1420 | { | 1420 | { |
1421 | struct se_subsystem_dev *su_dev = cmd->se_dev->se_sub_dev; | ||
1422 | u32 pr_reg_type = 0; | ||
1423 | u8 alua_ascq = 0; | ||
1424 | unsigned long flags; | ||
1421 | int ret; | 1425 | int ret; |
1422 | 1426 | ||
1423 | transport_generic_prepare_cdb(cdb); | 1427 | transport_generic_prepare_cdb(cdb); |
@@ -1457,6 +1461,58 @@ int target_setup_cmd_from_cdb( | |||
1457 | * Copy the original CDB into cmd-> | 1461 | * Copy the original CDB into cmd-> |
1458 | */ | 1462 | */ |
1459 | memcpy(cmd->t_task_cdb, cdb, scsi_command_size(cdb)); | 1463 | memcpy(cmd->t_task_cdb, cdb, scsi_command_size(cdb)); |
1464 | |||
1465 | /* | ||
1466 | * Check for an existing UNIT ATTENTION condition | ||
1467 | */ | ||
1468 | if (core_scsi3_ua_check(cmd, cdb) < 0) { | ||
1469 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
1470 | cmd->scsi_sense_reason = TCM_CHECK_CONDITION_UNIT_ATTENTION; | ||
1471 | return -EINVAL; | ||
1472 | } | ||
1473 | |||
1474 | ret = su_dev->t10_alua.alua_state_check(cmd, cdb, &alua_ascq); | ||
1475 | if (ret != 0) { | ||
1476 | /* | ||
1477 | * Set SCSI additional sense code (ASC) to 'LUN Not Accessible'; | ||
1478 | * The ALUA additional sense code qualifier (ASCQ) is determined | ||
1479 | * by the ALUA primary or secondary access state.. | ||
1480 | */ | ||
1481 | if (ret > 0) { | ||
1482 | pr_debug("[%s]: ALUA TG Port not available, " | ||
1483 | "SenseKey: NOT_READY, ASC/ASCQ: " | ||
1484 | "0x04/0x%02x\n", | ||
1485 | cmd->se_tfo->get_fabric_name(), alua_ascq); | ||
1486 | |||
1487 | transport_set_sense_codes(cmd, 0x04, alua_ascq); | ||
1488 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
1489 | cmd->scsi_sense_reason = TCM_CHECK_CONDITION_NOT_READY; | ||
1490 | return -EINVAL; | ||
1491 | } | ||
1492 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
1493 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | ||
1494 | return -EINVAL; | ||
1495 | } | ||
1496 | |||
1497 | /* | ||
1498 | * Check status for SPC-3 Persistent Reservations | ||
1499 | */ | ||
1500 | if (su_dev->t10_pr.pr_ops.t10_reservation_check(cmd, &pr_reg_type)) { | ||
1501 | if (su_dev->t10_pr.pr_ops.t10_seq_non_holder( | ||
1502 | cmd, cdb, pr_reg_type) != 0) { | ||
1503 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
1504 | cmd->se_cmd_flags |= SCF_SCSI_RESERVATION_CONFLICT; | ||
1505 | cmd->scsi_status = SAM_STAT_RESERVATION_CONFLICT; | ||
1506 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | ||
1507 | return -EBUSY; | ||
1508 | } | ||
1509 | /* | ||
1510 | * This means the CDB is allowed for the SCSI Initiator port | ||
1511 | * when said port is *NOT* holding the legacy SPC-2 or | ||
1512 | * SPC-3 Persistent Reservation. | ||
1513 | */ | ||
1514 | } | ||
1515 | |||
1460 | /* | 1516 | /* |
1461 | * Setup the received CDB based on SCSI defined opcodes and | 1517 | * Setup the received CDB based on SCSI defined opcodes and |
1462 | * perform unit attention, persistent reservations and ALUA | 1518 | * perform unit attention, persistent reservations and ALUA |
@@ -1466,6 +1522,11 @@ int target_setup_cmd_from_cdb( | |||
1466 | ret = transport_generic_cmd_sequencer(cmd, cdb); | 1522 | ret = transport_generic_cmd_sequencer(cmd, cdb); |
1467 | if (ret < 0) | 1523 | if (ret < 0) |
1468 | return ret; | 1524 | return ret; |
1525 | |||
1526 | spin_lock_irqsave(&cmd->t_state_lock, flags); | ||
1527 | cmd->se_cmd_flags |= SCF_SUPPORTED_SAM_OPCODE; | ||
1528 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | ||
1529 | |||
1469 | /* | 1530 | /* |
1470 | * Check for SAM Task Attribute Emulation | 1531 | * Check for SAM Task Attribute Emulation |
1471 | */ | 1532 | */ |
@@ -1889,15 +1950,6 @@ static inline unsigned long long transport_lba_64_ext(unsigned char *cdb) | |||
1889 | return ((unsigned long long)__v2) | (unsigned long long)__v1 << 32; | 1950 | return ((unsigned long long)__v2) | (unsigned long long)__v1 << 32; |
1890 | } | 1951 | } |
1891 | 1952 | ||
1892 | static void transport_set_supported_SAM_opcode(struct se_cmd *se_cmd) | ||
1893 | { | ||
1894 | unsigned long flags; | ||
1895 | |||
1896 | spin_lock_irqsave(&se_cmd->t_state_lock, flags); | ||
1897 | se_cmd->se_cmd_flags |= SCF_SUPPORTED_SAM_OPCODE; | ||
1898 | spin_unlock_irqrestore(&se_cmd->t_state_lock, flags); | ||
1899 | } | ||
1900 | |||
1901 | /* | 1953 | /* |
1902 | * Called from Fabric Module context from transport_execute_tasks() | 1954 | * Called from Fabric Module context from transport_execute_tasks() |
1903 | * | 1955 | * |
@@ -2370,74 +2422,15 @@ static int target_check_write_same_discard(unsigned char *flags, struct se_devic | |||
2370 | return 0; | 2422 | return 0; |
2371 | } | 2423 | } |
2372 | 2424 | ||
2373 | /* transport_generic_cmd_sequencer(): | ||
2374 | * | ||
2375 | * Generic Command Sequencer that should work for most DAS transport | ||
2376 | * drivers. | ||
2377 | * | ||
2378 | * Called from target_setup_cmd_from_cdb() in the $FABRIC_MOD | ||
2379 | * RX Thread. | ||
2380 | * | ||
2381 | * FIXME: Need to support other SCSI OPCODES where as well. | ||
2382 | */ | ||
2383 | static int transport_generic_cmd_sequencer( | 2425 | static int transport_generic_cmd_sequencer( |
2384 | struct se_cmd *cmd, | 2426 | struct se_cmd *cmd, |
2385 | unsigned char *cdb) | 2427 | unsigned char *cdb) |
2386 | { | 2428 | { |
2387 | struct se_device *dev = cmd->se_dev; | 2429 | struct se_device *dev = cmd->se_dev; |
2388 | struct se_subsystem_dev *su_dev = dev->se_sub_dev; | 2430 | struct se_subsystem_dev *su_dev = dev->se_sub_dev; |
2389 | int ret = 0, sector_ret = 0, passthrough; | 2431 | int sector_ret = 0, passthrough; |
2390 | u32 sectors = 0, size = 0, pr_reg_type = 0; | 2432 | u32 sectors = 0, size = 0; |
2391 | u16 service_action; | 2433 | u16 service_action; |
2392 | u8 alua_ascq = 0; | ||
2393 | /* | ||
2394 | * Check for an existing UNIT ATTENTION condition | ||
2395 | */ | ||
2396 | if (core_scsi3_ua_check(cmd, cdb) < 0) { | ||
2397 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
2398 | cmd->scsi_sense_reason = TCM_CHECK_CONDITION_UNIT_ATTENTION; | ||
2399 | return -EINVAL; | ||
2400 | } | ||
2401 | /* | ||
2402 | * Check status of Asymmetric Logical Unit Assignment port | ||
2403 | */ | ||
2404 | ret = su_dev->t10_alua.alua_state_check(cmd, cdb, &alua_ascq); | ||
2405 | if (ret != 0) { | ||
2406 | /* | ||
2407 | * Set SCSI additional sense code (ASC) to 'LUN Not Accessible'; | ||
2408 | * The ALUA additional sense code qualifier (ASCQ) is determined | ||
2409 | * by the ALUA primary or secondary access state.. | ||
2410 | */ | ||
2411 | if (ret > 0) { | ||
2412 | pr_debug("[%s]: ALUA TG Port not available," | ||
2413 | " SenseKey: NOT_READY, ASC/ASCQ: 0x04/0x%02x\n", | ||
2414 | cmd->se_tfo->get_fabric_name(), alua_ascq); | ||
2415 | |||
2416 | transport_set_sense_codes(cmd, 0x04, alua_ascq); | ||
2417 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
2418 | cmd->scsi_sense_reason = TCM_CHECK_CONDITION_NOT_READY; | ||
2419 | return -EINVAL; | ||
2420 | } | ||
2421 | goto out_invalid_cdb_field; | ||
2422 | } | ||
2423 | /* | ||
2424 | * Check status for SPC-3 Persistent Reservations | ||
2425 | */ | ||
2426 | if (su_dev->t10_pr.pr_ops.t10_reservation_check(cmd, &pr_reg_type) != 0) { | ||
2427 | if (su_dev->t10_pr.pr_ops.t10_seq_non_holder( | ||
2428 | cmd, cdb, pr_reg_type) != 0) { | ||
2429 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
2430 | cmd->se_cmd_flags |= SCF_SCSI_RESERVATION_CONFLICT; | ||
2431 | cmd->scsi_status = SAM_STAT_RESERVATION_CONFLICT; | ||
2432 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | ||
2433 | return -EBUSY; | ||
2434 | } | ||
2435 | /* | ||
2436 | * This means the CDB is allowed for the SCSI Initiator port | ||
2437 | * when said port is *NOT* holding the legacy SPC-2 or | ||
2438 | * SPC-3 Persistent Reservation. | ||
2439 | */ | ||
2440 | } | ||
2441 | 2434 | ||
2442 | /* | 2435 | /* |
2443 | * If we operate in passthrough mode we skip most CDB emulation and | 2436 | * If we operate in passthrough mode we skip most CDB emulation and |
@@ -2992,7 +2985,7 @@ static int transport_generic_cmd_sequencer( | |||
2992 | * Reject READ_* or WRITE_* with overflow/underflow for | 2985 | * Reject READ_* or WRITE_* with overflow/underflow for |
2993 | * type SCF_SCSI_DATA_SG_IO_CDB. | 2986 | * type SCF_SCSI_DATA_SG_IO_CDB. |
2994 | */ | 2987 | */ |
2995 | if (!ret && (dev->se_sub_dev->se_dev_attrib.block_size != 512)) { | 2988 | if (dev->se_sub_dev->se_dev_attrib.block_size != 512) { |
2996 | pr_err("Failing OVERFLOW/UNDERFLOW for LBA op" | 2989 | pr_err("Failing OVERFLOW/UNDERFLOW for LBA op" |
2997 | " CDB on non 512-byte sector setup subsystem" | 2990 | " CDB on non 512-byte sector setup subsystem" |
2998 | " plugin: %s\n", dev->transport->name); | 2991 | " plugin: %s\n", dev->transport->name); |
@@ -3032,8 +3025,7 @@ static int transport_generic_cmd_sequencer( | |||
3032 | (cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB))) | 3025 | (cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB))) |
3033 | goto out_unsupported_cdb; | 3026 | goto out_unsupported_cdb; |
3034 | 3027 | ||
3035 | transport_set_supported_SAM_opcode(cmd); | 3028 | return 0; |
3036 | return ret; | ||
3037 | 3029 | ||
3038 | out_unsupported_cdb: | 3030 | out_unsupported_cdb: |
3039 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | 3031 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; |
@@ -3967,10 +3959,7 @@ bool transport_wait_for_tasks(struct se_cmd *cmd) | |||
3967 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | 3959 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); |
3968 | return false; | 3960 | return false; |
3969 | } | 3961 | } |
3970 | /* | 3962 | |
3971 | * Only perform a possible wait_for_tasks if SCF_SUPPORTED_SAM_OPCODE | ||
3972 | * has been set in transport_set_supported_SAM_opcode(). | ||
3973 | */ | ||
3974 | if (!(cmd->se_cmd_flags & SCF_SUPPORTED_SAM_OPCODE) && | 3963 | if (!(cmd->se_cmd_flags & SCF_SUPPORTED_SAM_OPCODE) && |
3975 | !(cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)) { | 3964 | !(cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)) { |
3976 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | 3965 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); |