^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * linux/drivers/message/fusion/mptfc.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * For use with LSI PCI chip/adapter(s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * running LSI Fusion MPT (Message Passing Technology) firmware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (c) 1999-2008 LSI Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * (mailto:DL-MPTFusionLinux@lsi.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) This program is free software; you can redistribute it and/or modify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) it under the terms of the GNU General Public License as published by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) the Free Software Foundation; version 2 of the License.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) This program is distributed in the hope that it will be useful,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) but WITHOUT ANY WARRANTY; without even the implied warranty of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) GNU General Public License for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) NO WARRANTY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) solely responsible for determining the appropriateness of using and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) distributing the Program and assumes all risks associated with its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) exercise of rights under this Agreement, including but not limited to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) the risks and costs of program errors, damage to or loss of data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) programs or equipment, and unavailability or interruption of operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) DISCLAIMER OF LIABILITY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) You should have received a copy of the GNU General Public License
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) along with this program; if not, write to the Free Software
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include <linux/kdev_t.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #include <linux/blkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #include <linux/delay.h> /* for mdelay */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #include <linux/interrupt.h> /* needed for in_interrupt() proto */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #include <linux/reboot.h> /* notifier code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #include <linux/workqueue.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #include <linux/sort.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #include <scsi/scsi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #include <scsi/scsi_cmnd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #include <scsi/scsi_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #include <scsi/scsi_host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #include <scsi/scsi_tcq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #include <scsi/scsi_transport_fc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #include "mptbase.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #include "mptscsih.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define my_NAME "Fusion MPT FC Host driver"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define my_VERSION MPT_LINUX_VERSION_COMMON
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define MYNAM "mptfc"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) MODULE_AUTHOR(MODULEAUTHOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) MODULE_DESCRIPTION(my_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) MODULE_VERSION(my_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /* Command line args */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define MPTFC_DEV_LOSS_TMO (60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) static int mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO; /* reasonable default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) module_param(mptfc_dev_loss_tmo, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) MODULE_PARM_DESC(mptfc_dev_loss_tmo, " Initial time the driver programs the "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) " transport to wait for an rport to "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) " return following a device loss event."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) " Default=60.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) /* scsi-mid layer global parmeter is max_report_luns, which is 511 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define MPTFC_MAX_LUN (16895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) static int max_lun = MPTFC_MAX_LUN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) module_param(max_lun, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) MODULE_PARM_DESC(max_lun, " max lun, default=16895 ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) static u8 mptfcDoneCtx = MPT_MAX_PROTOCOL_DRIVERS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) static u8 mptfcTaskCtx = MPT_MAX_PROTOCOL_DRIVERS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) static u8 mptfcInternalCtx = MPT_MAX_PROTOCOL_DRIVERS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) static int mptfc_target_alloc(struct scsi_target *starget);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) static int mptfc_slave_alloc(struct scsi_device *sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static int mptfc_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static void mptfc_target_destroy(struct scsi_target *starget);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) static void mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static void mptfc_remove(struct pci_dev *pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) static int mptfc_abort(struct scsi_cmnd *SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) static int mptfc_dev_reset(struct scsi_cmnd *SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) static int mptfc_bus_reset(struct scsi_cmnd *SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static struct scsi_host_template mptfc_driver_template = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) .module = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) .proc_name = "mptfc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) .show_info = mptscsih_show_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) .name = "MPT FC Host",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) .info = mptscsih_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) .queuecommand = mptfc_qcmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) .target_alloc = mptfc_target_alloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) .slave_alloc = mptfc_slave_alloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) .slave_configure = mptscsih_slave_configure,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) .target_destroy = mptfc_target_destroy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) .slave_destroy = mptscsih_slave_destroy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) .change_queue_depth = mptscsih_change_queue_depth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) .eh_timed_out = fc_eh_timed_out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) .eh_abort_handler = mptfc_abort,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) .eh_device_reset_handler = mptfc_dev_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) .eh_bus_reset_handler = mptfc_bus_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) .eh_host_reset_handler = mptscsih_host_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) .bios_param = mptscsih_bios_param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) .can_queue = MPT_FC_CAN_QUEUE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) .this_id = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) .sg_tablesize = MPT_SCSI_SG_DEPTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) .max_sectors = 8192,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) .cmd_per_lun = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) .shost_attrs = mptscsih_host_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) /****************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * Supported hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) static struct pci_device_id mptfc_pci_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC909,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) PCI_ANY_ID, PCI_ANY_ID },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC919,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) PCI_ANY_ID, PCI_ANY_ID },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC929,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) PCI_ANY_ID, PCI_ANY_ID },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC919X,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) PCI_ANY_ID, PCI_ANY_ID },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC929X,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) PCI_ANY_ID, PCI_ANY_ID },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC939X,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) PCI_ANY_ID, PCI_ANY_ID },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC949X,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) PCI_ANY_ID, PCI_ANY_ID },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) { PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC949E,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) PCI_ANY_ID, PCI_ANY_ID },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) { PCI_VENDOR_ID_BROCADE, MPI_MANUFACTPAGE_DEVICEID_FC949E,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) PCI_ANY_ID, PCI_ANY_ID },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {0} /* Terminating entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) MODULE_DEVICE_TABLE(pci, mptfc_pci_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) static struct scsi_transport_template *mptfc_transport_template = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) static struct fc_function_template mptfc_transport_functions = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) .dd_fcrport_size = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) .show_host_node_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) .show_host_port_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) .show_host_supported_classes = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) .show_host_port_id = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) .show_rport_supported_classes = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) .show_starget_node_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) .show_starget_port_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) .show_starget_port_id = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) .set_rport_dev_loss_tmo = mptfc_set_rport_loss_tmo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) .show_rport_dev_loss_tmo = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) .show_host_supported_speeds = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) .show_host_maxframe_size = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) .show_host_speed = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) .show_host_fabric_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) .show_host_port_type = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) .show_host_port_state = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) .show_host_symbolic_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) mptfc_block_error_handler(struct scsi_cmnd *SCpnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) int (*func)(struct scsi_cmnd *SCpnt),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) const char *caller)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) MPT_SCSI_HOST *hd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) struct scsi_device *sdev = SCpnt->device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) struct Scsi_Host *shost = sdev->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) int ready;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) MPT_ADAPTER *ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) int loops = 40; /* seconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) hd = shost_priv(SCpnt->device->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) ioc = hd->ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) spin_lock_irqsave(shost->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) while ((ready = fc_remote_port_chkready(rport) >> 16) == DID_IMM_RETRY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) || (loops > 0 && ioc->active == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) spin_unlock_irqrestore(shost->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) "mptfc_block_error_handler.%d: %d:%llu, port status is "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) "%x, active flag %d, deferring %s recovery.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) ioc->name, ioc->sh->host_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) SCpnt->device->id, SCpnt->device->lun,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) ready, ioc->active, caller));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) msleep(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) spin_lock_irqsave(shost->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) loops --;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) spin_unlock_irqrestore(shost->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (ready == DID_NO_CONNECT || !SCpnt->device->hostdata
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) || ioc->active == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) "%s.%d: %d:%llu, failing recovery, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) "port state %x, active %d, vdevice %p.\n", caller,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) ioc->name, ioc->sh->host_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) SCpnt->device->id, SCpnt->device->lun, ready,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) ioc->active, SCpnt->device->hostdata));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) return FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) "%s.%d: %d:%llu, executing recovery.\n", caller,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) ioc->name, ioc->sh->host_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) SCpnt->device->id, SCpnt->device->lun));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) return (*func)(SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) mptfc_abort(struct scsi_cmnd *SCpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) mptfc_block_error_handler(SCpnt, mptscsih_abort, __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) mptfc_dev_reset(struct scsi_cmnd *SCpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) mptfc_block_error_handler(SCpnt, mptscsih_dev_reset, __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) mptfc_bus_reset(struct scsi_cmnd *SCpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) mptfc_block_error_handler(SCpnt, mptscsih_bus_reset, __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (timeout > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) rport->dev_loss_tmo = timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) rport->dev_loss_tmo = mptfc_dev_loss_tmo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) mptfc_FcDevPage0_cmp_func(const void *a, const void *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) FCDevicePage0_t **aa = (FCDevicePage0_t **)a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) FCDevicePage0_t **bb = (FCDevicePage0_t **)b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) if ((*aa)->CurrentBus == (*bb)->CurrentBus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) if ((*aa)->CurrentTargetID == (*bb)->CurrentTargetID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if ((*aa)->CurrentTargetID < (*bb)->CurrentTargetID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) if ((*aa)->CurrentBus < (*bb)->CurrentBus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) mptfc_GetFcDevPage0(MPT_ADAPTER *ioc, int ioc_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) void(*func)(MPT_ADAPTER *ioc,int channel, FCDevicePage0_t *arg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) ConfigPageHeader_t hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) CONFIGPARMS cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) FCDevicePage0_t *ppage0_alloc, *fc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) dma_addr_t page0_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) int data_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) int ii;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) FCDevicePage0_t *p0_array=NULL, *p_p0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) FCDevicePage0_t **pp0_array=NULL, **p_pp0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) int rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) U32 port_id = 0xffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) int num_targ = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) int max_bus = ioc->facts.MaxBuses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) int max_targ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) max_targ = (ioc->facts.MaxDevices == 0) ? 256 : ioc->facts.MaxDevices;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) data_sz = sizeof(FCDevicePage0_t) * max_bus * max_targ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) p_p0 = p0_array = kzalloc(data_sz, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) if (!p0_array)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) data_sz = sizeof(FCDevicePage0_t *) * max_bus * max_targ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) p_pp0 = pp0_array = kzalloc(data_sz, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (!pp0_array)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) /* Get FC Device Page 0 header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) hdr.PageVersion = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) hdr.PageLength = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) hdr.PageNumber = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) hdr.PageType = MPI_CONFIG_PAGETYPE_FC_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) cfg.cfghdr.hdr = &hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) cfg.physAddr = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) cfg.dir = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) cfg.pageAddr = port_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) cfg.timeout = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if ((rc = mpt_config(ioc, &cfg)) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) if (hdr.PageLength <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) data_sz = hdr.PageLength * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) ppage0_alloc = pci_alloc_consistent(ioc->pcidev, data_sz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) &page0_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) if (!ppage0_alloc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) cfg.physAddr = page0_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if ((rc = mpt_config(ioc, &cfg)) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) ppage0_alloc->PortIdentifier =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) le32_to_cpu(ppage0_alloc->PortIdentifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) ppage0_alloc->WWNN.Low =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) le32_to_cpu(ppage0_alloc->WWNN.Low);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) ppage0_alloc->WWNN.High =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) le32_to_cpu(ppage0_alloc->WWNN.High);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) ppage0_alloc->WWPN.Low =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) le32_to_cpu(ppage0_alloc->WWPN.Low);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) ppage0_alloc->WWPN.High =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) le32_to_cpu(ppage0_alloc->WWPN.High);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) ppage0_alloc->BBCredit =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) le16_to_cpu(ppage0_alloc->BBCredit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) ppage0_alloc->MaxRxFrameSize =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) le16_to_cpu(ppage0_alloc->MaxRxFrameSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) port_id = ppage0_alloc->PortIdentifier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) num_targ++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) *p_p0 = *ppage0_alloc; /* save data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) *p_pp0++ = p_p0++; /* save addr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) pci_free_consistent(ioc->pcidev, data_sz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) (u8 *) ppage0_alloc, page0_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (rc != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) } while (port_id <= 0xff0000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if (num_targ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) /* sort array */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) if (num_targ > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) sort (pp0_array, num_targ, sizeof(FCDevicePage0_t *),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) mptfc_FcDevPage0_cmp_func, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) /* call caller's func for each targ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) for (ii = 0; ii < num_targ; ii++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) fc = *(pp0_array+ii);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) func(ioc, ioc_port, fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) kfree(pp0_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) kfree(p0_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) mptfc_generate_rport_ids(FCDevicePage0_t *pg0, struct fc_rport_identifiers *rid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) /* not currently usable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if (pg0->Flags & (MPI_FC_DEVICE_PAGE0_FLAGS_PLOGI_INVALID |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) MPI_FC_DEVICE_PAGE0_FLAGS_PRLI_INVALID))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) if (!(pg0->Flags & MPI_FC_DEVICE_PAGE0_FLAGS_TARGETID_BUS_VALID))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) if (!(pg0->Protocol & MPI_FC_DEVICE_PAGE0_PROT_FCP_TARGET))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) * board data structure already normalized to platform endianness
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) * shifted to avoid unaligned access on 64 bit architecture
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) rid->node_name = ((u64)pg0->WWNN.High) << 32 | (u64)pg0->WWNN.Low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) rid->port_name = ((u64)pg0->WWPN.High) << 32 | (u64)pg0->WWPN.Low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) rid->port_id = pg0->PortIdentifier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) rid->roles = FC_RPORT_ROLE_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) struct fc_rport_identifiers rport_ids;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) struct fc_rport *rport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) struct mptfc_rport_info *ri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) int new_ri = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) u64 pn, nn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) VirtTarget *vtarget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) u32 roles = FC_RPORT_ROLE_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) if (mptfc_generate_rport_ids(pg0, &rport_ids) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) roles |= FC_RPORT_ROLE_FCP_TARGET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) if (pg0->Protocol & MPI_FC_DEVICE_PAGE0_PROT_FCP_INITIATOR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) roles |= FC_RPORT_ROLE_FCP_INITIATOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) /* scan list looking for a match */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) list_for_each_entry(ri, &ioc->fc_rports, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) if (pn == rport_ids.port_name) { /* match */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) list_move_tail(&ri->list, &ioc->fc_rports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) new_ri = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) if (new_ri) { /* allocate one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) ri = kzalloc(sizeof(struct mptfc_rport_info), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if (!ri)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) list_add_tail(&ri->list, &ioc->fc_rports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) ri->pg0 = *pg0; /* add/update pg0 data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) ri->flags &= ~MPT_RPORT_INFO_FLAGS_MISSING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) /* MPT_RPORT_INFO_FLAGS_REGISTERED - rport not previously deleted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) if (!(ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) ri->flags |= MPT_RPORT_INFO_FLAGS_REGISTERED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) rport = fc_remote_port_add(ioc->sh, channel, &rport_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) if (rport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) ri->rport = rport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) if (new_ri) /* may have been reset by user */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) rport->dev_loss_tmo = mptfc_dev_loss_tmo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) * if already mapped, remap here. If not mapped,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) * target_alloc will allocate vtarget and map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) * slave_alloc will fill in vdevice from vtarget.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) if (ri->starget) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) vtarget = ri->starget->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) if (vtarget) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) vtarget->id = pg0->CurrentTargetID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) vtarget->channel = pg0->CurrentBus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) vtarget->deleted = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) *((struct mptfc_rport_info **)rport->dd_data) = ri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) /* scan will be scheduled once rport becomes a target */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) fc_remote_port_rolechg(rport,roles);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) nn = (u64)ri->pg0.WWNN.High << 32 | (u64)ri->pg0.WWNN.Low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) "mptfc_reg_dev.%d: %x, %llx / %llx, tid %d, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) "rport tid %d, tmo %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) ioc->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) ioc->sh->host_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) pg0->PortIdentifier,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) (unsigned long long)nn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) (unsigned long long)pn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) pg0->CurrentTargetID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) ri->rport->scsi_target_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) ri->rport->dev_loss_tmo));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) list_del(&ri->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) kfree(ri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) ri = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) * OS entry point to allow for host driver to free allocated memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) * Called if no device present or device being unloaded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) mptfc_target_destroy(struct scsi_target *starget)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) struct fc_rport *rport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) struct mptfc_rport_info *ri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) rport = starget_to_rport(starget);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) if (rport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) ri = *((struct mptfc_rport_info **)rport->dd_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) if (ri) /* better be! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) ri->starget = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) kfree(starget->hostdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) starget->hostdata = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) * OS entry point to allow host driver to alloc memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) * for each scsi target. Called once per device the bus scan.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) * Return non-zero if allocation fails.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) mptfc_target_alloc(struct scsi_target *starget)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) VirtTarget *vtarget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) struct fc_rport *rport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) struct mptfc_rport_info *ri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) if (!vtarget)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) starget->hostdata = vtarget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) rport = starget_to_rport(starget);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) if (rport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) ri = *((struct mptfc_rport_info **)rport->dd_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) if (ri) { /* better be! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) vtarget->id = ri->pg0.CurrentTargetID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) vtarget->channel = ri->pg0.CurrentBus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) ri->starget = starget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (rc != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) kfree(vtarget);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) starget->hostdata = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) * mptfc_dump_lun_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) * @ioc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) * @rport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) * @sdev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) mptfc_dump_lun_info(MPT_ADAPTER *ioc, struct fc_rport *rport, struct scsi_device *sdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) VirtTarget *vtarget)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) u64 nn, pn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) struct mptfc_rport_info *ri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) ri = *((struct mptfc_rport_info **)rport->dd_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) nn = (u64)ri->pg0.WWNN.High << 32 | (u64)ri->pg0.WWNN.Low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) "mptfc_slv_alloc.%d: num_luns %d, sdev.id %d, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) "CurrentTargetID %d, %x %llx %llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) ioc->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) sdev->host->host_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) vtarget->num_luns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) sdev->id, ri->pg0.CurrentTargetID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) ri->pg0.PortIdentifier,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) (unsigned long long)pn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) (unsigned long long)nn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) * OS entry point to allow host driver to alloc memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) * for each scsi device. Called once per device the bus scan.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) * Return non-zero if allocation fails.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) * Init memory once per LUN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) mptfc_slave_alloc(struct scsi_device *sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) MPT_SCSI_HOST *hd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) VirtTarget *vtarget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) VirtDevice *vdevice;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) struct scsi_target *starget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) struct fc_rport *rport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) MPT_ADAPTER *ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) starget = scsi_target(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) rport = starget_to_rport(starget);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) if (!rport || fc_remote_port_chkready(rport))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) hd = shost_priv(sdev->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) ioc = hd->ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) vdevice = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) if (!vdevice) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) ioc->name, sizeof(VirtDevice));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) sdev->hostdata = vdevice;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) vtarget = starget->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) if (vtarget->num_luns == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) vtarget->ioc_id = ioc->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) vdevice->vtarget = vtarget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) vdevice->lun = sdev->lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) vtarget->num_luns++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) mptfc_dump_lun_info(ioc, rport, sdev, vtarget);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) mptfc_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *SCpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) struct mptfc_rport_info *ri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) VirtDevice *vdevice = SCpnt->device->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) if (!vdevice || !vdevice->vtarget) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) SCpnt->result = DID_NO_CONNECT << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) SCpnt->scsi_done(SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) err = fc_remote_port_chkready(rport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) if (unlikely(err)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) SCpnt->result = err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) SCpnt->scsi_done(SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) /* dd_data is null until finished adding target */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) ri = *((struct mptfc_rport_info **)rport->dd_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) if (unlikely(!ri)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) SCpnt->result = DID_IMM_RETRY << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) SCpnt->scsi_done(SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) return mptscsih_qcmd(SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) * mptfc_display_port_link_speed - displaying link speed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) * @ioc: Pointer to MPT_ADAPTER structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) * @portnum: IOC Port number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) * @pp0dest: port page0 data payload
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) mptfc_display_port_link_speed(MPT_ADAPTER *ioc, int portnum, FCPortPage0_t *pp0dest)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) u8 old_speed, new_speed, state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) char *old, *new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) if (portnum >= 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) old_speed = ioc->fc_link_speed[portnum];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) new_speed = pp0dest->CurrentSpeed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) state = pp0dest->PortState;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) if (state != MPI_FCPORTPAGE0_PORTSTATE_OFFLINE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) new_speed != MPI_FCPORTPAGE0_CURRENT_SPEED_UNKNOWN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) old = old_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_1GBIT ? "1 Gbps" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) old_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_2GBIT ? "2 Gbps" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) old_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_4GBIT ? "4 Gbps" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) "Unknown";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) new = new_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_1GBIT ? "1 Gbps" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) new_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_2GBIT ? "2 Gbps" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) new_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_4GBIT ? "4 Gbps" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) "Unknown";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) if (old_speed == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) printk(MYIOC_s_NOTE_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) "FC Link Established, Speed = %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) ioc->name, new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) else if (old_speed != new_speed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) printk(MYIOC_s_WARN_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) "FC Link Speed Change, Old Speed = %s, New Speed = %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) ioc->name, old, new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) ioc->fc_link_speed[portnum] = new_speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) * mptfc_GetFcPortPage0 - Fetch FCPort config Page0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) * @ioc: Pointer to MPT_ADAPTER structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) * @portnum: IOC Port number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) * Return: 0 for success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) * -ENOMEM if no memory available
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) * -EPERM if not allowed due to ISR context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) * -EAGAIN if no msg frames currently available
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) * -EFAULT for non-successful reply or no reply (timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) * -EINVAL portnum arg out of range (hardwired to two elements)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) mptfc_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) ConfigPageHeader_t hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) CONFIGPARMS cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) FCPortPage0_t *ppage0_alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) FCPortPage0_t *pp0dest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) dma_addr_t page0_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) int data_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) int copy_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) int count = 400;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) if (portnum > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) /* Get FCPort Page 0 header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) hdr.PageVersion = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) hdr.PageLength = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) hdr.PageNumber = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) cfg.cfghdr.hdr = &hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) cfg.physAddr = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) cfg.dir = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) cfg.pageAddr = portnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) cfg.timeout = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) if ((rc = mpt_config(ioc, &cfg)) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) if (hdr.PageLength == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) data_sz = hdr.PageLength * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) ppage0_alloc = pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) if (ppage0_alloc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) try_again:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) memset((u8 *)ppage0_alloc, 0, data_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) cfg.physAddr = page0_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) if ((rc = mpt_config(ioc, &cfg)) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) /* save the data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) pp0dest = &ioc->fc_port_page0[portnum];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) copy_sz = min_t(int, sizeof(FCPortPage0_t), data_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) memcpy(pp0dest, ppage0_alloc, copy_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) * Normalize endianness of structure data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) * by byte-swapping all > 1 byte fields!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) pp0dest->Flags = le32_to_cpu(pp0dest->Flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) pp0dest->PortIdentifier = le32_to_cpu(pp0dest->PortIdentifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) pp0dest->WWNN.Low = le32_to_cpu(pp0dest->WWNN.Low);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) pp0dest->WWNN.High = le32_to_cpu(pp0dest->WWNN.High);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) pp0dest->WWPN.Low = le32_to_cpu(pp0dest->WWPN.Low);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) pp0dest->WWPN.High = le32_to_cpu(pp0dest->WWPN.High);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) pp0dest->SupportedServiceClass = le32_to_cpu(pp0dest->SupportedServiceClass);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) pp0dest->SupportedSpeeds = le32_to_cpu(pp0dest->SupportedSpeeds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) pp0dest->CurrentSpeed = le32_to_cpu(pp0dest->CurrentSpeed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) pp0dest->MaxFrameSize = le32_to_cpu(pp0dest->MaxFrameSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) pp0dest->FabricWWNN.Low = le32_to_cpu(pp0dest->FabricWWNN.Low);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) pp0dest->FabricWWNN.High = le32_to_cpu(pp0dest->FabricWWNN.High);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) pp0dest->FabricWWPN.Low = le32_to_cpu(pp0dest->FabricWWPN.Low);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) pp0dest->FabricWWPN.High = le32_to_cpu(pp0dest->FabricWWPN.High);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) pp0dest->DiscoveredPortsCount = le32_to_cpu(pp0dest->DiscoveredPortsCount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) pp0dest->MaxInitiators = le32_to_cpu(pp0dest->MaxInitiators);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) * if still doing discovery,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) * hang loose a while until finished
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) if ((pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_UNKNOWN) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) (pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_ONLINE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) (pp0dest->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_TYPE_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) == MPI_FCPORTPAGE0_FLAGS_ATTACH_NO_INIT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) if (count-- > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) goto try_again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) printk(MYIOC_s_INFO_FMT "Firmware discovery not"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) " complete.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) ioc->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) mptfc_display_port_link_speed(ioc, portnum, pp0dest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) mptfc_WriteFcPortPage1(MPT_ADAPTER *ioc, int portnum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) ConfigPageHeader_t hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) CONFIGPARMS cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) if (portnum > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) if (!(ioc->fc_data.fc_port_page1[portnum].data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) /* get fcport page 1 header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) hdr.PageVersion = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) hdr.PageLength = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) hdr.PageNumber = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) cfg.cfghdr.hdr = &hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) cfg.physAddr = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) cfg.dir = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) cfg.pageAddr = portnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) cfg.timeout = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) if ((rc = mpt_config(ioc, &cfg)) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) if (hdr.PageLength == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) if (hdr.PageLength*4 != ioc->fc_data.fc_port_page1[portnum].pg_sz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) cfg.physAddr = ioc->fc_data.fc_port_page1[portnum].dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) cfg.dir = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) rc = mpt_config(ioc, &cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) mptfc_GetFcPortPage1(MPT_ADAPTER *ioc, int portnum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) ConfigPageHeader_t hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) CONFIGPARMS cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) FCPortPage1_t *page1_alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) dma_addr_t page1_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) int data_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) if (portnum > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) /* get fcport page 1 header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) hdr.PageVersion = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) hdr.PageLength = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) hdr.PageNumber = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) cfg.cfghdr.hdr = &hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) cfg.physAddr = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) cfg.dir = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) cfg.pageAddr = portnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) cfg.timeout = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) if ((rc = mpt_config(ioc, &cfg)) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) if (hdr.PageLength == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) start_over:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) if (ioc->fc_data.fc_port_page1[portnum].data == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) data_sz = hdr.PageLength * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) if (data_sz < sizeof(FCPortPage1_t))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) data_sz = sizeof(FCPortPage1_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) page1_alloc = pci_alloc_consistent(ioc->pcidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) data_sz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) &page1_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) if (!page1_alloc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) page1_alloc = ioc->fc_data.fc_port_page1[portnum].data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) page1_dma = ioc->fc_data.fc_port_page1[portnum].dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) data_sz = ioc->fc_data.fc_port_page1[portnum].pg_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) if (hdr.PageLength * 4 > data_sz) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) ioc->fc_data.fc_port_page1[portnum].data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) pci_free_consistent(ioc->pcidev, data_sz, (u8 *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) page1_alloc, page1_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) goto start_over;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) cfg.physAddr = page1_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) if ((rc = mpt_config(ioc, &cfg)) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) ioc->fc_data.fc_port_page1[portnum].data = page1_alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) ioc->fc_data.fc_port_page1[portnum].pg_sz = data_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) ioc->fc_data.fc_port_page1[portnum].dma = page1_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) ioc->fc_data.fc_port_page1[portnum].data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) pci_free_consistent(ioc->pcidev, data_sz, (u8 *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) page1_alloc, page1_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) mptfc_SetFcPortPage1_defaults(MPT_ADAPTER *ioc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) int ii;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) FCPortPage1_t *pp1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) #define MPTFC_FW_DEVICE_TIMEOUT (1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) #define MPTFC_FW_IO_PEND_TIMEOUT (1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) #define ON_FLAGS (MPI_FCPORTPAGE1_FLAGS_IMMEDIATE_ERROR_REPLY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) #define OFF_FLAGS (MPI_FCPORTPAGE1_FLAGS_VERBOSE_RESCAN_EVENTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) for (ii=0; ii<ioc->facts.NumberOfPorts; ii++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) if (mptfc_GetFcPortPage1(ioc, ii) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) pp1 = ioc->fc_data.fc_port_page1[ii].data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) if ((pp1->InitiatorDeviceTimeout == MPTFC_FW_DEVICE_TIMEOUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) && (pp1->InitiatorIoPendTimeout == MPTFC_FW_IO_PEND_TIMEOUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) && ((pp1->Flags & ON_FLAGS) == ON_FLAGS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) && ((pp1->Flags & OFF_FLAGS) == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) pp1->InitiatorDeviceTimeout = MPTFC_FW_DEVICE_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) pp1->InitiatorIoPendTimeout = MPTFC_FW_IO_PEND_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) pp1->Flags &= ~OFF_FLAGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) pp1->Flags |= ON_FLAGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) mptfc_WriteFcPortPage1(ioc, ii);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) mptfc_init_host_attr(MPT_ADAPTER *ioc,int portnum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) unsigned class = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) unsigned cos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) unsigned speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) unsigned port_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) unsigned port_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) FCPortPage0_t *pp0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) struct Scsi_Host *sh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) char *sn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) /* don't know what to do as only one scsi (fc) host was allocated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) if (portnum != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) pp0 = &ioc->fc_port_page0[portnum];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) sh = ioc->sh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) sn = fc_host_symbolic_name(sh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) snprintf(sn, FC_SYMBOLIC_NAME_SIZE, "%s %s%08xh",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) ioc->prod_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) MPT_FW_REV_MAGIC_ID_STRING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) ioc->facts.FWVersion.Word);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) fc_host_tgtid_bind_type(sh) = FC_TGTID_BIND_BY_WWPN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) fc_host_maxframe_size(sh) = pp0->MaxFrameSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) fc_host_node_name(sh) =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) (u64)pp0->WWNN.High << 32 | (u64)pp0->WWNN.Low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) fc_host_port_name(sh) =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) (u64)pp0->WWPN.High << 32 | (u64)pp0->WWPN.Low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) fc_host_port_id(sh) = pp0->PortIdentifier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) class = pp0->SupportedServiceClass;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) cos |= FC_COS_CLASS1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) cos |= FC_COS_CLASS2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) cos |= FC_COS_CLASS3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) fc_host_supported_classes(sh) = cos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_1GBIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) speed = FC_PORTSPEED_1GBIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) else if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_2GBIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) speed = FC_PORTSPEED_2GBIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) else if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_4GBIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) speed = FC_PORTSPEED_4GBIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) else if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_10GBIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) speed = FC_PORTSPEED_10GBIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) speed = FC_PORTSPEED_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) fc_host_speed(sh) = speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) speed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_1GBIT_SPEED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) speed |= FC_PORTSPEED_1GBIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_2GBIT_SPEED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) speed |= FC_PORTSPEED_2GBIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_4GBIT_SPEED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) speed |= FC_PORTSPEED_4GBIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_10GBIT_SPEED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) speed |= FC_PORTSPEED_10GBIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) fc_host_supported_speeds(sh) = speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) port_state = FC_PORTSTATE_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) if (pp0->PortState == MPI_FCPORTPAGE0_PORTSTATE_ONLINE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) port_state = FC_PORTSTATE_ONLINE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) else if (pp0->PortState == MPI_FCPORTPAGE0_PORTSTATE_OFFLINE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) port_state = FC_PORTSTATE_LINKDOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) fc_host_port_state(sh) = port_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) port_type = FC_PORTTYPE_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_POINT_TO_POINT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) port_type = FC_PORTTYPE_PTP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) else if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_PRIVATE_LOOP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) port_type = FC_PORTTYPE_LPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) else if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_PUBLIC_LOOP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) port_type = FC_PORTTYPE_NLPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) else if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_FABRIC_DIRECT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) port_type = FC_PORTTYPE_NPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) fc_host_port_type(sh) = port_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) fc_host_fabric_name(sh) =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_FABRIC_WWN_VALID) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) (u64) pp0->FabricWWNN.High << 32 | (u64) pp0->FabricWWPN.Low :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) (u64)pp0->WWNN.High << 32 | (u64)pp0->WWNN.Low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) mptfc_link_status_change(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) MPT_ADAPTER *ioc =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) container_of(work, MPT_ADAPTER, fc_rescan_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) int ii;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) for (ii=0; ii < ioc->facts.NumberOfPorts; ii++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) (void) mptfc_GetFcPortPage0(ioc, ii);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) mptfc_setup_reset(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) MPT_ADAPTER *ioc =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) container_of(work, MPT_ADAPTER, fc_setup_reset_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) u64 pn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) struct mptfc_rport_info *ri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) struct scsi_target *starget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) VirtTarget *vtarget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) /* reset about to happen, delete (block) all rports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) list_for_each_entry(ri, &ioc->fc_rports, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) ri->flags &= ~MPT_RPORT_INFO_FLAGS_REGISTERED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) fc_remote_port_delete(ri->rport); /* won't sleep */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) ri->rport = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) starget = ri->starget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) if (starget) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) vtarget = starget->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) if (vtarget)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) vtarget->deleted = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) pn = (u64)ri->pg0.WWPN.High << 32 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) (u64)ri->pg0.WWPN.Low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) "mptfc_setup_reset.%d: %llx deleted\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) ioc->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) ioc->sh->host_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) (unsigned long long)pn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) mptfc_rescan_devices(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) MPT_ADAPTER *ioc =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) container_of(work, MPT_ADAPTER, fc_rescan_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) int ii;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) u64 pn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) struct mptfc_rport_info *ri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) struct scsi_target *starget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) VirtTarget *vtarget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) /* start by tagging all ports as missing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) list_for_each_entry(ri, &ioc->fc_rports, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) ri->flags |= MPT_RPORT_INFO_FLAGS_MISSING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) * now rescan devices known to adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) * will reregister existing rports
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) (void) mptfc_GetFcPortPage0(ioc, ii);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) mptfc_init_host_attr(ioc, ii); /* refresh */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) mptfc_GetFcDevPage0(ioc, ii, mptfc_register_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) /* delete devices still missing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) list_for_each_entry(ri, &ioc->fc_rports, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) /* if newly missing, delete it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) if (ri->flags & MPT_RPORT_INFO_FLAGS_MISSING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) MPT_RPORT_INFO_FLAGS_MISSING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) fc_remote_port_delete(ri->rport); /* won't sleep */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) ri->rport = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) starget = ri->starget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) if (starget) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) vtarget = starget->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) if (vtarget)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) vtarget->deleted = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) pn = (u64)ri->pg0.WWPN.High << 32 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) (u64)ri->pg0.WWPN.Low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) "mptfc_rescan.%d: %llx deleted\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) ioc->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) ioc->sh->host_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) (unsigned long long)pn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) struct Scsi_Host *sh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) MPT_SCSI_HOST *hd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) MPT_ADAPTER *ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) int ii;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) int numSGE = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) int scale;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) int ioc_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) int error=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) if ((r = mpt_attach(pdev,id)) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) ioc = pci_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) ioc->DoneCtx = mptfcDoneCtx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) ioc->TaskCtx = mptfcTaskCtx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) ioc->InternalCtx = mptfcInternalCtx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) /* Added sanity check on readiness of the MPT adapter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) printk(MYIOC_s_WARN_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) "Skipping because it's not operational!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) ioc->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) error = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) goto out_mptfc_probe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) if (!ioc->active) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) ioc->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) error = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) goto out_mptfc_probe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) /* Sanity check - ensure at least 1 port is INITIATOR capable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) ioc_cap = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) if (ioc->pfacts[ii].ProtocolFlags &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) MPI_PORTFACTS_PROTOCOL_INITIATOR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) ioc_cap ++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) if (!ioc_cap) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) printk(MYIOC_s_WARN_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) ioc->name, ioc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) sh = scsi_host_alloc(&mptfc_driver_template, sizeof(MPT_SCSI_HOST));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) if (!sh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) printk(MYIOC_s_WARN_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) "Unable to register controller with SCSI subsystem\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) ioc->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) error = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) goto out_mptfc_probe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) spin_lock_init(&ioc->fc_rescan_work_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) INIT_WORK(&ioc->fc_rescan_work, mptfc_rescan_devices);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) INIT_WORK(&ioc->fc_setup_reset_work, mptfc_setup_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) INIT_WORK(&ioc->fc_lsc_work, mptfc_link_status_change);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) spin_lock_irqsave(&ioc->FreeQlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) /* Attach the SCSI Host to the IOC structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) ioc->sh = sh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) sh->io_port = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) sh->n_io_port = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) sh->irq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) /* set 16 byte cdb's */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) sh->max_cmd_len = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) sh->max_id = ioc->pfacts->MaxDevices;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) sh->max_lun = max_lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) /* Required entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) sh->unique_id = ioc->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) /* Verify that we won't exceed the maximum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) * number of chain buffers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) * We can optimize: ZZ = req_sz/sizeof(SGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) * For 32bit SGE's:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) * + (req_sz - 64)/sizeof(SGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) * A slightly different algorithm is required for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) * 64bit SGEs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) scale = ioc->req_sz/ioc->SGE_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) if (ioc->sg_addr_size == sizeof(u64)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) numSGE = (scale - 1) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) (ioc->facts.MaxChainDepth-1) + scale +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) (ioc->req_sz - 60) / ioc->SGE_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) numSGE = 1 + (scale - 1) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) (ioc->facts.MaxChainDepth-1) + scale +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) (ioc->req_sz - 64) / ioc->SGE_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) if (numSGE < sh->sg_tablesize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) /* Reset this value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) "Resetting sg_tablesize to %d from %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) ioc->name, numSGE, sh->sg_tablesize));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) sh->sg_tablesize = numSGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) spin_unlock_irqrestore(&ioc->FreeQlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) hd = shost_priv(sh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) hd->ioc = ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) /* SCSI needs scsi_cmnd lookup table!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) * (with size equal to req_depth*PtrSz!)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) ioc->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) if (!ioc->ScsiLookup) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) goto out_mptfc_probe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) spin_lock_init(&ioc->scsi_lookup_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) ioc->name, ioc->ScsiLookup));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) hd->last_queue_full = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) sh->transportt = mptfc_transport_template;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) error = scsi_add_host (sh, &ioc->pcidev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) if(error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) dprintk(ioc, printk(MYIOC_s_ERR_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) "scsi_add_host failed\n", ioc->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) goto out_mptfc_probe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) /* initialize workqueue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) snprintf(ioc->fc_rescan_work_q_name, sizeof(ioc->fc_rescan_work_q_name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) "mptfc_wq_%d", sh->host_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) ioc->fc_rescan_work_q =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) alloc_ordered_workqueue(ioc->fc_rescan_work_q_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) WQ_MEM_RECLAIM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) if (!ioc->fc_rescan_work_q) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) goto out_mptfc_host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) * Pre-fetch FC port WWN and stuff...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) * (FCPortPage0_t stuff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) (void) mptfc_GetFcPortPage0(ioc, ii);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) mptfc_SetFcPortPage1_defaults(ioc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) * scan for rports -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) * by doing it via the workqueue, some locking is eliminated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) queue_work(ioc->fc_rescan_work_q, &ioc->fc_rescan_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) flush_workqueue(ioc->fc_rescan_work_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) out_mptfc_host:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) scsi_remove_host(sh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) out_mptfc_probe:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) mptscsih_remove(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) static struct pci_driver mptfc_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) .name = "mptfc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) .id_table = mptfc_pci_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) .probe = mptfc_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) .remove = mptfc_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) .shutdown = mptscsih_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) .suspend = mptscsih_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) .resume = mptscsih_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) mptfc_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) MPT_SCSI_HOST *hd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) int rc=1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) if (ioc->bus_type != FC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) ioc->name, event));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) if (ioc->sh == NULL ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) ((hd = shost_priv(ioc->sh)) == NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) switch (event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) case MPI_EVENT_RESCAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) if (ioc->fc_rescan_work_q) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) queue_work(ioc->fc_rescan_work_q,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) &ioc->fc_rescan_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) case MPI_EVENT_LINK_STATUS_CHANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) if (ioc->fc_rescan_work_q) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) queue_work(ioc->fc_rescan_work_q,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) &ioc->fc_lsc_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) rc = mptscsih_event_process(ioc,pEvReply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) mptfc_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) rc = mptscsih_ioc_reset(ioc,reset_phase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) if ((ioc->bus_type != FC) || (!rc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) ": IOC %s_reset routed to FC host driver!\n",ioc->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) if (reset_phase == MPT_IOC_SETUP_RESET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) if (ioc->fc_rescan_work_q) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) queue_work(ioc->fc_rescan_work_q,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) &ioc->fc_setup_reset_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) else if (reset_phase == MPT_IOC_PRE_RESET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) else { /* MPT_IOC_POST_RESET */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) mptfc_SetFcPortPage1_defaults(ioc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) if (ioc->fc_rescan_work_q) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) queue_work(ioc->fc_rescan_work_q,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) &ioc->fc_rescan_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) * mptfc_init - Register MPT adapter(s) as SCSI host(s) with SCSI mid-layer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) * Returns 0 for success, non-zero for failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) static int __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) mptfc_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) show_mptmod_ver(my_NAME, my_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) /* sanity check module parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) if (mptfc_dev_loss_tmo <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) mptfc_transport_template =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) fc_attach_transport(&mptfc_transport_functions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) if (!mptfc_transport_template)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) mptfcDoneCtx = mpt_register(mptscsih_io_done, MPTFC_DRIVER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) "mptscsih_scandv_complete");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) mptfcTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTFC_DRIVER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) "mptscsih_scandv_complete");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) mptfcInternalCtx = mpt_register(mptscsih_scandv_complete, MPTFC_DRIVER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) "mptscsih_scandv_complete");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) mpt_event_register(mptfcDoneCtx, mptfc_event_process);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) mpt_reset_register(mptfcDoneCtx, mptfc_ioc_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) error = pci_register_driver(&mptfc_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) fc_release_transport(mptfc_transport_template);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) * mptfc_remove - Remove fc infrastructure for devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) * @pdev: Pointer to pci_dev structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) static void mptfc_remove(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) struct mptfc_rport_info *p, *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) struct workqueue_struct *work_q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) int ii;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) /* destroy workqueue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) if ((work_q=ioc->fc_rescan_work_q)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) ioc->fc_rescan_work_q = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) destroy_workqueue(work_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) fc_remove_host(ioc->sh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) list_for_each_entry_safe(p, n, &ioc->fc_rports, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) list_del(&p->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) kfree(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) for (ii=0; ii<ioc->facts.NumberOfPorts; ii++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) if (ioc->fc_data.fc_port_page1[ii].data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) pci_free_consistent(ioc->pcidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) ioc->fc_data.fc_port_page1[ii].pg_sz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) (u8 *) ioc->fc_data.fc_port_page1[ii].data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) ioc->fc_data.fc_port_page1[ii].dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) ioc->fc_data.fc_port_page1[ii].data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) scsi_remove_host(ioc->sh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) mptscsih_remove(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) * mptfc_exit - Unregisters MPT adapter(s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) static void __exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) mptfc_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) pci_unregister_driver(&mptfc_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) fc_release_transport(mptfc_transport_template);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) mpt_reset_deregister(mptfcDoneCtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) mpt_event_deregister(mptfcDoneCtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) mpt_deregister(mptfcInternalCtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) mpt_deregister(mptfcTaskCtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) mpt_deregister(mptfcDoneCtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) module_init(mptfc_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) module_exit(mptfc_exit);