Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  *	Adaptec AAC series RAID controller driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *	(c) Copyright 2001 Red Hat Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  * based on the old aacraid driver that is..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  * Adaptec aacraid device driver for Linux.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  * Copyright (c) 2000-2010 Adaptec, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  *               2010-2015 PMC-Sierra, Inc. (aacraid@pmc-sierra.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11)  *		 2016-2017 Microsemi Corp. (aacraid@microsemi.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13)  * Module Name:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14)  *   linit.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16)  * Abstract: Linux Driver entry module for Adaptec RAID Array Controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <linux/compat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <linux/blkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include <linux/completion.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) #include <linux/moduleparam.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #include <linux/aer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) #include <linux/syscalls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) #include <linux/kthread.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) #include <linux/msdos_partition.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) #include <scsi/scsi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) #include <scsi/scsi_cmnd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) #include <scsi/scsi_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) #include <scsi/scsi_host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) #include <scsi/scsi_tcq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) #include <scsi/scsicam.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) #include <scsi/scsi_eh.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) #include "aacraid.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) #define AAC_DRIVER_VERSION		"1.2.1"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) #ifndef AAC_DRIVER_BRANCH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) #define AAC_DRIVER_BRANCH		""
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) #define AAC_DRIVERNAME			"aacraid"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) #ifdef AAC_DRIVER_BUILD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) #define _str(x) #x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) #define str(x) _str(x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) #define AAC_DRIVER_FULL_VERSION	AAC_DRIVER_VERSION "[" str(AAC_DRIVER_BUILD) "]" AAC_DRIVER_BRANCH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) #define AAC_DRIVER_FULL_VERSION	AAC_DRIVER_VERSION AAC_DRIVER_BRANCH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) MODULE_AUTHOR("Red Hat Inc and Adaptec");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) MODULE_DESCRIPTION("Dell PERC2, 2/Si, 3/Si, 3/Di, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 		   "Adaptec Advanced Raid Products, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 		   "HP NetRAID-4M, IBM ServeRAID & ICP SCSI driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) MODULE_VERSION(AAC_DRIVER_FULL_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) static DEFINE_MUTEX(aac_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) static LIST_HEAD(aac_devices);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) static int aac_cfg_major = AAC_CHARDEV_UNREGISTERED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) char aac_driver_version[] = AAC_DRIVER_FULL_VERSION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75)  * Because of the way Linux names scsi devices, the order in this table has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76)  * become important.  Check for on-board Raid first, add-in cards second.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78)  * Note: The last field is used to index into aac_drivers below.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) static const struct pci_device_id aac_pci_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 	{ 0x1028, 0x0001, 0x1028, 0x0001, 0, 0, 0 }, /* PERC 2/Si (Iguana/PERC2Si) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 	{ 0x1028, 0x0002, 0x1028, 0x0002, 0, 0, 1 }, /* PERC 3/Di (Opal/PERC3Di) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 	{ 0x1028, 0x0003, 0x1028, 0x0003, 0, 0, 2 }, /* PERC 3/Si (SlimFast/PERC3Si */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 	{ 0x1028, 0x0004, 0x1028, 0x00d0, 0, 0, 3 }, /* PERC 3/Di (Iguana FlipChip/PERC3DiF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 	{ 0x1028, 0x0002, 0x1028, 0x00d1, 0, 0, 4 }, /* PERC 3/Di (Viper/PERC3DiV) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 	{ 0x1028, 0x0002, 0x1028, 0x00d9, 0, 0, 5 }, /* PERC 3/Di (Lexus/PERC3DiL) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 	{ 0x1028, 0x000a, 0x1028, 0x0106, 0, 0, 6 }, /* PERC 3/Di (Jaguar/PERC3DiJ) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 	{ 0x1028, 0x000a, 0x1028, 0x011b, 0, 0, 7 }, /* PERC 3/Di (Dagger/PERC3DiD) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 	{ 0x1028, 0x000a, 0x1028, 0x0121, 0, 0, 8 }, /* PERC 3/Di (Boxster/PERC3DiB) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 	{ 0x9005, 0x0283, 0x9005, 0x0283, 0, 0, 9 }, /* catapult */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 	{ 0x9005, 0x0284, 0x9005, 0x0284, 0, 0, 10 }, /* tomcat */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 	{ 0x9005, 0x0285, 0x9005, 0x0286, 0, 0, 11 }, /* Adaptec 2120S (Crusader) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 	{ 0x9005, 0x0285, 0x9005, 0x0285, 0, 0, 12 }, /* Adaptec 2200S (Vulcan) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 	{ 0x9005, 0x0285, 0x9005, 0x0287, 0, 0, 13 }, /* Adaptec 2200S (Vulcan-2m) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 	{ 0x9005, 0x0285, 0x17aa, 0x0286, 0, 0, 14 }, /* Legend S220 (Legend Crusader) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 	{ 0x9005, 0x0285, 0x17aa, 0x0287, 0, 0, 15 }, /* Legend S230 (Legend Vulcan) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 	{ 0x9005, 0x0285, 0x9005, 0x0288, 0, 0, 16 }, /* Adaptec 3230S (Harrier) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 	{ 0x9005, 0x0285, 0x9005, 0x0289, 0, 0, 17 }, /* Adaptec 3240S (Tornado) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 	{ 0x9005, 0x0285, 0x9005, 0x028a, 0, 0, 18 }, /* ASR-2020ZCR SCSI PCI-X ZCR (Skyhawk) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 	{ 0x9005, 0x0285, 0x9005, 0x028b, 0, 0, 19 }, /* ASR-2025ZCR SCSI SO-DIMM PCI-X ZCR (Terminator) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 	{ 0x9005, 0x0286, 0x9005, 0x028c, 0, 0, 20 }, /* ASR-2230S + ASR-2230SLP PCI-X (Lancer) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 	{ 0x9005, 0x0286, 0x9005, 0x028d, 0, 0, 21 }, /* ASR-2130S (Lancer) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 	{ 0x9005, 0x0286, 0x9005, 0x029b, 0, 0, 22 }, /* AAR-2820SA (Intruder) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 	{ 0x9005, 0x0286, 0x9005, 0x029c, 0, 0, 23 }, /* AAR-2620SA (Intruder) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 	{ 0x9005, 0x0286, 0x9005, 0x029d, 0, 0, 24 }, /* AAR-2420SA (Intruder) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 	{ 0x9005, 0x0286, 0x9005, 0x029e, 0, 0, 25 }, /* ICP9024RO (Lancer) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 	{ 0x9005, 0x0286, 0x9005, 0x029f, 0, 0, 26 }, /* ICP9014RO (Lancer) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 	{ 0x9005, 0x0286, 0x9005, 0x02a0, 0, 0, 27 }, /* ICP9047MA (Lancer) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 	{ 0x9005, 0x0286, 0x9005, 0x02a1, 0, 0, 28 }, /* ICP9087MA (Lancer) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 	{ 0x9005, 0x0286, 0x9005, 0x02a3, 0, 0, 29 }, /* ICP5445AU (Hurricane44) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 	{ 0x9005, 0x0285, 0x9005, 0x02a4, 0, 0, 30 }, /* ICP9085LI (Marauder-X) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 	{ 0x9005, 0x0285, 0x9005, 0x02a5, 0, 0, 31 }, /* ICP5085BR (Marauder-E) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 	{ 0x9005, 0x0286, 0x9005, 0x02a6, 0, 0, 32 }, /* ICP9067MA (Intruder-6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 	{ 0x9005, 0x0287, 0x9005, 0x0800, 0, 0, 33 }, /* Themisto Jupiter Platform */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 	{ 0x9005, 0x0200, 0x9005, 0x0200, 0, 0, 33 }, /* Themisto Jupiter Platform */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 	{ 0x9005, 0x0286, 0x9005, 0x0800, 0, 0, 34 }, /* Callisto Jupiter Platform */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 	{ 0x9005, 0x0285, 0x9005, 0x028e, 0, 0, 35 }, /* ASR-2020SA SATA PCI-X ZCR (Skyhawk) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 	{ 0x9005, 0x0285, 0x9005, 0x028f, 0, 0, 36 }, /* ASR-2025SA SATA SO-DIMM PCI-X ZCR (Terminator) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 	{ 0x9005, 0x0285, 0x9005, 0x0290, 0, 0, 37 }, /* AAR-2410SA PCI SATA 4ch (Jaguar II) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 	{ 0x9005, 0x0285, 0x1028, 0x0291, 0, 0, 38 }, /* CERC SATA RAID 2 PCI SATA 6ch (DellCorsair) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 	{ 0x9005, 0x0285, 0x9005, 0x0292, 0, 0, 39 }, /* AAR-2810SA PCI SATA 8ch (Corsair-8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 	{ 0x9005, 0x0285, 0x9005, 0x0293, 0, 0, 40 }, /* AAR-21610SA PCI SATA 16ch (Corsair-16) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 	{ 0x9005, 0x0285, 0x9005, 0x0294, 0, 0, 41 }, /* ESD SO-DIMM PCI-X SATA ZCR (Prowler) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 	{ 0x9005, 0x0285, 0x103C, 0x3227, 0, 0, 42 }, /* AAR-2610SA PCI SATA 6ch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 	{ 0x9005, 0x0285, 0x9005, 0x0296, 0, 0, 43 }, /* ASR-2240S (SabreExpress) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 	{ 0x9005, 0x0285, 0x9005, 0x0297, 0, 0, 44 }, /* ASR-4005 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 	{ 0x9005, 0x0285, 0x1014, 0x02F2, 0, 0, 45 }, /* IBM 8i (AvonPark) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 	{ 0x9005, 0x0285, 0x1014, 0x0312, 0, 0, 45 }, /* IBM 8i (AvonPark Lite) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 	{ 0x9005, 0x0286, 0x1014, 0x9580, 0, 0, 46 }, /* IBM 8k/8k-l8 (Aurora) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	{ 0x9005, 0x0286, 0x1014, 0x9540, 0, 0, 47 }, /* IBM 8k/8k-l4 (Aurora Lite) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	{ 0x9005, 0x0285, 0x9005, 0x0298, 0, 0, 48 }, /* ASR-4000 (BlackBird) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 	{ 0x9005, 0x0285, 0x9005, 0x0299, 0, 0, 49 }, /* ASR-4800SAS (Marauder-X) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	{ 0x9005, 0x0285, 0x9005, 0x029a, 0, 0, 50 }, /* ASR-4805SAS (Marauder-E) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 	{ 0x9005, 0x0286, 0x9005, 0x02a2, 0, 0, 51 }, /* ASR-3800 (Hurricane44) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 	{ 0x9005, 0x0285, 0x1028, 0x0287, 0, 0, 52 }, /* Perc 320/DC*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 	{ 0x1011, 0x0046, 0x9005, 0x0365, 0, 0, 53 }, /* Adaptec 5400S (Mustang)*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 	{ 0x1011, 0x0046, 0x9005, 0x0364, 0, 0, 54 }, /* Adaptec 5400S (Mustang)*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	{ 0x1011, 0x0046, 0x9005, 0x1364, 0, 0, 55 }, /* Dell PERC2/QC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 	{ 0x1011, 0x0046, 0x103c, 0x10c2, 0, 0, 56 }, /* HP NetRAID-4M */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 	{ 0x9005, 0x0285, 0x1028, PCI_ANY_ID, 0, 0, 57 }, /* Dell Catchall */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 	{ 0x9005, 0x0285, 0x17aa, PCI_ANY_ID, 0, 0, 58 }, /* Legend Catchall */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 	{ 0x9005, 0x0285, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 59 }, /* Adaptec Catch All */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 	{ 0x9005, 0x0286, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 60 }, /* Adaptec Rocket Catch All */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 	{ 0x9005, 0x0288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 61 }, /* Adaptec NEMER/ARK Catch All */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 	{ 0x9005, 0x028b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 62 }, /* Adaptec PMC Series 6 (Tupelo) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 	{ 0x9005, 0x028c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 63 }, /* Adaptec PMC Series 7 (Denali) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 	{ 0x9005, 0x028d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 64 }, /* Adaptec PMC Series 8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 	{ 0,}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) MODULE_DEVICE_TABLE(pci, aac_pci_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156)  * dmb - For now we add the number of channels to this structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157)  * In the future we should add a fib that reports the number of channels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158)  * for the card.  At that time we can remove the channels from here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) static struct aac_driver_ident aac_drivers[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 	{ aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* PERC 2/Si (Iguana/PERC2Si) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 	{ aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* PERC 3/Di (Opal/PERC3Di) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 	{ aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* PERC 3/Si (SlimFast/PERC3Si */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 	{ aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* PERC 3/Di (Iguana FlipChip/PERC3DiF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 	{ aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* PERC 3/Di (Viper/PERC3DiV) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 	{ aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* PERC 3/Di (Lexus/PERC3DiL) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 	{ aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 1, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* PERC 3/Di (Jaguar/PERC3DiJ) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 	{ aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* PERC 3/Di (Dagger/PERC3DiD) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 	{ aac_rx_init, "percraid", "DELL    ", "PERCRAID        ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* PERC 3/Di (Boxster/PERC3DiB) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 	{ aac_rx_init, "aacraid",  "ADAPTEC ", "catapult        ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* catapult */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 	{ aac_rx_init, "aacraid",  "ADAPTEC ", "tomcat          ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* tomcat */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 	{ aac_rx_init, "aacraid",  "ADAPTEC ", "Adaptec 2120S   ", 1, AAC_QUIRK_31BIT | AAC_QUIRK_34SG },		      /* Adaptec 2120S (Crusader) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 	{ aac_rx_init, "aacraid",  "ADAPTEC ", "Adaptec 2200S   ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG },		      /* Adaptec 2200S (Vulcan) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 	{ aac_rx_init, "aacraid",  "ADAPTEC ", "Adaptec 2200S   ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* Adaptec 2200S (Vulcan-2m) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 	{ aac_rx_init, "aacraid",  "Legend  ", "Legend S220     ", 1, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* Legend S220 (Legend Crusader) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 	{ aac_rx_init, "aacraid",  "Legend  ", "Legend S230     ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* Legend S230 (Legend Vulcan) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 	{ aac_rx_init, "aacraid",  "ADAPTEC ", "Adaptec 3230S   ", 2 }, /* Adaptec 3230S (Harrier) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 	{ aac_rx_init, "aacraid",  "ADAPTEC ", "Adaptec 3240S   ", 2 }, /* Adaptec 3240S (Tornado) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 	{ aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-2020ZCR     ", 2 }, /* ASR-2020ZCR SCSI PCI-X ZCR (Skyhawk) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 	{ aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-2025ZCR     ", 2 }, /* ASR-2025ZCR SCSI SO-DIMM PCI-X ZCR (Terminator) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 	{ aac_rkt_init, "aacraid",  "ADAPTEC ", "ASR-2230S PCI-X ", 2 }, /* ASR-2230S + ASR-2230SLP PCI-X (Lancer) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 	{ aac_rkt_init, "aacraid",  "ADAPTEC ", "ASR-2130S PCI-X ", 1 }, /* ASR-2130S (Lancer) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 	{ aac_rkt_init, "aacraid",  "ADAPTEC ", "AAR-2820SA      ", 1 }, /* AAR-2820SA (Intruder) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 	{ aac_rkt_init, "aacraid",  "ADAPTEC ", "AAR-2620SA      ", 1 }, /* AAR-2620SA (Intruder) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 	{ aac_rkt_init, "aacraid",  "ADAPTEC ", "AAR-2420SA      ", 1 }, /* AAR-2420SA (Intruder) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 	{ aac_rkt_init, "aacraid",  "ICP     ", "ICP9024RO       ", 2 }, /* ICP9024RO (Lancer) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 	{ aac_rkt_init, "aacraid",  "ICP     ", "ICP9014RO       ", 1 }, /* ICP9014RO (Lancer) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 	{ aac_rkt_init, "aacraid",  "ICP     ", "ICP9047MA       ", 1 }, /* ICP9047MA (Lancer) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 	{ aac_rkt_init, "aacraid",  "ICP     ", "ICP9087MA       ", 1 }, /* ICP9087MA (Lancer) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 	{ aac_rkt_init, "aacraid",  "ICP     ", "ICP5445AU       ", 1 }, /* ICP5445AU (Hurricane44) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 	{ aac_rx_init, "aacraid",  "ICP     ", "ICP9085LI       ", 1 }, /* ICP9085LI (Marauder-X) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 	{ aac_rx_init, "aacraid",  "ICP     ", "ICP5085BR       ", 1 }, /* ICP5085BR (Marauder-E) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 	{ aac_rkt_init, "aacraid",  "ICP     ", "ICP9067MA       ", 1 }, /* ICP9067MA (Intruder-6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	{ NULL        , "aacraid",  "ADAPTEC ", "Themisto        ", 0, AAC_QUIRK_SLAVE }, /* Jupiter Platform */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 	{ aac_rkt_init, "aacraid",  "ADAPTEC ", "Callisto        ", 2, AAC_QUIRK_MASTER }, /* Jupiter Platform */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 	{ aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-2020SA       ", 1 }, /* ASR-2020SA SATA PCI-X ZCR (Skyhawk) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 	{ aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-2025SA       ", 1 }, /* ASR-2025SA SATA SO-DIMM PCI-X ZCR (Terminator) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 	{ aac_rx_init, "aacraid",  "ADAPTEC ", "AAR-2410SA SATA ", 1, AAC_QUIRK_17SG }, /* AAR-2410SA PCI SATA 4ch (Jaguar II) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	{ aac_rx_init, "aacraid",  "DELL    ", "CERC SR2        ", 1, AAC_QUIRK_17SG }, /* CERC SATA RAID 2 PCI SATA 6ch (DellCorsair) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	{ aac_rx_init, "aacraid",  "ADAPTEC ", "AAR-2810SA SATA ", 1, AAC_QUIRK_17SG }, /* AAR-2810SA PCI SATA 8ch (Corsair-8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 	{ aac_rx_init, "aacraid",  "ADAPTEC ", "AAR-21610SA SATA", 1, AAC_QUIRK_17SG }, /* AAR-21610SA PCI SATA 16ch (Corsair-16) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 	{ aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-2026ZCR     ", 1 }, /* ESD SO-DIMM PCI-X SATA ZCR (Prowler) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 	{ aac_rx_init, "aacraid",  "ADAPTEC ", "AAR-2610SA      ", 1 }, /* SATA 6Ch (Bearcat) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 	{ aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-2240S       ", 1 }, /* ASR-2240S (SabreExpress) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 	{ aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-4005        ", 1 }, /* ASR-4005 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	{ aac_rx_init, "ServeRAID","IBM     ", "ServeRAID 8i    ", 1 }, /* IBM 8i (AvonPark) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	{ aac_rkt_init, "ServeRAID","IBM     ", "ServeRAID 8k-l8 ", 1 }, /* IBM 8k/8k-l8 (Aurora) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 	{ aac_rkt_init, "ServeRAID","IBM     ", "ServeRAID 8k-l4 ", 1 }, /* IBM 8k/8k-l4 (Aurora Lite) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 	{ aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-4000        ", 1 }, /* ASR-4000 (BlackBird & AvonPark) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	{ aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-4800SAS     ", 1 }, /* ASR-4800SAS (Marauder-X) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 	{ aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-4805SAS     ", 1 }, /* ASR-4805SAS (Marauder-E) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 	{ aac_rkt_init, "aacraid",  "ADAPTEC ", "ASR-3800        ", 1 }, /* ASR-3800 (Hurricane44) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 	{ aac_rx_init, "percraid", "DELL    ", "PERC 320/DC     ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Perc 320/DC*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 	{ aac_sa_init, "aacraid",  "ADAPTEC ", "Adaptec 5400S   ", 4, AAC_QUIRK_34SG }, /* Adaptec 5400S (Mustang)*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 	{ aac_sa_init, "aacraid",  "ADAPTEC ", "AAC-364         ", 4, AAC_QUIRK_34SG }, /* Adaptec 5400S (Mustang)*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 	{ aac_sa_init, "percraid", "DELL    ", "PERCRAID        ", 4, AAC_QUIRK_34SG }, /* Dell PERC2/QC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 	{ aac_sa_init, "hpnraid",  "HP      ", "NetRAID         ", 4, AAC_QUIRK_34SG }, /* HP NetRAID-4M */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	{ aac_rx_init, "aacraid",  "DELL    ", "RAID            ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* Dell Catchall */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	{ aac_rx_init, "aacraid",  "Legend  ", "RAID            ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* Legend Catchall */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 	{ aac_rx_init, "aacraid",  "ADAPTEC ", "RAID            ", 2 }, /* Adaptec Catch All */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 	{ aac_rkt_init, "aacraid", "ADAPTEC ", "RAID            ", 2 }, /* Adaptec Rocket Catch All */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 	{ aac_nark_init, "aacraid", "ADAPTEC ", "RAID           ", 2 }, /* Adaptec NEMER/ARK Catch All */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 	{ aac_src_init, "aacraid", "ADAPTEC ", "RAID            ", 2, AAC_QUIRK_SRC }, /* Adaptec PMC Series 6 (Tupelo) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 	{ aac_srcv_init, "aacraid", "ADAPTEC ", "RAID            ", 2, AAC_QUIRK_SRC }, /* Adaptec PMC Series 7 (Denali) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 	{ aac_srcv_init, "aacraid", "ADAPTEC ", "RAID            ", 2, AAC_QUIRK_SRC }, /* Adaptec PMC Series 8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232)  *	aac_queuecommand	-	queue a SCSI command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233)  *	@shost:		Scsi host to queue command on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234)  *	@cmd:		SCSI command to queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236)  *	Queues a command for execution by the associated Host Adapter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238)  *	TODO: unify with aac_scsi_cmd().
^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 aac_queuecommand(struct Scsi_Host *shost,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 			    struct scsi_cmnd *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 	int r = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 	cmd->SCp.phase = AAC_OWNER_LOWLEVEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 	r = (aac_scsi_cmd(cmd) ? FAILED : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 	return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251)  *	aac_info		-	Returns the host adapter name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252)  *	@shost:		Scsi host to report on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254)  *	Returns a static string describing the device in question
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) static const char *aac_info(struct Scsi_Host *shost)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 	struct aac_dev *dev = (struct aac_dev *)shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 	return aac_drivers[dev->cardtype].name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) }
^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)  *	aac_get_driver_ident
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265)  *	@devtype: index into lookup table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267)  *	Returns a pointer to the entry in the driver lookup table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) struct aac_driver_ident* aac_get_driver_ident(int devtype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 	return &aac_drivers[devtype];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276)  *	aac_biosparm	-	return BIOS parameters for disk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277)  *	@sdev: The scsi device corresponding to the disk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278)  *	@bdev: the block device corresponding to the disk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279)  *	@capacity: the sector capacity of the disk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280)  *	@geom: geometry block to fill in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282)  *	Return the Heads/Sectors/Cylinders BIOS Disk Parameters for Disk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283)  *	The default disk geometry is 64 heads, 32 sectors, and the appropriate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284)  *	number of cylinders so as not to exceed drive capacity.  In order for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285)  *	disks equal to or larger than 1 GB to be addressable by the BIOS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286)  *	without exceeding the BIOS limitation of 1024 cylinders, Extended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287)  *	Translation should be enabled.   With Extended Translation enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288)  *	drives between 1 GB inclusive and 2 GB exclusive are given a disk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289)  *	geometry of 128 heads and 32 sectors, and drives above 2 GB inclusive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290)  *	are given a disk geometry of 255 heads and 63 sectors.  However, if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291)  *	the BIOS detects that the Extended Translation setting does not match
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292)  *	the geometry in the partition table, then the translation inferred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293)  *	from the partition table will be used by the BIOS, and a warning may
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294)  *	be displayed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) static int aac_biosparm(struct scsi_device *sdev, struct block_device *bdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 			sector_t capacity, int *geom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 	struct diskparm *param = (struct diskparm *)geom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 	unsigned char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 	dprintk((KERN_DEBUG "aac_biosparm.\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 	 *	Assuming extended translation is enabled - #REVISIT#
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 	if (capacity >= 2 * 1024 * 1024) { /* 1 GB in 512 byte sectors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 		if(capacity >= 4 * 1024 * 1024) { /* 2 GB in 512 byte sectors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 			param->heads = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 			param->sectors = 63;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 			param->heads = 128;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 			param->sectors = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 		param->heads = 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 		param->sectors = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 	param->cylinders = cap_to_cyls(capacity, param->heads * param->sectors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 	 *	Read the first 1024 bytes from the disk device, if the boot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 	 *	sector partition table is valid, search for a partition table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 	 *	entry whose end_head matches one of the standard geometry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 	 *	translations ( 64/32, 128/32, 255/63 ).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	buf = scsi_bios_ptable(bdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 	if (*(__le16 *)(buf + 0x40) == cpu_to_le16(MSDOS_LABEL_MAGIC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 		struct msdos_partition *first = (struct msdos_partition *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 		struct msdos_partition *entry = first;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 		int saved_cylinders = param->cylinders;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 		int num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 		unsigned char end_head, end_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 		for(num = 0; num < 4; num++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 			end_head = entry->end_head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 			end_sec = entry->end_sector & 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 			if(end_head == 63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 				param->heads = 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 				param->sectors = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 			} else if(end_head == 127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 				param->heads = 128;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 				param->sectors = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 			} else if(end_head == 254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 				param->heads = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 				param->sectors = 63;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 			entry++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 		if (num == 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 			end_head = first->end_head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 			end_sec = first->end_sector & 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 		param->cylinders = cap_to_cyls(capacity, param->heads * param->sectors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 		if (num < 4 && end_sec == param->sectors) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 			if (param->cylinders != saved_cylinders) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 				dprintk((KERN_DEBUG "Adopting geometry: heads=%d, sectors=%d from partition table %d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 					param->heads, param->sectors, num));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 		} else if (end_head > 0 || end_sec > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 			dprintk((KERN_DEBUG "Strange geometry: heads=%d, sectors=%d in partition table %d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 				end_head + 1, end_sec, num));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 			dprintk((KERN_DEBUG "Using geometry: heads=%d, sectors=%d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 					param->heads, param->sectors));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382)  *	aac_slave_configure		-	compute queue depths
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383)  *	@sdev:	SCSI device we are considering
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385)  *	Selects queue depths for each target device based on the host adapter's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386)  *	total capacity and the queue depth supported by the target device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387)  *	A queue depth of one automatically disables tagged queueing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) static int aac_slave_configure(struct scsi_device *sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 	struct aac_dev *aac = (struct aac_dev *)sdev->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 	int chn, tid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 	unsigned int depth = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 	unsigned int set_timeout = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 	int timeout = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 	bool set_qd_dev_type = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 	u8 devtype = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 	chn = aac_logical_to_phys(sdev_channel(sdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 	tid = sdev_id(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	if (chn < AAC_MAX_BUSES && tid < AAC_MAX_TARGETS && aac->sa_firmware) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 		devtype = aac->hba_map[chn][tid].devtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 		if (devtype == AAC_DEVTYPE_NATIVE_RAW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 			depth = aac->hba_map[chn][tid].qd_limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 			set_timeout = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 			goto common_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 		if (devtype == AAC_DEVTYPE_ARC_RAW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 			set_qd_dev_type = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 			set_timeout = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 			goto common_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 	if (aac->jbod && (sdev->type == TYPE_DISK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 		sdev->removable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 	if (sdev->type == TYPE_DISK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 	 && sdev_channel(sdev) != CONTAINER_CHANNEL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 	 && (!aac->jbod || sdev->inq_periph_qual)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 	 && (!aac->raid_scsi_mode || (sdev_channel(sdev) != 2))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 		if (expose_physicals == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 			return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 		if (expose_physicals < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 			sdev->no_uld_attach = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 	if (sdev->tagged_supported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 	 &&  sdev->type == TYPE_DISK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 	 &&  (!aac->raid_scsi_mode || (sdev_channel(sdev) != 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 	 && !sdev->no_uld_attach) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 		struct scsi_device * dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 		struct Scsi_Host *host = sdev->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 		unsigned num_lsu = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 		unsigned num_one = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 		unsigned cid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 		set_timeout = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 		for (cid = 0; cid < aac->maximum_num_containers; ++cid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 			if (aac->fsa_dev[cid].valid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 				++num_lsu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 		__shost_for_each_device(dev, host) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 			if (dev->tagged_supported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 			 && dev->type == TYPE_DISK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 			 && (!aac->raid_scsi_mode || (sdev_channel(sdev) != 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 			 && !dev->no_uld_attach) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 				if ((sdev_channel(dev) != CONTAINER_CHANNEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 				 || !aac->fsa_dev[sdev_id(dev)].valid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 					++num_lsu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 				++num_one;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 		if (num_lsu == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 			++num_lsu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 		depth = (host->can_queue - num_one) / num_lsu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 		if (sdev_channel(sdev) != NATIVE_CHANNEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 			goto common_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 		set_qd_dev_type = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) common_config:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 	 * Check if SATA drive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 	if (set_qd_dev_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 		if (strncmp(sdev->vendor, "ATA", 3) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 			depth = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 			depth = 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 	 * Firmware has an individual device recovery time typically
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 	 * of 35 seconds, give us a margin. Thor devices can take longer in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 	 * error recovery, hence different value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 	if (set_timeout) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 		timeout = aac->sa_firmware ? AAC_SA_TIMEOUT : AAC_ARC_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 		blk_queue_rq_timeout(sdev->request_queue, timeout * HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 	if (depth > 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 		depth = 256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 	else if (depth < 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 		depth = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 	scsi_change_queue_depth(sdev, depth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 	sdev->tagged_supported = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510)  *	aac_change_queue_depth		-	alter queue depths
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511)  *	@sdev:	SCSI device we are considering
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512)  *	@depth:	desired queue depth
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514)  *	Alters queue depths for target device based on the host adapter's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515)  *	total capacity and the queue depth supported by the target device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) static int aac_change_queue_depth(struct scsi_device *sdev, int depth)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 	struct aac_dev *aac = (struct aac_dev *)(sdev->host->hostdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 	int chn, tid, is_native_device = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 	chn = aac_logical_to_phys(sdev_channel(sdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 	tid = sdev_id(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 	if (chn < AAC_MAX_BUSES && tid < AAC_MAX_TARGETS &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 		aac->hba_map[chn][tid].devtype == AAC_DEVTYPE_NATIVE_RAW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 		is_native_device = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 	if (sdev->tagged_supported && (sdev->type == TYPE_DISK) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 	    (sdev_channel(sdev) == CONTAINER_CHANNEL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 		struct scsi_device * dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 		struct Scsi_Host *host = sdev->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 		unsigned num = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 		__shost_for_each_device(dev, host) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 			if (dev->tagged_supported && (dev->type == TYPE_DISK) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 			    (sdev_channel(dev) == CONTAINER_CHANNEL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 				++num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 			++num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 		if (num >= host->can_queue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 			num = host->can_queue - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 		if (depth > (host->can_queue - num))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 			depth = host->can_queue - num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 		if (depth > 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 			depth = 256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 		else if (depth < 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 			depth = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 		return scsi_change_queue_depth(sdev, depth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 	} else if (is_native_device) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 		scsi_change_queue_depth(sdev, aac->hba_map[chn][tid].qd_limit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 		scsi_change_queue_depth(sdev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 	return sdev->queue_depth;
^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) static ssize_t aac_show_raid_level(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 	struct scsi_device *sdev = to_scsi_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 	struct aac_dev *aac = (struct aac_dev *)(sdev->host->hostdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 	if (sdev_channel(sdev) != CONTAINER_CHANNEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 		return snprintf(buf, PAGE_SIZE, sdev->no_uld_attach
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 		  ? "Hidden\n" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 		  ((aac->jbod && (sdev->type == TYPE_DISK)) ? "JBOD\n" : ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 	return snprintf(buf, PAGE_SIZE, "%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 	  get_container_type(aac->fsa_dev[sdev_id(sdev)].type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) static struct device_attribute aac_raid_level_attr = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 	.attr = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 		.name = "level",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 		.mode = S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 	.show = aac_show_raid_level
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) static ssize_t aac_show_unique_id(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	     struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 	struct scsi_device *sdev = to_scsi_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 	struct aac_dev *aac = (struct aac_dev *)(sdev->host->hostdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 	unsigned char sn[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 	memset(sn, 0, sizeof(sn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 	if (sdev_channel(sdev) == CONTAINER_CHANNEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 		memcpy(sn, aac->fsa_dev[sdev_id(sdev)].identifier, sizeof(sn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 	return snprintf(buf, 16 * 2 + 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 		"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 		sn[0], sn[1], sn[2], sn[3],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 		sn[4], sn[5], sn[6], sn[7],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 		sn[8], sn[9], sn[10], sn[11],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 		sn[12], sn[13], sn[14], sn[15]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) static struct device_attribute aac_unique_id_attr = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 	.attr = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 		.name = "unique_id",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 		.mode = 0444,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 	.show = aac_show_unique_id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) static struct device_attribute *aac_dev_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 	&aac_raid_level_attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 	&aac_unique_id_attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 	NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) static int aac_ioctl(struct scsi_device *sdev, unsigned int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 		     void __user *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 	int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 	struct aac_dev *dev = (struct aac_dev *)sdev->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 	if (!capable(CAP_SYS_RAWIO))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 	retval = aac_adapter_check_health(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 	return aac_do_ioctl(dev, cmd, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) struct fib_count_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 	int mlcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 	int llcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 	int ehcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 	int fwcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 	int krlcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) static bool fib_count_iter(struct scsi_cmnd *scmnd, void *data, bool reserved)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 	struct fib_count_data *fib_count = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 	switch (scmnd->SCp.phase) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 	case AAC_OWNER_FIRMWARE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 		fib_count->fwcnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 	case AAC_OWNER_ERROR_HANDLER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 		fib_count->ehcnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 	case AAC_OWNER_LOWLEVEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 		fib_count->llcnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 	case AAC_OWNER_MIDLEVEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 		fib_count->mlcnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 		fib_count->krlcnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) /* Called during SCSI EH, so we don't need to block requests */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) static int get_num_of_incomplete_fibs(struct aac_dev *aac)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 	struct Scsi_Host *shost = aac->scsi_host_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 	struct device *ctrl_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 	struct fib_count_data fcnt = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 	scsi_host_busy_iter(shost, fib_count_iter, &fcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 	ctrl_dev = &aac->pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 	dev_info(ctrl_dev, "outstanding cmd: midlevel-%d\n", fcnt.mlcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 	dev_info(ctrl_dev, "outstanding cmd: lowlevel-%d\n", fcnt.llcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 	dev_info(ctrl_dev, "outstanding cmd: error handler-%d\n", fcnt.ehcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 	dev_info(ctrl_dev, "outstanding cmd: firmware-%d\n", fcnt.fwcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 	dev_info(ctrl_dev, "outstanding cmd: kernel-%d\n", fcnt.krlcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 	return fcnt.mlcnt + fcnt.llcnt + fcnt.ehcnt + fcnt.fwcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) static int aac_eh_abort(struct scsi_cmnd* cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 	struct scsi_device * dev = cmd->device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 	struct Scsi_Host * host = dev->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 	struct aac_dev * aac = (struct aac_dev *)host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 	int count, found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 	u32 bus, cid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 	int ret = FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 	if (aac_adapter_check_health(aac))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 	bus = aac_logical_to_phys(scmd_channel(cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 	cid = scmd_id(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 	if (aac->hba_map[bus][cid].devtype == AAC_DEVTYPE_NATIVE_RAW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 		struct fib *fib;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 		struct aac_hba_tm_req *tmf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 		int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 		u64 address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 		pr_err("%s: Host adapter abort request (%d,%d,%d,%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 		 AAC_DRIVERNAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 		 host->host_no, sdev_channel(dev), sdev_id(dev), (int)dev->lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 		found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 		for (count = 0; count < (host->can_queue + AAC_NUM_MGT_FIB); ++count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 			fib = &aac->fibs[count];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 			if (*(u8 *)fib->hw_fib_va != 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 				(fib->flags & FIB_CONTEXT_FLAG_NATIVE_HBA) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 				(fib->callback_data == cmd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 				found = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 		if (!found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 		/* start a HBA_TMF_ABORT_TASK TMF request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 		fib = aac_fib_alloc(aac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 		if (!fib)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 		tmf = (struct aac_hba_tm_req *)fib->hw_fib_va;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 		memset(tmf, 0, sizeof(*tmf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 		tmf->tmf = HBA_TMF_ABORT_TASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 		tmf->it_nexus = aac->hba_map[bus][cid].rmw_nexus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 		tmf->lun[1] = cmd->device->lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 		address = (u64)fib->hw_error_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 		tmf->error_ptr_hi = cpu_to_le32((u32)(address >> 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 		tmf->error_ptr_lo = cpu_to_le32((u32)(address & 0xffffffff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 		tmf->error_length = cpu_to_le32(FW_ERROR_BUFFER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 		fib->hbacmd_size = sizeof(*tmf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 		cmd->SCp.sent_command = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 		status = aac_hba_send(HBA_IU_TYPE_SCSI_TM_REQ, fib,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 				  (fib_callback) aac_hba_callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 				  (void *) cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 		if (status != -EINPROGRESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 			aac_fib_complete(fib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 			aac_fib_free(fib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 		/* Wait up to 15 secs for completion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 		for (count = 0; count < 15; ++count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 			if (cmd->SCp.sent_command) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 				ret = SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 			msleep(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 		if (ret != SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 			pr_err("%s: Host adapter abort request timed out\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 			AAC_DRIVERNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 		pr_err(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 			"%s: Host adapter abort request.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 			"%s: Outstanding commands on (%d,%d,%d,%d):\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 			AAC_DRIVERNAME, AAC_DRIVERNAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 			host->host_no, sdev_channel(dev), sdev_id(dev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 			(int)dev->lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 		switch (cmd->cmnd[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 		case SERVICE_ACTION_IN_16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 			if (!(aac->raw_io_interface) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 			    !(aac->raw_io_64) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 			    ((cmd->cmnd[1] & 0x1f) != SAI_READ_CAPACITY_16))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 			fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 		case INQUIRY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 		case READ_CAPACITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 			 * Mark associated FIB to not complete,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 			 * eh handler does this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 			for (count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 				count < (host->can_queue + AAC_NUM_MGT_FIB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 				++count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 				struct fib *fib = &aac->fibs[count];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 				if (fib->hw_fib_va->header.XferState &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 				(fib->flags & FIB_CONTEXT_FLAG) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 				(fib->callback_data == cmd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 					fib->flags |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 						FIB_CONTEXT_FLAG_TIMED_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 					cmd->SCp.phase =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 						AAC_OWNER_ERROR_HANDLER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 					ret = SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 		case TEST_UNIT_READY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 			 * Mark associated FIB to not complete,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 			 * eh handler does this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 			for (count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 				count < (host->can_queue + AAC_NUM_MGT_FIB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 				++count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 				struct scsi_cmnd *command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 				struct fib *fib = &aac->fibs[count];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 				command = fib->callback_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 				if ((fib->hw_fib_va->header.XferState &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 					cpu_to_le32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 					(Async | NoResponseExpected)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 					(fib->flags & FIB_CONTEXT_FLAG) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 					((command)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 					(command->device == cmd->device)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 					fib->flags |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 						FIB_CONTEXT_FLAG_TIMED_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 					command->SCp.phase =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 						AAC_OWNER_ERROR_HANDLER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 					if (command == cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 						ret = SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) static u8 aac_eh_tmf_lun_reset_fib(struct aac_hba_map_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 				   struct fib *fib, u64 tmf_lun)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 	struct aac_hba_tm_req *tmf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 	u64 address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 	/* start a HBA_TMF_LUN_RESET TMF request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 	tmf = (struct aac_hba_tm_req *)fib->hw_fib_va;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 	memset(tmf, 0, sizeof(*tmf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 	tmf->tmf = HBA_TMF_LUN_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 	tmf->it_nexus = info->rmw_nexus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 	int_to_scsilun(tmf_lun, (struct scsi_lun *)tmf->lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 	address = (u64)fib->hw_error_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 	tmf->error_ptr_hi = cpu_to_le32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 		((u32)(address >> 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 	tmf->error_ptr_lo = cpu_to_le32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 		((u32)(address & 0xffffffff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 	tmf->error_length = cpu_to_le32(FW_ERROR_BUFFER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 	fib->hbacmd_size = sizeof(*tmf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 	return HBA_IU_TYPE_SCSI_TM_REQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) static u8 aac_eh_tmf_hard_reset_fib(struct aac_hba_map_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 				    struct fib *fib)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	struct aac_hba_reset_req *rst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	u64 address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 	/* already tried, start a hard reset now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 	rst = (struct aac_hba_reset_req *)fib->hw_fib_va;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 	memset(rst, 0, sizeof(*rst));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 	rst->it_nexus = info->rmw_nexus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 	address = (u64)fib->hw_error_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 	rst->error_ptr_hi = cpu_to_le32((u32)(address >> 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 	rst->error_ptr_lo = cpu_to_le32((u32)(address & 0xffffffff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 	rst->error_length = cpu_to_le32(FW_ERROR_BUFFER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 	fib->hbacmd_size = sizeof(*rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865)        return HBA_IU_TYPE_SATA_REQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) static void aac_tmf_callback(void *context, struct fib *fibptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 	struct aac_hba_resp *err =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 		&((struct aac_native_hba *)fibptr->hw_fib_va)->resp.err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 	struct aac_hba_map_info *info = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 	int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 	switch (err->service_response) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 	case HBA_RESP_SVCRES_TMF_REJECTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 		res = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 	case HBA_RESP_SVCRES_TMF_LUN_INVALID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 		res = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 	case HBA_RESP_SVCRES_TMF_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 	case HBA_RESP_SVCRES_TMF_SUCCEEDED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 		res = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 		res = -2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 	aac_fib_complete(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 	info->reset_state = res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896)  *	aac_eh_dev_reset	- Device reset command handling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897)  *	@scsi_cmd:	SCSI command block causing the reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) static int aac_eh_dev_reset(struct scsi_cmnd *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 	struct scsi_device * dev = cmd->device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 	struct Scsi_Host * host = dev->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 	struct aac_dev * aac = (struct aac_dev *)host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 	struct aac_hba_map_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 	int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	u32 bus, cid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 	struct fib *fib;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 	int ret = FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 	int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 	u8 command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 	bus = aac_logical_to_phys(scmd_channel(cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 	cid = scmd_id(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 	if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 		return FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 	info = &aac->hba_map[bus][cid];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 	if (!(info->devtype == AAC_DEVTYPE_NATIVE_RAW &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 	 !(info->reset_state > 0)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 		return FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 	pr_err("%s: Host device reset request. SCSI hang ?\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 	       AAC_DRIVERNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 	fib = aac_fib_alloc(aac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 	if (!fib)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 	/* start a HBA_TMF_LUN_RESET TMF request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 	command = aac_eh_tmf_lun_reset_fib(info, fib, dev->lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 	info->reset_state = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 	status = aac_hba_send(command, fib,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 			      (fib_callback) aac_tmf_callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 			      (void *) info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 	if (status != -EINPROGRESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 		info->reset_state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 		aac_fib_complete(fib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 		aac_fib_free(fib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 	/* Wait up to 15 seconds for completion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	for (count = 0; count < 15; ++count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 		if (info->reset_state == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 			ret = info->reset_state == 0 ? SUCCESS : FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 		msleep(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959)  *	aac_eh_target_reset	- Target reset command handling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960)  *	@scsi_cmd:	SCSI command block causing the reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) static int aac_eh_target_reset(struct scsi_cmnd *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 	struct scsi_device * dev = cmd->device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	struct Scsi_Host * host = dev->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 	struct aac_dev * aac = (struct aac_dev *)host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 	struct aac_hba_map_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 	int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 	u32 bus, cid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 	int ret = FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 	struct fib *fib;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 	int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 	u8 command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 	bus = aac_logical_to_phys(scmd_channel(cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 	cid = scmd_id(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 	if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 		return FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	info = &aac->hba_map[bus][cid];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 	if (!(info->devtype == AAC_DEVTYPE_NATIVE_RAW &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	 !(info->reset_state > 0)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 		return FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 	pr_err("%s: Host target reset request. SCSI hang ?\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 	       AAC_DRIVERNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 	fib = aac_fib_alloc(aac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 	if (!fib)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 	/* already tried, start a hard reset now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	command = aac_eh_tmf_hard_reset_fib(info, fib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 	info->reset_state = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 	status = aac_hba_send(command, fib,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 			      (fib_callback) aac_tmf_callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 			      (void *) info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 	if (status != -EINPROGRESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 		info->reset_state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 		aac_fib_complete(fib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 		aac_fib_free(fib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 	/* Wait up to 15 seconds for completion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 	for (count = 0; count < 15; ++count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 		if (info->reset_state <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 			ret = info->reset_state == 0 ? SUCCESS : FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 		msleep(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)  *	aac_eh_bus_reset	- Bus reset command handling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026)  *	@scsi_cmd:	SCSI command block causing the reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) static int aac_eh_bus_reset(struct scsi_cmnd* cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	struct scsi_device * dev = cmd->device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 	struct Scsi_Host * host = dev->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 	struct aac_dev * aac = (struct aac_dev *)host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 	int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 	u32 cmd_bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 	int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 	cmd_bus = aac_logical_to_phys(scmd_channel(cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 	/* Mark the assoc. FIB to not complete, eh handler does this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 	for (count = 0; count < (host->can_queue + AAC_NUM_MGT_FIB); ++count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 		struct fib *fib = &aac->fibs[count];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 		if (fib->hw_fib_va->header.XferState &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 		    (fib->flags & FIB_CONTEXT_FLAG) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 		    (fib->flags & FIB_CONTEXT_FLAG_SCSI_CMD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 			struct aac_hba_map_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 			u32 bus, cid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 			cmd = (struct scsi_cmnd *)fib->callback_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 			bus = aac_logical_to_phys(scmd_channel(cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 			if (bus != cmd_bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 			cid = scmd_id(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 			info = &aac->hba_map[bus][cid];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 			if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 			    info->devtype != AAC_DEVTYPE_NATIVE_RAW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 				fib->flags |= FIB_CONTEXT_FLAG_EH_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 				cmd->SCp.phase = AAC_OWNER_ERROR_HANDLER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 		}
^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) 	pr_err("%s: Host bus reset request. SCSI hang ?\n", AAC_DRIVERNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 	 * Check the health of the controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 	status = aac_adapter_check_health(aac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 	if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 		dev_err(&aac->pdev->dev, "Adapter health - %d\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 	count = get_num_of_incomplete_fibs(aac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 	return (count == 0) ? SUCCESS : FAILED;
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)  *	aac_eh_host_reset	- Host reset command handling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079)  *	@scsi_cmd:	SCSI command block causing the reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) static int aac_eh_host_reset(struct scsi_cmnd *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 	struct scsi_device * dev = cmd->device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 	struct Scsi_Host * host = dev->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 	struct aac_dev * aac = (struct aac_dev *)host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 	int ret = FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 	__le32 supported_options2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 	bool is_mu_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 	bool is_ignore_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 	bool is_doorbell_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 	 * Check if reset is supported by the firmware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 	supported_options2 = aac->supplement_adapter_info.supported_options2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 	is_mu_reset = supported_options2 & AAC_OPTION_MU_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 	is_doorbell_reset = supported_options2 & AAC_OPTION_DOORBELL_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 	is_ignore_reset = supported_options2 & AAC_OPTION_IGNORE_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 	 * This adapter needs a blind reset, only do so for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 	 * Adapters that support a register, instead of a commanded,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 	 * reset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 	if ((is_mu_reset || is_doorbell_reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 	 && aac_check_reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 	 && (aac_check_reset != -1 || !is_ignore_reset)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 		/* Bypass wait for command quiesce */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 		if (aac_reset_adapter(aac, 2, IOP_HWSOFT_RESET) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 			ret = SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 	 * Reset EH state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 	if (ret == SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 		int bus, cid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 		struct aac_hba_map_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 		for (bus = 0; bus < AAC_MAX_BUSES; bus++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 			for (cid = 0; cid < AAC_MAX_TARGETS; cid++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 				info = &aac->hba_map[bus][cid];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 				if (info->devtype == AAC_DEVTYPE_NATIVE_RAW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 					info->reset_state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 	return ret;
^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) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131)  *	aac_cfg_open		-	open a configuration file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)  *	@inode: inode being opened
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)  *	@file: file handle attached
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135)  *	Called when the configuration device is opened. Does the needed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)  *	set up on the handle and then returns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)  *	Bugs: This needs extending to check a given adapter is present
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139)  *	so we can support hot plugging, and to ref count adapters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) static int aac_cfg_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 	struct aac_dev *aac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 	unsigned minor_number = iminor(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 	int err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 	mutex_lock(&aac_mutex);  /* BKL pushdown: nothing else protects this list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 	list_for_each_entry(aac, &aac_devices, entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 		if (aac->id == minor_number) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 			file->private_data = aac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 			err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 	mutex_unlock(&aac_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162)  *	aac_cfg_ioctl		-	AAC configuration request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)  *	@file: file handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)  *	@cmd: ioctl command code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165)  *	@arg: argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167)  *	Handles a configuration ioctl. Currently this involves wrapping it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)  *	up and feeding it into the nasty windowsalike glue layer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)  *	Bugs: Needs locking against parallel ioctls lower down
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171)  *	Bugs: Needs to handle hot plugging
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) static long aac_cfg_ioctl(struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 		unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 	struct aac_dev *aac = (struct aac_dev *)file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 	if (!capable(CAP_SYS_RAWIO))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 	return aac_do_ioctl(aac, cmd, (void __user *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) static ssize_t aac_show_model(struct device *device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 			      struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 	struct aac_dev *dev = (struct aac_dev*)class_to_shost(device)->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 	int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 	if (dev->supplement_adapter_info.adapter_type_text[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 		char *cp = dev->supplement_adapter_info.adapter_type_text;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 		while (*cp && *cp != ' ')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 			++cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 		while (*cp == ' ')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 			++cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 		len = snprintf(buf, PAGE_SIZE, "%s\n", cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 		len = snprintf(buf, PAGE_SIZE, "%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 		  aac_drivers[dev->cardtype].model);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 	return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) static ssize_t aac_show_vendor(struct device *device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 			       struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 	struct aac_dev *dev = (struct aac_dev*)class_to_shost(device)->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 	struct aac_supplement_adapter_info *sup_adap_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 	int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 	sup_adap_info = &dev->supplement_adapter_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 	if (sup_adap_info->adapter_type_text[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 		char *cp = sup_adap_info->adapter_type_text;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 		while (*cp && *cp != ' ')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 			++cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 		len = snprintf(buf, PAGE_SIZE, "%.*s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 			(int)(cp - (char *)sup_adap_info->adapter_type_text),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 					sup_adap_info->adapter_type_text);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 		len = snprintf(buf, PAGE_SIZE, "%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 			aac_drivers[dev->cardtype].vname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 	return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) static ssize_t aac_show_flags(struct device *cdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 			      struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 	int len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 	struct aac_dev *dev = (struct aac_dev*)class_to_shost(cdev)->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 	if (nblank(dprintk(x)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 		len = snprintf(buf, PAGE_SIZE, "dprintk\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) #ifdef AAC_DETAILED_STATUS_INFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 	len += scnprintf(buf + len, PAGE_SIZE - len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 			 "AAC_DETAILED_STATUS_INFO\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 	if (dev->raw_io_interface && dev->raw_io_64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 		len += scnprintf(buf + len, PAGE_SIZE - len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 				 "SAI_READ_CAPACITY_16\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 	if (dev->jbod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 		len += scnprintf(buf + len, PAGE_SIZE - len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 				 "SUPPORTED_JBOD\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 	if (dev->supplement_adapter_info.supported_options2 &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 		AAC_OPTION_POWER_MANAGEMENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 		len += scnprintf(buf + len, PAGE_SIZE - len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 				 "SUPPORTED_POWER_MANAGEMENT\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 	if (dev->msi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 		len += scnprintf(buf + len, PAGE_SIZE - len, "PCI_HAS_MSI\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 	return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) static ssize_t aac_show_kernel_version(struct device *device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 				       struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 				       char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 	struct aac_dev *dev = (struct aac_dev*)class_to_shost(device)->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 	int len, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 	tmp = le32_to_cpu(dev->adapter_info.kernelrev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 	len = snprintf(buf, PAGE_SIZE, "%d.%d-%d[%d]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 	  tmp >> 24, (tmp >> 16) & 0xff, tmp & 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 	  le32_to_cpu(dev->adapter_info.kernelbuild));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 	return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) static ssize_t aac_show_monitor_version(struct device *device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 					struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 					char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 	struct aac_dev *dev = (struct aac_dev*)class_to_shost(device)->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 	int len, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 	tmp = le32_to_cpu(dev->adapter_info.monitorrev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 	len = snprintf(buf, PAGE_SIZE, "%d.%d-%d[%d]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 	  tmp >> 24, (tmp >> 16) & 0xff, tmp & 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 	  le32_to_cpu(dev->adapter_info.monitorbuild));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 	return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) static ssize_t aac_show_bios_version(struct device *device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 				     struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 				     char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 	struct aac_dev *dev = (struct aac_dev*)class_to_shost(device)->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 	int len, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 	tmp = le32_to_cpu(dev->adapter_info.biosrev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 	len = snprintf(buf, PAGE_SIZE, "%d.%d-%d[%d]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 	  tmp >> 24, (tmp >> 16) & 0xff, tmp & 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 	  le32_to_cpu(dev->adapter_info.biosbuild));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 	return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) static ssize_t aac_show_driver_version(struct device *device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 					struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 					char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 	return snprintf(buf, PAGE_SIZE, "%s\n", aac_driver_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) static ssize_t aac_show_serial_number(struct device *device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 			       struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) 	struct aac_dev *dev = (struct aac_dev*)class_to_shost(device)->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 	int len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 	if (le32_to_cpu(dev->adapter_info.serial[0]) != 0xBAD0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 		len = snprintf(buf, 16, "%06X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 		  le32_to_cpu(dev->adapter_info.serial[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 	if (len &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 	  !memcmp(&dev->supplement_adapter_info.mfg_pcba_serial_no[
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 	    sizeof(dev->supplement_adapter_info.mfg_pcba_serial_no)-len],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 	  buf, len-1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 		len = snprintf(buf, 16, "%.*s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 		  (int)sizeof(dev->supplement_adapter_info.mfg_pcba_serial_no),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 		  dev->supplement_adapter_info.mfg_pcba_serial_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 	return min(len, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) static ssize_t aac_show_max_channel(struct device *device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 				    struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 	return snprintf(buf, PAGE_SIZE, "%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 	  class_to_shost(device)->max_channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) static ssize_t aac_show_max_id(struct device *device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 			       struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 	return snprintf(buf, PAGE_SIZE, "%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 	  class_to_shost(device)->max_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) static ssize_t aac_store_reset_adapter(struct device *device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 				       struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 				       const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 	int retval = -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 	if (!capable(CAP_SYS_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 		return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 	retval = aac_reset_adapter(shost_priv(class_to_shost(device)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 					buf[0] == '!', IOP_HWSOFT_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 	if (retval >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 		retval = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 	return retval;
^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 ssize_t aac_show_reset_adapter(struct device *device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 				      struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 				      char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 	struct aac_dev *dev = (struct aac_dev*)class_to_shost(device)->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 	int len, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 	tmp = aac_adapter_check_health(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 	if ((tmp == 0) && dev->in_reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 		tmp = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 	len = snprintf(buf, PAGE_SIZE, "0x%x\n", tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 	return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) static struct device_attribute aac_model = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 	.attr = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 		.name = "model",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 		.mode = S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 	.show = aac_show_model,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) static struct device_attribute aac_vendor = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 	.attr = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 		.name = "vendor",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 		.mode = S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 	.show = aac_show_vendor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) static struct device_attribute aac_flags = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 	.attr = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 		.name = "flags",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 		.mode = S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 	.show = aac_show_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) static struct device_attribute aac_kernel_version = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 	.attr = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 		.name = "hba_kernel_version",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 		.mode = S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 	.show = aac_show_kernel_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) static struct device_attribute aac_monitor_version = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) 	.attr = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 		.name = "hba_monitor_version",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 		.mode = S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 	.show = aac_show_monitor_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) static struct device_attribute aac_bios_version = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 	.attr = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 		.name = "hba_bios_version",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 		.mode = S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 	.show = aac_show_bios_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) static struct device_attribute aac_lld_version = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 	.attr = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 		.name = "driver_version",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 		.mode = 0444,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 	.show = aac_show_driver_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) static struct device_attribute aac_serial_number = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) 	.attr = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 		.name = "serial_number",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 		.mode = S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 	.show = aac_show_serial_number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) static struct device_attribute aac_max_channel = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 	.attr = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 		.name = "max_channel",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 		.mode = S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 	.show = aac_show_max_channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) static struct device_attribute aac_max_id = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) 	.attr = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 		.name = "max_id",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 		.mode = S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) 	.show = aac_show_max_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) static struct device_attribute aac_reset = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 	.attr = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 		.name = "reset_host",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 		.mode = S_IWUSR|S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 	.store = aac_store_reset_adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 	.show = aac_show_reset_adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) static struct device_attribute *aac_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 	&aac_model,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) 	&aac_vendor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 	&aac_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 	&aac_kernel_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) 	&aac_monitor_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 	&aac_bios_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 	&aac_lld_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 	&aac_serial_number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 	&aac_max_channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 	&aac_max_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 	&aac_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 	NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) ssize_t aac_get_serial_number(struct device *device, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 	return aac_show_serial_number(device, &aac_serial_number, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) static const struct file_operations aac_cfg_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 	.owner		= THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 	.unlocked_ioctl	= aac_cfg_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 	.compat_ioctl   = aac_cfg_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 	.open		= aac_cfg_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 	.llseek		= noop_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) static struct scsi_host_template aac_driver_template = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) 	.module				= THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) 	.name				= "AAC",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) 	.proc_name			= AAC_DRIVERNAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) 	.info				= aac_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 	.ioctl				= aac_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 	.compat_ioctl			= aac_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 	.queuecommand			= aac_queuecommand,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 	.bios_param			= aac_biosparm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) 	.shost_attrs			= aac_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 	.slave_configure		= aac_slave_configure,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) 	.change_queue_depth		= aac_change_queue_depth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) 	.sdev_attrs			= aac_dev_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) 	.eh_abort_handler		= aac_eh_abort,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 	.eh_device_reset_handler	= aac_eh_dev_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 	.eh_target_reset_handler	= aac_eh_target_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 	.eh_bus_reset_handler		= aac_eh_bus_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) 	.eh_host_reset_handler		= aac_eh_host_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 	.can_queue			= AAC_NUM_IO_FIB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) 	.this_id			= MAXIMUM_NUM_CONTAINERS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 	.sg_tablesize			= 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) 	.max_sectors			= 128,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) #if (AAC_NUM_IO_FIB > 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) 	.cmd_per_lun			= 256,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) 	.cmd_per_lun			= AAC_NUM_IO_FIB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) 	.emulated			= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) 	.no_write_same			= 1,
^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) static void __aac_shutdown(struct aac_dev * aac)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 	mutex_lock(&aac->ioctl_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 	aac->adapter_shutdown = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) 	mutex_unlock(&aac->ioctl_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 	if (aac->aif_thread) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) 		int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) 		/* Clear out events first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 		for (i = 0; i < (aac->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 			struct fib *fib = &aac->fibs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 			if (!(fib->hw_fib_va->header.XferState & cpu_to_le32(NoResponseExpected | Async)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 			    (fib->hw_fib_va->header.XferState & cpu_to_le32(ResponseExpected)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 				complete(&fib->event_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) 		kthread_stop(aac->thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) 		aac->thread = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 	aac_send_shutdown(aac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) 	aac_adapter_disable_int(aac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 	if (aac_is_src(aac)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 		if (aac->max_msix > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 			for (i = 0; i < aac->max_msix; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 				free_irq(pci_irq_vector(aac->pdev, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) 					 &(aac->aac_msix[i]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 			free_irq(aac->pdev->irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 				 &(aac->aac_msix[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 		free_irq(aac->pdev->irq, aac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 	if (aac->msi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 		pci_disable_msi(aac->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) 	else if (aac->max_msix > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) 		pci_disable_msix(aac->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) static void aac_init_char(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 	aac_cfg_major = register_chrdev(0, "aac", &aac_cfg_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) 	if (aac_cfg_major < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) 		pr_err("aacraid: unable to register \"aac\" device.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) void aac_reinit_aif(struct aac_dev *aac, unsigned int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) 	 * Firmware may send a AIF messages very early and the Driver may have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) 	 * ignored as it is not fully ready to process the messages. Send
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) 	 * AIF to firmware so that if there are any unprocessed events they
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 	 * can be processed now.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 	if (aac_drivers[index].quirks & AAC_QUIRK_SRC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) 		aac_intr_normal(aac, 0, 2, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) 	unsigned index = id->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) 	struct Scsi_Host *shost;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) 	struct aac_dev *aac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) 	struct list_head *insert = &aac_devices;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 	int unique_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 	u64 dmamask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) 	int mask_bits = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 	extern int aac_sync_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 	 * Only series 7 needs freset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 	if (pdev->device == PMC_DEVICE_S7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 		pdev->needs_freset = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) 	list_for_each_entry(aac, &aac_devices, entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 		if (aac->id > unique_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 		insert = &aac->entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 		unique_id++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 	pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 			       PCIE_LINK_STATE_CLKPM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) 	error = pci_enable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) 	if (!(aac_drivers[index].quirks & AAC_QUIRK_SRC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) 		error = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) 		if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 			dev_err(&pdev->dev, "PCI 32 BIT dma mask set failed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 			goto out_disable_pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 	 * If the quirk31 bit is set, the adapter needs adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) 	 * to driver communication memory to be allocated below 2gig
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) 	if (aac_drivers[index].quirks & AAC_QUIRK_31BIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) 		dmamask = DMA_BIT_MASK(31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) 		mask_bits = 31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) 		dmamask = DMA_BIT_MASK(32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) 		mask_bits = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) 	error = dma_set_coherent_mask(&pdev->dev, dmamask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) 	if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) 		dev_err(&pdev->dev, "PCI %d B consistent dma mask set failed\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) 				, mask_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) 		goto out_disable_pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) 	pci_set_master(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) 	shost = scsi_host_alloc(&aac_driver_template, sizeof(struct aac_dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) 	if (!shost) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) 		error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) 		goto out_disable_pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) 	shost->irq = pdev->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) 	shost->unique_id = unique_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) 	shost->max_cmd_len = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) 	if (aac_cfg_major == AAC_CHARDEV_NEEDS_REINIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) 		aac_init_char();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) 	aac = (struct aac_dev *)shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) 	aac->base_start = pci_resource_start(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 	aac->scsi_host_ptr = shost;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) 	aac->pdev = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) 	aac->name = aac_driver_template.name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) 	aac->id = shost->unique_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) 	aac->cardtype = index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) 	INIT_LIST_HEAD(&aac->entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) 	if (aac_reset_devices || reset_devices)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) 		aac->init_reset = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) 	aac->fibs = kcalloc(shost->can_queue + AAC_NUM_MGT_FIB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) 			    sizeof(struct fib),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) 			    GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) 	if (!aac->fibs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) 		error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) 		goto out_free_host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) 	spin_lock_init(&aac->fib_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) 	mutex_init(&aac->ioctl_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) 	mutex_init(&aac->scan_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) 	INIT_DELAYED_WORK(&aac->safw_rescan_work, aac_safw_rescan_worker);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) 	INIT_DELAYED_WORK(&aac->src_reinit_aif_worker,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) 				aac_src_reinit_aif_worker);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) 	 *	Map in the registers from the adapter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) 	aac->base_size = AAC_MIN_FOOTPRINT_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) 	if ((*aac_drivers[index].init)(aac)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) 		error = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) 		goto out_unmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) 	if (aac->sync_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) 		if (aac_sync_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) 			printk(KERN_INFO "%s%d: Sync. mode enforced "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) 				"by driver parameter. This will cause "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) 				"a significant performance decrease!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) 				aac->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) 				aac->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) 			printk(KERN_INFO "%s%d: Async. mode not supported "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) 				"by current driver, sync. mode enforced."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) 				"\nPlease update driver to get full performance.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) 				aac->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) 				aac->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) 	 *	Start any kernel threads needed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) 	aac->thread = kthread_run(aac_command_thread, aac, AAC_DRIVERNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) 	if (IS_ERR(aac->thread)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) 		printk(KERN_ERR "aacraid: Unable to create command thread.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) 		error = PTR_ERR(aac->thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) 		aac->thread = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) 		goto out_deinit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) 	aac->maximum_num_channels = aac_drivers[index].channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) 	error = aac_get_adapter_info(aac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) 	if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) 		goto out_deinit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) 	 * Lets override negotiations and drop the maximum SG limit to 34
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) 	if ((aac_drivers[index].quirks & AAC_QUIRK_34SG) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) 			(shost->sg_tablesize > 34)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) 		shost->sg_tablesize = 34;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) 		shost->max_sectors = (shost->sg_tablesize * 8) + 112;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) 	if ((aac_drivers[index].quirks & AAC_QUIRK_17SG) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) 			(shost->sg_tablesize > 17)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) 		shost->sg_tablesize = 17;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) 		shost->max_sectors = (shost->sg_tablesize * 8) + 112;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) 	if (aac->adapter_info.options & AAC_OPT_NEW_COMM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) 		shost->max_segment_size = shost->max_sectors << 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) 		shost->max_segment_size = 65536;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) 	 * Firmware printf works only with older firmware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) 	if (aac_drivers[index].quirks & AAC_QUIRK_34SG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) 		aac->printf_enabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) 		aac->printf_enabled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) 	 * max channel will be the physical channels plus 1 virtual channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) 	 * all containers are on the virtual channel 0 (CONTAINER_CHANNEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) 	 * physical channels are address by their actual physical number+1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) 	if (aac->nondasd_support || expose_physicals || aac->jbod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) 		shost->max_channel = aac->maximum_num_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) 		shost->max_channel = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) 	aac_get_config_status(aac, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) 	aac_get_containers(aac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) 	list_add(&aac->entry, insert);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) 	shost->max_id = aac->maximum_num_containers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) 	if (shost->max_id < aac->maximum_num_physicals)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) 		shost->max_id = aac->maximum_num_physicals;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) 	if (shost->max_id < MAXIMUM_NUM_CONTAINERS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) 		shost->max_id = MAXIMUM_NUM_CONTAINERS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) 		shost->this_id = shost->max_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) 	if (!aac->sa_firmware && aac_drivers[index].quirks & AAC_QUIRK_SRC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) 		aac_intr_normal(aac, 0, 2, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) 	 * dmb - we may need to move the setting of these parms somewhere else once
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) 	 * we get a fib that can report the actual numbers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) 	shost->max_lun = AAC_MAX_LUN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) 	pci_set_drvdata(pdev, shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) 	error = scsi_add_host(shost, &pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) 		goto out_deinit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) 	aac_scan_host(aac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) 	pci_enable_pcie_error_reporting(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) 	pci_save_state(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786)  out_deinit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) 	__aac_shutdown(aac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788)  out_unmap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) 	aac_fib_map_free(aac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) 	if (aac->comm_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) 		dma_free_coherent(&aac->pdev->dev, aac->comm_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) 				  aac->comm_addr, aac->comm_phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) 	kfree(aac->queues);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) 	aac_adapter_ioremap(aac, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) 	kfree(aac->fibs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) 	kfree(aac->fsa_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797)  out_free_host:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) 	scsi_host_put(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799)  out_disable_pdev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) 	pci_disable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801)  out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) static void aac_release_resources(struct aac_dev *aac)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) 	aac_adapter_disable_int(aac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) 	aac_free_irq(aac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) static int aac_acquire_resources(struct aac_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) 	unsigned long status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) 	 *	First clear out all interrupts.  Then enable the one's that we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) 	 *	can handle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) 	while (!((status = src_readl(dev, MUnit.OMR)) & KERNEL_UP_AND_RUNNING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) 		|| status == 0xffffffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) 			msleep(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) 	aac_adapter_disable_int(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) 	aac_adapter_enable_int(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) 	if (aac_is_src(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) 		aac_define_int_mode(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) 	if (dev->msi_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) 		aac_src_access_devreg(dev, AAC_ENABLE_MSIX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) 	if (aac_acquire_irq(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) 		goto error_iounmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) 	aac_adapter_enable_int(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) 	/*max msix may change  after EEH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) 	 * Re-assign vectors to fibs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) 	aac_fib_vector_assign(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) 	if (!dev->sync_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) 		/* After EEH recovery or suspend resume, max_msix count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) 		 * may change, therefore updating in init as well.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) 		dev->init->r7.no_of_msix_vectors = cpu_to_le32(dev->max_msix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) 		aac_adapter_start(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) error_iounmap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) #if (defined(CONFIG_PM))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) static int aac_suspend(struct pci_dev *pdev, pm_message_t state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) 	struct Scsi_Host *shost = pci_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) 	struct aac_dev *aac = (struct aac_dev *)shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) 	scsi_host_block(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) 	aac_cancel_rescan_worker(aac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) 	aac_send_shutdown(aac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) 	aac_release_resources(aac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) 	pci_set_drvdata(pdev, shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) 	pci_save_state(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) 	pci_disable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) 	pci_set_power_state(pdev, pci_choose_state(pdev, state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) static int aac_resume(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) 	struct Scsi_Host *shost = pci_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) 	struct aac_dev *aac = (struct aac_dev *)shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) 	int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) 	pci_set_power_state(pdev, PCI_D0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) 	pci_enable_wake(pdev, PCI_D0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) 	pci_restore_state(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) 	r = pci_enable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) 	if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) 		goto fail_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) 	pci_set_master(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) 	if (aac_acquire_resources(aac))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) 		goto fail_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) 	* reset this flag to unblock ioctl() as it was set at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) 	* aac_send_shutdown() to block ioctls from upperlayer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) 	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) 	aac->adapter_shutdown = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) 	scsi_host_unblock(shost, SDEV_RUNNING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) fail_device:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) 	printk(KERN_INFO "%s%d: resume failed.\n", aac->name, aac->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) 	scsi_host_put(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) 	pci_disable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) 	return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) static void aac_shutdown(struct pci_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) 	struct Scsi_Host *shost = pci_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) 	scsi_host_block(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) 	__aac_shutdown((struct aac_dev *)shost->hostdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) static void aac_remove_one(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) 	struct Scsi_Host *shost = pci_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) 	struct aac_dev *aac = (struct aac_dev *)shost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) 	aac_cancel_rescan_worker(aac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) 	scsi_remove_host(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) 	__aac_shutdown(aac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) 	aac_fib_map_free(aac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) 	dma_free_coherent(&aac->pdev->dev, aac->comm_size, aac->comm_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) 			  aac->comm_phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) 	kfree(aac->queues);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) 	aac_adapter_ioremap(aac, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) 	kfree(aac->fibs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) 	kfree(aac->fsa_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) 	list_del(&aac->entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) 	scsi_host_put(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) 	pci_disable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) 	if (list_empty(&aac_devices)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) 		unregister_chrdev(aac_cfg_major, "aac");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) 		aac_cfg_major = AAC_CHARDEV_NEEDS_REINIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) static pci_ers_result_t aac_pci_error_detected(struct pci_dev *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) 					pci_channel_state_t error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) 	struct Scsi_Host *shost = pci_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) 	struct aac_dev *aac = shost_priv(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) 	dev_err(&pdev->dev, "aacraid: PCI error detected %x\n", error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) 	switch (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) 	case pci_channel_io_normal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) 		return PCI_ERS_RESULT_CAN_RECOVER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) 	case pci_channel_io_frozen:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) 		aac->handle_pci_error = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) 		scsi_host_block(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) 		aac_cancel_rescan_worker(aac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) 		scsi_host_complete_all_commands(shost, DID_NO_CONNECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) 		aac_release_resources(aac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) 		pci_disable_pcie_error_reporting(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) 		aac_adapter_ioremap(aac, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) 		return PCI_ERS_RESULT_NEED_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) 	case pci_channel_io_perm_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) 		aac->handle_pci_error = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) 		scsi_host_complete_all_commands(shost, DID_NO_CONNECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) 		return PCI_ERS_RESULT_DISCONNECT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) 	return PCI_ERS_RESULT_NEED_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) static pci_ers_result_t aac_pci_mmio_enabled(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) 	dev_err(&pdev->dev, "aacraid: PCI error - mmio enabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) 	return PCI_ERS_RESULT_NEED_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) static pci_ers_result_t aac_pci_slot_reset(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) 	dev_err(&pdev->dev, "aacraid: PCI error - slot reset\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) 	pci_restore_state(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) 	if (pci_enable_device(pdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) 		dev_warn(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) 			"aacraid: failed to enable slave\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) 		goto fail_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) 	pci_set_master(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) 	if (pci_enable_device_mem(pdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) 		dev_err(&pdev->dev, "pci_enable_device_mem failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) 		goto fail_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) 	return PCI_ERS_RESULT_RECOVERED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) fail_device:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) 	dev_err(&pdev->dev, "aacraid: PCI error - slot reset failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) 	return PCI_ERS_RESULT_DISCONNECT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) static void aac_pci_resume(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) 	struct Scsi_Host *shost = pci_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) 	struct aac_dev *aac = (struct aac_dev *)shost_priv(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) 	if (aac_adapter_ioremap(aac, aac->base_size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) 		dev_err(&pdev->dev, "aacraid: ioremap failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) 		/* remap failed, go back ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) 		aac->comm_interface = AAC_COMM_PRODUCER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) 		if (aac_adapter_ioremap(aac, AAC_MIN_FOOTPRINT_SIZE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) 			dev_warn(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) 				"aacraid: unable to map adapter.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) 	msleep(10000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) 	aac_acquire_resources(aac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) 	 * reset this flag to unblock ioctl() as it was set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) 	 * at aac_send_shutdown() to block ioctls from upperlayer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) 	aac->adapter_shutdown = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) 	aac->handle_pci_error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) 	scsi_host_unblock(shost, SDEV_RUNNING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) 	aac_scan_host(aac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) 	pci_save_state(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) 	dev_err(&pdev->dev, "aacraid: PCI error - resume\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) static struct pci_error_handlers aac_pci_err_handler = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) 	.error_detected		= aac_pci_error_detected,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) 	.mmio_enabled		= aac_pci_mmio_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) 	.slot_reset		= aac_pci_slot_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) 	.resume			= aac_pci_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) static struct pci_driver aac_pci_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) 	.name		= AAC_DRIVERNAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) 	.id_table	= aac_pci_tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) 	.probe		= aac_probe_one,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) 	.remove		= aac_remove_one,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) #if (defined(CONFIG_PM))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) 	.suspend	= aac_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) 	.resume		= aac_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) 	.shutdown	= aac_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) 	.err_handler    = &aac_pci_err_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) static int __init aac_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) 	printk(KERN_INFO "Adaptec %s driver %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) 	  AAC_DRIVERNAME, aac_driver_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) 	error = pci_register_driver(&aac_pci_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) 	if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) 	aac_init_char();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) static void __exit aac_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) 	if (aac_cfg_major > -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) 		unregister_chrdev(aac_cfg_major, "aac");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) 	pci_unregister_driver(&aac_pci_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) module_init(aac_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) module_exit(aac_exit);