Commit 3df824af authored by Ching Huang's avatar Ching Huang Committed by Christoph Hellwig

arcmsr: limit max. number of SCSI command request

This patch limits the max. number of SCSI commmand request to avoid command
overflow.
Signed-off-by: default avatarChing Huang <ching2048@areca.com.tw>
Reviewed-by: default avatarTomas Henzl <thenzl@redhat.com>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
parent 61cda87f
...@@ -45,11 +45,12 @@ ...@@ -45,11 +45,12 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
struct device_attribute; struct device_attribute;
/*The limit of outstanding scsi command that firmware can handle*/ /*The limit of outstanding scsi command that firmware can handle*/
#define ARCMSR_MAX_OUTSTANDING_CMD 256
#ifdef CONFIG_XEN #ifdef CONFIG_XEN
#define ARCMSR_MAX_FREECCB_NUM 160 #define ARCMSR_MAX_FREECCB_NUM 160
#define ARCMSR_MAX_OUTSTANDING_CMD 155
#else #else
#define ARCMSR_MAX_FREECCB_NUM 320 #define ARCMSR_MAX_FREECCB_NUM 320
#define ARCMSR_MAX_OUTSTANDING_CMD 255
#endif #endif
#define ARCMSR_DRIVER_VERSION "v1.30.00.04-20140428" #define ARCMSR_DRIVER_VERSION "v1.30.00.04-20140428"
#define ARCMSR_SCSI_INITIATOR_ID 255 #define ARCMSR_SCSI_INITIATOR_ID 255
...@@ -598,6 +599,7 @@ struct AdapterControlBlock ...@@ -598,6 +599,7 @@ struct AdapterControlBlock
#define FW_DEADLOCK 0x0010 #define FW_DEADLOCK 0x0010
atomic_t rq_map_token; atomic_t rq_map_token;
atomic_t ante_token_value; atomic_t ante_token_value;
uint32_t maxOutstanding;
int msix_vector_count; int msix_vector_count;
};/* HW_DEVICE_EXTENSION */ };/* HW_DEVICE_EXTENSION */
/* /*
......
...@@ -134,7 +134,7 @@ static struct scsi_host_template arcmsr_scsi_host_template = { ...@@ -134,7 +134,7 @@ static struct scsi_host_template arcmsr_scsi_host_template = {
.eh_bus_reset_handler = arcmsr_bus_reset, .eh_bus_reset_handler = arcmsr_bus_reset,
.bios_param = arcmsr_bios_param, .bios_param = arcmsr_bios_param,
.change_queue_depth = arcmsr_adjust_disk_queue_depth, .change_queue_depth = arcmsr_adjust_disk_queue_depth,
.can_queue = ARCMSR_MAX_FREECCB_NUM, .can_queue = ARCMSR_MAX_OUTSTANDING_CMD,
.this_id = ARCMSR_SCSI_INITIATOR_ID, .this_id = ARCMSR_SCSI_INITIATOR_ID,
.sg_tablesize = ARCMSR_DEFAULT_SG_ENTRIES, .sg_tablesize = ARCMSR_DEFAULT_SG_ENTRIES,
.max_sectors = ARCMSR_MAX_XFER_SECTORS_C, .max_sectors = ARCMSR_MAX_XFER_SECTORS_C,
...@@ -693,7 +693,7 @@ static int arcmsr_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -693,7 +693,7 @@ static int arcmsr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
host->max_lun = ARCMSR_MAX_TARGETLUN; host->max_lun = ARCMSR_MAX_TARGETLUN;
host->max_id = ARCMSR_MAX_TARGETID; /*16:8*/ host->max_id = ARCMSR_MAX_TARGETID; /*16:8*/
host->max_cmd_len = 16; /*this is issue of 64bit LBA ,over 2T byte*/ host->max_cmd_len = 16; /*this is issue of 64bit LBA ,over 2T byte*/
host->can_queue = ARCMSR_MAX_FREECCB_NUM; /* max simultaneous cmds */ host->can_queue = ARCMSR_MAX_OUTSTANDING_CMD;
host->cmd_per_lun = ARCMSR_MAX_CMD_PERLUN; host->cmd_per_lun = ARCMSR_MAX_CMD_PERLUN;
host->this_id = ARCMSR_SCSI_INITIATOR_ID; host->this_id = ARCMSR_SCSI_INITIATOR_ID;
host->unique_id = (bus << 8) | dev_fun; host->unique_id = (bus << 8) | dev_fun;
...@@ -2216,9 +2216,6 @@ static int arcmsr_queue_command_lck(struct scsi_cmnd *cmd, ...@@ -2216,9 +2216,6 @@ static int arcmsr_queue_command_lck(struct scsi_cmnd *cmd,
arcmsr_handle_virtual_command(acb, cmd); arcmsr_handle_virtual_command(acb, cmd);
return 0; return 0;
} }
if (atomic_read(&acb->ccboutstandingcount) >=
ARCMSR_MAX_OUTSTANDING_CMD)
return SCSI_MLQUEUE_HOST_BUSY;
ccb = arcmsr_get_freeccb(acb); ccb = arcmsr_get_freeccb(acb);
if (!ccb) if (!ccb)
return SCSI_MLQUEUE_HOST_BUSY; return SCSI_MLQUEUE_HOST_BUSY;
...@@ -2428,12 +2425,27 @@ static bool arcmsr_get_hbc_config(struct AdapterControlBlock *pACB) ...@@ -2428,12 +2425,27 @@ static bool arcmsr_get_hbc_config(struct AdapterControlBlock *pACB)
} }
static bool arcmsr_get_firmware_spec(struct AdapterControlBlock *acb) static bool arcmsr_get_firmware_spec(struct AdapterControlBlock *acb)
{ {
if (acb->adapter_type == ACB_ADAPTER_TYPE_A) bool rtn = false;
return arcmsr_get_hba_config(acb);
else if (acb->adapter_type == ACB_ADAPTER_TYPE_B) switch (acb->adapter_type) {
return arcmsr_get_hbb_config(acb); case ACB_ADAPTER_TYPE_A:
rtn = arcmsr_get_hba_config(acb);
break;
case ACB_ADAPTER_TYPE_B:
rtn = arcmsr_get_hbb_config(acb);
break;
case ACB_ADAPTER_TYPE_C:
rtn = arcmsr_get_hbc_config(acb);
break;
default:
break;
}
if (acb->firm_numbers_queue > ARCMSR_MAX_OUTSTANDING_CMD)
acb->maxOutstanding = ARCMSR_MAX_OUTSTANDING_CMD;
else else
return arcmsr_get_hbc_config(acb); acb->maxOutstanding = acb->firm_numbers_queue - 1;
acb->host->can_queue = acb->maxOutstanding;
return rtn;
} }
static int arcmsr_polling_hba_ccbdone(struct AdapterControlBlock *acb, static int arcmsr_polling_hba_ccbdone(struct AdapterControlBlock *acb,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment