mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-16 18:21:27 +00:00
Patch from Grigory Eykalis <Grigory.Eykalis@dothill.com> with some changes implementing pass-through functionality
git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@3422 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -1048,6 +1048,198 @@ static struct bin_attribute sysfs_sfp_attr = {
|
||||
.read = qla2x00_sysfs_read_sfp,
|
||||
};
|
||||
|
||||
static void
|
||||
qla2x00_wait_for_passthru_completion(struct scsi_qla_host *ha)
|
||||
{
|
||||
unsigned long timeout;
|
||||
|
||||
if (unlikely(pci_channel_offline(ha->pdev)))
|
||||
return;
|
||||
|
||||
timeout = ((ha->r_a_tov / 10 * 2) + 5) * HZ;
|
||||
if (!wait_for_completion_timeout(&ha->pass_thru_intr_comp, timeout)) {
|
||||
DEBUG2(qla_printk(KERN_WARNING, ha,
|
||||
"Passthru request timed out.\n"));
|
||||
if (IS_QLA82XX(ha))
|
||||
set_bit(FCOE_CTX_RESET_NEEDED, &ha->dpc_flags);
|
||||
else {
|
||||
ha->isp_ops->fw_dump(ha, 0);
|
||||
set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
|
||||
}
|
||||
qla2xxx_wake_dpc(ha);
|
||||
ha->pass_thru_cmd_result = 0;
|
||||
ha->pass_thru_cmd_in_process = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
qla2x00_sysfs_read_ct(struct kobject *kobj,
|
||||
struct bin_attribute *bin_attr,
|
||||
char *buf,
|
||||
loff_t off, size_t count)
|
||||
{
|
||||
struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj,
|
||||
struct device, kobj)));
|
||||
|
||||
if (!ha->pass_thru_cmd_in_process || !ha->pass_thru_cmd_result) {
|
||||
DEBUG3(qla_printk(KERN_WARNING, ha,
|
||||
"Passthru CT response is not available.\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(buf, ha->pass_thru, count);
|
||||
|
||||
ha->pass_thru_cmd_result = 0;
|
||||
ha->pass_thru_cmd_in_process = 0;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
qla2x00_sysfs_write_ct(struct kobject *kobj,
|
||||
struct bin_attribute *bin_attr,
|
||||
char *buf,
|
||||
loff_t off, size_t count)
|
||||
{
|
||||
struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj,
|
||||
struct device, kobj)));
|
||||
fc_ct_request_t *request = (void *)buf;
|
||||
struct ct_entry_24xx *ct_iocb = NULL;
|
||||
ms_iocb_entry_t *ct_iocb_2G = NULL;
|
||||
unsigned long flags;
|
||||
|
||||
if (test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) ||
|
||||
test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags) ||
|
||||
test_bit(ISP_ABORT_RETRY, &ha->dpc_flags)) {
|
||||
DEBUG2_3_11(qla_printk(KERN_INFO, ha,
|
||||
"%s(%ld): isp reset in progress.\n",
|
||||
__func__, ha->host_no));
|
||||
goto ct_error0;
|
||||
}
|
||||
if (atomic_read(&ha->loop_state) != LOOP_READY)
|
||||
goto ct_error0;
|
||||
if (count < sizeof(request->ct_iu)) {
|
||||
DEBUG2(qla_printk(KERN_WARNING, ha,
|
||||
"Passthru CT buffer insufficient size %zu...\n", count));
|
||||
goto ct_error0;
|
||||
}
|
||||
if (ha->pass_thru_cmd_in_process || ha->pass_thru_cmd_result) {
|
||||
DEBUG2(qla_printk(KERN_WARNING, ha,
|
||||
"Passthru CT request is already progress\n"));
|
||||
goto ct_error0;
|
||||
}
|
||||
if (qla2x00_mgmt_svr_login(ha)) {
|
||||
DEBUG2(qla_printk(KERN_WARNING, ha,
|
||||
"Passthru CT request failed to login management server\n"));
|
||||
goto ct_error0;
|
||||
}
|
||||
|
||||
ha->pass_thru_cmd_in_process = 1;
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
|
||||
if (count > PAGE_SIZE) {
|
||||
DEBUG2(qla_printk(KERN_INFO, ha,
|
||||
"Passthru CT request excessive size %d...\n",
|
||||
(int)count));
|
||||
count = PAGE_SIZE;
|
||||
}
|
||||
|
||||
memset(ha->pass_thru, 0, PAGE_SIZE);
|
||||
memcpy(ha->pass_thru, &request->ct_iu, count);
|
||||
|
||||
if (IS_FWI2_CAPABLE(ha)) {
|
||||
ct_iocb = (void *)qla2x00_req_pkt(ha);
|
||||
|
||||
if (ct_iocb == NULL) {
|
||||
DEBUG2(qla_printk(KERN_WARNING, ha,
|
||||
"Passthru CT request failed to get request "
|
||||
"packet\n"));
|
||||
goto ct_error1;
|
||||
}
|
||||
|
||||
ct_iocb->entry_type = CT_IOCB_TYPE;
|
||||
ct_iocb->entry_count = 1;
|
||||
ct_iocb->entry_status = 0;
|
||||
ct_iocb->comp_status = __constant_cpu_to_le16(0);
|
||||
if (*(buf+4) & 0xfc)
|
||||
ct_iocb->nport_handle = __constant_cpu_to_le16(NPH_SNS);
|
||||
else
|
||||
ct_iocb->nport_handle = cpu_to_le16(ha->mgmt_svr_loop_id);
|
||||
ct_iocb->cmd_dsd_count = __constant_cpu_to_le16(1);
|
||||
ct_iocb->vp_index = ha->vp_idx;
|
||||
ct_iocb->timeout = (cpu_to_le16(ha->r_a_tov / 10 * 2) + 2);
|
||||
ct_iocb->rsp_dsd_count = __constant_cpu_to_le16(1);
|
||||
ct_iocb->rsp_byte_count = cpu_to_le32(PAGE_SIZE);
|
||||
ct_iocb->cmd_byte_count = cpu_to_le32(count);
|
||||
|
||||
ct_iocb->dseg_0_address[0] = cpu_to_le32(LSD(ha->pass_thru_dma));
|
||||
ct_iocb->dseg_0_address[1] = cpu_to_le32(MSD(ha->pass_thru_dma));
|
||||
ct_iocb->dseg_0_len = ct_iocb->cmd_byte_count;
|
||||
|
||||
ct_iocb->dseg_1_address[0] = cpu_to_le32(LSD(ha->pass_thru_dma));
|
||||
ct_iocb->dseg_1_address[1] = cpu_to_le32(MSD(ha->pass_thru_dma));
|
||||
ct_iocb->dseg_1_len = ct_iocb->rsp_byte_count;
|
||||
} else {
|
||||
ct_iocb_2G = (void *)qla2x00_req_pkt(ha);
|
||||
|
||||
if (ct_iocb_2G == NULL) {
|
||||
DEBUG2(qla_printk(KERN_WARNING, ha,
|
||||
"Passthru CT request failed to get request "
|
||||
"packet\n"));
|
||||
goto ct_error1;
|
||||
}
|
||||
|
||||
ct_iocb_2G->entry_type = CT_IOCB_TYPE;
|
||||
ct_iocb_2G->entry_count = 1;
|
||||
ct_iocb_2G->entry_status = 0;
|
||||
SET_TARGET_ID(ha, ct_iocb_2G->loop_id, ha->mgmt_svr_loop_id);
|
||||
ct_iocb_2G->status = __constant_cpu_to_le16(0);
|
||||
ct_iocb_2G->control_flags = __constant_cpu_to_le16(0);
|
||||
ct_iocb_2G->timeout = (cpu_to_le16(ha->r_a_tov / 10 * 2) + 2);
|
||||
ct_iocb_2G->cmd_dsd_count = __constant_cpu_to_le16(1);
|
||||
ct_iocb_2G->total_dsd_count = __constant_cpu_to_le16(2);
|
||||
ct_iocb_2G->rsp_bytecount = cpu_to_le32(PAGE_SIZE);
|
||||
ct_iocb_2G->req_bytecount = cpu_to_le32(count);
|
||||
|
||||
ct_iocb_2G->dseg_req_address[0] = cpu_to_le32(LSD(ha->pass_thru_dma));
|
||||
ct_iocb_2G->dseg_req_address[1] = cpu_to_le32(MSD(ha->pass_thru_dma));
|
||||
ct_iocb_2G->dseg_req_length = ct_iocb_2G->req_bytecount;
|
||||
|
||||
ct_iocb_2G->dseg_rsp_address[0] = cpu_to_le32(LSD(ha->pass_thru_dma));
|
||||
ct_iocb_2G->dseg_rsp_address[1] = cpu_to_le32(MSD(ha->pass_thru_dma));
|
||||
ct_iocb_2G->dseg_rsp_length = ct_iocb_2G->rsp_bytecount;
|
||||
}
|
||||
|
||||
wmb();
|
||||
qla2x00_isp_cmd(ha);
|
||||
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
|
||||
qla2x00_wait_for_passthru_completion(ha);
|
||||
|
||||
return count;
|
||||
|
||||
ct_error1:
|
||||
ha->pass_thru_cmd_in_process = 0;
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
|
||||
ct_error0:
|
||||
DEBUG3(qla_printk(KERN_WARNING, ha,
|
||||
"Passthru CT failed on scsi(%ld)\n", ha->host_no));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct bin_attribute sysfs_ct_attr = {
|
||||
.attr = {
|
||||
.name = "ct",
|
||||
.mode = S_IRUSR | S_IWUSR,
|
||||
},
|
||||
.size = 0,
|
||||
.read = qla2x00_sysfs_read_ct,
|
||||
.write = qla2x00_sysfs_write_ct,
|
||||
};
|
||||
|
||||
|
||||
static struct sysfs_entry {
|
||||
char *name;
|
||||
struct bin_attribute *attr;
|
||||
@@ -1059,6 +1251,7 @@ static struct sysfs_entry {
|
||||
{ "optrom_ctl", &sysfs_optrom_ctl_attr, },
|
||||
{ "vpd", &sysfs_vpd_attr, 1 },
|
||||
{ "sfp", &sysfs_sfp_attr, 1 },
|
||||
{ "ct", &sysfs_ct_attr, },
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
|
||||
@@ -94,6 +94,68 @@
|
||||
#define LSD(x) ((uint32_t)((uint64_t)(x)))
|
||||
#define MSD(x) ((uint32_t)((((uint64_t)(x)) >> 16) >> 16))
|
||||
|
||||
/* CT IU */
|
||||
typedef struct{
|
||||
uint8_t revision;
|
||||
uint8_t in_id[3];
|
||||
uint8_t gs_type;
|
||||
uint8_t gs_subtype;
|
||||
uint8_t options;
|
||||
uint8_t reserved0;
|
||||
uint16_t command;
|
||||
uint16_t max_rsp_size;
|
||||
uint8_t fragment_id;
|
||||
uint8_t reserved1[3];
|
||||
} ct_iu_t;
|
||||
|
||||
/* CT request format */
|
||||
typedef struct {
|
||||
ct_iu_t ct_iu;
|
||||
union {
|
||||
struct {
|
||||
uint8_t reserved;
|
||||
uint8_t port_id[3];
|
||||
} port_id;
|
||||
|
||||
struct {
|
||||
uint8_t port_type;
|
||||
uint8_t domain;
|
||||
uint8_t area;
|
||||
uint8_t reserved;
|
||||
} gid_pt;
|
||||
|
||||
struct {
|
||||
uint8_t reserved;
|
||||
uint8_t port_id[3];
|
||||
uint8_t fc4_types[32];
|
||||
} rft_id;
|
||||
|
||||
struct {
|
||||
uint8_t reserved;
|
||||
uint8_t port_id[3];
|
||||
uint16_t reserved2;
|
||||
uint8_t fc4_feature;
|
||||
uint8_t fc4_type;
|
||||
} rff_id;
|
||||
|
||||
struct {
|
||||
uint8_t reserved;
|
||||
uint8_t port_id[3];
|
||||
uint8_t node_name[8];
|
||||
} rnn_id;
|
||||
|
||||
struct {
|
||||
uint8_t node_name[8];
|
||||
uint8_t name_len;
|
||||
uint8_t sym_node_name[255];
|
||||
} rsnn_nn;
|
||||
|
||||
struct {
|
||||
uint8_t hba_indentifier[8];
|
||||
} ghat;
|
||||
} extended;
|
||||
} fc_ct_request_t;
|
||||
|
||||
/*
|
||||
* I/O register
|
||||
*/
|
||||
@@ -2251,6 +2313,7 @@ typedef struct scsi_qla_host {
|
||||
#define REGISTER_FDMI_NEEDED 26
|
||||
#define FCPORT_UPDATE_NEEDED 27
|
||||
#define VP_DPC_NEEDED 28 /* wake up for VP dpc handling */
|
||||
#define FCOE_CTX_RESET_NEEDED 18 /* Initiate FCoE context reset */
|
||||
|
||||
uint32_t device_flags;
|
||||
#define DFLG_LOCAL_DEVICES BIT_0
|
||||
@@ -2275,6 +2338,7 @@ typedef struct scsi_qla_host {
|
||||
#define DT_ISP5432 BIT_10
|
||||
#define DT_ISP2532 BIT_11
|
||||
#define DT_ISP8432 BIT_12
|
||||
#define DT_ISP8021 BIT_14
|
||||
#define DT_ISP_LAST (DT_ISP8432 << 1)
|
||||
|
||||
#define DT_IIDMA BIT_26
|
||||
@@ -2298,6 +2362,7 @@ typedef struct scsi_qla_host {
|
||||
#define IS_QLA5432(ha) (DT_MASK(ha) & DT_ISP5432)
|
||||
#define IS_QLA2532(ha) (DT_MASK(ha) & DT_ISP2532)
|
||||
#define IS_QLA8432(ha) (DT_MASK(ha) & DT_ISP8432)
|
||||
#define IS_QLA82XX(ha) (DT_MASK(ha) & DT_ISP8021)
|
||||
|
||||
#define IS_QLA23XX(ha) (IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA2322(ha) || \
|
||||
IS_QLA6312(ha) || IS_QLA6322(ha))
|
||||
@@ -2473,6 +2538,9 @@ typedef struct scsi_qla_host {
|
||||
struct sns_cmd_pkt *sns_cmd;
|
||||
dma_addr_t sns_cmd_dma;
|
||||
|
||||
char *pass_thru;
|
||||
dma_addr_t pass_thru_dma;
|
||||
|
||||
#define SFP_DEV_SIZE 256
|
||||
#define SFP_BLOCK_SIZE 64
|
||||
void *sfp_data;
|
||||
@@ -2514,6 +2582,7 @@ typedef struct scsi_qla_host {
|
||||
struct mutex vport_lock; /* Virtual port synchronization */
|
||||
struct completion mbx_cmd_comp; /* Serialize mbx access */
|
||||
struct completion mbx_intr_comp; /* Used for completion notification */
|
||||
struct completion pass_thru_intr_comp; /* For pass thru notification */
|
||||
|
||||
uint32_t mbx_flags;
|
||||
#define MBX_IN_PROGRESS BIT_0
|
||||
@@ -2672,6 +2741,10 @@ typedef struct scsi_qla_host {
|
||||
uint16_t max_npiv_vports; /* 63 or 125 per topoloty */
|
||||
int cur_vport_count;
|
||||
|
||||
/* Pass through support */
|
||||
int pass_thru_cmd_result;
|
||||
int pass_thru_cmd_in_process;
|
||||
|
||||
struct qla_chip_state_84xx *cs84xx;
|
||||
} scsi_qla_host_t;
|
||||
|
||||
|
||||
@@ -361,6 +361,7 @@ extern int qla2x00_fdmi_register(scsi_qla_host_t *);
|
||||
extern int qla2x00_gfpn_id(scsi_qla_host_t *, sw_info_t *);
|
||||
extern int qla2x00_gpsc(scsi_qla_host_t *, sw_info_t *);
|
||||
extern void qla2x00_get_sym_node_name(scsi_qla_host_t *, uint8_t *);
|
||||
extern int qla2x00_mgmt_svr_login(scsi_qla_host_t *);
|
||||
|
||||
/*
|
||||
* Global Function Prototypes in qla_attr.c source file.
|
||||
|
||||
@@ -1106,7 +1106,7 @@ qla2x00_sns_rnn_id(scsi_qla_host_t *ha)
|
||||
*
|
||||
* Returns 0 on success.
|
||||
*/
|
||||
static int
|
||||
int
|
||||
qla2x00_mgmt_svr_login(scsi_qla_host_t *ha)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@@ -16,6 +16,9 @@ static void qla2x00_process_completed_request(struct scsi_qla_host *, uint32_t);
|
||||
static void qla2x00_status_entry(scsi_qla_host_t *, void *);
|
||||
static void qla2x00_status_cont_entry(scsi_qla_host_t *, sts_cont_entry_t *);
|
||||
static void qla2x00_error_entry(scsi_qla_host_t *, sts_entry_t *);
|
||||
static void qla2x00_ms_entry(scsi_qla_host_t *, ms_iocb_entry_t *);
|
||||
static void qla24xx_ms_entry(scsi_qla_host_t *, struct ct_entry_24xx *);
|
||||
|
||||
|
||||
/**
|
||||
* qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200.
|
||||
@@ -964,6 +967,21 @@ qla2x00_process_response_queue(struct scsi_qla_host *ha)
|
||||
break;
|
||||
case MARKER_TYPE:
|
||||
break;
|
||||
case MS_IOCB_TYPE:
|
||||
if (ha->outstanding_cmds[pkt->handle])
|
||||
qla2x00_ms_entry(ha, (ms_iocb_entry_t *)pkt);
|
||||
else {
|
||||
if (ha->pass_thru_cmd_result)
|
||||
DEBUG2(qla_printk(KERN_INFO, ha,
|
||||
"Passthru cmd result on.\n"));
|
||||
if (!ha->pass_thru_cmd_in_process)
|
||||
DEBUG2(qla_printk(KERN_INFO, ha,
|
||||
"Passthru in process off.\n"));
|
||||
|
||||
ha->pass_thru_cmd_result = 1;
|
||||
complete(&ha->pass_thru_intr_comp);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* Type Not Supported. */
|
||||
DEBUG4(printk(KERN_WARNING
|
||||
@@ -1499,6 +1517,43 @@ qla2x00_error_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* qla2x00_ms_entry() - Process a Management Server entry.
|
||||
* @ha: SCSI driver HA context
|
||||
* @index: Response queue out pointer
|
||||
*/
|
||||
static void
|
||||
qla2x00_ms_entry(scsi_qla_host_t *ha, ms_iocb_entry_t *pkt)
|
||||
{
|
||||
srb_t *sp;
|
||||
|
||||
DEBUG3(printk("%s(%ld): pkt=%p pkthandle=%d.\n",
|
||||
__func__, ha->host_no, pkt, pkt->handle1));
|
||||
|
||||
/* Validate handle. */
|
||||
if (pkt->handle1 < MAX_OUTSTANDING_COMMANDS)
|
||||
sp = ha->outstanding_cmds[pkt->handle1];
|
||||
else
|
||||
sp = NULL;
|
||||
|
||||
if (sp == NULL) {
|
||||
DEBUG2(printk("scsi(%ld): MS entry - invalid handle\n",
|
||||
ha->host_no));
|
||||
qla_printk(KERN_WARNING, ha, "MS entry - invalid handle\n");
|
||||
|
||||
set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
|
||||
return;
|
||||
}
|
||||
|
||||
CMD_COMPL_STATUS(sp->cmd) = le16_to_cpu(pkt->status);
|
||||
CMD_ENTRY_STATUS(sp->cmd) = pkt->entry_status;
|
||||
|
||||
/* Free outstanding command slot. */
|
||||
ha->outstanding_cmds[pkt->handle1] = NULL;
|
||||
|
||||
qla2x00_sp_compl(ha, sp);
|
||||
}
|
||||
|
||||
/**
|
||||
* qla24xx_mbx_completion() - Process mailbox command completions.
|
||||
* @ha: SCSI driver HA context
|
||||
@@ -1668,6 +1723,32 @@ qla24xx_process_response_queue(struct scsi_qla_host *ha)
|
||||
#endif /* CONFIG_SCSI_QLA2XXX_TARGET */
|
||||
case MARKER_TYPE:
|
||||
break;
|
||||
case MS_IOCB_TYPE:
|
||||
if (ha->outstanding_cmds[pkt->handle])
|
||||
qla24xx_ms_entry(ha, (void *)pkt);
|
||||
else {
|
||||
if (ha->pass_thru_cmd_result)
|
||||
DEBUG2(qla_printk(KERN_INFO, ha,
|
||||
"Passthru cmd result on.\n"));
|
||||
if (!ha->pass_thru_cmd_in_process)
|
||||
DEBUG2(qla_printk(KERN_INFO, ha,
|
||||
"Passthru in process off.\n"));
|
||||
|
||||
ha->pass_thru_cmd_result = 1;
|
||||
complete(&ha->pass_thru_intr_comp);
|
||||
}
|
||||
break;
|
||||
case ELS_IOCB_TYPE:
|
||||
if (ha->pass_thru_cmd_result)
|
||||
DEBUG2(qla_printk(KERN_INFO, ha,
|
||||
"Passthru cmd result on.\n"));
|
||||
if (!ha->pass_thru_cmd_in_process)
|
||||
DEBUG2(qla_printk(KERN_INFO, ha,
|
||||
"Passthru in process off.\n"));
|
||||
|
||||
ha->pass_thru_cmd_result = 1;
|
||||
complete(&ha->pass_thru_intr_comp);
|
||||
break;
|
||||
default:
|
||||
/* Type Not Supported. */
|
||||
DEBUG4(printk(KERN_WARNING
|
||||
@@ -1834,6 +1915,49 @@ qla24xx_intr_handler(int irq, void *dev_id)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/**
|
||||
* qla24xx_ms_entry() - Process a Management Server entry.
|
||||
* @ha: SCSI driver HA context
|
||||
* @index: Response queue out pointer
|
||||
*/
|
||||
static void
|
||||
qla24xx_ms_entry(scsi_qla_host_t *ha, struct ct_entry_24xx *pkt)
|
||||
{
|
||||
srb_t *sp;
|
||||
|
||||
DEBUG3(printk("%s(%ld): pkt=%p pkthandle=%d.\n",
|
||||
__func__, ha->host_no, pkt, pkt->handle));
|
||||
|
||||
DEBUG9(printk("%s: ct pkt dump:\n", __func__));
|
||||
DEBUG9(qla2x00_dump_buffer((void *)pkt, sizeof(struct ct_entry_24xx)));
|
||||
|
||||
/* Validate handle. */
|
||||
if (pkt->handle < MAX_OUTSTANDING_COMMANDS)
|
||||
sp = ha->outstanding_cmds[pkt->handle];
|
||||
else
|
||||
sp = NULL;
|
||||
|
||||
if (sp == NULL) {
|
||||
DEBUG2(printk("scsi(%ld): MS entry - invalid handle\n",
|
||||
ha->host_no));
|
||||
DEBUG10(printk("scsi(%ld): MS entry - invalid handle\n",
|
||||
ha->host_no));
|
||||
qla_printk(KERN_WARNING, ha, "MS entry - invalid handle %d\n",
|
||||
pkt->handle);
|
||||
|
||||
set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
|
||||
return;
|
||||
}
|
||||
|
||||
CMD_COMPL_STATUS(sp->cmd) = le16_to_cpu(pkt->comp_status);
|
||||
CMD_ENTRY_STATUS(sp->cmd) = pkt->entry_status;
|
||||
|
||||
/* Free outstanding command slot. */
|
||||
ha->outstanding_cmds[pkt->handle] = NULL;
|
||||
|
||||
qla2x00_sp_compl(ha, sp);
|
||||
}
|
||||
|
||||
static irqreturn_t
|
||||
qla24xx_msix_rsp_q(int irq, void *dev_id)
|
||||
{
|
||||
|
||||
@@ -1933,6 +1933,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
init_completion(&ha->mbx_cmd_comp);
|
||||
complete(&ha->mbx_cmd_comp);
|
||||
init_completion(&ha->mbx_intr_comp);
|
||||
init_completion(&ha->pass_thru_intr_comp);
|
||||
|
||||
INIT_LIST_HEAD(&ha->list);
|
||||
INIT_LIST_HEAD(&ha->fcports);
|
||||
@@ -2347,10 +2348,23 @@ qla2x00_mem_alloc(scsi_qla_host_t *ha)
|
||||
sizeof(struct ct_sns_pkt), &ha->ct_sns_dma, GFP_KERNEL);
|
||||
if (!ha->ct_sns)
|
||||
goto fail_free_ms_iocb;
|
||||
|
||||
/* Get consistent memory allocated for pass-thru commands */
|
||||
ha->pass_thru = dma_alloc_coherent(&ha->pdev->dev,
|
||||
PAGE_SIZE, &ha->pass_thru_dma, GFP_KERNEL);
|
||||
if (!ha->pass_thru) {
|
||||
qla_printk(KERN_WARNING, ha,
|
||||
"Memory Allocation failed - pass_thru\n");
|
||||
goto fail_free_pass_thru;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail_free_pass_thru:
|
||||
dma_free_coherent(&ha->pdev->dev,
|
||||
PAGE_SIZE, ha->pass_thru, ha->pass_thru_dma);
|
||||
ha->pass_thru = NULL;
|
||||
fail_free_ms_iocb:
|
||||
dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma);
|
||||
ha->ms_iocb = NULL;
|
||||
@@ -2468,6 +2482,10 @@ qla2x00_mem_free(scsi_qla_host_t *ha)
|
||||
(ha->request_q_length + 1) * sizeof(request_t),
|
||||
ha->request_ring, ha->request_dma);
|
||||
|
||||
if (ha->pass_thru)
|
||||
dma_free_coherent(&ha->pdev->dev,
|
||||
PAGE_SIZE, ha->pass_thru, ha->pass_thru_dma);
|
||||
|
||||
ha->srb_mempool = NULL;
|
||||
ha->eft = NULL;
|
||||
ha->eft_dma = 0;
|
||||
@@ -2485,6 +2503,8 @@ qla2x00_mem_free(scsi_qla_host_t *ha)
|
||||
ha->gid_list = NULL;
|
||||
ha->gid_list_dma = 0;
|
||||
|
||||
ha->pass_thru = NULL;
|
||||
|
||||
ha->response_ring = NULL;
|
||||
ha->response_dma = 0;
|
||||
ha->request_ring = NULL;
|
||||
|
||||
Reference in New Issue
Block a user