mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-16 16:46:43 +07:00
scsi: aacraid: Reworked scsi command submission path
Moved the READ and WRITE switch cases to the top. Added a default case to the switch case and replaced duplicate scsi result value with a macro. The idea is that since most of scsi commands we care about performance wise are read or write, we need to process them first. Internally the compiler (GCC) converts a switch case into either a jump table or a bunch of if else conditions, so placing the often used read, write cases at the top is an effort in optimization. Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com> Signed-off-by: Dave Carroll <David.Carroll@microsemi.com> Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
c83b11e31c
commit
c4e2fbca37
@ -106,6 +106,8 @@
|
|||||||
#define ASENCODE_LUN_FAILED_SELF_CONFIG 0x00
|
#define ASENCODE_LUN_FAILED_SELF_CONFIG 0x00
|
||||||
#define ASENCODE_OVERLAPPED_COMMAND 0x00
|
#define ASENCODE_OVERLAPPED_COMMAND 0x00
|
||||||
|
|
||||||
|
#define AAC_STAT_GOOD (DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD)
|
||||||
|
|
||||||
#define BYTE0(x) (unsigned char)(x)
|
#define BYTE0(x) (unsigned char)(x)
|
||||||
#define BYTE1(x) (unsigned char)((x) >> 8)
|
#define BYTE1(x) (unsigned char)((x) >> 8)
|
||||||
#define BYTE2(x) (unsigned char)((x) >> 16)
|
#define BYTE2(x) (unsigned char)((x) >> 16)
|
||||||
@ -2476,8 +2478,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
|||||||
if((cid >= dev->maximum_num_containers) ||
|
if((cid >= dev->maximum_num_containers) ||
|
||||||
(scsicmd->device->lun != 0)) {
|
(scsicmd->device->lun != 0)) {
|
||||||
scsicmd->result = DID_NO_CONNECT << 16;
|
scsicmd->result = DID_NO_CONNECT << 16;
|
||||||
scsicmd->scsi_done(scsicmd);
|
goto scsi_done_ret;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2512,8 +2513,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
|||||||
return aac_send_srb_fib(scsicmd);
|
return aac_send_srb_fib(scsicmd);
|
||||||
} else {
|
} else {
|
||||||
scsicmd->result = DID_NO_CONNECT << 16;
|
scsicmd->result = DID_NO_CONNECT << 16;
|
||||||
scsicmd->scsi_done(scsicmd);
|
goto scsi_done_ret;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2531,13 +2531,34 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
|||||||
memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
|
memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
|
||||||
min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data),
|
min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data),
|
||||||
SCSI_SENSE_BUFFERSIZE));
|
SCSI_SENSE_BUFFERSIZE));
|
||||||
scsicmd->scsi_done(scsicmd);
|
goto scsi_done_ret;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Handle commands here that don't really require going out to the adapter */
|
|
||||||
switch (scsicmd->cmnd[0]) {
|
switch (scsicmd->cmnd[0]) {
|
||||||
|
case READ_6:
|
||||||
|
case READ_10:
|
||||||
|
case READ_12:
|
||||||
|
case READ_16:
|
||||||
|
if (dev->in_reset)
|
||||||
|
return -1;
|
||||||
|
return aac_read(scsicmd);
|
||||||
|
|
||||||
|
case WRITE_6:
|
||||||
|
case WRITE_10:
|
||||||
|
case WRITE_12:
|
||||||
|
case WRITE_16:
|
||||||
|
if (dev->in_reset)
|
||||||
|
return -1;
|
||||||
|
return aac_write(scsicmd);
|
||||||
|
|
||||||
|
case SYNCHRONIZE_CACHE:
|
||||||
|
if (((aac_cache & 6) == 6) && dev->cache_protected) {
|
||||||
|
scsicmd->result = AAC_STAT_GOOD;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* Issue FIB to tell Firmware to flush it's cache */
|
||||||
|
if ((aac_cache & 6) != 2)
|
||||||
|
return aac_synchronize(scsicmd);
|
||||||
case INQUIRY:
|
case INQUIRY:
|
||||||
{
|
{
|
||||||
struct inquiry_data inq_data;
|
struct inquiry_data inq_data;
|
||||||
@ -2560,8 +2581,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
|||||||
arr[1] = scsicmd->cmnd[2];
|
arr[1] = scsicmd->cmnd[2];
|
||||||
scsi_sg_copy_from_buffer(scsicmd, &inq_data,
|
scsi_sg_copy_from_buffer(scsicmd, &inq_data,
|
||||||
sizeof(inq_data));
|
sizeof(inq_data));
|
||||||
scsicmd->result = DID_OK << 16 |
|
scsicmd->result = AAC_STAT_GOOD;
|
||||||
COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
|
|
||||||
} else if (scsicmd->cmnd[2] == 0x80) {
|
} else if (scsicmd->cmnd[2] == 0x80) {
|
||||||
/* unit serial number page */
|
/* unit serial number page */
|
||||||
arr[3] = setinqserial(dev, &arr[4],
|
arr[3] = setinqserial(dev, &arr[4],
|
||||||
@ -2572,8 +2592,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
|||||||
if (aac_wwn != 2)
|
if (aac_wwn != 2)
|
||||||
return aac_get_container_serial(
|
return aac_get_container_serial(
|
||||||
scsicmd);
|
scsicmd);
|
||||||
scsicmd->result = DID_OK << 16 |
|
scsicmd->result = AAC_STAT_GOOD;
|
||||||
COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
|
|
||||||
} else if (scsicmd->cmnd[2] == 0x83) {
|
} else if (scsicmd->cmnd[2] == 0x83) {
|
||||||
/* vpd page 0x83 - Device Identification Page */
|
/* vpd page 0x83 - Device Identification Page */
|
||||||
char *sno = (char *)&inq_data;
|
char *sno = (char *)&inq_data;
|
||||||
@ -2582,8 +2601,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
|||||||
if (aac_wwn != 2)
|
if (aac_wwn != 2)
|
||||||
return aac_get_container_serial(
|
return aac_get_container_serial(
|
||||||
scsicmd);
|
scsicmd);
|
||||||
scsicmd->result = DID_OK << 16 |
|
scsicmd->result = AAC_STAT_GOOD;
|
||||||
COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
|
|
||||||
} else {
|
} else {
|
||||||
/* vpd page not implemented */
|
/* vpd page not implemented */
|
||||||
scsicmd->result = DID_OK << 16 |
|
scsicmd->result = DID_OK << 16 |
|
||||||
@ -2598,8 +2616,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
|||||||
sizeof(dev->fsa_dev[cid].sense_data),
|
sizeof(dev->fsa_dev[cid].sense_data),
|
||||||
SCSI_SENSE_BUFFERSIZE));
|
SCSI_SENSE_BUFFERSIZE));
|
||||||
}
|
}
|
||||||
scsicmd->scsi_done(scsicmd);
|
break;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
inq_data.inqd_ver = 2; /* claim compliance to SCSI-2 */
|
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_rdf = 2; /* A response data format value of two indicates that the data shall be in the format specified in SCSI-2 */
|
||||||
@ -2615,9 +2632,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
|||||||
inq_data.inqd_pdt = INQD_PDT_PROC; /* Processor device */
|
inq_data.inqd_pdt = INQD_PDT_PROC; /* Processor device */
|
||||||
scsi_sg_copy_from_buffer(scsicmd, &inq_data,
|
scsi_sg_copy_from_buffer(scsicmd, &inq_data,
|
||||||
sizeof(inq_data));
|
sizeof(inq_data));
|
||||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
|
scsicmd->result = AAC_STAT_GOOD;
|
||||||
scsicmd->scsi_done(scsicmd);
|
break;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
if (dev->in_reset)
|
if (dev->in_reset)
|
||||||
return -1;
|
return -1;
|
||||||
@ -2665,10 +2681,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
|||||||
/* Do not cache partition table for arrays */
|
/* Do not cache partition table for arrays */
|
||||||
scsicmd->device->removable = 1;
|
scsicmd->device->removable = 1;
|
||||||
|
|
||||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
|
scsicmd->result = AAC_STAT_GOOD;
|
||||||
scsicmd->scsi_done(scsicmd);
|
break;
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case READ_CAPACITY:
|
case READ_CAPACITY:
|
||||||
@ -2693,11 +2707,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
|||||||
scsi_sg_copy_from_buffer(scsicmd, cp, sizeof(cp));
|
scsi_sg_copy_from_buffer(scsicmd, cp, sizeof(cp));
|
||||||
/* Do not cache partition table for arrays */
|
/* Do not cache partition table for arrays */
|
||||||
scsicmd->device->removable = 1;
|
scsicmd->device->removable = 1;
|
||||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
scsicmd->result = AAC_STAT_GOOD;
|
||||||
SAM_STAT_GOOD;
|
break;
|
||||||
scsicmd->scsi_done(scsicmd);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case MODE_SENSE:
|
case MODE_SENSE:
|
||||||
@ -2775,10 +2786,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
|||||||
scsi_sg_copy_from_buffer(scsicmd,
|
scsi_sg_copy_from_buffer(scsicmd,
|
||||||
(char *)&mpd,
|
(char *)&mpd,
|
||||||
mode_buf_length);
|
mode_buf_length);
|
||||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
|
scsicmd->result = AAC_STAT_GOOD;
|
||||||
scsicmd->scsi_done(scsicmd);
|
break;
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
case MODE_SENSE_10:
|
case MODE_SENSE_10:
|
||||||
{
|
{
|
||||||
@ -2854,18 +2863,17 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
|||||||
(char *)&mpd10,
|
(char *)&mpd10,
|
||||||
mode_buf_length);
|
mode_buf_length);
|
||||||
|
|
||||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
|
scsicmd->result = AAC_STAT_GOOD;
|
||||||
scsicmd->scsi_done(scsicmd);
|
break;
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
case REQUEST_SENSE:
|
case REQUEST_SENSE:
|
||||||
dprintk((KERN_DEBUG "REQUEST SENSE command.\n"));
|
dprintk((KERN_DEBUG "REQUEST SENSE command.\n"));
|
||||||
memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data, sizeof (struct sense_data));
|
memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
|
||||||
memset(&dev->fsa_dev[cid].sense_data, 0, sizeof (struct sense_data));
|
sizeof(struct sense_data));
|
||||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
|
memset(&dev->fsa_dev[cid].sense_data, 0,
|
||||||
scsicmd->scsi_done(scsicmd);
|
sizeof(struct sense_data));
|
||||||
return 0;
|
scsicmd->result = AAC_STAT_GOOD;
|
||||||
|
break;
|
||||||
|
|
||||||
case ALLOW_MEDIUM_REMOVAL:
|
case ALLOW_MEDIUM_REMOVAL:
|
||||||
dprintk((KERN_DEBUG "LOCK command.\n"));
|
dprintk((KERN_DEBUG "LOCK command.\n"));
|
||||||
@ -2874,9 +2882,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
|||||||
else
|
else
|
||||||
fsa_dev_ptr[cid].locked = 0;
|
fsa_dev_ptr[cid].locked = 0;
|
||||||
|
|
||||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
|
scsicmd->result = AAC_STAT_GOOD;
|
||||||
scsicmd->scsi_done(scsicmd);
|
break;
|
||||||
return 0;
|
|
||||||
/*
|
/*
|
||||||
* These commands are all No-Ops
|
* These commands are all No-Ops
|
||||||
*/
|
*/
|
||||||
@ -2892,80 +2899,41 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
|
|||||||
min_t(size_t,
|
min_t(size_t,
|
||||||
sizeof(dev->fsa_dev[cid].sense_data),
|
sizeof(dev->fsa_dev[cid].sense_data),
|
||||||
SCSI_SENSE_BUFFERSIZE));
|
SCSI_SENSE_BUFFERSIZE));
|
||||||
scsicmd->scsi_done(scsicmd);
|
break;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
/* FALLTHRU */
|
|
||||||
case RESERVE:
|
case RESERVE:
|
||||||
case RELEASE:
|
case RELEASE:
|
||||||
case REZERO_UNIT:
|
case REZERO_UNIT:
|
||||||
case REASSIGN_BLOCKS:
|
case REASSIGN_BLOCKS:
|
||||||
case SEEK_10:
|
case SEEK_10:
|
||||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
|
scsicmd->result = AAC_STAT_GOOD;
|
||||||
scsicmd->scsi_done(scsicmd);
|
break;
|
||||||
return 0;
|
|
||||||
|
|
||||||
case START_STOP:
|
case START_STOP:
|
||||||
return aac_start_stop(scsicmd);
|
return aac_start_stop(scsicmd);
|
||||||
}
|
|
||||||
|
|
||||||
switch (scsicmd->cmnd[0])
|
/* FALLTHRU */
|
||||||
{
|
default:
|
||||||
case READ_6:
|
/*
|
||||||
case READ_10:
|
* Unhandled commands
|
||||||
case READ_12:
|
*/
|
||||||
case READ_16:
|
dprintk((KERN_WARNING "Unhandled SCSI Command: 0x%x.\n",
|
||||||
if (dev->in_reset)
|
scsicmd->cmnd[0]));
|
||||||
return -1;
|
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
|
||||||
/*
|
SAM_STAT_CHECK_CONDITION;
|
||||||
* Hack to keep track of ordinal number of the device that
|
set_sense(&dev->fsa_dev[cid].sense_data,
|
||||||
* corresponds to a container. Needed to convert
|
|
||||||
* containers to /dev/sd device names
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (scsicmd->request->rq_disk)
|
|
||||||
strlcpy(fsa_dev_ptr[cid].devname,
|
|
||||||
scsicmd->request->rq_disk->disk_name,
|
|
||||||
min(sizeof(fsa_dev_ptr[cid].devname),
|
|
||||||
sizeof(scsicmd->request->rq_disk->disk_name) + 1));
|
|
||||||
|
|
||||||
return aac_read(scsicmd);
|
|
||||||
|
|
||||||
case WRITE_6:
|
|
||||||
case WRITE_10:
|
|
||||||
case WRITE_12:
|
|
||||||
case WRITE_16:
|
|
||||||
if (dev->in_reset)
|
|
||||||
return -1;
|
|
||||||
return aac_write(scsicmd);
|
|
||||||
|
|
||||||
case SYNCHRONIZE_CACHE:
|
|
||||||
if (((aac_cache & 6) == 6) && dev->cache_protected) {
|
|
||||||
scsicmd->result = DID_OK << 16 |
|
|
||||||
COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
|
|
||||||
scsicmd->scsi_done(scsicmd);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/* Issue FIB to tell Firmware to flush it's cache */
|
|
||||||
if ((aac_cache & 6) != 2)
|
|
||||||
return aac_synchronize(scsicmd);
|
|
||||||
/* FALLTHRU */
|
|
||||||
default:
|
|
||||||
/*
|
|
||||||
* Unhandled commands
|
|
||||||
*/
|
|
||||||
dprintk((KERN_WARNING "Unhandled SCSI Command: 0x%x.\n", scsicmd->cmnd[0]));
|
|
||||||
scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION;
|
|
||||||
set_sense(&dev->fsa_dev[cid].sense_data,
|
|
||||||
ILLEGAL_REQUEST, SENCODE_INVALID_COMMAND,
|
ILLEGAL_REQUEST, SENCODE_INVALID_COMMAND,
|
||||||
ASENCODE_INVALID_COMMAND, 0, 0);
|
ASENCODE_INVALID_COMMAND, 0, 0);
|
||||||
memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
|
memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
|
||||||
min_t(size_t,
|
min_t(size_t,
|
||||||
sizeof(dev->fsa_dev[cid].sense_data),
|
sizeof(dev->fsa_dev[cid].sense_data),
|
||||||
SCSI_SENSE_BUFFERSIZE));
|
SCSI_SENSE_BUFFERSIZE));
|
||||||
scsicmd->scsi_done(scsicmd);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scsi_done_ret:
|
||||||
|
|
||||||
|
scsicmd->scsi_done(scsicmd);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int query_disk(struct aac_dev *dev, void __user *arg)
|
static int query_disk(struct aac_dev *dev, void __user *arg)
|
||||||
|
Loading…
Reference in New Issue
Block a user