Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 344721
b: refs/heads/master
c: d1b1f80
h: refs/heads/master
i:
  344719: 2b608d9
v: v3
  • Loading branch information
Christoph Hellwig authored and Nicholas Bellinger committed Nov 7, 2012
1 parent 4106257 commit 0f0b02f
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 66 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9e999a6c51fe74a41a76038c64ce038ff9243bfb
refs/heads/master: d1b1f8053401aaf1dfe636afa6d361301e3ae8b7
63 changes: 0 additions & 63 deletions trunk/drivers/target/target_core_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -646,69 +646,6 @@ void core_dev_unexport(
lun->lun_se_dev = NULL;
}

int target_report_luns(struct se_cmd *se_cmd)
{
struct se_dev_entry *deve;
struct se_session *se_sess = se_cmd->se_sess;
unsigned char *buf;
u32 lun_count = 0, offset = 8, i;

if (se_cmd->data_length < 16) {
pr_warn("REPORT LUNS allocation length %u too small\n",
se_cmd->data_length);
se_cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
return -EINVAL;
}

buf = transport_kmap_data_sg(se_cmd);
if (!buf)
return -ENOMEM;

/*
* If no struct se_session pointer is present, this struct se_cmd is
* coming via a target_core_mod PASSTHROUGH op, and not through
* a $FABRIC_MOD. In that case, report LUN=0 only.
*/
if (!se_sess) {
int_to_scsilun(0, (struct scsi_lun *)&buf[offset]);
lun_count = 1;
goto done;
}

spin_lock_irq(&se_sess->se_node_acl->device_list_lock);
for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) {
deve = se_sess->se_node_acl->device_list[i];
if (!(deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS))
continue;
/*
* We determine the correct LUN LIST LENGTH even once we
* have reached the initial allocation length.
* See SPC2-R20 7.19.
*/
lun_count++;
if ((offset + 8) > se_cmd->data_length)
continue;

int_to_scsilun(deve->mapped_lun, (struct scsi_lun *)&buf[offset]);
offset += 8;
}
spin_unlock_irq(&se_sess->se_node_acl->device_list_lock);

/*
* See SPC3 r07, page 159.
*/
done:
lun_count *= 8;
buf[0] = ((lun_count >> 24) & 0xff);
buf[1] = ((lun_count >> 16) & 0xff);
buf[2] = ((lun_count >> 8) & 0xff);
buf[3] = (lun_count & 0xff);
transport_kunmap_data_sg(se_cmd);

target_complete_cmd(se_cmd, GOOD);
return 0;
}

static void se_release_vpd_for_dev(struct se_device *dev)
{
struct t10_vpd *vpd, *vpd_tmp;
Expand Down
1 change: 0 additions & 1 deletion trunk/drivers/target/target_core_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ int core_dev_export(struct se_device *, struct se_portal_group *,
struct se_lun *);
void core_dev_unexport(struct se_device *, struct se_portal_group *,
struct se_lun *);
int target_report_luns(struct se_cmd *);
int se_dev_set_task_timeout(struct se_device *, u32);
int se_dev_set_max_unmap_lba_count(struct se_device *, u32);
int se_dev_set_max_unmap_block_desc_count(struct se_device *, u32);
Expand Down
65 changes: 64 additions & 1 deletion trunk/drivers/target/target_core_spc.c
Original file line number Diff line number Diff line change
Expand Up @@ -908,6 +908,69 @@ static int spc_emulate_request_sense(struct se_cmd *cmd)
return 0;
}

static int spc_emulate_report_luns(struct se_cmd *cmd)
{
struct se_dev_entry *deve;
struct se_session *sess = cmd->se_sess;
unsigned char *buf;
u32 lun_count = 0, offset = 8, i;

if (cmd->data_length < 16) {
pr_warn("REPORT LUNS allocation length %u too small\n",
cmd->data_length);
cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
return -EINVAL;
}

buf = transport_kmap_data_sg(cmd);
if (!buf)
return -ENOMEM;

/*
* If no struct se_session pointer is present, this struct se_cmd is
* coming via a target_core_mod PASSTHROUGH op, and not through
* a $FABRIC_MOD. In that case, report LUN=0 only.
*/
if (!sess) {
int_to_scsilun(0, (struct scsi_lun *)&buf[offset]);
lun_count = 1;
goto done;
}

spin_lock_irq(&sess->se_node_acl->device_list_lock);
for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) {
deve = sess->se_node_acl->device_list[i];
if (!(deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS))
continue;
/*
* We determine the correct LUN LIST LENGTH even once we
* have reached the initial allocation length.
* See SPC2-R20 7.19.
*/
lun_count++;
if ((offset + 8) > cmd->data_length)
continue;

int_to_scsilun(deve->mapped_lun, (struct scsi_lun *)&buf[offset]);
offset += 8;
}
spin_unlock_irq(&sess->se_node_acl->device_list_lock);

/*
* See SPC3 r07, page 159.
*/
done:
lun_count *= 8;
buf[0] = ((lun_count >> 24) & 0xff);
buf[1] = ((lun_count >> 16) & 0xff);
buf[2] = ((lun_count >> 8) & 0xff);
buf[3] = (lun_count & 0xff);
transport_kunmap_data_sg(cmd);

target_complete_cmd(cmd, GOOD);
return 0;
}

static int spc_emulate_testunitready(struct se_cmd *cmd)
{
target_complete_cmd(cmd, GOOD);
Expand Down Expand Up @@ -1013,7 +1076,7 @@ int spc_parse_cdb(struct se_cmd *cmd, unsigned int *size)
*size = (cdb[6] << 16) + (cdb[7] << 8) + cdb[8];
break;
case REPORT_LUNS:
cmd->execute_cmd = target_report_luns;
cmd->execute_cmd = spc_emulate_report_luns;
*size = (cdb[6] << 24) | (cdb[7] << 16) | (cdb[8] << 8) | cdb[9];
/*
* Do implict HEAD_OF_QUEUE processing for REPORT_LUNS
Expand Down

0 comments on commit 0f0b02f

Please sign in to comment.