aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2012-05-20 11:59:10 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2012-07-16 20:25:55 -0400
commitcb4f4d3c7398a709b48d397e0520ee2509a953a4 (patch)
tree044ed92284a78cc2f0cb9fc69ca13bece0bd676c /drivers
parent1765fe5edcb83f53fc67edeb559fcf4bc82c6460 (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.c143
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
1892static 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 */
2383static int transport_generic_cmd_sequencer( 2425static 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
3038out_unsupported_cdb: 3030out_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);