diff options
Diffstat (limited to 'drivers/target')
-rw-r--r-- | drivers/target/iscsi/iscsi_target.c | 12 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_core.h | 4 | ||||
-rw-r--r-- | drivers/target/target_core_device.c | 54 | ||||
-rw-r--r-- | drivers/target/target_core_file.c | 12 | ||||
-rw-r--r-- | drivers/target/target_core_iblock.c | 3 | ||||
-rw-r--r-- | drivers/target/target_core_pr.c | 12 | ||||
-rw-r--r-- | drivers/target/target_core_rd.c | 1 | ||||
-rw-r--r-- | drivers/target/target_core_sbc.c | 15 | ||||
-rw-r--r-- | drivers/target/target_core_spc.c | 5 | ||||
-rw-r--r-- | drivers/target/target_core_user.c | 1 |
10 files changed, 36 insertions, 83 deletions
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 55f6774f706f..aebde3289c50 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c | |||
@@ -2027,10 +2027,10 @@ iscsit_process_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
2027 | goto reject; | 2027 | goto reject; |
2028 | } | 2028 | } |
2029 | if (!strncmp("=All", text_ptr, 4)) { | 2029 | if (!strncmp("=All", text_ptr, 4)) { |
2030 | cmd->cmd_flags |= IFC_SENDTARGETS_ALL; | 2030 | cmd->cmd_flags |= ICF_SENDTARGETS_ALL; |
2031 | } else if (!strncmp("=iqn.", text_ptr, 5) || | 2031 | } else if (!strncmp("=iqn.", text_ptr, 5) || |
2032 | !strncmp("=eui.", text_ptr, 5)) { | 2032 | !strncmp("=eui.", text_ptr, 5)) { |
2033 | cmd->cmd_flags |= IFC_SENDTARGETS_SINGLE; | 2033 | cmd->cmd_flags |= ICF_SENDTARGETS_SINGLE; |
2034 | } else { | 2034 | } else { |
2035 | pr_err("Unable to locate valid SendTargets=%s value\n", text_ptr); | 2035 | pr_err("Unable to locate valid SendTargets=%s value\n", text_ptr); |
2036 | goto reject; | 2036 | goto reject; |
@@ -3415,10 +3415,10 @@ iscsit_build_sendtargets_response(struct iscsi_cmd *cmd, | |||
3415 | return -ENOMEM; | 3415 | return -ENOMEM; |
3416 | } | 3416 | } |
3417 | /* | 3417 | /* |
3418 | * Locate pointer to iqn./eui. string for IFC_SENDTARGETS_SINGLE | 3418 | * Locate pointer to iqn./eui. string for ICF_SENDTARGETS_SINGLE |
3419 | * explicit case.. | 3419 | * explicit case.. |
3420 | */ | 3420 | */ |
3421 | if (cmd->cmd_flags & IFC_SENDTARGETS_SINGLE) { | 3421 | if (cmd->cmd_flags & ICF_SENDTARGETS_SINGLE) { |
3422 | text_ptr = strchr(text_in, '='); | 3422 | text_ptr = strchr(text_in, '='); |
3423 | if (!text_ptr) { | 3423 | if (!text_ptr) { |
3424 | pr_err("Unable to locate '=' string in text_in:" | 3424 | pr_err("Unable to locate '=' string in text_in:" |
@@ -3434,7 +3434,7 @@ iscsit_build_sendtargets_response(struct iscsi_cmd *cmd, | |||
3434 | 3434 | ||
3435 | spin_lock(&tiqn_lock); | 3435 | spin_lock(&tiqn_lock); |
3436 | list_for_each_entry(tiqn, &g_tiqn_list, tiqn_list) { | 3436 | list_for_each_entry(tiqn, &g_tiqn_list, tiqn_list) { |
3437 | if ((cmd->cmd_flags & IFC_SENDTARGETS_SINGLE) && | 3437 | if ((cmd->cmd_flags & ICF_SENDTARGETS_SINGLE) && |
3438 | strcmp(tiqn->tiqn, text_ptr)) { | 3438 | strcmp(tiqn->tiqn, text_ptr)) { |
3439 | continue; | 3439 | continue; |
3440 | } | 3440 | } |
@@ -3512,7 +3512,7 @@ eob: | |||
3512 | if (end_of_buf) | 3512 | if (end_of_buf) |
3513 | break; | 3513 | break; |
3514 | 3514 | ||
3515 | if (cmd->cmd_flags & IFC_SENDTARGETS_SINGLE) | 3515 | if (cmd->cmd_flags & ICF_SENDTARGETS_SINGLE) |
3516 | break; | 3516 | break; |
3517 | } | 3517 | } |
3518 | spin_unlock(&tiqn_lock); | 3518 | spin_unlock(&tiqn_lock); |
diff --git a/drivers/target/iscsi/iscsi_target_core.h b/drivers/target/iscsi/iscsi_target_core.h index 09a522bae222..cbcff38ac9b7 100644 --- a/drivers/target/iscsi/iscsi_target_core.h +++ b/drivers/target/iscsi/iscsi_target_core.h | |||
@@ -135,8 +135,8 @@ enum cmd_flags_table { | |||
135 | ICF_CONTIG_MEMORY = 0x00000020, | 135 | ICF_CONTIG_MEMORY = 0x00000020, |
136 | ICF_ATTACHED_TO_RQUEUE = 0x00000040, | 136 | ICF_ATTACHED_TO_RQUEUE = 0x00000040, |
137 | ICF_OOO_CMDSN = 0x00000080, | 137 | ICF_OOO_CMDSN = 0x00000080, |
138 | IFC_SENDTARGETS_ALL = 0x00000100, | 138 | ICF_SENDTARGETS_ALL = 0x00000100, |
139 | IFC_SENDTARGETS_SINGLE = 0x00000200, | 139 | ICF_SENDTARGETS_SINGLE = 0x00000200, |
140 | }; | 140 | }; |
141 | 141 | ||
142 | /* struct iscsi_cmd->i_state */ | 142 | /* struct iscsi_cmd->i_state */ |
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 7653cfb027a2..58f49ff69b14 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c | |||
@@ -1103,51 +1103,6 @@ int se_dev_set_queue_depth(struct se_device *dev, u32 queue_depth) | |||
1103 | } | 1103 | } |
1104 | EXPORT_SYMBOL(se_dev_set_queue_depth); | 1104 | EXPORT_SYMBOL(se_dev_set_queue_depth); |
1105 | 1105 | ||
1106 | int se_dev_set_fabric_max_sectors(struct se_device *dev, u32 fabric_max_sectors) | ||
1107 | { | ||
1108 | int block_size = dev->dev_attrib.block_size; | ||
1109 | |||
1110 | if (dev->export_count) { | ||
1111 | pr_err("dev[%p]: Unable to change SE Device" | ||
1112 | " fabric_max_sectors while export_count is %d\n", | ||
1113 | dev, dev->export_count); | ||
1114 | return -EINVAL; | ||
1115 | } | ||
1116 | if (!fabric_max_sectors) { | ||
1117 | pr_err("dev[%p]: Illegal ZERO value for" | ||
1118 | " fabric_max_sectors\n", dev); | ||
1119 | return -EINVAL; | ||
1120 | } | ||
1121 | if (fabric_max_sectors < DA_STATUS_MAX_SECTORS_MIN) { | ||
1122 | pr_err("dev[%p]: Passed fabric_max_sectors: %u less than" | ||
1123 | " DA_STATUS_MAX_SECTORS_MIN: %u\n", dev, fabric_max_sectors, | ||
1124 | DA_STATUS_MAX_SECTORS_MIN); | ||
1125 | return -EINVAL; | ||
1126 | } | ||
1127 | if (fabric_max_sectors > DA_STATUS_MAX_SECTORS_MAX) { | ||
1128 | pr_err("dev[%p]: Passed fabric_max_sectors: %u" | ||
1129 | " greater than DA_STATUS_MAX_SECTORS_MAX:" | ||
1130 | " %u\n", dev, fabric_max_sectors, | ||
1131 | DA_STATUS_MAX_SECTORS_MAX); | ||
1132 | return -EINVAL; | ||
1133 | } | ||
1134 | /* | ||
1135 | * Align max_sectors down to PAGE_SIZE to follow transport_allocate_data_tasks() | ||
1136 | */ | ||
1137 | if (!block_size) { | ||
1138 | block_size = 512; | ||
1139 | pr_warn("Defaulting to 512 for zero block_size\n"); | ||
1140 | } | ||
1141 | fabric_max_sectors = se_dev_align_max_sectors(fabric_max_sectors, | ||
1142 | block_size); | ||
1143 | |||
1144 | dev->dev_attrib.fabric_max_sectors = fabric_max_sectors; | ||
1145 | pr_debug("dev[%p]: SE Device max_sectors changed to %u\n", | ||
1146 | dev, fabric_max_sectors); | ||
1147 | return 0; | ||
1148 | } | ||
1149 | EXPORT_SYMBOL(se_dev_set_fabric_max_sectors); | ||
1150 | |||
1151 | int se_dev_set_optimal_sectors(struct se_device *dev, u32 optimal_sectors) | 1106 | int se_dev_set_optimal_sectors(struct se_device *dev, u32 optimal_sectors) |
1152 | { | 1107 | { |
1153 | if (dev->export_count) { | 1108 | if (dev->export_count) { |
@@ -1156,10 +1111,10 @@ int se_dev_set_optimal_sectors(struct se_device *dev, u32 optimal_sectors) | |||
1156 | dev, dev->export_count); | 1111 | dev, dev->export_count); |
1157 | return -EINVAL; | 1112 | return -EINVAL; |
1158 | } | 1113 | } |
1159 | if (optimal_sectors > dev->dev_attrib.fabric_max_sectors) { | 1114 | if (optimal_sectors > dev->dev_attrib.hw_max_sectors) { |
1160 | pr_err("dev[%p]: Passed optimal_sectors %u cannot be" | 1115 | pr_err("dev[%p]: Passed optimal_sectors %u cannot be" |
1161 | " greater than fabric_max_sectors: %u\n", dev, | 1116 | " greater than hw_max_sectors: %u\n", dev, |
1162 | optimal_sectors, dev->dev_attrib.fabric_max_sectors); | 1117 | optimal_sectors, dev->dev_attrib.hw_max_sectors); |
1163 | return -EINVAL; | 1118 | return -EINVAL; |
1164 | } | 1119 | } |
1165 | 1120 | ||
@@ -1553,8 +1508,6 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name) | |||
1553 | dev->dev_attrib.unmap_granularity_alignment = | 1508 | dev->dev_attrib.unmap_granularity_alignment = |
1554 | DA_UNMAP_GRANULARITY_ALIGNMENT_DEFAULT; | 1509 | DA_UNMAP_GRANULARITY_ALIGNMENT_DEFAULT; |
1555 | dev->dev_attrib.max_write_same_len = DA_MAX_WRITE_SAME_LEN; | 1510 | dev->dev_attrib.max_write_same_len = DA_MAX_WRITE_SAME_LEN; |
1556 | dev->dev_attrib.fabric_max_sectors = DA_FABRIC_MAX_SECTORS; | ||
1557 | dev->dev_attrib.optimal_sectors = DA_FABRIC_MAX_SECTORS; | ||
1558 | 1511 | ||
1559 | xcopy_lun = &dev->xcopy_lun; | 1512 | xcopy_lun = &dev->xcopy_lun; |
1560 | xcopy_lun->lun_se_dev = dev; | 1513 | xcopy_lun->lun_se_dev = dev; |
@@ -1595,6 +1548,7 @@ int target_configure_device(struct se_device *dev) | |||
1595 | dev->dev_attrib.hw_max_sectors = | 1548 | dev->dev_attrib.hw_max_sectors = |
1596 | se_dev_align_max_sectors(dev->dev_attrib.hw_max_sectors, | 1549 | se_dev_align_max_sectors(dev->dev_attrib.hw_max_sectors, |
1597 | dev->dev_attrib.hw_block_size); | 1550 | dev->dev_attrib.hw_block_size); |
1551 | dev->dev_attrib.optimal_sectors = dev->dev_attrib.hw_max_sectors; | ||
1598 | 1552 | ||
1599 | dev->dev_index = scsi_get_new_index(SCSI_DEVICE_INDEX); | 1553 | dev->dev_index = scsi_get_new_index(SCSI_DEVICE_INDEX); |
1600 | dev->creation_time = get_jiffies_64(); | 1554 | dev->creation_time = get_jiffies_64(); |
diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c index c2aea099ea4a..d836de200a03 100644 --- a/drivers/target/target_core_file.c +++ b/drivers/target/target_core_file.c | |||
@@ -621,7 +621,16 @@ fd_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents, | |||
621 | struct fd_prot fd_prot; | 621 | struct fd_prot fd_prot; |
622 | sense_reason_t rc; | 622 | sense_reason_t rc; |
623 | int ret = 0; | 623 | int ret = 0; |
624 | 624 | /* | |
625 | * We are currently limited by the number of iovecs (2048) per | ||
626 | * single vfs_[writev,readv] call. | ||
627 | */ | ||
628 | if (cmd->data_length > FD_MAX_BYTES) { | ||
629 | pr_err("FILEIO: Not able to process I/O of %u bytes due to" | ||
630 | "FD_MAX_BYTES: %u iovec count limitiation\n", | ||
631 | cmd->data_length, FD_MAX_BYTES); | ||
632 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
633 | } | ||
625 | /* | 634 | /* |
626 | * Call vectorized fileio functions to map struct scatterlist | 635 | * Call vectorized fileio functions to map struct scatterlist |
627 | * physical memory addresses to struct iovec virtual memory. | 636 | * physical memory addresses to struct iovec virtual memory. |
@@ -959,7 +968,6 @@ static struct configfs_attribute *fileio_backend_dev_attrs[] = { | |||
959 | &fileio_dev_attrib_hw_block_size.attr, | 968 | &fileio_dev_attrib_hw_block_size.attr, |
960 | &fileio_dev_attrib_block_size.attr, | 969 | &fileio_dev_attrib_block_size.attr, |
961 | &fileio_dev_attrib_hw_max_sectors.attr, | 970 | &fileio_dev_attrib_hw_max_sectors.attr, |
962 | &fileio_dev_attrib_fabric_max_sectors.attr, | ||
963 | &fileio_dev_attrib_optimal_sectors.attr, | 971 | &fileio_dev_attrib_optimal_sectors.attr, |
964 | &fileio_dev_attrib_hw_queue_depth.attr, | 972 | &fileio_dev_attrib_hw_queue_depth.attr, |
965 | &fileio_dev_attrib_queue_depth.attr, | 973 | &fileio_dev_attrib_queue_depth.attr, |
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c index 3efff94fbd97..78346b850968 100644 --- a/drivers/target/target_core_iblock.c +++ b/drivers/target/target_core_iblock.c | |||
@@ -124,7 +124,7 @@ static int iblock_configure_device(struct se_device *dev) | |||
124 | q = bdev_get_queue(bd); | 124 | q = bdev_get_queue(bd); |
125 | 125 | ||
126 | dev->dev_attrib.hw_block_size = bdev_logical_block_size(bd); | 126 | dev->dev_attrib.hw_block_size = bdev_logical_block_size(bd); |
127 | dev->dev_attrib.hw_max_sectors = UINT_MAX; | 127 | dev->dev_attrib.hw_max_sectors = queue_max_hw_sectors(q); |
128 | dev->dev_attrib.hw_queue_depth = q->nr_requests; | 128 | dev->dev_attrib.hw_queue_depth = q->nr_requests; |
129 | 129 | ||
130 | /* | 130 | /* |
@@ -883,7 +883,6 @@ static struct configfs_attribute *iblock_backend_dev_attrs[] = { | |||
883 | &iblock_dev_attrib_hw_block_size.attr, | 883 | &iblock_dev_attrib_hw_block_size.attr, |
884 | &iblock_dev_attrib_block_size.attr, | 884 | &iblock_dev_attrib_block_size.attr, |
885 | &iblock_dev_attrib_hw_max_sectors.attr, | 885 | &iblock_dev_attrib_hw_max_sectors.attr, |
886 | &iblock_dev_attrib_fabric_max_sectors.attr, | ||
887 | &iblock_dev_attrib_optimal_sectors.attr, | 886 | &iblock_dev_attrib_optimal_sectors.attr, |
888 | &iblock_dev_attrib_hw_queue_depth.attr, | 887 | &iblock_dev_attrib_hw_queue_depth.attr, |
889 | &iblock_dev_attrib_queue_depth.attr, | 888 | &iblock_dev_attrib_queue_depth.attr, |
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index d56f2aaba9af..283cf786ef98 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c | |||
@@ -528,6 +528,18 @@ static int core_scsi3_pr_seq_non_holder( | |||
528 | 528 | ||
529 | return 0; | 529 | return 0; |
530 | } | 530 | } |
531 | } else if (we && registered_nexus) { | ||
532 | /* | ||
533 | * Reads are allowed for Write Exclusive locks | ||
534 | * from all registrants. | ||
535 | */ | ||
536 | if (cmd->data_direction == DMA_FROM_DEVICE) { | ||
537 | pr_debug("Allowing READ CDB: 0x%02x for %s" | ||
538 | " reservation\n", cdb[0], | ||
539 | core_scsi3_pr_dump_type(pr_reg_type)); | ||
540 | |||
541 | return 0; | ||
542 | } | ||
531 | } | 543 | } |
532 | pr_debug("%s Conflict for %sregistered nexus %s CDB: 0x%2x" | 544 | pr_debug("%s Conflict for %sregistered nexus %s CDB: 0x%2x" |
533 | " for %s reservation\n", transport_dump_cmd_direction(cmd), | 545 | " for %s reservation\n", transport_dump_cmd_direction(cmd), |
diff --git a/drivers/target/target_core_rd.c b/drivers/target/target_core_rd.c index 60ebd170a561..98e83ac5661b 100644 --- a/drivers/target/target_core_rd.c +++ b/drivers/target/target_core_rd.c | |||
@@ -657,7 +657,6 @@ static struct configfs_attribute *rd_mcp_backend_dev_attrs[] = { | |||
657 | &rd_mcp_dev_attrib_hw_block_size.attr, | 657 | &rd_mcp_dev_attrib_hw_block_size.attr, |
658 | &rd_mcp_dev_attrib_block_size.attr, | 658 | &rd_mcp_dev_attrib_block_size.attr, |
659 | &rd_mcp_dev_attrib_hw_max_sectors.attr, | 659 | &rd_mcp_dev_attrib_hw_max_sectors.attr, |
660 | &rd_mcp_dev_attrib_fabric_max_sectors.attr, | ||
661 | &rd_mcp_dev_attrib_optimal_sectors.attr, | 660 | &rd_mcp_dev_attrib_optimal_sectors.attr, |
662 | &rd_mcp_dev_attrib_hw_queue_depth.attr, | 661 | &rd_mcp_dev_attrib_hw_queue_depth.attr, |
663 | &rd_mcp_dev_attrib_queue_depth.attr, | 662 | &rd_mcp_dev_attrib_queue_depth.attr, |
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index 11bea1952435..cd4bed7b2757 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c | |||
@@ -953,21 +953,6 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) | |||
953 | 953 | ||
954 | if (cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) { | 954 | if (cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) { |
955 | unsigned long long end_lba; | 955 | unsigned long long end_lba; |
956 | |||
957 | if (sectors > dev->dev_attrib.fabric_max_sectors) { | ||
958 | printk_ratelimited(KERN_ERR "SCSI OP %02xh with too" | ||
959 | " big sectors %u exceeds fabric_max_sectors:" | ||
960 | " %u\n", cdb[0], sectors, | ||
961 | dev->dev_attrib.fabric_max_sectors); | ||
962 | return TCM_INVALID_CDB_FIELD; | ||
963 | } | ||
964 | if (sectors > dev->dev_attrib.hw_max_sectors) { | ||
965 | printk_ratelimited(KERN_ERR "SCSI OP %02xh with too" | ||
966 | " big sectors %u exceeds backend hw_max_sectors:" | ||
967 | " %u\n", cdb[0], sectors, | ||
968 | dev->dev_attrib.hw_max_sectors); | ||
969 | return TCM_INVALID_CDB_FIELD; | ||
970 | } | ||
971 | check_lba: | 956 | check_lba: |
972 | end_lba = dev->transport->get_blocks(dev) + 1; | 957 | end_lba = dev->transport->get_blocks(dev) + 1; |
973 | if (cmd->t_task_lba + sectors > end_lba) { | 958 | if (cmd->t_task_lba + sectors > end_lba) { |
diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c index 1307600fe726..4c71657da56a 100644 --- a/drivers/target/target_core_spc.c +++ b/drivers/target/target_core_spc.c | |||
@@ -505,7 +505,6 @@ static sense_reason_t | |||
505 | spc_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf) | 505 | spc_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf) |
506 | { | 506 | { |
507 | struct se_device *dev = cmd->se_dev; | 507 | struct se_device *dev = cmd->se_dev; |
508 | u32 max_sectors; | ||
509 | int have_tp = 0; | 508 | int have_tp = 0; |
510 | int opt, min; | 509 | int opt, min; |
511 | 510 | ||
@@ -539,9 +538,7 @@ spc_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf) | |||
539 | /* | 538 | /* |
540 | * Set MAXIMUM TRANSFER LENGTH | 539 | * Set MAXIMUM TRANSFER LENGTH |
541 | */ | 540 | */ |
542 | max_sectors = min(dev->dev_attrib.fabric_max_sectors, | 541 | put_unaligned_be32(dev->dev_attrib.hw_max_sectors, &buf[8]); |
543 | dev->dev_attrib.hw_max_sectors); | ||
544 | put_unaligned_be32(max_sectors, &buf[8]); | ||
545 | 542 | ||
546 | /* | 543 | /* |
547 | * Set OPTIMAL TRANSFER LENGTH | 544 | * Set OPTIMAL TRANSFER LENGTH |
diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c index 8bfa61c9693d..1157b559683b 100644 --- a/drivers/target/target_core_user.c +++ b/drivers/target/target_core_user.c | |||
@@ -1118,7 +1118,6 @@ static struct configfs_attribute *tcmu_backend_dev_attrs[] = { | |||
1118 | &tcmu_dev_attrib_hw_block_size.attr, | 1118 | &tcmu_dev_attrib_hw_block_size.attr, |
1119 | &tcmu_dev_attrib_block_size.attr, | 1119 | &tcmu_dev_attrib_block_size.attr, |
1120 | &tcmu_dev_attrib_hw_max_sectors.attr, | 1120 | &tcmu_dev_attrib_hw_max_sectors.attr, |
1121 | &tcmu_dev_attrib_fabric_max_sectors.attr, | ||
1122 | &tcmu_dev_attrib_optimal_sectors.attr, | 1121 | &tcmu_dev_attrib_optimal_sectors.attr, |
1123 | &tcmu_dev_attrib_hw_queue_depth.attr, | 1122 | &tcmu_dev_attrib_hw_queue_depth.attr, |
1124 | &tcmu_dev_attrib_queue_depth.attr, | 1123 | &tcmu_dev_attrib_queue_depth.attr, |