Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 62716
b: refs/heads/master
c: 88e2f98
h: refs/heads/master
v: v3
  • Loading branch information
Salyzyn, Mark authored and James Bottomley committed Jul 18, 2007
1 parent bfe0530 commit eb84a76
Show file tree
Hide file tree
Showing 3 changed files with 153 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9ad5204d68a3b48b92907d88d1c28d33fde6ba2a
refs/heads/master: 88e2f98e1b3eb27ae708daa3b37dd50f3f06c952
138 changes: 138 additions & 0 deletions trunk/drivers/scsi/aacraid/aachba.c
Original file line number Diff line number Diff line change
Expand Up @@ -751,6 +751,101 @@ static void setinqstr(struct aac_dev *dev, void *data, int tindex)
inqstrcpy ("V1.0", str->prl);
}

static void get_container_serial_callback(void *context, struct fib * fibptr)
{
struct aac_get_serial_resp * get_serial_reply;
struct scsi_cmnd * scsicmd;

BUG_ON(fibptr == NULL);

scsicmd = (struct scsi_cmnd *) context;
if (!aac_valid_context(scsicmd, fibptr))
return;

get_serial_reply = (struct aac_get_serial_resp *) fib_data(fibptr);
/* Failure is irrelevant, using default value instead */
if (le32_to_cpu(get_serial_reply->status) == CT_OK) {
char sp[13];
/* EVPD bit set */
sp[0] = INQD_PDT_DA;
sp[1] = scsicmd->cmnd[2];
sp[2] = 0;
sp[3] = snprintf(sp+4, sizeof(sp)-4, "%08X",
le32_to_cpu(get_serial_reply->uid));
aac_internal_transfer(scsicmd, sp, 0, sizeof(sp));
}

scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;

aac_fib_complete(fibptr);
aac_fib_free(fibptr);
scsicmd->scsi_done(scsicmd);
}

/**
* aac_get_container_serial - get container serial, none blocking.
*/
static int aac_get_container_serial(struct scsi_cmnd * scsicmd)
{
int status;
struct aac_get_serial *dinfo;
struct fib * cmd_fibcontext;
struct aac_dev * dev;

dev = (struct aac_dev *)scsicmd->device->host->hostdata;

if (!(cmd_fibcontext = aac_fib_alloc(dev)))
return -ENOMEM;

aac_fib_init(cmd_fibcontext);
dinfo = (struct aac_get_serial *) fib_data(cmd_fibcontext);

dinfo->command = cpu_to_le32(VM_ContainerConfig);
dinfo->type = cpu_to_le32(CT_CID_TO_32BITS_UID);
dinfo->cid = cpu_to_le32(scmd_id(scsicmd));

status = aac_fib_send(ContainerCommand,
cmd_fibcontext,
sizeof (struct aac_get_serial),
FsaNormal,
0, 1,
(fib_callback) get_container_serial_callback,
(void *) scsicmd);

/*
* Check that the command queued to the controller
*/
if (status == -EINPROGRESS) {
scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
return 0;
}

printk(KERN_WARNING "aac_get_container_serial: aac_fib_send failed with status: %d.\n", status);
aac_fib_complete(cmd_fibcontext);
aac_fib_free(cmd_fibcontext);
return -1;
}

/* Function: setinqserial
*
* Arguments: [1] pointer to void [1] int
*
* Purpose: Sets SCSI Unit Serial number.
* This is a fake. We should read a proper
* serial number from the container. <SuSE>But
* without docs it's quite hard to do it :-)
* So this will have to do in the meantime.</SuSE>
*/

static int setinqserial(struct aac_dev *dev, void *data, int cid)
{
/*
* This breaks array migration.
*/
return snprintf((char *)(data), sizeof(struct scsi_inq) - 4, "%08X%02X",
le32_to_cpu(dev->adapter_info.serial[0]), cid);
}

static void set_sense(u8 *sense_buf, u8 sense_key, u8 sense_code,
u8 a_sense_code, u8 incorrect_length,
u8 bit_pointer, u16 field_pointer,
Expand Down Expand Up @@ -1798,6 +1893,49 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
dprintk((KERN_DEBUG "INQUIRY command, ID: %d.\n", cid));
memset(&inq_data, 0, sizeof (struct inquiry_data));

if (scsicmd->cmnd[1] & 0x1 ) {
char *arr = (char *)&inq_data;

/* EVPD bit set */
arr[0] = (scmd_id(scsicmd) == host->this_id) ?
INQD_PDT_PROC : INQD_PDT_DA;
if (scsicmd->cmnd[2] == 0) {
/* supported vital product data pages */
arr[3] = 2;
arr[4] = 0x0;
arr[5] = 0x80;
arr[1] = scsicmd->cmnd[2];
aac_internal_transfer(scsicmd, &inq_data, 0,
sizeof(inq_data));
scsicmd->result = DID_OK << 16 |
COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
} else if (scsicmd->cmnd[2] == 0x80) {
/* unit serial number page */
arr[3] = setinqserial(dev, &arr[4],
scmd_id(scsicmd));
arr[1] = scsicmd->cmnd[2];
aac_internal_transfer(scsicmd, &inq_data, 0,
sizeof(inq_data));
return aac_get_container_serial(scsicmd);
} else {
/* vpd page not implemented */
scsicmd->result = DID_OK << 16 |
COMMAND_COMPLETE << 8 |
SAM_STAT_CHECK_CONDITION;
set_sense((u8 *) &dev->fsa_dev[cid].sense_data,
ILLEGAL_REQUEST,
SENCODE_INVALID_CDB_FIELD,
ASENCODE_NO_SENSE, 0, 7, 2, 0);
memcpy(scsicmd->sense_buffer,
&dev->fsa_dev[cid].sense_data,
(sizeof(dev->fsa_dev[cid].sense_data) >
sizeof(scsicmd->sense_buffer))
? sizeof(scsicmd->sense_buffer)
: sizeof(dev->fsa_dev[cid].sense_data));
}
scsicmd->scsi_done(scsicmd);
return 0;
}
inq_data.inqd_ver = 2; /* claim compliance to SCSI-2 */
inq_data.inqd_rdf = 2; /* A response data format value of two indicates that the data shall be in the format specified in SCSI-2 */
inq_data.inqd_len = 31;
Expand Down
14 changes: 14 additions & 0 deletions trunk/drivers/scsi/aacraid/aacraid.h
Original file line number Diff line number Diff line change
Expand Up @@ -1567,6 +1567,20 @@ struct aac_get_name_resp {
u8 data[16];
};

#define CT_CID_TO_32BITS_UID 165
struct aac_get_serial {
__le32 command; /* VM_ContainerConfig */
__le32 type; /* CT_CID_TO_32BITS_UID */
__le32 cid;
};

struct aac_get_serial_resp {
__le32 dummy0;
__le32 dummy1;
__le32 status; /* CT_OK */
__le32 uid;
};

/*
* The following command is sent to shut down each container.
*/
Expand Down

0 comments on commit eb84a76

Please sign in to comment.