Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 313723 Details for
Bug 455900
[QLogic 5.3 feat] qla2xxx - mgmt. API, CT pass thru
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
CT pass thru kernel patch
qla2xxx_rhel5.3_ctpt3_patch05_V2.txt (text/plain), 19.13 KB, created by
Marcus Barrow
on 2008-08-07 17:54:14 UTC
(
hide
)
Description:
CT pass thru kernel patch
Filename:
MIME Type:
Creator:
Marcus Barrow
Created:
2008-08-07 17:54:14 UTC
Size:
19.13 KB
patch
obsolete
> >BZ 455900 [QLogic 5.3] qla2xxx - mgmt. API, CT pass thru > >This is version 2 of this patch, changed to correct a compiler warning >and an offset in applying the patch. > >This patch provides information for our management API for Fibre Channel devices. >This provides functionality that would formerly have been performed by ioctl's. >It creates two more entries in sysfs, along with our VPD info, SFP info and option >rom control. These entries are used to pass thru commands. > >Tested at QLogic. I believe it's submitted or queued for upstream. >( person on vacation ) > >The management API support is considered critacal for our products by QLogic and our OEM's. > > >--- > drivers/scsi/qla2xxx/qla_attr.c | 292 +++++++++++++++++++++++++++++++++++++++ > drivers/scsi/qla2xxx/qla_dbg.c | 30 ++++ > drivers/scsi/qla2xxx/qla_def.h | 92 ++++++++++++ > drivers/scsi/qla2xxx/qla_gbl.h | 5 + > drivers/scsi/qla2xxx/qla_gs.c | 2 +- > drivers/scsi/qla2xxx/qla_iocb.c | 6 +- > drivers/scsi/qla2xxx/qla_isr.c | 25 ++++- > drivers/scsi/qla2xxx/qla_os.c | 23 +++ > 8 files changed, 469 insertions(+), 6 deletions(-) > >diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c >index ab70be2..31888b3 100644 >--- a/drivers/scsi/qla2xxx/qla_attr.c >+++ b/drivers/scsi/qla2xxx/qla_attr.c >@@ -460,6 +460,296 @@ static struct bin_attribute sysfs_sfp_at > .read = qla2x00_sysfs_read_sfp, > }; > >+static fc_port_t * >+qla2x00_find_port(struct scsi_qla_host *ha, uint8_t *pn) >+{ >+ fc_port_t *fcport; >+ >+ list_for_each_entry(fcport, &ha->fcports, list) >+ if (!memcmp(pn, fcport->port_name, sizeof(fcport->port_name))) >+ return fcport; >+ >+ return NULL; >+} >+ >+static void >+qla2x00_wait_for_passthru_completion(struct scsi_qla_host *ha) >+{ >+ if (wait_for_completion_timeout(&ha->pass_thru_intr_comp, 10 * HZ)) >+ qla_printk(KERN_INFO, ha, "Passthru request completed.\n"); >+ else { >+ qla_printk(KERN_WARNING, ha, "Passthru request timed out.\n"); >+ ha->isp_ops->fw_dump(ha, 0); >+ } >+} >+ >+static ssize_t >+qla2x00_sysfs_read_els(struct kobject *kobj, char *buf, loff_t off, >+ size_t count) >+{ >+ struct scsi_qla_host *ha = to_qla_host(dev_to_shost( >+ container_of(kobj, struct device, kobj))); >+ >+ if (!ha->pass_thru_cmd_in_process || !ha->pass_thru_cmd_result) { >+ qla_printk(KERN_WARNING, ha, >+ "Passthru ELS response is not available.\n"); >+ return 0; >+ } >+ >+ memcpy(buf, ha->pass_thru, count); >+ >+ qla_printk(KERN_INFO, ha, "Passthru ELS response %X:\n", >+ ((ct_iu_t *)buf)->command); >+ qla2x00_print_byte_buf(buf, min(count, (size_t)64), 16); >+ >+ ha->pass_thru_cmd_result = 0; >+ ha->pass_thru_cmd_in_process = 0; >+ >+ return count; >+} >+ >+static ssize_t >+qla2x00_sysfs_write_els(struct kobject *kobj, char *buf, loff_t off, >+ size_t count) >+{ >+ struct scsi_qla_host *ha = to_qla_host(dev_to_shost( >+ container_of(kobj, struct device, kobj))); >+ els_request_t *request = (void *)buf; >+ struct els_entry_24xx *els_iocb; >+ unsigned long flags; >+ uint16_t nextlid = 0; >+ fc_port_t *fcport; >+ >+ count -= sizeof(request->header); >+ >+ if (count < sizeof(request->ct_iu)) { >+ qla_printk(KERN_WARNING, ha, >+ "Passthru ELS buffer insufficient size %d...\n", >+ (int)count); >+ goto els_error0; >+ } >+ >+ if (ha->pass_thru_cmd_in_process || ha->pass_thru_cmd_result) { >+ qla_printk(KERN_WARNING, ha, >+ "Passthru ELS request is already progress\n"); >+ goto els_error0; >+ } >+ >+ fcport = qla2x00_find_port(ha, request->header.WWPN); >+ if (!fcport) { >+ qla_printk(KERN_WARNING, ha, >+ "Passthru ELS request failed find port\n"); >+ goto els_error0; >+ } >+ >+ if (qla2x00_fabric_login(ha, fcport, &nextlid)) { >+ qla_printk(KERN_WARNING, ha, >+ "Passthru ELS request failed to login port %06X\n", >+ fcport->d_id.b24); >+ goto els_error0; >+ } >+ >+ ha->pass_thru_cmd_in_process = 1; >+ spin_lock_irqsave(&ha->hardware_lock, flags); >+ >+ els_iocb = (void *)qla2x00_req_pkt(ha); >+ if (els_iocb == NULL) { >+ qla_printk(KERN_WARNING, ha, >+ "Passthru ELS request failed to get request packet\n"); >+ goto els_error1; >+ } >+ >+ if (count > PAGE_SIZE) { >+ qla_printk(KERN_INFO, ha, >+ "Passthru ELS 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); >+ >+ els_iocb->entry_type = ELS_IOCB_TYPE; >+ els_iocb->entry_count = 1; >+ els_iocb->sys_define = 0; >+ els_iocb->entry_status = 0; >+ els_iocb->nport_handle = cpu_to_le16(fcport->loop_id); >+ els_iocb->tx_dsd_count = __constant_cpu_to_le16(1); >+ els_iocb->vp_index = ha->vp_idx; >+ els_iocb->sof_type = EST_SOFI3; >+ els_iocb->rx_dsd_count = __constant_cpu_to_le16(1); >+ els_iocb->opcode = 0; >+ els_iocb->port_id[0] = fcport->d_id.b.al_pa; >+ els_iocb->port_id[1] = fcport->d_id.b.area; >+ els_iocb->port_id[2] = fcport->d_id.b.domain; >+ els_iocb->control_flags = __constant_cpu_to_le16(0); >+ els_iocb->rx_byte_count = cpu_to_le32(PAGE_SIZE); >+ els_iocb->tx_byte_count = cpu_to_le32(count); >+ els_iocb->tx_address[0] = cpu_to_le32(LSD(ha->pass_thru_dma)); >+ els_iocb->tx_address[1] = cpu_to_le32(MSD(ha->pass_thru_dma)); >+ els_iocb->tx_len = els_iocb->tx_byte_count; >+ els_iocb->rx_address[0] = cpu_to_le32(LSD(ha->pass_thru_dma)); >+ els_iocb->rx_address[1] = cpu_to_le32(MSD(ha->pass_thru_dma)); >+ els_iocb->rx_len = els_iocb->rx_byte_count; >+ >+ qla_printk(KERN_INFO, ha, "Passthru ELS request:\n"); >+ qla2x00_print_byte_buf(ha->pass_thru, min(count, (size_t)32), 16); >+ >+ qla_printk(KERN_INFO, ha, "Passthru ELS IOCB:\n"); >+ qla2x00_print_word_buf(els_iocb, sizeof(*els_iocb), 8); >+ >+ wmb(); >+ qla2x00_isp_cmd(ha); >+ >+ spin_unlock_irqrestore(&ha->hardware_lock, flags); >+ qla2x00_wait_for_passthru_completion(ha); >+ >+ return count; >+ >+els_error1: >+ ha->pass_thru_cmd_in_process = 0; >+ spin_unlock_irqrestore(&ha->hardware_lock, flags); >+els_error0: >+ qla_printk(KERN_WARNING, ha, "Passthru ELS failed\n"); >+ return 0; >+} >+ >+static struct bin_attribute sysfs_els_attr = { >+ .attr = { >+ .name = "els", >+ .mode = S_IRUSR | S_IWUSR, >+ .owner = THIS_MODULE, >+ }, >+ .size = 0, >+ .read = qla2x00_sysfs_read_els, >+ .write = qla2x00_sysfs_write_els, >+}; >+ >+static ssize_t >+qla2x00_sysfs_read_ct(struct kobject *kobj, char *buf, loff_t off, >+ size_t count) >+{ >+ struct scsi_qla_host *ha = to_qla_host(dev_to_shost( >+ container_of(kobj, struct device, kobj))); >+ >+ if (!ha->pass_thru_cmd_in_process || !ha->pass_thru_cmd_result) { >+ qla_printk(KERN_WARNING, ha, >+ "Passthru CT response is not available.\n"); >+ return 0; >+ } >+ >+ memcpy(buf, ha->pass_thru, count); >+ >+ qla_printk(KERN_INFO, ha, "Passthru CT response %X:\n", >+ ((ct_iu_t *)buf)->command); >+ qla2x00_print_byte_buf(buf, min(count, (size_t)64), 16); >+ >+ 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, char *buf, loff_t off, >+ size_t count) >+{ >+ struct scsi_qla_host *ha = to_qla_host(dev_to_shost( >+ container_of(kobj, struct device, kobj))); >+ fc_ct_request_t *request = (void *)buf; >+ struct ct_entry_24xx *ct_iocb; >+ unsigned long flags; >+ >+ if (count < sizeof(request->ct_iu)) { >+ qla_printk(KERN_WARNING, ha, >+ "Passthru CT buffer insufficient size %d...\n", >+ (int)count); >+ goto ct_error0; >+ } >+ >+ if (ha->pass_thru_cmd_in_process || ha->pass_thru_cmd_result) { >+ qla_printk(KERN_WARNING, ha, >+ "Passthru CT request is already progress\n"); >+ goto ct_error0; >+ } >+ >+ if (qla2x00_mgmt_svr_login(ha)) { >+ 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); >+ >+ ct_iocb = (void *)qla2x00_req_pkt(ha); >+ if (ct_iocb == NULL) { >+ qla_printk(KERN_WARNING, ha, >+ "Passthru CT request failed to get request packet\n"); >+ goto ct_error1; >+ } >+ >+ if (count > PAGE_SIZE) { >+ 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); >+ >+ 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); >+ 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 = __constant_cpu_to_le16(25); >+ 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; >+ >+ qla_printk(KERN_INFO, ha, "Passthru CT request:\n"); >+ qla2x00_print_byte_buf(ha->pass_thru, min(count, (size_t)32), 16); >+ >+ qla_printk(KERN_INFO, ha, "Passthru CT IOCB:\n"); >+ qla2x00_print_word_buf(ct_iocb, sizeof(*ct_iocb), 8); >+ >+ 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: >+ qla_printk(KERN_WARNING, ha, "Passthru CT failed\n"); >+ return 0; >+} >+ >+static struct bin_attribute sysfs_ct_attr = { >+ .attr = { >+ .name = "ct", >+ .mode = S_IRUSR | S_IWUSR, >+ .owner = THIS_MODULE, >+ }, >+ .size = 0, >+ .read = qla2x00_sysfs_read_ct, >+ .write = qla2x00_sysfs_write_ct, >+}; >+ > static struct sysfs_entry { > char *name; > struct bin_attribute *attr; >@@ -471,6 +761,8 @@ static struct sysfs_entry { > { "optrom_ctl", &sysfs_optrom_ctl_attr, }, > { "vpd", &sysfs_vpd_attr, 1 }, > { "sfp", &sysfs_sfp_attr, 1 }, >+ { "els", &sysfs_els_attr, 1 }, >+ { "ct", &sysfs_ct_attr, 1 }, > { NULL }, > }; > >diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c >index ca7f70d..35f4448 100644 >--- a/drivers/scsi/qla2xxx/qla_dbg.c >+++ b/drivers/scsi/qla2xxx/qla_dbg.c >@@ -1443,6 +1443,36 @@ qla2x00_dump_pkt(void *pkt) > printk("\n"); > } > >+void >+qla2x00_print_byte_buf(void *buffer, size_t count, size_t per_line) >+{ >+ uint8_t *p = buffer; >+ size_t i; >+ >+ for (i = 0; i < count; i++){ >+ if (i && per_line && !(i % per_line)) >+ printk("\n"); >+ printk(" %02X", *p++); >+ } >+ printk("\n"); >+} >+ >+void >+qla2x00_print_word_buf(void *buffer, size_t count, size_t per_line) >+{ >+ uint16_t *p = buffer; >+ size_t i; >+ >+ count /= sizeof(*p); >+ >+ for (i = 0; i < count; i++) { >+ if (i && per_line && !(i % per_line)) >+ printk("\n"); >+ printk(" %04X", *p++); >+ } >+ printk("\n"); >+} >+ > #if defined(QL_DEBUG_ROUTINES) > /* > * qla2x00_formatted_dump_buffer >diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h >index 2226de1..c3257d3 100644 >--- a/drivers/scsi/qla2xxx/qla_def.h >+++ b/drivers/scsi/qla2xxx/qla_def.h >@@ -94,6 +94,89 @@ > #define MSD(x) ((uint32_t)((((uint64_t)(x)) >> 16) >> 16)) > > >+/* ELS PT request buffer = 32 bytes */ >+#define EXT_ELS_PT_REQ_WWPN_VALID 0x1 >+#define EXT_ELS_PT_REQ_WWNN_VALID 0x2 >+#define EXT_ELS_PT_REQ_PID_VALID 0x4 >+typedef struct { >+ uint8_t WWNN[8]; >+ uint8_t WWPN[8]; >+ uint8_t Id[4]; >+ uint16_t ValidMask; >+ uint16_t Lid; >+ uint16_t Rxid; >+ uint16_t AccRjt; >+ uint32_t Reserved; >+} ext_els_pt_req; >+ >+/* 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; >+ >+/* ELS request format */ >+typedef struct { >+ ext_els_pt_req header; >+ ct_iu_t ct_iu; >+} els_request_t; >+ > /* > * I/O register > */ >@@ -2409,6 +2492,8 @@ typedef struct scsi_qla_host { > /* SNS command interfaces for 2200. */ > 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 >@@ -2451,6 +2536,8 @@ typedef struct scsi_qla_host { > struct semaphore vport_sem; /* Virtual port synchronization */ > struct semaphore mbx_intr_sem; /* Used for completion notification */ > >+ struct completion pass_thru_intr_comp; /* For pass thru notification */ >+ > uint32_t mbx_flags; > #define MBX_IN_PROGRESS BIT_0 > #define MBX_BUSY BIT_1 /* Got the Access */ >@@ -2576,6 +2663,11 @@ typedef struct scsi_qla_host { > #define FC_VPORT_NO_FABRIC_SUPP 6 > #define FC_VPORT_NO_FABRIC_RSCS 7 > #define FC_VPORT_FAILED 8 >+ >+ /* pass through support */ >+ int pass_thru_cmd_result; >+ int pass_thru_cmd_in_process; >+ > struct qla_chip_state_84xx *cs84xx; > struct qla_statistics qla_stats; > } scsi_qla_host_t; >diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h >index 0409064..3106455 100644 >--- a/drivers/scsi/qla2xxx/qla_gbl.h >+++ b/drivers/scsi/qla2xxx/qla_gbl.h >@@ -132,6 +132,8 @@ extern int qla2x00_start_scsi(srb_t *sp) > extern int qla24xx_start_scsi(srb_t *sp); > int qla2x00_marker(scsi_qla_host_t *, uint16_t, uint16_t, uint8_t); > int __qla2x00_marker(scsi_qla_host_t *, uint16_t, uint16_t, uint8_t); >+extern request_t * qla2x00_req_pkt(scsi_qla_host_t *); >+extern void qla2x00_isp_cmd(scsi_qla_host_t *ha); > > /* > * Global Function Prototypes in qla_mbx.c source file. >@@ -338,6 +340,8 @@ extern void qla2x00_dump_regs(scsi_qla_h > extern void qla2x00_dump_buffer(uint8_t *, uint32_t); > extern void qla2x00_print_scsi_cmd(struct scsi_cmnd *); > extern void qla2x00_dump_pkt(void *); >+extern void qla2x00_print_byte_buf(void *, size_t, size_t); >+extern void qla2x00_print_word_buf(void *, size_t, size_t); > > /* > * Global Function Prototypes in qla_gs.c source file. >@@ -358,6 +362,7 @@ extern int qla2x00_fdmi_register(scsi_ql > 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. >diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c >index d5f2896..fe7f501 100644 >--- a/drivers/scsi/qla2xxx/qla_gs.c >+++ b/drivers/scsi/qla2xxx/qla_gs.c >@@ -1099,7 +1099,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; >diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c >index 84e10ed..65a6bb9 100644 >--- a/drivers/scsi/qla2xxx/qla_iocb.c >+++ b/drivers/scsi/qla2xxx/qla_iocb.c >@@ -14,8 +14,6 @@ > static inline uint16_t qla2x00_get_cmd_direction(struct scsi_cmnd *cmd); > static inline cont_entry_t *qla2x00_prep_cont_type0_iocb(scsi_qla_host_t *); > static inline cont_a64_entry_t *qla2x00_prep_cont_type1_iocb(scsi_qla_host_t *); >-static request_t *qla2x00_req_pkt(scsi_qla_host_t *ha); >-static void qla2x00_isp_cmd(scsi_qla_host_t *ha); > > /** > * qla2x00_get_cmd_direction() - Determine control_flag data direction. >@@ -508,7 +506,7 @@ qla2x00_marker(scsi_qla_host_t *ha, uint > * > * Returns NULL if function failed, else, a pointer to the request packet. > */ >-static request_t * >+request_t * > qla2x00_req_pkt(scsi_qla_host_t *ha) > { > device_reg_t __iomem *reg = ha->iobase; >@@ -578,7 +576,7 @@ qla2x00_req_pkt(scsi_qla_host_t *ha) > * > * Note: The caller must hold the hardware lock before calling this routine. > */ >-static void >+void > qla2x00_isp_cmd(scsi_qla_host_t *ha) > { > device_reg_t __iomem *reg = ha->iobase; >diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c >index 8530e9b..cef0cc1 100644 >--- a/drivers/scsi/qla2xxx/qla_isr.c >+++ b/drivers/scsi/qla2xxx/qla_isr.c >@@ -1502,7 +1502,30 @@ qla24xx_process_response_queue(struct sc > qla2x00_status_cont_entry(ha, (sts_cont_entry_t *)pkt); > break; > case MS_IOCB_TYPE: >- qla24xx_ms_entry(ha, (struct ct_entry_24xx *)pkt); >+ if (ha->outstanding_cmds[pkt->handle]) >+ qla24xx_ms_entry(ha, (void *)pkt); >+ else { >+ if (ha->pass_thru_cmd_result) >+ qla_printk(KERN_INFO, ha, >+ "Passthru cmd result on.\n"); >+ if (!ha->pass_thru_cmd_in_process) >+ 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) >+ qla_printk(KERN_INFO, ha, >+ "Passthru cmd result on.\n"); >+ if (!ha->pass_thru_cmd_in_process) >+ qla_printk(KERN_INFO, ha, >+ "Passthru in process off.\n"); >+ >+ ha->pass_thru_cmd_result = 1; >+ complete(&ha->pass_thru_intr_comp); > break; > case VP_RPT_ID_IOCB_TYPE: > qla24xx_report_id_acquisition(ha, >diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c >index 4836b23..83386fe 100644 >--- a/drivers/scsi/qla2xxx/qla_os.c >+++ b/drivers/scsi/qla2xxx/qla_os.c >@@ -1720,6 +1720,8 @@ qla2x00_probe_one(struct pci_dev *pdev, > /* load the F/W, read paramaters, and init the H/W */ > ha->instance = num_hosts; > >+ init_completion(&ha->pass_thru_intr_comp); >+ > init_MUTEX(&ha->mbx_cmd_sem); > init_MUTEX(&ha->vport_sem); > init_MUTEX_LOCKED(&ha->mbx_intr_sem); >@@ -2213,6 +2215,21 @@ qla2x00_mem_alloc(scsi_qla_host_t *ha) > } > memset(ha->ct_sns, 0, sizeof(struct ct_sns_pkt)); > >+ /*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 == NULL) { >+ /* error */ >+ qla_printk(KERN_WARNING, ha, >+ "Memory Allocation failed - pass_thru\n"); >+ >+ qla2x00_mem_free(ha); >+ msleep(100); >+ >+ continue; >+ } >+ memset(ha->pass_thru, 0, PAGE_SIZE); >+ > if (IS_FWI2_CAPABLE(ha)) { > /* > * Get consistent memory allocated for SFP >@@ -2297,6 +2314,10 @@ qla2x00_mem_free(scsi_qla_host_t *ha) > dma_free_coherent(&ha->pdev->dev, sizeof(struct ct_sns_pkt), > ha->ct_sns, ha->ct_sns_dma); > >+ if (ha->pass_thru) >+ dma_free_coherent(&ha->pdev->dev, PAGE_SIZE, >+ ha->pass_thru, ha->pass_thru_dma); >+ > if (ha->sfp_data) > dma_pool_free(ha->s_dma_pool, ha->sfp_data, ha->sfp_data_dma); > >@@ -2330,6 +2351,8 @@ qla2x00_mem_free(scsi_qla_host_t *ha) > ha->sns_cmd_dma = 0; > ha->ct_sns = NULL; > ha->ct_sns_dma = 0; >+ ha->pass_thru = NULL; >+ ha->pass_thru_dma = 0; > ha->ms_iocb = NULL; > ha->ms_iocb_dma = 0; > ha->init_cb = NULL; >-- >1.4.4.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 455900
: 313723