aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_init.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c99
1 files changed, 67 insertions, 32 deletions
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index fbb6feee40cf..290a6b92616c 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -1,20 +1,8 @@
1/* 1/*
2 * QLOGIC LINUX SOFTWARE 2 * QLogic Fibre Channel HBA Driver
3 * 3 * Copyright (c) 2003-2005 QLogic Corporation
4 * QLogic ISP2x00 device driver for Linux 2.6.x
5 * Copyright (C) 2003-2005 QLogic Corporation
6 * (www.qlogic.com)
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2, or (at your option) any
11 * later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 * 4 *
5 * See LICENSE.qla2xxx for copyright and licensing details.
18 */ 6 */
19#include "qla_def.h" 7#include "qla_def.h"
20 8
@@ -1372,7 +1360,6 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
1372 nvram_t *nv = (nvram_t *)ha->request_ring; 1360 nvram_t *nv = (nvram_t *)ha->request_ring;
1373 uint8_t *ptr = (uint8_t *)ha->request_ring; 1361 uint8_t *ptr = (uint8_t *)ha->request_ring;
1374 struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; 1362 struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
1375 uint8_t timer_mode;
1376 1363
1377 rval = QLA_SUCCESS; 1364 rval = QLA_SUCCESS;
1378 1365
@@ -1650,22 +1637,26 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
1650 1637
1651 ha->flags.process_response_queue = 1; 1638 ha->flags.process_response_queue = 1;
1652 } else { 1639 } else {
1653 /* Enable ZIO -- Support mode 5 only. */ 1640 /* Enable ZIO. */
1654 timer_mode = icb->add_firmware_options[0] & 1641 if (!ha->flags.init_done) {
1655 (BIT_3 | BIT_2 | BIT_1 | BIT_0); 1642 ha->zio_mode = icb->add_firmware_options[0] &
1643 (BIT_3 | BIT_2 | BIT_1 | BIT_0);
1644 ha->zio_timer = icb->interrupt_delay_timer ?
1645 icb->interrupt_delay_timer: 2;
1646 }
1656 icb->add_firmware_options[0] &= 1647 icb->add_firmware_options[0] &=
1657 ~(BIT_3 | BIT_2 | BIT_1 | BIT_0); 1648 ~(BIT_3 | BIT_2 | BIT_1 | BIT_0);
1658 if (ql2xenablezio) 1649 ha->flags.process_response_queue = 0;
1659 timer_mode = BIT_2 | BIT_0; 1650 if (ha->zio_mode != QLA_ZIO_DISABLED) {
1660 if (timer_mode == (BIT_2 | BIT_0)) { 1651 DEBUG2(printk("scsi(%ld): ZIO mode %d enabled; timer "
1661 DEBUG2(printk("scsi(%ld): ZIO enabled; timer delay " 1652 "delay (%d us).\n", ha->host_no, ha->zio_mode,
1662 "(%d).\n", ha->host_no, ql2xintrdelaytimer)); 1653 ha->zio_timer * 100));
1663 qla_printk(KERN_INFO, ha, 1654 qla_printk(KERN_INFO, ha,
1664 "ZIO enabled; timer delay (%d).\n", 1655 "ZIO mode %d enabled; timer delay (%d us).\n",
1665 ql2xintrdelaytimer); 1656 ha->zio_mode, ha->zio_timer * 100);
1666 1657
1667 icb->add_firmware_options[0] |= timer_mode; 1658 icb->add_firmware_options[0] |= (uint8_t)ha->zio_mode;
1668 icb->interrupt_delay_timer = ql2xintrdelaytimer; 1659 icb->interrupt_delay_timer = (uint8_t)ha->zio_timer;
1669 ha->flags.process_response_queue = 1; 1660 ha->flags.process_response_queue = 1;
1670 } 1661 }
1671 } 1662 }
@@ -1677,6 +1668,24 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
1677 return (rval); 1668 return (rval);
1678} 1669}
1679 1670
1671static void
1672qla2x00_rport_add(void *data)
1673{
1674 fc_port_t *fcport = data;
1675
1676 qla2x00_reg_remote_port(fcport->ha, fcport);
1677}
1678
1679static void
1680qla2x00_rport_del(void *data)
1681{
1682 fc_port_t *fcport = data;
1683
1684 if (fcport->rport)
1685 fc_remote_port_delete(fcport->rport);
1686 fcport->rport = NULL;
1687}
1688
1680/** 1689/**
1681 * qla2x00_alloc_fcport() - Allocate a generic fcport. 1690 * qla2x00_alloc_fcport() - Allocate a generic fcport.
1682 * @ha: HA context 1691 * @ha: HA context
@@ -1702,6 +1711,8 @@ qla2x00_alloc_fcport(scsi_qla_host_t *ha, gfp_t flags)
1702 atomic_set(&fcport->state, FCS_UNCONFIGURED); 1711 atomic_set(&fcport->state, FCS_UNCONFIGURED);
1703 fcport->flags = FCF_RLC_SUPPORT; 1712 fcport->flags = FCF_RLC_SUPPORT;
1704 fcport->supported_classes = FC_COS_UNSPECIFIED; 1713 fcport->supported_classes = FC_COS_UNSPECIFIED;
1714 INIT_WORK(&fcport->rport_add_work, qla2x00_rport_add, fcport);
1715 INIT_WORK(&fcport->rport_del_work, qla2x00_rport_del, fcport);
1705 1716
1706 return (fcport); 1717 return (fcport);
1707} 1718}
@@ -2065,8 +2076,8 @@ qla2x00_reg_remote_port(scsi_qla_host_t *ha, fc_port_t *fcport)
2065 struct fc_rport *rport; 2076 struct fc_rport *rport;
2066 2077
2067 if (fcport->rport) { 2078 if (fcport->rport) {
2068 fc_remote_port_unblock(fcport->rport); 2079 fc_remote_port_delete(fcport->rport);
2069 return; 2080 fcport->rport = NULL;
2070 } 2081 }
2071 2082
2072 rport_ids.node_name = wwn_to_u64(fcport->node_name); 2083 rport_ids.node_name = wwn_to_u64(fcport->node_name);
@@ -2080,7 +2091,7 @@ qla2x00_reg_remote_port(scsi_qla_host_t *ha, fc_port_t *fcport)
2080 "Unable to allocate fc remote port!\n"); 2091 "Unable to allocate fc remote port!\n");
2081 return; 2092 return;
2082 } 2093 }
2083 rport->dd_data = fcport; 2094 *((fc_port_t **)rport->dd_data) = fcport;
2084 rport->supported_classes = fcport->supported_classes; 2095 rport->supported_classes = fcport->supported_classes;
2085 2096
2086 rport_ids.roles = FC_RPORT_ROLE_UNKNOWN; 2097 rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
@@ -2858,7 +2869,7 @@ qla2x00_fabric_login(scsi_qla_host_t *ha, fc_port_t *fcport,
2858 fcport->d_id.b.domain, fcport->d_id.b.area, 2869 fcport->d_id.b.domain, fcport->d_id.b.area,
2859 fcport->d_id.b.al_pa); 2870 fcport->d_id.b.al_pa);
2860 fcport->loop_id = FC_NO_LOOP_ID; 2871 fcport->loop_id = FC_NO_LOOP_ID;
2861 atomic_set(&fcport->state, FCS_DEVICE_DEAD); 2872 fcport->login_retry = 0;
2862 2873
2863 rval = 3; 2874 rval = 3;
2864 break; 2875 break;
@@ -3442,6 +3453,30 @@ qla24xx_nvram_config(scsi_qla_host_t *ha)
3442 if (ql2xloginretrycount) 3453 if (ql2xloginretrycount)
3443 ha->login_retry_count = ql2xloginretrycount; 3454 ha->login_retry_count = ql2xloginretrycount;
3444 3455
3456 /* Enable ZIO. */
3457 if (!ha->flags.init_done) {
3458 ha->zio_mode = le32_to_cpu(icb->firmware_options_2) &
3459 (BIT_3 | BIT_2 | BIT_1 | BIT_0);
3460 ha->zio_timer = le16_to_cpu(icb->interrupt_delay_timer) ?
3461 le16_to_cpu(icb->interrupt_delay_timer): 2;
3462 }
3463 icb->firmware_options_2 &= __constant_cpu_to_le32(
3464 ~(BIT_3 | BIT_2 | BIT_1 | BIT_0));
3465 ha->flags.process_response_queue = 0;
3466 if (ha->zio_mode != QLA_ZIO_DISABLED) {
3467 DEBUG2(printk("scsi(%ld): ZIO mode %d enabled; timer delay "
3468 "(%d us).\n", ha->host_no, ha->zio_mode,
3469 ha->zio_timer * 100));
3470 qla_printk(KERN_INFO, ha,
3471 "ZIO mode %d enabled; timer delay (%d us).\n",
3472 ha->zio_mode, ha->zio_timer * 100);
3473
3474 icb->firmware_options_2 |= cpu_to_le32(
3475 (uint32_t)ha->zio_mode);
3476 icb->interrupt_delay_timer = cpu_to_le16(ha->zio_timer);
3477 ha->flags.process_response_queue = 1;
3478 }
3479
3445 if (rval) { 3480 if (rval) {
3446 DEBUG2_3(printk(KERN_WARNING 3481 DEBUG2_3(printk(KERN_WARNING
3447 "scsi(%ld): NVRAM configuration failed!\n", ha->host_no)); 3482 "scsi(%ld): NVRAM configuration failed!\n", ha->host_no));