diff options
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_init.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 99 |
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 | ||
1671 | static void | ||
1672 | qla2x00_rport_add(void *data) | ||
1673 | { | ||
1674 | fc_port_t *fcport = data; | ||
1675 | |||
1676 | qla2x00_reg_remote_port(fcport->ha, fcport); | ||
1677 | } | ||
1678 | |||
1679 | static void | ||
1680 | qla2x00_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)); |