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 158005 Details for
Bug 245631
[QLogic 4.6 bug] [1/4] Update qla2xxx driver to version 8.01.07-d1 - Various fixes
[?]
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 for issues described in this BZ.
QLogic_4.6_patch1.patch (text/plain), 39.79 KB, created by
Marcus Barrow
on 2007-06-27 13:46:48 UTC
(
hide
)
Description:
Patch for issues described in this BZ.
Filename:
MIME Type:
Creator:
Marcus Barrow
Created:
2007-06-27 13:46:48 UTC
Size:
39.79 KB
patch
obsolete
>From 7e90db18fcfe889862c6e6e336cbc2e131aeb6bb Mon Sep 17 00:00:00 2001 >From: Marcus Barrow <mbarrow@dhcp83-183.boston.redhat.com> >Date: Fri, 4 May 2007 12:19:01 -0400 >Subject: [PATCH] Workaround D3 power-management issues. > > Recent ISP24xx firmwares now require software to insure a > 'proper' shutdown. This is needed to workaround a hardware > issue where some ISP2432 cards operate improperly in an D3 > power-management state. > > Ported from qla2xxx-std tree. >--- > drivers/scsi/qla2xxx/qla_gbl.h | 2 ++ > drivers/scsi/qla2xxx/qla_init.c | 23 +++++++++++++++++++++++ > drivers/scsi/qla2xxx/qla_os.c | 6 +++--- > 3 files changed, 28 insertions(+), 3 deletions(-) > >diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h >index 495e773..e942b36 100644 >--- a/drivers/scsi/qla2xxx/qla_gbl.h >+++ b/drivers/scsi/qla2xxx/qla_gbl.h >@@ -48,6 +48,8 @@ extern void qla2x00_tgt_free(scsi_qla_ho > > extern int qla2x00_abort_isp(scsi_qla_host_t *); > >+extern void qla2x00_try_to_stop_firmware(scsi_qla_host_t *); >+ > /* > * Global Data in qla_os.c source file. > */ >diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c >index dafa0c6..4d58123 100644 >--- a/drivers/scsi/qla2xxx/qla_init.c >+++ b/drivers/scsi/qla2xxx/qla_init.c >@@ -4982,3 +4982,26 @@ qla24xx_update_fw_options(scsi_qla_host_ > "Unable to update Serial Link options (%x).\n", rval); > } > } >+ >+void >+qla2x00_try_to_stop_firmware(scsi_qla_host_t *ha) >+{ >+ int ret, retries; >+ >+ if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) >+ return; >+ if (!ha->fw_major_version) >+ return; >+ >+ ret = qla2x00_stop_firmware(ha); >+ for (retries = 5; ret != QLA_SUCCESS && retries ; retries--) { >+ qla2x00_reset_chip(ha); >+ if (qla2x00_chip_diag(ha) != QLA_SUCCESS) >+ continue; >+ if (qla2x00_setup_chip(ha) != QLA_SUCCESS) >+ continue; >+ qla_printk(KERN_INFO, ha, >+ "Attempting retry of stop-firmware command...\n"); >+ ret = qla2x00_stop_firmware(ha); >+ } >+} >diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c >index e1dc42a..3062d34 100644 >--- a/drivers/scsi/qla2xxx/qla_os.c >+++ b/drivers/scsi/qla2xxx/qla_os.c >@@ -2441,8 +2441,10 @@ qla2x00_free_device(scsi_qla_host_t *ha) > } > } > >+ ha->flags.online = 0; >+ > /* Stop currently executing firmware. */ >- qla2x00_stop_firmware(ha); >+ qla2x00_try_to_stop_firmware(ha); > > /* turn-off interrupts on the card */ > if (ha->interrupts_on) >@@ -2450,8 +2452,6 @@ qla2x00_free_device(scsi_qla_host_t *ha) > > qla2x00_mem_free(ha); > >- ha->flags.online = 0; >- > /* Detach interrupts */ > if (ha->pdev->irq) > free_irq(ha->pdev->irq, ha); >-- >1.4.4.1 > >From d8133d6640a51ff7637a24a53976e645840f1d0b Mon Sep 17 00:00:00 2001 >From: Marcus Barrow <mbarrow@dhcp83-183.boston.redhat.com> >Date: Fri, 4 May 2007 12:21:52 -0400 >Subject: [PATCH] Port of queue-full changes in qla2xxx-std. > > Enable queue-full throttling when UNDERRUN detected. > > As ISP24xx firmware can return a CS_DATA_UNDERRUN completion > status when the storage has returned a > SAM_STAT_TASK_SET_FULL scsi-status. > > The starget_for_each_device() API was not introduced until > 2.6.11. Update queue-full handling codes to iterate over > all scsi-devices via the standard shost_for_each_device() > API. > > - Drop queue-depths across all luns for a given fcport > during TASK_SET_FULL statuses. > - Intelligently ramp-up I/Os after throttling. > - Consolidate completion-status handling of CS_QUEUE_FULL with > CS_COMPLETE as ISP24xx firmware no longer reports > CS_QUEUE_FULL. >--- > drivers/scsi/qla2xxx/qla_def.h | 3 + > drivers/scsi/qla2xxx/qla_gbl.h | 1 + > drivers/scsi/qla2xxx/qla_isr.c | 128 ++++++++++++++++++++++++++++++++------- > drivers/scsi/qla2xxx/qla_os.c | 7 ++ > 4 files changed, 116 insertions(+), 23 deletions(-) > >diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h >index c05e30b..380f69a 100644 >--- a/drivers/scsi/qla2xxx/qla_def.h >+++ b/drivers/scsi/qla2xxx/qla_def.h >@@ -1748,6 +1748,9 @@ typedef struct fc_port { > uint8_t cur_path; /* current path id */ > > lun_bit_mask_t lun_mask; >+ >+ unsigned long last_queue_full; >+ unsigned long last_ramp_up; > } fc_port_t; > > /* >diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h >index e942b36..2f55531 100644 >--- a/drivers/scsi/qla2xxx/qla_gbl.h >+++ b/drivers/scsi/qla2xxx/qla_gbl.h >@@ -73,6 +73,7 @@ extern int ql2xprocessrscn; > extern int extended_error_logging; > extern int ql2xfwloadbin; > extern int ql2xfdmienable; >+extern int ql2xqfullrampup; > > extern int ConfigRequired; > >diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c >index 5702f7b..c4dbed6 100644 >--- a/drivers/scsi/qla2xxx/qla_isr.c >+++ b/drivers/scsi/qla2xxx/qla_isr.c >@@ -18,6 +18,8 @@ > */ > #include "qla_def.h" > >+#include <scsi/scsi_tcq.h> >+ > static void qla2x00_mbx_completion(scsi_qla_host_t *, uint16_t); > static void qla2x00_async_event(scsi_qla_host_t *, uint16_t *); > static void qla2x00_process_completed_request(struct scsi_qla_host *, uint32_t); >@@ -684,6 +686,47 @@ qla2x00_async_event(scsi_qla_host_t *ha, > } > } > >+static inline void >+qla2x00_ramp_up_queue_depth(scsi_qla_host_t *ha, srb_t *sp) >+{ >+ fc_port_t *fcport; >+ struct scsi_device *sdev, *isdev; >+ >+ sdev = sp->cmd->device; >+ if (sdev->queue_depth >= ql2xmaxqdepth) >+ return; >+ >+ fcport = sp->fclun->fcport; >+ if (time_before(jiffies, >+ fcport->last_ramp_up + ql2xqfullrampup * HZ)) >+ return; >+ if (time_before(jiffies, >+ fcport->last_queue_full + ql2xqfullrampup * HZ)) >+ return; >+ >+ shost_for_each_device(isdev, sdev->host) { >+ if (isdev->channel != sdev->channel || isdev->id != sdev->id) >+ continue; >+ >+ if (ql2xmaxqdepth <= isdev->queue_depth) >+ continue; >+ >+ if (isdev->ordered_tags) >+ scsi_adjust_queue_depth(isdev, MSG_ORDERED_TAG, >+ isdev->queue_depth + 1); >+ else >+ scsi_adjust_queue_depth(isdev, MSG_SIMPLE_TAG, >+ isdev->queue_depth + 1); >+ >+ fcport->last_ramp_up = jiffies; >+ >+ DEBUG2(qla_printk(KERN_INFO, ha, >+ "scsi(%ld:%d:%d:%d): Queue depth adjusted-up to %d.\n", >+ ha->host_no, isdev->channel, isdev->id, isdev->lun, >+ isdev->queue_depth)); >+ } >+} >+ > /** > * qla2x00_process_completed_request() - Process a Fast Post response. > * @ha: SCSI driver HA context >@@ -719,6 +762,8 @@ qla2x00_process_completed_request(struct > /* Save ISP completion status */ > sp->cmd->result = DID_OK << 16; > sp->fo_retry_cnt = 0; >+ >+ qla2x00_ramp_up_queue_depth(ha, sp); > add_to_done_queue(ha, sp); > } else { > DEBUG2(printk("scsi(%ld): Invalid ISP SCSI completion handle\n", >@@ -833,12 +878,12 @@ qla2x00_process_response_queue(struct sc > static void > qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) > { >- int ret; > srb_t *sp; > os_lun_t *lq; > os_tgt_t *tq; > fc_port_t *fcport; > struct scsi_cmnd *cp; >+ struct scsi_device *isdev; > sts_entry_t *sts; > struct sts_entry_24xx *sts24; > uint16_t comp_status; >@@ -981,6 +1026,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha > */ > switch (comp_status) { > case CS_COMPLETE: >+ case CS_QUEUE_FULL: > if (scsi_status == 0) { > cp->result = DID_OK << 16; > break; >@@ -1009,8 +1055,33 @@ qla2x00_status_entry(scsi_qla_host_t *ha > } > > cp->result = DID_OK << 16 | lscsi_status; >- if (lscsi_status == SS_BUSY_CONDITION) >+ >+ if (lscsi_status == SAM_STAT_TASK_SET_FULL) { >+ DEBUG2(printk(KERN_INFO >+ "scsi(%ld): QUEUE FULL status detected " >+ "0x%x-0x%x.\n", ha->host_no, comp_status, >+ scsi_status)); >+ >+ /* Adjust queue depth for all luns on the port. */ >+ fcport = sp->fclun->fcport; >+ fcport->last_queue_full = jiffies; >+ shost_for_each_device(isdev, cp->device->host) { >+ if (isdev->channel != cp->device->channel || >+ isdev->id != cp->device->id) >+ continue; >+ >+ if (!scsi_track_queue_full(isdev, >+ isdev->queue_depth - 1)) >+ continue; >+ >+ DEBUG2(qla_printk(KERN_INFO, ha, >+ "scsi(%ld:%d:%d:%d): Queue depth " >+ "adjusted-down to %d.\n", ha->host_no, >+ isdev->channel, isdev->id, isdev->lun, >+ isdev->queue_depth)); >+ } > break; >+ } > > if (lscsi_status != SS_CHECK_CONDITION) > break; >@@ -1077,6 +1148,38 @@ qla2x00_status_entry(scsi_qla_host_t *ha > if (lscsi_status == SS_BUSY_CONDITION) > break; > >+ if (lscsi_status == SAM_STAT_TASK_SET_FULL) { >+ DEBUG2(printk(KERN_INFO >+ "scsi(%ld): QUEUE FULL status detected " >+ "0x%x-0x%x.\n", ha->host_no, comp_status, >+ scsi_status)); >+ >+ /* >+ * Adjust queue depth for all luns on the >+ * port. >+ */ >+ fcport = sp->fclun->fcport; >+ fcport->last_queue_full = jiffies; >+ shost_for_each_device(isdev, cp->device->host) { >+ if (isdev->channel != >+ cp->device->channel || >+ isdev->id != cp->device->id) >+ continue; >+ >+ if (!scsi_track_queue_full(isdev, >+ isdev->queue_depth - 1)) >+ continue; >+ >+ DEBUG2(qla_printk(KERN_INFO, ha, >+ "scsi(%ld:%d:%d:%d): Queue depth " >+ "adjusted-down to %d.\n", >+ ha->host_no, isdev->channel, >+ isdev->id, isdev->lun, >+ isdev->queue_depth)); >+ } >+ break; >+ } >+ > if (lscsi_status != SS_CHECK_CONDITION) > break; > >@@ -1260,27 +1363,6 @@ qla2x00_status_entry(scsi_qla_host_t *ha > } > break; > >- case CS_QUEUE_FULL: >- DEBUG2(printk(KERN_INFO >- "scsi(%ld): QUEUE FULL status detected 0x%x-0x%x.\n", >- ha->host_no, comp_status, scsi_status)); >- >- /* SCSI Mid-Layer handles device queue full */ >- >- cp->result = DID_OK << 16 | lscsi_status; >- >- /* TODO: ??? */ >- /* Adjust queue depth */ >- ret = scsi_track_queue_full(cp->device, >- sp->lun_queue->out_cnt - 1); >- if (ret) { >- qla_printk(KERN_INFO, ha, >- "scsi(%ld:%d:%d:%d): Queue depth adjusted to %d.\n", >- ha->host_no, cp->device->channel, cp->device->id, >- cp->device->lun, ret); >- } >- break; >- > default: > DEBUG3(printk("scsi(%ld): Error detected (unknown status) " > "0x%x-0x%x.\n", ha->host_no, comp_status, scsi_status)); >diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c >index 3062d34..fbd1904 100644 >--- a/drivers/scsi/qla2xxx/qla_os.c >+++ b/drivers/scsi/qla2xxx/qla_os.c >@@ -171,6 +171,13 @@ MODULE_PARM_DESC(ql2xfdmienable, > "Enables FDMI registratons " > "Default is 0 - no FDMI. 1 - perfom FDMI."); > >+int ql2xqfullrampup = 120; >+module_param(ql2xqfullrampup, int, S_IRUGO|S_IWUSR); >+MODULE_PARM_DESC(ql2xqfullrampup, >+ "Number of seconds to wait to begin to ramp-up the queue " >+ "depth for a device after a queue-full condition has been " >+ "detected. Default is 120 seconds."); >+ > /* > * List of host adapters > */ >-- >1.4.4.1 > >From cce957a4f7328c5c37c2b26666c11fa36516371c Mon Sep 17 00:00:00 2001 >From: Marcus Barrow <mbarrow@marcus-barrows-computer.local> >Date: Wed, 9 May 2007 21:53:29 -0400 >Subject: [PATCH] Generalized iIDMA support. > > In preparation for new ISP types. > > Correct issues where the iIDMA speed was not being returned. > Add support for iIDMA updates via EXIOCTs. > Reserve IOCTL #defines for iIDMA procedures. > > Add iIDMA support. > > iIDMA (Intelligent Interleaved Direct Memory Access) allows for > the HBA hardware to send FC frames at the rate at which they can > be received by a target device. By taking advantage of the > higher link rate, the HBA can maximize bandwidth utilization in a > heterogeneous multi-speed SAN. > > Within a fabric topology, port speed detection is done via a Name > Server command (GFPN_ID) followed by a Fabric Management command > (GPSC). In an FCAL/N2N topology, port speed is based on the HBA > link-rate. >--- > drivers/scsi/qla2xxx/exioctln.h | 3 + > drivers/scsi/qla2xxx/inioct.h | 7 ++ > drivers/scsi/qla2xxx/qim_inioct.c | 143 ++++++++++++++++++++++++++ > drivers/scsi/qla2xxx/qim_mbx.c | 1 + > drivers/scsi/qla2xxx/qim_xioct.c | 5 + > drivers/scsi/qla2xxx/qla_def.h | 39 +++++++- > drivers/scsi/qla2xxx/qla_gbl.h | 8 ++ > drivers/scsi/qla2xxx/qla_gs.c | 199 +++++++++++++++++++++++++++++++++++++ > drivers/scsi/qla2xxx/qla_init.c | 81 +++++++++++++++ > drivers/scsi/qla2xxx/qla_isr.c | 2 + > drivers/scsi/qla2xxx/qla_mbx.c | 86 ++++++++++++++++ > drivers/scsi/qla2xxx/qla_os.c | 2 + > 12 files changed, 575 insertions(+), 1 deletions(-) > >diff --git a/drivers/scsi/qla2xxx/exioctln.h b/drivers/scsi/qla2xxx/exioctln.h >index 2b4f585..7c2264e 100644 >--- a/drivers/scsi/qla2xxx/exioctln.h >+++ b/drivers/scsi/qla2xxx/exioctln.h >@@ -278,6 +278,9 @@ > #define EXT_CC_RESERVED0K_OS \ > QL_IOCTL_CMD(0x12) > >+#define EXT_CC_RESERVED0N_OS \ >+ QL_IOCTL_CMD(0x15) >+ > #define EXT_CC_RESERVED0Z_OS \ > QL_IOCTL_CMD(0x21) > >diff --git a/drivers/scsi/qla2xxx/inioct.h b/drivers/scsi/qla2xxx/inioct.h >index f2a18fd..1490056 100644 >--- a/drivers/scsi/qla2xxx/inioct.h >+++ b/drivers/scsi/qla2xxx/inioct.h >@@ -94,6 +94,7 @@ > #define INT_CC_GET_OPTION_ROM_LAYOUT EXT_CC_RESERVED0I_OS > #define INT_CC_GET_VPD EXT_CC_RESERVED0J_OS > #define INT_CC_UPDATE_VPD EXT_CC_RESERVED0K_OS >+#define INT_CC_PORT_PARAM EXT_CC_RESERVED0N_OS > #define INT_CC_LEGACY_LOOPBACK EXT_CC_RESERVED0Z_OS > > >@@ -292,6 +293,12 @@ typedef struct _OPT_ROM_TABLE > INT_OPT_ROM_REGION Region; > } OPT_ROM_TABLE, *POPT_ROM_TABLE; > >+typedef struct _INT_PORT_PARAM { >+ EXT_DEST_ADDR FCScsiAddr; >+ UINT16 Mode; >+ UINT16 Speed; >+} INT_PORT_PARAM, *PINT_PORT_PARAM; >+ > #ifdef _MSC_VER > #pragma pack() > #endif >diff --git a/drivers/scsi/qla2xxx/qim_inioct.c b/drivers/scsi/qla2xxx/qim_inioct.c >index 1114b7f..e555107 100644 >--- a/drivers/scsi/qla2xxx/qim_inioct.c >+++ b/drivers/scsi/qla2xxx/qim_inioct.c >@@ -1062,3 +1062,146 @@ qim_fw_dump(struct qla_host_ioctl *ha, E > } > > >+ >+int >+qim2x00_update_port_param(struct qla_host_ioctl *ha, EXT_IOCTL *pext, int mode) >+{ >+ int ret = 0, rval, port_found; >+ uint16_t mb[MAILBOX_REGISTER_COUNT]; >+ uint16_t idma_speed; >+ uint8_t *usr_temp; >+ fc_port_t *fcport; >+ INT_PORT_PARAM port_param; >+ struct scsi_qla_host *dr_ha = ha->dr_data; >+ >+ if (!IS_IIDMA_CAPABLE(dr_ha)) { >+ pext->Status = EXT_STATUS_INVALID_REQUEST; >+ DEBUG9_10(printk( >+ "%s(%ld): inst=%ld not 24xx. exiting.\n", >+ __func__, dr_ha->host_no, dr_ha->instance)); >+ return (ret); >+ } >+ >+ /* Copy request buffer */ >+ usr_temp = (uint8_t *)Q64BIT_TO_PTR(pext->RequestAdr, >+ pext->AddrMode); >+ ret = copy_from_user((uint8_t *)&port_param, usr_temp, >+ sizeof(INT_PORT_PARAM)); >+ if (ret) { >+ pext->Status = EXT_STATUS_COPY_ERR; >+ DEBUG9_10(printk( >+ "%s(%ld): inst=%ld ERROR copy req buf ret=%d\n", >+ __func__, dr_ha->host_no, dr_ha->instance, ret)); >+ return (-EFAULT); >+ } >+ >+ if (port_param.FCScsiAddr.DestType != EXT_DEF_TYPE_WWPN) { >+ pext->Status = EXT_STATUS_DEV_NOT_FOUND; >+ DEBUG9_10(printk("%s(%ld): inst=%ld ERROR -wrong Dest " >+ "type.\n", __func__, dr_ha->host_no, dr_ha->instance)); >+ return (ret); >+ } >+ >+ port_found = 0; >+ list_for_each_entry(fcport, &dr_ha->fcports, list) { >+ if (memcmp(fcport->port_name, >+ port_param.FCScsiAddr.DestAddr.WWPN, WWN_SIZE)) >+ continue; >+ >+ port_found++; >+ break; >+ } >+ if (!port_found) { >+ pext->Status = EXT_STATUS_DEV_NOT_FOUND; >+ DEBUG9_10(printk("%s(%ld): inst=%ld FC AddrFormat - DID NOT " >+ "FIND Port matching WWPN.\n", >+ __func__, dr_ha->host_no, dr_ha->instance)); >+ return (ret); >+ } >+ >+ /* Go with operation. */ >+ if (port_param.Mode) { >+ switch (port_param.Speed) { >+ case EXT_DEF_PORTSPEED_1GBIT: >+ idma_speed = PORT_SPEED_1GB; >+ break; >+ case EXT_DEF_PORTSPEED_2GBIT: >+ idma_speed = PORT_SPEED_2GB; >+ break; >+ case EXT_DEF_PORTSPEED_4GBIT: >+ idma_speed = PORT_SPEED_4GB; >+ break; >+ default: >+ pext->Status = EXT_STATUS_INVALID_PARAM; >+ DEBUG9_10(printk("%s(%ld): inst=%ld ERROR -invalid " >+ "speed.\n", __func__, dr_ha->host_no, dr_ha->instance)); >+ return (ret); >+ } >+ >+ rval = qla2x00_set_idma_speed(dr_ha, fcport->loop_id, idma_speed, >+ mb); >+ if (rval != QLA_SUCCESS) { >+ if (mb[0] == MBS_COMMAND_ERROR && mb[1] == 0x09) >+ pext->Status = EXT_STATUS_DEVICE_NOT_READY; >+ else if (mb[0] == MBS_COMMAND_PARAMETER_ERROR) >+ pext->Status = EXT_STATUS_INVALID_PARAM; >+ else >+ pext->Status = EXT_STATUS_ERR; >+ >+ DEBUG9_10(printk("%s(%ld): inst=%ld set iDMA cmd " >+ "FAILED=%x.\n", __func__, dr_ha->host_no, >+ dr_ha->instance, mb[0])); >+ return (ret); >+ } >+ } else { >+ rval = qla2x00_get_idma_speed(dr_ha, fcport->loop_id, >+ &idma_speed, mb); >+ if (rval != QLA_SUCCESS) { >+ if (mb[0] == MBS_COMMAND_ERROR && mb[1] == 0x09) >+ pext->Status = EXT_STATUS_DEVICE_NOT_READY; >+ else if (mb[0] == MBS_COMMAND_PARAMETER_ERROR) >+ pext->Status = EXT_STATUS_INVALID_PARAM; >+ else >+ pext->Status = EXT_STATUS_ERR; >+ >+ DEBUG9_10(printk("%s(%ld): inst=%ld get iDMA cmd " >+ "FAILED=%x.\n", __func__, dr_ha->host_no, >+ dr_ha->instance, mb[0])); >+ return (ret); >+ } >+ >+ switch (idma_speed) { >+ case PORT_SPEED_1GB: >+ port_param.Speed = EXT_DEF_PORTSPEED_1GBIT; >+ break; >+ case PORT_SPEED_2GB: >+ port_param.Speed = EXT_DEF_PORTSPEED_2GBIT; >+ break; >+ case PORT_SPEED_4GB: >+ port_param.Speed = EXT_DEF_PORTSPEED_4GBIT; >+ break; >+ default: >+ port_param.Speed = 0xFFFF; >+ break; >+ } >+ >+ usr_temp = (uint8_t *)Q64BIT_TO_PTR(pext->ResponseAdr, >+ pext->AddrMode); >+ ret = copy_to_user(usr_temp, (uint8_t *)&port_param, >+ sizeof(INT_PORT_PARAM)); >+ if (ret) { >+ pext->Status = EXT_STATUS_COPY_ERR; >+ DEBUG9_10(printk( >+ "%s(%ld): inst=%ld ERROR copy rsp buf ret=%d\n", >+ __func__, dr_ha->host_no, dr_ha->instance, ret)); >+ return (-EFAULT); >+ } >+ } >+ >+ pext->Status = EXT_STATUS_OK; >+ pext->DetailStatus = EXT_STATUS_OK; >+ >+ DEBUG9(printk("%s(%ld): exiting.\n", __func__, dr_ha->host_no)); >+ >+ return (ret); >+} >diff --git a/drivers/scsi/qla2xxx/qim_mbx.c b/drivers/scsi/qla2xxx/qim_mbx.c >index b8392f2..f800688 100644 >--- a/drivers/scsi/qla2xxx/qim_mbx.c >+++ b/drivers/scsi/qla2xxx/qim_mbx.c >@@ -18,6 +18,7 @@ > */ > #include "qim_def.h" > #include "exioctln.h" >+#include "exioct.h" > #include "inioct.h" > > #include <linux/delay.h> >diff --git a/drivers/scsi/qla2xxx/qim_xioct.c b/drivers/scsi/qla2xxx/qim_xioct.c >index b484d6d..55809c8 100644 >--- a/drivers/scsi/qla2xxx/qim_xioct.c >+++ b/drivers/scsi/qla2xxx/qim_xioct.c >@@ -70,6 +70,7 @@ extern int qim_update_option_rom(struct > extern int qim_get_option_rom_layout(struct qla_host_ioctl *, EXT_IOCTL *, int); > extern int qim_get_vpd(struct qla_host_ioctl *, EXT_IOCTL *, int); > extern int qim_update_vpd(struct qla_host_ioctl *, EXT_IOCTL *, int); >+extern int qim2x00_update_port_param(struct qla_host_ioctl *, EXT_IOCTL *, int); > > /* > * Local prototypes >@@ -797,6 +798,10 @@ qim_send_ioctl(struct scsi_device *dev, > ret = qim_update_vpd(ha, pext, mode); > break; > >+ case INT_CC_PORT_PARAM: >+ ret = qim2x00_update_port_param(ha, pext, mode); >+ break; >+ > /* all others go here */ > /* > case EXT_CC_PLATFORM_REG: >diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h >index 380f69a..adbd91f 100644 >--- a/drivers/scsi/qla2xxx/qla_def.h >+++ b/drivers/scsi/qla2xxx/qla_def.h >@@ -694,6 +694,7 @@ typedef struct { > */ > #define MBC_SERDES_PARAMS 0x10 /* Serdes Tx Parameters. */ > #define MBC_GET_IOCB_STATUS 0x12 /* Get IOCB status command. */ >+#define MBC_PORT_PARAMS 0x1A /* Port iDMA Parameters. */ > #define MBC_GET_TIMEOUT_PARAMS 0x22 /* Get FW timeouts. */ > #define MBC_GEN_SYSTEM_ERROR 0x2a /* Generate System Error. */ > #define MBC_SET_TIMEOUT_PARAMS 0x32 /* Set FW timeouts. */ >@@ -1574,6 +1575,9 @@ typedef struct { > port_id_t d_id; > uint8_t node_name[WWN_SIZE]; > uint8_t port_name[WWN_SIZE]; >+ uint8_t fabric_port_name[WWN_SIZE]; >+ uint16_t fp_speeds; >+ uint16_t fp_speed; > } sw_info_t; > > /* >@@ -1727,6 +1731,9 @@ typedef struct fc_port { > uint16_t loop_id; > uint16_t old_loop_id; > >+ uint8_t fabric_port_name[WWN_SIZE]; >+ uint16_t fp_speed; >+ > fc_port_type_t port_type; > > atomic_t state; >@@ -1824,6 +1831,7 @@ typedef struct fc_lun { > > #define CT_REJECT_RESPONSE 0x8001 > #define CT_ACCEPT_RESPONSE 0x8002 >+#define CT_REASON_INVALID_COMMAND_CODE 0x01 > #define CT_REASON_CANNOT_PERFORM 0x09 > #define CT_EXPL_ALREADY_REGISTERED 0x10 > >@@ -1867,6 +1875,15 @@ typedef struct fc_lun { > #define RSNN_NN_REQ_SIZE (16 + 8 + 1 + 255) > #define RSNN_NN_RSP_SIZE 16 > >+#define GFPN_ID_CMD 0x11C >+#define GFPN_ID_REQ_SIZE (16 + 4) >+#define GFPN_ID_RSP_SIZE (16 + 8) >+ >+#define GPSC_CMD 0x127 >+#define GPSC_REQ_SIZE (16 + 8) >+#define GPSC_RSP_SIZE (16 + 2 + 2) >+ >+ > /* > * HBA attribute types. > */ >@@ -1980,7 +1997,7 @@ struct ct_sns_req { > uint8_t reserved[3]; > > union { >- /* GA_NXT, GPN_ID, GNN_ID, GFT_ID */ >+ /* GA_NXT, GPN_ID, GNN_ID, GFT_ID, GFPN_ID */ > struct { > uint8_t reserved; > uint8_t port_id[3]; >@@ -2055,6 +2072,10 @@ struct ct_sns_req { > struct { > uint8_t port_name[8]; > } dpa; >+ >+ struct { >+ uint8_t port_name[8]; >+ } gpsc; > } req; > }; > >@@ -2118,6 +2139,15 @@ struct ct_sns_rsp { > uint8_t port_name[8]; > struct ct_fdmi_hba_attributes attrs; > } ghat; >+ >+ struct { >+ uint8_t port_name[8]; >+ } gfpn_id; >+ >+ struct { >+ uint16_t speeds; >+ uint16_t speed; >+ } gpsc; > } rsp; > }; > >@@ -2269,6 +2299,7 @@ typedef struct scsi_qla_host { > uint32_t msi_enabled :1; > uint32_t msix_enabled :1; > uint32_t enable_ip :1; >+ uint32_t gpsc_supported :1; > } flags; > > atomic_t loop_state; >@@ -2329,6 +2360,7 @@ typedef struct scsi_qla_host { > #define DT_ISP5432 BIT_10 > #define DT_ISP_LAST (DT_ISP5432 << 1) > >+#define DT_IIDMA BIT_26 > #define DT_OEM_001 BIT_29 > #define DT_ISP2200A BIT_30 > #define DT_EXTENDED_IDS BIT_31 >@@ -2351,6 +2383,7 @@ typedef struct scsi_qla_host { > #define IS_QLA24XX(ha) (IS_QLA2422(ha) || IS_QLA2432(ha)) > #define IS_QLA54XX(ha) (IS_QLA5422(ha) || IS_QLA5432(ha)) > >+#define IS_IIDMA_CAPABLE(ha) ((ha)->device_type & DT_IIDMA) > #define IS_OEM_001(ha) ((ha)->device_type & DT_OEM_001) > #define HAS_EXTENDED_IDS(ha) ((ha)->device_type & DT_EXTENDED_IDS) > >@@ -2441,6 +2474,10 @@ typedef struct scsi_qla_host { > uint16_t max_public_loop_ids; > uint16_t min_external_loopid; /* First external loop Id */ > >+#define PORT_SPEED_UNKNOWN 0xFFFF >+#define PORT_SPEED_1GB 0x00 >+#define PORT_SPEED_2GB 0x01 >+#define PORT_SPEED_4GB 0x03 > uint16_t link_data_rate; /* F/W operating speed */ > > uint8_t current_topology; >diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h >index 2f55531..cdc232b 100644 >--- a/drivers/scsi/qla2xxx/qla_gbl.h >+++ b/drivers/scsi/qla2xxx/qla_gbl.h >@@ -220,6 +220,12 @@ qla2x00_set_serdes_params(scsi_qla_host_ > extern int > qla2x00_stop_firmware(scsi_qla_host_t *); > >+extern int >+qla2x00_get_idma_speed(scsi_qla_host_t *, uint16_t, uint16_t *, uint16_t *); >+ >+extern int >+qla2x00_set_idma_speed(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t *); >+ > /* > * Global Function Prototypes in qla_isr.c source file. > */ >@@ -269,6 +275,8 @@ extern int qla2x00_rff_id(scsi_qla_host_ > extern int qla2x00_rnn_id(scsi_qla_host_t *); > extern int qla2x00_rsnn_nn(scsi_qla_host_t *); > 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 *); > > /* > * Global Function Prototypes in qla_rscn.c source file. >diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c >index 8658ebf..7177c59 100644 >--- a/drivers/scsi/qla2xxx/qla_gs.c >+++ b/drivers/scsi/qla2xxx/qla_gs.c >@@ -153,6 +153,7 @@ qla2x00_chk_ms_status(scsi_qla_host_t *h > DEBUG2_3(qla2x00_dump_buffer( > (uint8_t *)&ct_rsp->header, > sizeof(struct ct_rsp_hdr))); >+ rval = QLA_INVALID_COMMAND; > } else > rval = QLA_SUCCESS; > break; >@@ -1664,3 +1665,201 @@ qla2x00_fdmi_register(scsi_qla_host_t *h > return rval; > } > >+/** >+ * qla2x00_gfpn_id() - SNS Get Fabric Port Name (GFPN_ID) query. >+ * @ha: HA context >+ * @list: switch info entries to populate >+ * >+ * Returns 0 on success. >+ */ >+int >+qla2x00_gfpn_id(scsi_qla_host_t *ha, sw_info_t *list) >+{ >+ int rval; >+ uint16_t i; >+ >+ ms_iocb_entry_t *ms_pkt; >+ struct ct_sns_req *ct_req; >+ struct ct_sns_rsp *ct_rsp; >+ >+ if (!IS_IIDMA_CAPABLE(ha)) >+ return QLA_FUNCTION_FAILED; >+ >+ for (i = 0; i < MAX_FIBRE_DEVICES; i++) { >+ /* Issue GFPN_ID */ >+ memset(list[i].fabric_port_name, 0, WWN_SIZE); >+ >+ /* Prepare common MS IOCB */ >+ ms_pkt = qla2x00_prep_ms_iocb(ha, GFPN_ID_REQ_SIZE, >+ GFPN_ID_RSP_SIZE); >+ >+ /* Prepare CT request */ >+ ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GFPN_ID_CMD, >+ GFPN_ID_RSP_SIZE); >+ ct_rsp = &ha->ct_sns->p.rsp; >+ >+ /* Prepare CT arguments -- port_id */ >+ ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain; >+ ct_req->req.port_id.port_id[1] = list[i].d_id.b.area; >+ ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa; >+ >+ /* Execute MS IOCB */ >+ rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma, >+ sizeof(ms_iocb_entry_t)); >+ if (rval != QLA_SUCCESS) { >+ /*EMPTY*/ >+ DEBUG2_3(printk("scsi(%ld): GFPN_ID issue IOCB " >+ "failed (%d).\n", ha->host_no, rval)); >+ } else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, >+ "GFPN_ID") != QLA_SUCCESS) { >+ rval = QLA_FUNCTION_FAILED; >+ } else { >+ /* Save fabric portname */ >+ memcpy(list[i].fabric_port_name, >+ ct_rsp->rsp.gfpn_id.port_name, WWN_SIZE); >+ } >+ >+ /* Last device exit. */ >+ if (list[i].d_id.b.rsvd_1 != 0) >+ break; >+ } >+ >+ return (rval); >+} >+ >+static inline void * >+qla24xx_prep_ms_fm_iocb(scsi_qla_host_t *ha, uint32_t req_size, >+ uint32_t rsp_size) >+{ >+ struct ct_entry_24xx *ct_pkt; >+ >+ ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb; >+ memset(ct_pkt, 0, sizeof(struct ct_entry_24xx)); >+ >+ ct_pkt->entry_type = CT_IOCB_TYPE; >+ ct_pkt->entry_count = 1; >+ ct_pkt->nport_handle = cpu_to_le16(ha->mgmt_svr_loop_id); >+ ct_pkt->timeout = __constant_cpu_to_le16(59); >+ ct_pkt->cmd_dsd_count = __constant_cpu_to_le16(1); >+ ct_pkt->rsp_dsd_count = __constant_cpu_to_le16(1); >+ ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size); >+ ct_pkt->cmd_byte_count = cpu_to_le32(req_size); >+ >+ ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); >+ ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); >+ ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count; >+ >+ ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); >+ ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); >+ ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count; >+ >+ return ct_pkt; >+} >+ >+ >+static inline struct ct_sns_req * >+qla24xx_prep_ct_fm_req(struct ct_sns_req *ct_req, uint16_t cmd, >+ uint16_t rsp_size) >+{ >+ memset(ct_req, 0, sizeof(struct ct_sns_pkt)); >+ >+ ct_req->header.revision = 0x01; >+ ct_req->header.gs_type = 0xFA; >+ ct_req->header.gs_subtype = 0x01; >+ ct_req->command = cpu_to_be16(cmd); >+ ct_req->max_rsp_size = cpu_to_be16((rsp_size - 16) / 4); >+ >+ return ct_req; >+} >+ >+/** >+ * qla2x00_gpsc() - FCS Get Port Speed Capabilities (GPSC) query. >+ * @ha: HA context >+ * @list: switch info entries to populate >+ * >+ * Returns 0 on success. >+ */ >+int >+qla2x00_gpsc(scsi_qla_host_t *ha, sw_info_t *list) >+{ >+ int rval; >+ uint16_t i; >+ >+ ms_iocb_entry_t *ms_pkt; >+ struct ct_sns_req *ct_req; >+ struct ct_sns_rsp *ct_rsp; >+ >+ if (!IS_IIDMA_CAPABLE(ha)) >+ return QLA_FUNCTION_FAILED; >+ if (!ha->flags.gpsc_supported) >+ return QLA_FUNCTION_FAILED; >+ >+ rval = qla2x00_mgmt_svr_login(ha); >+ if (rval) >+ return rval; >+ >+ for (i = 0; i < MAX_FIBRE_DEVICES; i++) { >+ /* Issue GFPN_ID */ >+ list[i].fp_speeds = list[i].fp_speed = 0; >+ >+ /* Prepare common MS IOCB */ >+ ms_pkt = qla24xx_prep_ms_fm_iocb(ha, GPSC_REQ_SIZE, >+ GPSC_RSP_SIZE); >+ >+ /* Prepare CT request */ >+ ct_req = qla24xx_prep_ct_fm_req(&ha->ct_sns->p.req, >+ GPSC_CMD, GPSC_RSP_SIZE); >+ ct_rsp = &ha->ct_sns->p.rsp; >+ >+ /* Prepare CT arguments -- port_name */ >+ memcpy(ct_req->req.gpsc.port_name, list[i].fabric_port_name, >+ WWN_SIZE); >+ >+ /* Execute MS IOCB */ >+ rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma, >+ sizeof(ms_iocb_entry_t)); >+ if (rval != QLA_SUCCESS) { >+ /*EMPTY*/ >+ DEBUG2_3(printk("scsi(%ld): GPSC issue IOCB " >+ "failed (%d).\n", ha->host_no, rval)); >+ } else if ((rval = qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, >+ "GPSC")) != QLA_SUCCESS) { >+ /* FM command unsupported? */ >+ if (rval == QLA_INVALID_COMMAND && >+ ct_rsp->header.reason_code == >+ CT_REASON_INVALID_COMMAND_CODE) { >+ DEBUG2(printk("scsi(%ld): GPSC command " >+ "unsupported, disabling query...\n", >+ ha->host_no)); >+ ha->flags.gpsc_supported = 0; >+ rval = QLA_FUNCTION_FAILED; >+ break; >+ } >+ rval = QLA_FUNCTION_FAILED; >+ } else { >+ /* Save portname */ >+ list[i].fp_speeds = ct_rsp->rsp.gpsc.speeds; >+ list[i].fp_speed = ct_rsp->rsp.gpsc.speed; >+ >+ DEBUG2_3(printk("scsi(%ld): GPSC ext entry - " >+ "fpn %02x%02x%02x%02x%02x%02x%02x%02x speeds=%04x " >+ "speed=%04x.\n", ha->host_no, >+ list[i].fabric_port_name[0], >+ list[i].fabric_port_name[1], >+ list[i].fabric_port_name[2], >+ list[i].fabric_port_name[3], >+ list[i].fabric_port_name[4], >+ list[i].fabric_port_name[5], >+ list[i].fabric_port_name[6], >+ list[i].fabric_port_name[7], >+ be16_to_cpu(list[i].fp_speeds), >+ be16_to_cpu(list[i].fp_speed))); >+ } >+ >+ /* Last device exit. */ >+ if (list[i].d_id.b.rsvd_1 != 0) >+ break; >+ } >+ >+ return (rval); >+} >diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c >index 4d58123..ea6ac3a 100644 >--- a/drivers/scsi/qla2xxx/qla_init.c >+++ b/drivers/scsi/qla2xxx/qla_init.c >@@ -2028,6 +2028,19 @@ qla2x00_configure_local_loop(scsi_qla_ho > new_fcport->flags &= ~FCF_FABRIC_DEVICE; > } > >+ /* Base iIDMA settings on HBA port speed. */ >+ switch (ha->link_data_rate) { >+ case PORT_SPEED_1GB: >+ fcport->fp_speed = cpu_to_be16(BIT_15); >+ break; >+ case PORT_SPEED_2GB: >+ fcport->fp_speed = cpu_to_be16(BIT_14); >+ break; >+ case PORT_SPEED_4GB: >+ fcport->fp_speed = cpu_to_be16(BIT_13); >+ break; >+ } >+ > qla2x00_update_fcport(ha, fcport); > > found_devs++; >@@ -2064,6 +2077,62 @@ qla2x00_probe_for_all_luns(scsi_qla_host > } > } > >+static void >+qla2x00_iidma_fcport(scsi_qla_host_t *ha, fc_port_t *fcport) >+{ >+#define LS_UNKNOWN 2 >+ static char *link_speeds[5] = { "1", "2", "?", "4" }; >+ int rval; >+ uint16_t port_speed, mb[6]; >+ >+ if (!IS_IIDMA_CAPABLE(ha)) >+ return; >+ >+ switch (be16_to_cpu(fcport->fp_speed)) { >+ case BIT_15: >+ port_speed = PORT_SPEED_1GB; >+ break; >+ case BIT_14: >+ port_speed = PORT_SPEED_2GB; >+ break; >+ case BIT_13: >+ port_speed = PORT_SPEED_4GB; >+ break; >+ default: >+ DEBUG2(printk("scsi(%ld): %02x%02x%02x%02x%02x%02x%02x%02x -- " >+ "unsupported FM port operating speed (%04x).\n", >+ ha->host_no, fcport->port_name[0], fcport->port_name[1], >+ fcport->port_name[2], fcport->port_name[3], >+ fcport->port_name[4], fcport->port_name[5], >+ fcport->port_name[6], fcport->port_name[7], >+ be16_to_cpu(fcport->fp_speed))); >+ port_speed = PORT_SPEED_UNKNOWN; >+ break; >+ } >+ if (port_speed == PORT_SPEED_UNKNOWN) >+ return; >+ >+ rval = qla2x00_set_idma_speed(ha, fcport->loop_id, port_speed, mb); >+ if (rval != QLA_SUCCESS) { >+ DEBUG2(printk("scsi(%ld): Unable to adjust iIDMA " >+ "%02x%02x%02x%02x%02x%02x%02x%02x -- %04x %x %04x %04x.\n", >+ ha->host_no, fcport->port_name[0], fcport->port_name[1], >+ fcport->port_name[2], fcport->port_name[3], >+ fcport->port_name[4], fcport->port_name[5], >+ fcport->port_name[6], fcport->port_name[7], rval, >+ port_speed, mb[0], mb[1])); >+ } else { >+ DEBUG2(qla_printk(KERN_INFO, ha, >+ "iIDMA adjusted to %s GB/s on " >+ "%02x%02x%02x%02x%02x%02x%02x%02x.\n", >+ link_speeds[port_speed], fcport->port_name[0], >+ fcport->port_name[1], fcport->port_name[2], >+ fcport->port_name[3], fcport->port_name[4], >+ fcport->port_name[5], fcport->port_name[6], >+ fcport->port_name[7])); >+ } >+} >+ > /* > * qla2x00_update_fcport > * Updates device on list. >@@ -2094,6 +2163,8 @@ qla2x00_update_fcport(scsi_qla_host_t *h > PORT_RETRY_TIME); > fcport->flags &= ~FCF_LOGIN_NEEDED; > >+ qla2x00_iidma_fcport(ha, fcport); >+ > /* > * Check for outstanding cmd on tape Bypass LUN discovery if active > * command on tape. >@@ -2926,6 +2997,8 @@ qla2x00_find_all_fabric_devs(scsi_qla_ho > } else if (qla2x00_gnn_id(ha, swl) != QLA_SUCCESS) { > kfree(swl); > swl = NULL; >+ } else if (qla2x00_gfpn_id(ha, swl) == QLA_SUCCESS) { >+ qla2x00_gpsc(ha, swl); > } > } > swl_idx = 0; >@@ -2961,6 +3034,9 @@ qla2x00_find_all_fabric_devs(scsi_qla_ho > swl[swl_idx].node_name, WWN_SIZE); > memcpy(new_fcport->port_name, > swl[swl_idx].port_name, WWN_SIZE); >+ memcpy(new_fcport->fabric_port_name, >+ swl[swl_idx].fabric_port_name, WWN_SIZE); >+ new_fcport->fp_speed = swl[swl_idx].fp_speed; > > if (swl[swl_idx].d_id.b.rsvd_1 != 0) { > last_dev = 1; >@@ -3018,6 +3094,11 @@ qla2x00_find_all_fabric_devs(scsi_qla_ho > > found++; > >+ /* Update port state. */ >+ memcpy(fcport->fabric_port_name, >+ new_fcport->fabric_port_name, WWN_SIZE); >+ fcport->fp_speed = new_fcport->fp_speed; >+ > /* > * If address the same and state FCS_ONLINE, nothing > * changed. >diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c >index c4dbed6..b71badb 100644 >--- a/drivers/scsi/qla2xxx/qla_isr.c >+++ b/drivers/scsi/qla2xxx/qla_isr.c >@@ -529,6 +529,8 @@ qla2x00_async_event(scsi_qla_host_t *ha, > set_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); > } > set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags); >+ >+ ha->flags.gpsc_supported = 1; > break; > > case MBA_CHG_IN_CONNECTION: /* Change in connection mode */ >diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c >index bee91b6..c4c028c 100644 >--- a/drivers/scsi/qla2xxx/qla_mbx.c >+++ b/drivers/scsi/qla2xxx/qla_mbx.c >@@ -2526,3 +2526,89 @@ qla2x00_stop_firmware(scsi_qla_host_t *h > > return rval; > } >+ >+int >+qla2x00_get_idma_speed(scsi_qla_host_t *ha, uint16_t loop_id, >+ uint16_t *port_speed, uint16_t *mb) >+{ >+ int rval; >+ mbx_cmd_t mc; >+ mbx_cmd_t *mcp = &mc; >+ >+ if (!IS_IIDMA_CAPABLE(ha)) >+ return QLA_FUNCTION_FAILED; >+ >+ DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); >+ >+ mcp->mb[0] = MBC_PORT_PARAMS; >+ mcp->mb[1] = loop_id; >+ mcp->mb[2] = mcp->mb[3] = mcp->mb[4] = mcp->mb[5] = 0; >+ mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; >+ mcp->in_mb = MBX_5|MBX_4|MBX_3|MBX_1|MBX_0; >+ mcp->tov = 30; >+ mcp->flags = 0; >+ rval = qla2x00_mailbox_command(ha, mcp); >+ >+ /* Return mailbox statuses. */ >+ if (mb != NULL) { >+ mb[0] = mcp->mb[0]; >+ mb[1] = mcp->mb[1]; >+ mb[3] = mcp->mb[3]; >+ mb[4] = mcp->mb[4]; >+ mb[5] = mcp->mb[5]; >+ } >+ >+ if (rval != QLA_SUCCESS) { >+ DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__, >+ ha->host_no, rval)); >+ } else { >+ DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); >+ if (port_speed) >+ *port_speed = mcp->mb[3]; >+ } >+ >+ return rval; >+} >+ >+int >+qla2x00_set_idma_speed(scsi_qla_host_t *ha, uint16_t loop_id, >+ uint16_t port_speed, uint16_t *mb) >+{ >+ int rval; >+ mbx_cmd_t mc; >+ mbx_cmd_t *mcp = &mc; >+ >+ if (!IS_IIDMA_CAPABLE(ha)) >+ return QLA_FUNCTION_FAILED; >+ >+ DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); >+ >+ mcp->mb[0] = MBC_PORT_PARAMS; >+ mcp->mb[1] = loop_id; >+ mcp->mb[2] = BIT_0; >+ mcp->mb[3] = port_speed & (BIT_2|BIT_1|BIT_0); >+ mcp->mb[4] = mcp->mb[5] = 0; >+ mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; >+ mcp->in_mb = MBX_5|MBX_4|MBX_3|MBX_1|MBX_0; >+ mcp->tov = 30; >+ mcp->flags = 0; >+ rval = qla2x00_mailbox_command(ha, mcp); >+ >+ /* Return mailbox statuses. */ >+ if (mb != NULL) { >+ mb[0] = mcp->mb[0]; >+ mb[1] = mcp->mb[1]; >+ mb[3] = mcp->mb[3]; >+ mb[4] = mcp->mb[4]; >+ mb[5] = mcp->mb[5]; >+ } >+ >+ if (rval != QLA_SUCCESS) { >+ DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__, >+ ha->host_no, rval)); >+ } else { >+ DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); >+ } >+ >+ return rval; >+} >diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c >index fbd1904..bd79cf9 100644 >--- a/drivers/scsi/qla2xxx/qla_os.c >+++ b/drivers/scsi/qla2xxx/qla_os.c >@@ -1128,9 +1128,11 @@ qla2x00_set_isp_flags(scsi_qla_host_t *h > break; > case PCI_DEVICE_ID_QLOGIC_ISP2422: > ha->device_type |= DT_ISP2422; >+ ha->device_type |= DT_IIDMA; > break; > case PCI_DEVICE_ID_QLOGIC_ISP2432: > ha->device_type |= DT_ISP2432; >+ ha->device_type |= DT_IIDMA; > break; > case PCI_DEVICE_ID_QLOGIC_ISP5422: > ha->device_type |= DT_ISP5422; >-- >1.4.4.1 > >From 876e5ca0beee6a3487d007870e9dc1aed8e5680e Mon Sep 17 00:00:00 2001 >From: Marcus Barrow <mbarrow@marcus-barrows-computer.local> >Date: Mon, 14 May 2007 15:52:56 -0400 >Subject: [PATCH] fixes for IRQ-0, RSCN on big-endian, byteswap fc_host fabric_name. > > ported these changes from qla2xxx-std treen: > > Handle IRQ-0 assignments by the system. > > No restriction should be placed on the IRQ number assigned > to a given ISP. Original code incorrectly assumed a > non-zero IRQ number assignment by the system. In these > circumstances the proper freeing of the IRQ (via free_irq()) > would not take place. > > Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com> > > Fix RSCN handling on big-endian systems > > qla2xxx driver fails to handle RSCN events affecting area or domain due > to an endian issue on big endian systems. This fixes the port_id_t > structure on big endian systems. > > Signed-off-by: Malahal Naineni <malahal@us.ibm.com> > Acked-by: Seokmann Ju <seokmann.ju@qlogic.com> > Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com> > > Fix for byteswap in fc_host fabric_name. > > FROM: linux-scsi mailing list. > > This patch fixes byte swap issue in qla2xxx driver > to fix corrupted fabric_name passed to > /sys/class/fc_host/host*/fabric_name. > > Signed-off-by: Richard Lary <rlary@us.ibm.com> > Acked-by: Seokmann Ju <seokmann.ju@qlogic.com> > Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com> >--- > drivers/scsi/qla2xxx/qla_def.h | 9 +++++++++ > drivers/scsi/qla2xxx/qla_mbx.c | 16 ++++++++-------- > drivers/scsi/qla2xxx/qla_os.c | 3 ++- > 3 files changed, 19 insertions(+), 9 deletions(-) > >diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h >index adbd91f..235b698 100644 >--- a/drivers/scsi/qla2xxx/qla_def.h >+++ b/drivers/scsi/qla2xxx/qla_def.h >@@ -1560,9 +1560,17 @@ typedef union { > } r; > > struct { >+#ifdef __BIG_ENDIAN >+ uint8_t domain; >+ uint8_t area; >+ uint8_t al_pa; >+#elif __LITTLE_ENDIAN > uint8_t al_pa; > uint8_t area; > uint8_t domain; >+#else >+#error "__BIG_ENDIAN or __LITTLE_ENDIAN must be defined!" >+#endif > uint8_t rsvd_1; > } b; > } port_id_t; >@@ -2296,6 +2304,7 @@ typedef struct scsi_qla_host { > uint32_t enable_lip_full_login :1; > uint32_t enable_target_reset :1; > uint32_t enable_led_scheme :1; >+ uint32_t inta_enabled :1; > uint32_t msi_enabled :1; > uint32_t msix_enabled :1; > uint32_t enable_ip :1; >diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c >index c4c028c..576918a 100644 >--- a/drivers/scsi/qla2xxx/qla_mbx.c >+++ b/drivers/scsi/qla2xxx/qla_mbx.c >@@ -1418,14 +1418,14 @@ qla2x00_get_port_name(scsi_qla_host_t *h > } else { > if (name != NULL) { > /* This function returns name in big endian. */ >- name[0] = LSB(mcp->mb[2]); >- name[1] = MSB(mcp->mb[2]); >- name[2] = LSB(mcp->mb[3]); >- name[3] = MSB(mcp->mb[3]); >- name[4] = LSB(mcp->mb[6]); >- name[5] = MSB(mcp->mb[6]); >- name[6] = LSB(mcp->mb[7]); >- name[7] = MSB(mcp->mb[7]); >+ name[0] = MSB(mcp->mb[2]); >+ name[1] = LSB(mcp->mb[2]); >+ name[2] = MSB(mcp->mb[3]); >+ name[3] = LSB(mcp->mb[3]); >+ name[4] = MSB(mcp->mb[6]); >+ name[5] = LSB(mcp->mb[6]); >+ name[6] = MSB(mcp->mb[7]); >+ name[7] = LSB(mcp->mb[7]); > } > > DEBUG11(printk("qla2x00_get_port_name(%ld): done.\n", >diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c >index bd79cf9..cd70f10 100644 >--- a/drivers/scsi/qla2xxx/qla_os.c >+++ b/drivers/scsi/qla2xxx/qla_os.c >@@ -2284,6 +2284,7 @@ int qla2x00_probe_one(struct pci_dev *pd > pdev->irq); > goto probe_failed; > } >+ ha->flags.inta_enabled = 1; > host->irq = pdev->irq; > > /* Initialized the timer */ >@@ -2462,7 +2463,7 @@ qla2x00_free_device(scsi_qla_host_t *ha) > qla2x00_mem_free(ha); > > /* Detach interrupts */ >- if (ha->pdev->irq) >+ if (ha->flags.inta_enabled) > free_irq(ha->pdev->irq, ha); > > #ifdef ENABLE_MSI >-- >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 Raw
Actions:
View
Attachments on
bug 245631
: 158005