^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* ips.c -- driver for the Adaptec / IBM ServeRAID controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) /* Written By: Keith Mitchell, IBM Corporation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) /* Jack Hammer, Adaptec, Inc. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) /* David Jeffery, Adaptec, Inc. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) /* Copyright (C) 2000 IBM Corporation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) /* Copyright (C) 2002,2003 Adaptec, Inc. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) /* This program is free software; you can redistribute it and/or modify */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) /* it under the terms of the GNU General Public License as published by */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) /* the Free Software Foundation; either version 2 of the License, or */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) /* (at your option) any later version. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) /* This program is distributed in the hope that it will be useful, */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) /* GNU General Public License for more details. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) /* NO WARRANTY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) /* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) /* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) /* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) /* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) /* solely responsible for determining the appropriateness of using and */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) /* distributing the Program and assumes all risks associated with its */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) /* exercise of rights under this Agreement, including but not limited to */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) /* the risks and costs of program errors, damage to or loss of data, */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) /* programs or equipment, and unavailability or interruption of operations. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) /* DISCLAIMER OF LIABILITY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) /* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) /* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) /* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) /* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) /* USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) /* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /* You should have received a copy of the GNU General Public License */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) /* along with this program; if not, write to the Free Software */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /* Bugs/Comments/Suggestions about this driver should be mailed to: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /* ipslinux@adaptec.com */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /* For system support issues, contact your local IBM Customer support. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) /* Directions to find IBM Customer Support for each country can be found at: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) /* http://www.ibm.com/planetwide/ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) /*****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) /*****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) /* Change Log */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /* 0.99.02 - Breakup commands that are bigger than 8 * the stripe size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) /* 0.99.03 - Make interrupt routine handle all completed request on the */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /* adapter not just the first one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) /* - Make sure passthru commands get woken up if we run out of */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) /* SCBs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) /* - Send all of the commands on the queue at once rather than */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) /* one at a time since the card will support it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) /* 0.99.04 - Fix race condition in the passthru mechanism -- this required */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /* the interface to the utilities to change */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /* - Fix error recovery code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /* 0.99.05 - Fix an oops when we get certain passthru commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) /* 1.00.00 - Initial Public Release */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) /* Functionally equivalent to 0.99.05 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) /* 3.60.00 - Bump max commands to 128 for use with firmware 3.60 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /* - Change version to 3.60 to coincide with release numbering. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) /* 3.60.01 - Remove bogus error check in passthru routine */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) /* 3.60.02 - Make DCDB direction based on lookup table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) /* - Only allow one DCDB command to a SCSI ID at a time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /* 4.00.00 - Add support for ServeRAID 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) /* 4.00.01 - Add support for First Failure Data Capture */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /* 4.00.02 - Fix problem with PT DCDB with no buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /* 4.00.03 - Add alternative passthru interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /* - Add ability to flash BIOS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) /* 4.00.04 - Rename structures/constants to be prefixed with IPS_ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) /* 4.00.05 - Remove wish_block from init routine */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) /* - Use linux/spinlock.h instead of asm/spinlock.h for kernels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) /* 2.3.18 and later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /* - Sync with other changes from the 2.3 kernels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) /* 4.00.06 - Fix timeout with initial FFDC command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) /* 4.00.06a - Port to 2.4 (trivial) -- Christoph Hellwig <hch@infradead.org> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /* 4.10.00 - Add support for ServeRAID 4M/4L */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) /* 4.10.13 - Fix for dynamic unload and proc file system */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) /* 4.20.03 - Rename version to coincide with new release schedules */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) /* Performance fixes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) /* Fix truncation of /proc files with cat */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) /* Merge in changes through kernel 2.4.0test1ac21 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) /* 4.20.13 - Fix some failure cases / reset code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /* - Hook into the reboot_notifier to flush the controller cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) /* 4.50.01 - Fix problem when there is a hole in logical drive numbering */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) /* 4.70.09 - Use a Common ( Large Buffer ) for Flashing from the JCRM CD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) /* - Add IPSSEND Flash Support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) /* - Set Sense Data for Unknown SCSI Command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) /* - Use Slot Number from NVRAM Page 5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) /* - Restore caller's DCDB Structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) /* 4.70.12 - Corrective actions for bad controller ( during initialization )*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /* 4.70.13 - Don't Send CDB's if we already know the device is not present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) /* - Don't release HA Lock in ips_next() until SC taken off queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /* - Unregister SCSI device in ips_release() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /* 4.70.15 - Fix Breakup for very large ( non-SG ) requests in ips_done() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /* 4.71.00 - Change all memory allocations to not use GFP_DMA flag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /* Code Clean-Up for 2.4.x kernel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) /* 4.72.00 - Allow for a Scatter-Gather Element to exceed MAX_XFER Size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) /* 4.72.01 - I/O Mapped Memory release ( so "insmod ips" does not Fail ) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /* - Don't Issue Internal FFDC Command if there are Active Commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) /* - Close Window for getting too many IOCTL's active */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /* 4.80.00 - Make ia64 Safe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /* 4.80.04 - Eliminate calls to strtok() if 2.4.x or greater */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /* - Adjustments to Device Queue Depth */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) /* 4.80.14 - Take all semaphores off stack */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) /* - Clean Up New_IOCTL path */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) /* 4.80.20 - Set max_sectors in Scsi_Host structure ( if >= 2.4.7 kernel ) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) /* - 5 second delay needed after resetting an i960 adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) /* 4.80.26 - Clean up potential code problems ( Arjan's recommendations ) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /* 4.90.01 - Version Matching for FirmWare, BIOS, and Driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) /* 4.90.05 - Use New PCI Architecture to facilitate Hot Plug Development */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) /* 4.90.08 - Increase Delays in Flashing ( Trombone Only - 4H ) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /* 4.90.08 - Data Corruption if First Scatter Gather Element is > 64K */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) /* 4.90.11 - Don't actually RESET unless it's physically required */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) /* - Remove unused compile options */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) /* 5.00.01 - Sarasota ( 5i ) adapters must always be scanned first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /* - Get rid on IOCTL_NEW_COMMAND code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /* - Add Extended DCDB Commands for Tape Support in 5I */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) /* 5.10.12 - use pci_dma interfaces, update for 2.5 kernel changes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /* 5.10.15 - remove unused code (sem, macros, etc.) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) /* 5.30.00 - use __devexit_p() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /* 6.00.00 - Add 6x Adapters and Battery Flash */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) /* 6.10.00 - Remove 1G Addressing Limitations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) /* 6.11.xx - Get VersionInfo buffer off the stack ! DDTS 60401 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) /* 6.11.xx - Make Logical Drive Info structure safe for DMA DDTS 60639 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) /* 7.10.18 - Add highmem_io flag in SCSI Templete for 2.4 kernels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) /* - Fix path/name for scsi_hosts.h include for 2.6 kernels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) /* - Fix sort order of 7k */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) /* - Remove 3 unused "inline" functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /* 7.12.xx - Use STATIC functions wherever possible */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) /* - Clean up deprecated MODULE_PARM calls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) /* 7.12.05 - Remove Version Matching per IBM request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) /*****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) * Conditional Compilation directives for this driver:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * IPS_DEBUG - Turn on debugging info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * Parameters:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * debug:<number> - Set debug level to <number>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * NOTE: only works when IPS_DEBUG compile directive is used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * 1 - Normal debug messages
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * 2 - Verbose debug messages
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * 11 - Method trace (non interrupt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * 12 - Method trace (includes interrupt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * noi2o - Don't use I2O Queues (ServeRAID 4 only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * nommap - Don't use memory mapped I/O
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * ioctlsize - Initial size of the IOCTL buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #include <asm/byteorder.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) #include <asm/page.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) #include <linux/stddef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) #include <linux/proc_fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) #include <linux/reboot.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) #include <linux/blkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) #include <scsi/sg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) #include "scsi.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) #include <scsi/scsi_host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) #include "ips.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) #include <linux/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) #include <linux/smp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) #ifdef MODULE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) static char *ips = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) module_param(ips, charp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * DRIVER_VER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) #define IPS_VERSION_HIGH IPS_VER_MAJOR_STRING "." IPS_VER_MINOR_STRING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) #define IPS_VERSION_LOW "." IPS_VER_BUILD_STRING " "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) #define IPS_DMA_DIR(scb) ((!scb->scsi_cmd || ips_is_passthru(scb->scsi_cmd) || \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) DMA_NONE == scb->scsi_cmd->sc_data_direction) ? \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) DMA_BIDIRECTIONAL : \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) scb->scsi_cmd->sc_data_direction)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) #ifdef IPS_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) #define METHOD_TRACE(s, i) if (ips_debug >= (i+10)) printk(KERN_NOTICE s "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) #define DEBUG(i, s) if (ips_debug >= i) printk(KERN_NOTICE s "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) #define DEBUG_VAR(i, s, v...) if (ips_debug >= i) printk(KERN_NOTICE s "\n", v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) #define METHOD_TRACE(s, i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) #define DEBUG(i, s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) #define DEBUG_VAR(i, s, v...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) * Function prototypes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) static int ips_eh_abort(struct scsi_cmnd *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) static int ips_eh_reset(struct scsi_cmnd *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) static int ips_queue(struct Scsi_Host *, struct scsi_cmnd *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) static const char *ips_info(struct Scsi_Host *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) static irqreturn_t do_ipsintr(int, void *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) static int ips_hainit(ips_ha_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) static int ips_map_status(ips_ha_t *, ips_scb_t *, ips_stat_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) static int ips_send_wait(ips_ha_t *, ips_scb_t *, int, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) static int ips_send_cmd(ips_ha_t *, ips_scb_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static int ips_online(ips_ha_t *, ips_scb_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) static int ips_inquiry(ips_ha_t *, ips_scb_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) static int ips_rdcap(ips_ha_t *, ips_scb_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) static int ips_msense(ips_ha_t *, ips_scb_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) static int ips_reqsen(ips_ha_t *, ips_scb_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) static int ips_deallocatescbs(ips_ha_t *, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) static int ips_allocatescbs(ips_ha_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) static int ips_reset_copperhead(ips_ha_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) static int ips_reset_copperhead_memio(ips_ha_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) static int ips_reset_morpheus(ips_ha_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) static int ips_issue_copperhead(ips_ha_t *, ips_scb_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) static int ips_issue_copperhead_memio(ips_ha_t *, ips_scb_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static int ips_issue_i2o(ips_ha_t *, ips_scb_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) static int ips_issue_i2o_memio(ips_ha_t *, ips_scb_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) static int ips_isintr_copperhead(ips_ha_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) static int ips_isintr_copperhead_memio(ips_ha_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) static int ips_isintr_morpheus(ips_ha_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) static int ips_wait(ips_ha_t *, int, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) static int ips_write_driver_status(ips_ha_t *, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) static int ips_read_adapter_status(ips_ha_t *, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) static int ips_read_subsystem_parameters(ips_ha_t *, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) static int ips_read_config(ips_ha_t *, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) static int ips_clear_adapter(ips_ha_t *, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) static int ips_readwrite_page5(ips_ha_t *, int, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) static int ips_init_copperhead(ips_ha_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) static int ips_init_copperhead_memio(ips_ha_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) static int ips_init_morpheus(ips_ha_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) static int ips_isinit_copperhead(ips_ha_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) static int ips_isinit_copperhead_memio(ips_ha_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) static int ips_isinit_morpheus(ips_ha_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) static int ips_erase_bios(ips_ha_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) static int ips_program_bios(ips_ha_t *, char *, uint32_t, uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) static int ips_verify_bios(ips_ha_t *, char *, uint32_t, uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) static int ips_erase_bios_memio(ips_ha_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) static int ips_program_bios_memio(ips_ha_t *, char *, uint32_t, uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) static int ips_verify_bios_memio(ips_ha_t *, char *, uint32_t, uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) static int ips_flash_copperhead(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) static int ips_flash_bios(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) static int ips_flash_firmware(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) static void ips_free_flash_copperhead(ips_ha_t * ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) static void ips_get_bios_version(ips_ha_t *, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) static void ips_identify_controller(ips_ha_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) static void ips_chkstatus(ips_ha_t *, IPS_STATUS *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) static void ips_enable_int_copperhead(ips_ha_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) static void ips_enable_int_copperhead_memio(ips_ha_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) static void ips_enable_int_morpheus(ips_ha_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) static int ips_intr_copperhead(ips_ha_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) static int ips_intr_morpheus(ips_ha_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) static void ips_next(ips_ha_t *, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) static void ipsintr_blocking(ips_ha_t *, struct ips_scb *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) static void ipsintr_done(ips_ha_t *, struct ips_scb *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) static void ips_done(ips_ha_t *, ips_scb_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) static void ips_free(ips_ha_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) static void ips_init_scb(ips_ha_t *, ips_scb_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) static void ips_freescb(ips_ha_t *, ips_scb_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) static void ips_setup_funclist(ips_ha_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) static void ips_statinit(ips_ha_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) static void ips_statinit_memio(ips_ha_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) static void ips_fix_ffdc_time(ips_ha_t *, ips_scb_t *, time64_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) static void ips_ffdc_reset(ips_ha_t *, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) static void ips_ffdc_time(ips_ha_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) static uint32_t ips_statupd_copperhead(ips_ha_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) static uint32_t ips_statupd_copperhead_memio(ips_ha_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) static uint32_t ips_statupd_morpheus(ips_ha_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) static ips_scb_t *ips_getscb(ips_ha_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) static void ips_putq_scb_head(ips_scb_queue_t *, ips_scb_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) static void ips_putq_wait_tail(ips_wait_queue_entry_t *, struct scsi_cmnd *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) static void ips_putq_copp_tail(ips_copp_queue_t *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) ips_copp_wait_item_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) static ips_scb_t *ips_removeq_scb_head(ips_scb_queue_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) static ips_scb_t *ips_removeq_scb(ips_scb_queue_t *, ips_scb_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) static struct scsi_cmnd *ips_removeq_wait_head(ips_wait_queue_entry_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) static struct scsi_cmnd *ips_removeq_wait(ips_wait_queue_entry_t *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) struct scsi_cmnd *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) static ips_copp_wait_item_t *ips_removeq_copp(ips_copp_queue_t *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) ips_copp_wait_item_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) static ips_copp_wait_item_t *ips_removeq_copp_head(ips_copp_queue_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) static int ips_is_passthru(struct scsi_cmnd *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) static int ips_make_passthru(ips_ha_t *, struct scsi_cmnd *, ips_scb_t *, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) static int ips_usrcmd(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) static void ips_cleanup_passthru(ips_ha_t *, ips_scb_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) static void ips_scmd_buf_write(struct scsi_cmnd * scmd, void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) unsigned int count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) static void ips_scmd_buf_read(struct scsi_cmnd * scmd, void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) unsigned int count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) static int ips_write_info(struct Scsi_Host *, char *, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) static int ips_show_info(struct seq_file *, struct Scsi_Host *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) static int ips_host_info(ips_ha_t *, struct seq_file *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) static int ips_abort_init(ips_ha_t * ha, int index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) static int ips_init_phase2(int index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) static int ips_init_phase1(struct pci_dev *pci_dev, int *indexPtr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) static int ips_register_scsi(int index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) static int ips_poll_for_flush_complete(ips_ha_t * ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) static void ips_flush_and_reset(ips_ha_t *ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) * global variables
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) static const char ips_name[] = "ips";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) static struct Scsi_Host *ips_sh[IPS_MAX_ADAPTERS]; /* Array of host controller structures */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) static ips_ha_t *ips_ha[IPS_MAX_ADAPTERS]; /* Array of HA structures */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) static unsigned int ips_next_controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) static unsigned int ips_num_controllers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) static unsigned int ips_released_controllers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) static int ips_hotplug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) static int ips_cmd_timeout = 60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) static int ips_reset_timeout = 60 * 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) static int ips_force_memio = 1; /* Always use Memory Mapped I/O */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) static int ips_force_i2o = 1; /* Always use I2O command delivery */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) static int ips_ioctlsize = IPS_IOCTL_SIZE; /* Size of the ioctl buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) static int ips_cd_boot; /* Booting from Manager CD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) static char *ips_FlashData = NULL; /* CD Boot - Flash Data Buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) static dma_addr_t ips_flashbusaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) static long ips_FlashDataInUse; /* CD Boot - Flash Data In Use Flag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) static uint32_t MaxLiteCmds = 32; /* Max Active Cmds for a Lite Adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) static struct scsi_host_template ips_driver_template = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) .info = ips_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) .queuecommand = ips_queue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) .eh_abort_handler = ips_eh_abort,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) .eh_host_reset_handler = ips_eh_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) .proc_name = "ips",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) .show_info = ips_show_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) .write_info = ips_write_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) .slave_configure = ips_slave_configure,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) .bios_param = ips_biosparam,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) .this_id = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) .sg_tablesize = IPS_MAX_SG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) .cmd_per_lun = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) .no_write_same = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) /* This table describes all ServeRAID Adapters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) static struct pci_device_id ips_pci_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) { 0x1014, 0x002E, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) { 0x1014, 0x01BD, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) { 0x9005, 0x0250, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) { 0, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) MODULE_DEVICE_TABLE( pci, ips_pci_table );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) static char ips_hot_plug_name[] = "ips";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) static int ips_insert_device(struct pci_dev *pci_dev, const struct pci_device_id *ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) static void ips_remove_device(struct pci_dev *pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) static struct pci_driver ips_pci_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) .name = ips_hot_plug_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) .id_table = ips_pci_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) .probe = ips_insert_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) .remove = ips_remove_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) * Necessary forward function protoypes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) static int ips_halt(struct notifier_block *nb, ulong event, void *buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) #define MAX_ADAPTER_NAME 15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) static char ips_adapter_name[][30] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) "ServeRAID",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) "ServeRAID II",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) "ServeRAID on motherboard",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) "ServeRAID on motherboard",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) "ServeRAID 3H",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) "ServeRAID 3L",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) "ServeRAID 4H",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) "ServeRAID 4M",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) "ServeRAID 4L",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) "ServeRAID 4Mx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) "ServeRAID 4Lx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) "ServeRAID 5i",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) "ServeRAID 5i",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) "ServeRAID 6M",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) "ServeRAID 6i",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) "ServeRAID 7t",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) "ServeRAID 7k",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) "ServeRAID 7M"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) static struct notifier_block ips_notifier = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) ips_halt, NULL, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) * Direction table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) static char ips_command_direction[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_IN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) IPS_DATA_UNK, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_UNK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) IPS_DATA_UNK, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_UNK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) IPS_DATA_NONE, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_IN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^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) /* Routine Name: ips_setup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) /* setup parameters to the driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) ips_setup(char *ips_str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) char *key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) char *value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) static const IPS_OPTION options[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) {"noi2o", &ips_force_i2o, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) {"nommap", &ips_force_memio, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) {"ioctlsize", &ips_ioctlsize, IPS_IOCTL_SIZE},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) {"cdboot", &ips_cd_boot, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) {"maxcmds", &MaxLiteCmds, 32},
^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) /* Don't use strtok() anymore ( if 2.4 Kernel or beyond ) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) /* Search for value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) while ((key = strsep(&ips_str, ",."))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) if (!*key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) value = strchr(key, ':');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) if (value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) *value++ = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) * We now have key/value pairs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) * Update the variables
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) for (i = 0; i < ARRAY_SIZE(options); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) if (strncasecmp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) (key, options[i].option_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) strlen(options[i].option_name)) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) if (value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) *options[i].option_flag =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) simple_strtoul(value, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) *options[i].option_flag =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) options[i].option_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) __setup("ips=", ips_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) /* Routine Name: ips_detect */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) /* Detect and initialize the driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) /* NOTE: this routine is called under the io_request_lock spinlock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) ips_detect(struct scsi_host_template * SHT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) METHOD_TRACE("ips_detect", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) #ifdef MODULE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) if (ips)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) ips_setup(ips);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) for (i = 0; i < ips_num_controllers; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) if (ips_register_scsi(i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) ips_free(ips_ha[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) ips_released_controllers++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) ips_hotplug = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) return (ips_num_controllers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) /* configure the function pointers to use the functions that will work */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) /* with the found version of the adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) ips_setup_funclist(ips_ha_t * ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) * Setup Functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) if (IPS_IS_MORPHEUS(ha) || IPS_IS_MARCO(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) /* morpheus / marco / sebring */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) ha->func.isintr = ips_isintr_morpheus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) ha->func.isinit = ips_isinit_morpheus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) ha->func.issue = ips_issue_i2o_memio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) ha->func.init = ips_init_morpheus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) ha->func.statupd = ips_statupd_morpheus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) ha->func.reset = ips_reset_morpheus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) ha->func.intr = ips_intr_morpheus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) ha->func.enableint = ips_enable_int_morpheus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) } else if (IPS_USE_MEMIO(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) /* copperhead w/MEMIO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) ha->func.isintr = ips_isintr_copperhead_memio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) ha->func.isinit = ips_isinit_copperhead_memio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) ha->func.init = ips_init_copperhead_memio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) ha->func.statupd = ips_statupd_copperhead_memio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) ha->func.statinit = ips_statinit_memio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) ha->func.reset = ips_reset_copperhead_memio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) ha->func.intr = ips_intr_copperhead;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) ha->func.erasebios = ips_erase_bios_memio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) ha->func.programbios = ips_program_bios_memio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) ha->func.verifybios = ips_verify_bios_memio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) ha->func.enableint = ips_enable_int_copperhead_memio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) if (IPS_USE_I2O_DELIVER(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) ha->func.issue = ips_issue_i2o_memio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) ha->func.issue = ips_issue_copperhead_memio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) /* copperhead */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) ha->func.isintr = ips_isintr_copperhead;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) ha->func.isinit = ips_isinit_copperhead;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) ha->func.init = ips_init_copperhead;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) ha->func.statupd = ips_statupd_copperhead;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) ha->func.statinit = ips_statinit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) ha->func.reset = ips_reset_copperhead;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) ha->func.intr = ips_intr_copperhead;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) ha->func.erasebios = ips_erase_bios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) ha->func.programbios = ips_program_bios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) ha->func.verifybios = ips_verify_bios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) ha->func.enableint = ips_enable_int_copperhead;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) if (IPS_USE_I2O_DELIVER(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) ha->func.issue = ips_issue_i2o;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) ha->func.issue = ips_issue_copperhead;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) /* Routine Name: ips_release */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) /* Remove a driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) ips_release(struct Scsi_Host *sh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) ips_scb_t *scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) ips_ha_t *ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) METHOD_TRACE("ips_release", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) scsi_remove_host(sh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) for (i = 0; i < IPS_MAX_ADAPTERS && ips_sh[i] != sh; i++) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) if (i == IPS_MAX_ADAPTERS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) "(%s) release, invalid Scsi_Host pointer.\n", ips_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) return (FALSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) ha = IPS_HA(sh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) if (!ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) return (FALSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) /* flush the cache on the controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) scb = &ha->scbs[ha->max_cmds - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) ips_init_scb(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) scb->timeout = ips_cmd_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) scb->cdb[0] = IPS_CMD_FLUSH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) scb->cmd.flush_cache.command_id = IPS_COMMAND_ID(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) scb->cmd.flush_cache.state = IPS_NORM_STATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) scb->cmd.flush_cache.reserved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) scb->cmd.flush_cache.reserved2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) scb->cmd.flush_cache.reserved3 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) scb->cmd.flush_cache.reserved4 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) IPS_PRINTK(KERN_WARNING, ha->pcidev, "Flushing Cache.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) /* send command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) if (ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_ON) == IPS_FAILURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) IPS_PRINTK(KERN_WARNING, ha->pcidev, "Incomplete Flush.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) IPS_PRINTK(KERN_WARNING, ha->pcidev, "Flushing Complete.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) ips_sh[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) ips_ha[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) /* free extra memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) ips_free(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) /* free IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) free_irq(ha->pcidev->irq, ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) scsi_host_put(sh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) ips_released_controllers++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) return (FALSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) /* Routine Name: ips_halt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) /* Perform cleanup when the system reboots */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) ips_halt(struct notifier_block *nb, ulong event, void *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) ips_scb_t *scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) ips_ha_t *ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) if ((event != SYS_RESTART) && (event != SYS_HALT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) (event != SYS_POWER_OFF))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) return (NOTIFY_DONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) for (i = 0; i < ips_next_controller; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) ha = (ips_ha_t *) ips_ha[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) if (!ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) if (!ha->active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) /* flush the cache on the controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) scb = &ha->scbs[ha->max_cmds - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) ips_init_scb(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) scb->timeout = ips_cmd_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) scb->cdb[0] = IPS_CMD_FLUSH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) scb->cmd.flush_cache.command_id = IPS_COMMAND_ID(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) scb->cmd.flush_cache.state = IPS_NORM_STATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) scb->cmd.flush_cache.reserved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) scb->cmd.flush_cache.reserved2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) scb->cmd.flush_cache.reserved3 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) scb->cmd.flush_cache.reserved4 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) IPS_PRINTK(KERN_WARNING, ha->pcidev, "Flushing Cache.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) /* send command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) if (ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_ON) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) IPS_FAILURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) IPS_PRINTK(KERN_WARNING, ha->pcidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) "Incomplete Flush.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) IPS_PRINTK(KERN_WARNING, ha->pcidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) "Flushing Complete.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) return (NOTIFY_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) /* Routine Name: ips_eh_abort */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) /* Abort a command (using the new error code stuff) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) /* Note: this routine is called under the io_request_lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) int ips_eh_abort(struct scsi_cmnd *SC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) ips_ha_t *ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) ips_copp_wait_item_t *item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) struct Scsi_Host *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) METHOD_TRACE("ips_eh_abort", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) if (!SC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) return (FAILED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) host = SC->device->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) ha = (ips_ha_t *) SC->device->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) if (!ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) return (FAILED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) if (!ha->active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) return (FAILED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) spin_lock(host->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) /* See if the command is on the copp queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) item = ha->copp_waitlist.head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) while ((item) && (item->scsi_cmd != SC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) item = item->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) if (item) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) /* Found it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) ips_removeq_copp(&ha->copp_waitlist, item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) ret = (SUCCESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) /* See if the command is on the wait queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) } else if (ips_removeq_wait(&ha->scb_waitlist, SC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) /* command not sent yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) ret = (SUCCESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) /* command must have already been sent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) ret = (FAILED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) spin_unlock(host->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) return ret;
^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) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) /* Routine Name: ips_eh_reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) /* Reset the controller (with new eh error code) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) /* NOTE: this routine is called under the io_request_lock spinlock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) static int __ips_eh_reset(struct scsi_cmnd *SC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) ips_ha_t *ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) ips_scb_t *scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) ips_copp_wait_item_t *item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) METHOD_TRACE("ips_eh_reset", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) #ifdef NO_IPS_RESET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) return (FAILED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) if (!SC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) DEBUG(1, "Reset called with NULL scsi command");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) return (FAILED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) ha = (ips_ha_t *) SC->device->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) if (!ha) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) DEBUG(1, "Reset called with NULL ha struct");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) return (FAILED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) if (!ha->active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) return (FAILED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) /* See if the command is on the copp queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) item = ha->copp_waitlist.head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) while ((item) && (item->scsi_cmd != SC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) item = item->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) if (item) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) /* Found it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) ips_removeq_copp(&ha->copp_waitlist, item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) return (SUCCESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) /* See if the command is on the wait queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) if (ips_removeq_wait(&ha->scb_waitlist, SC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) /* command not sent yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) return (SUCCESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) /* An explanation for the casual observer: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) /* Part of the function of a RAID controller is automatic error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) /* detection and recovery. As such, the only problem that physically */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) /* resetting an adapter will ever fix is when, for some reason, */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) /* the driver is not successfully communicating with the adapter. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) /* Therefore, we will attempt to flush this adapter. If that succeeds, */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) /* then there's no real purpose in a physical reset. This will complete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) /* much faster and avoids any problems that might be caused by a */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) /* physical reset ( such as having to fail all the outstanding I/O's ). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) if (ha->ioctl_reset == 0) { /* IF Not an IOCTL Requested Reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) scb = &ha->scbs[ha->max_cmds - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) ips_init_scb(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) scb->timeout = ips_cmd_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) scb->cdb[0] = IPS_CMD_FLUSH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) scb->cmd.flush_cache.command_id = IPS_COMMAND_ID(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) scb->cmd.flush_cache.state = IPS_NORM_STATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) scb->cmd.flush_cache.reserved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) scb->cmd.flush_cache.reserved2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) scb->cmd.flush_cache.reserved3 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) scb->cmd.flush_cache.reserved4 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) /* Attempt the flush command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) ret = ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_IORL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) if (ret == IPS_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) IPS_PRINTK(KERN_NOTICE, ha->pcidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) "Reset Request - Flushed Cache\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) return (SUCCESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) /* Either we can't communicate with the adapter or it's an IOCTL request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) /* from a utility. A physical reset is needed at this point. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) ha->ioctl_reset = 0; /* Reset the IOCTL Requested Reset Flag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) * command must have already been sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) * reset the controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) IPS_PRINTK(KERN_NOTICE, ha->pcidev, "Resetting controller.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) ret = (*ha->func.reset) (ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) struct scsi_cmnd *scsi_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) IPS_PRINTK(KERN_NOTICE, ha->pcidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) "Controller reset failed - controller now offline.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) /* Now fail all of the active commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) DEBUG_VAR(1, "(%s%d) Failing active commands",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) ips_name, ha->host_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) scb->scsi_cmd->result = DID_ERROR << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) scb->scsi_cmd->scsi_done(scb->scsi_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) ips_freescb(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) /* Now fail all of the pending commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) DEBUG_VAR(1, "(%s%d) Failing pending commands",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) ips_name, ha->host_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) while ((scsi_cmd = ips_removeq_wait_head(&ha->scb_waitlist))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) scsi_cmd->result = DID_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) scsi_cmd->scsi_done(scsi_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) ha->active = FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) return (FAILED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) if (!ips_clear_adapter(ha, IPS_INTR_IORL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) struct scsi_cmnd *scsi_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) IPS_PRINTK(KERN_NOTICE, ha->pcidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) "Controller reset failed - controller now offline.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) /* Now fail all of the active commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) DEBUG_VAR(1, "(%s%d) Failing active commands",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) ips_name, ha->host_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) scb->scsi_cmd->result = DID_ERROR << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) scb->scsi_cmd->scsi_done(scb->scsi_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) ips_freescb(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) /* Now fail all of the pending commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) DEBUG_VAR(1, "(%s%d) Failing pending commands",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) ips_name, ha->host_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) while ((scsi_cmd = ips_removeq_wait_head(&ha->scb_waitlist))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) scsi_cmd->result = DID_ERROR << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) scsi_cmd->scsi_done(scsi_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) ha->active = FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) return (FAILED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) /* FFDC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) if (le32_to_cpu(ha->subsys->param[3]) & 0x300000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) ha->last_ffdc = ktime_get_real_seconds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) ha->reset_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) ips_ffdc_reset(ha, IPS_INTR_IORL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) /* Now fail all of the active commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) DEBUG_VAR(1, "(%s%d) Failing active commands", ips_name, ha->host_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) scb->scsi_cmd->result = DID_RESET << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) scb->scsi_cmd->scsi_done(scb->scsi_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) ips_freescb(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) /* Reset DCDB active command bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) for (i = 1; i < ha->nbus; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) ha->dcdb_active[i - 1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) /* Reset the number of active IOCTLs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) ha->num_ioctl = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) ips_next(ha, IPS_INTR_IORL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) return (SUCCESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) #endif /* NO_IPS_RESET */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) static int ips_eh_reset(struct scsi_cmnd *SC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) spin_lock_irq(SC->device->host->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) rc = __ips_eh_reset(SC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) spin_unlock_irq(SC->device->host->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) /* Routine Name: ips_queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) /* Send a command to the controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) /* NOTE: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) /* Linux obtains io_request_lock before calling this function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) static int ips_queue_lck(struct scsi_cmnd *SC, void (*done) (struct scsi_cmnd *))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) ips_ha_t *ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) ips_passthru_t *pt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) METHOD_TRACE("ips_queue", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) ha = (ips_ha_t *) SC->device->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) if (!ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) if (!ha->active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) return (DID_ERROR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) if (ips_is_passthru(SC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) if (ha->copp_waitlist.count == IPS_MAX_IOCTL_QUEUE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) SC->result = DID_BUS_BUSY << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) done(SC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) } else if (ha->scb_waitlist.count == IPS_MAX_QUEUE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) SC->result = DID_BUS_BUSY << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) done(SC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) return (0);
^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) SC->scsi_done = done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) DEBUG_VAR(2, "(%s%d): ips_queue: cmd 0x%X (%d %d %d)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) ips_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) ha->host_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) SC->cmnd[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) SC->device->channel, SC->device->id, SC->device->lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) /* Check for command to initiator IDs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) if ((scmd_channel(SC) > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) && (scmd_id(SC) == ha->ha_id[scmd_channel(SC)])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) SC->result = DID_NO_CONNECT << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) done(SC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) if (ips_is_passthru(SC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) ips_copp_wait_item_t *scratch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) /* A Reset IOCTL is only sent by the boot CD in extreme cases. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) /* There can never be any system activity ( network or disk ), but check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) /* anyway just as a good practice. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) pt = (ips_passthru_t *) scsi_sglist(SC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) if ((pt->CoppCP.cmd.reset.op_code == IPS_CMD_RESET_CHANNEL) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) (pt->CoppCP.cmd.reset.adapter_flag == 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) if (ha->scb_activelist.count != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) SC->result = DID_BUS_BUSY << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) done(SC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) ha->ioctl_reset = 1; /* This reset request is from an IOCTL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) __ips_eh_reset(SC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) SC->result = DID_OK << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) SC->scsi_done(SC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) /* allocate space for the scribble */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) scratch = kmalloc(sizeof (ips_copp_wait_item_t), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) if (!scratch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) SC->result = DID_ERROR << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) done(SC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) scratch->scsi_cmd = SC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) scratch->next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) ips_putq_copp_tail(&ha->copp_waitlist, scratch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) ips_putq_wait_tail(&ha->scb_waitlist, SC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) ips_next(ha, IPS_INTR_IORL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) static DEF_SCSI_QCMD(ips_queue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) /* Routine Name: ips_biosparam */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) /* Set bios geometry for the controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) static int ips_biosparam(struct scsi_device *sdev, struct block_device *bdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) sector_t capacity, int geom[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) ips_ha_t *ha = (ips_ha_t *) sdev->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) int heads;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) int sectors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) int cylinders;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) METHOD_TRACE("ips_biosparam", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) if (!ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) /* ?!?! host adater info invalid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) if (!ha->active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) if (!ips_read_adapter_status(ha, IPS_INTR_ON))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) /* ?!?! Enquiry command failed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) if ((capacity > 0x400000) && ((ha->enq->ucMiscFlag & 0x8) == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) heads = IPS_NORM_HEADS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) sectors = IPS_NORM_SECTORS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) heads = IPS_COMP_HEADS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) sectors = IPS_COMP_SECTORS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) cylinders = (unsigned long) capacity / (heads * sectors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) DEBUG_VAR(2, "Geometry: heads: %d, sectors: %d, cylinders: %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) heads, sectors, cylinders);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) geom[0] = heads;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) geom[1] = sectors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) geom[2] = cylinders;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) /* Routine Name: ips_slave_configure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) /* Set queue depths on devices once scan is complete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) ips_slave_configure(struct scsi_device * SDptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) ips_ha_t *ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) int min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) ha = IPS_HA(SDptr->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) if (SDptr->tagged_supported && SDptr->type == TYPE_DISK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) min = ha->max_cmds / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) if (ha->enq->ucLogDriveCount <= 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) min = ha->max_cmds - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) scsi_change_queue_depth(SDptr, min);
^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) SDptr->skip_ms_page_8 = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) SDptr->skip_ms_page_3f = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) /* Routine Name: do_ipsintr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) /* Wrapper for the interrupt handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) static irqreturn_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) do_ipsintr(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) ips_ha_t *ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) struct Scsi_Host *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) int irqstatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) METHOD_TRACE("do_ipsintr", 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) ha = (ips_ha_t *) dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) if (!ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) host = ips_sh[ha->host_num];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) /* interrupt during initialization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) if (!host) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) (*ha->func.intr) (ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) spin_lock(host->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) if (!ha->active) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) spin_unlock(host->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) irqstatus = (*ha->func.intr) (ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) spin_unlock(host->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) /* start the next command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) ips_next(ha, IPS_INTR_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) return IRQ_RETVAL(irqstatus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) /* Routine Name: ips_intr_copperhead */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) /* Polling interrupt handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) /* ASSUMES interrupts are disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) ips_intr_copperhead(ips_ha_t * ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) ips_stat_t *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) ips_scb_t *scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) IPS_STATUS cstatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) int intrstatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) METHOD_TRACE("ips_intr", 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) if (!ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) if (!ha->active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) intrstatus = (*ha->func.isintr) (ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) if (!intrstatus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) * Unexpected/Shared interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) while (TRUE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) sp = &ha->sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) intrstatus = (*ha->func.isintr) (ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) if (!intrstatus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) cstatus.value = (*ha->func.statupd) (ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) if (cstatus.fields.command_id > (IPS_MAX_CMDS - 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) /* Spurious Interrupt ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) ips_chkstatus(ha, &cstatus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) scb = (ips_scb_t *) sp->scb_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) * use the callback function to finish things up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) * NOTE: interrupts are OFF for this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) (*scb->callback) (ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) } /* end while */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) /* Routine Name: ips_intr_morpheus */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) /* Polling interrupt handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) /* ASSUMES interrupts are disabled */
^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) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) ips_intr_morpheus(ips_ha_t * ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) ips_stat_t *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) ips_scb_t *scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) IPS_STATUS cstatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) int intrstatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) METHOD_TRACE("ips_intr_morpheus", 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) if (!ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) if (!ha->active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) intrstatus = (*ha->func.isintr) (ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) if (!intrstatus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) * Unexpected/Shared interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) while (TRUE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) sp = &ha->sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) intrstatus = (*ha->func.isintr) (ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) if (!intrstatus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) cstatus.value = (*ha->func.statupd) (ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) if (cstatus.value == 0xffffffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) /* No more to process */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) if (cstatus.fields.command_id > (IPS_MAX_CMDS - 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) IPS_PRINTK(KERN_WARNING, ha->pcidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) "Spurious interrupt; no ccb.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) ips_chkstatus(ha, &cstatus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) scb = (ips_scb_t *) sp->scb_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) * use the callback function to finish things up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) * NOTE: interrupts are OFF for this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) (*scb->callback) (ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) } /* end while */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) /* Routine Name: ips_info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) /* Return info about the driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) static const char *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) ips_info(struct Scsi_Host *SH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) static char buffer[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) char *bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) ips_ha_t *ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) METHOD_TRACE("ips_info", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) ha = IPS_HA(SH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) if (!ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) return (NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) bp = &buffer[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) memset(bp, 0, sizeof (buffer));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) sprintf(bp, "%s%s%s Build %d", "IBM PCI ServeRAID ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) IPS_VERSION_HIGH, IPS_VERSION_LOW, IPS_BUILD_IDENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) if (ha->ad_type > 0 && ha->ad_type <= MAX_ADAPTER_NAME) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) strcat(bp, " <");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) strcat(bp, ips_adapter_name[ha->ad_type - 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) strcat(bp, ">");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) return (bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) ips_write_info(struct Scsi_Host *host, char *buffer, int length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) ips_ha_t *ha = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) /* Find our host structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) for (i = 0; i < ips_next_controller; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) if (ips_sh[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) if (ips_sh[i] == host) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) ha = (ips_ha_t *) ips_sh[i]->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) if (!ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) return (-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) ips_show_info(struct seq_file *m, struct Scsi_Host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) ips_ha_t *ha = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) /* Find our host structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) for (i = 0; i < ips_next_controller; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) if (ips_sh[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) if (ips_sh[i] == host) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) ha = (ips_ha_t *) ips_sh[i]->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) if (!ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) return (-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) return ips_host_info(ha, m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) /*--------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) /* Helper Functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) /*--------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472)
^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) /* Routine Name: ips_is_passthru */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) /* Determine if the specified SCSI command is really a passthru command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) static int ips_is_passthru(struct scsi_cmnd *SC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) METHOD_TRACE("ips_is_passthru", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) if (!SC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) if ((SC->cmnd[0] == IPS_IOCTL_COMMAND) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) (SC->device->channel == 0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) (SC->device->id == IPS_ADAPTER_ID) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) (SC->device->lun == 0) && scsi_sglist(SC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) struct scatterlist *sg = scsi_sglist(SC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) char *buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) /* kmap_atomic() ensures addressability of the user buffer.*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) /* local_irq_save() protects the KM_IRQ0 address slot. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) buffer = kmap_atomic(sg_page(sg)) + sg->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) if (buffer && buffer[0] == 'C' && buffer[1] == 'O' &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) buffer[2] == 'P' && buffer[3] == 'P') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) kunmap_atomic(buffer - sg->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) kunmap_atomic(buffer - sg->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) /* Routine Name: ips_alloc_passthru_buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) /* allocate a buffer large enough for the ioctl data if the ioctl buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) /* is too small or doesn't exist */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) ips_alloc_passthru_buffer(ips_ha_t * ha, int length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) void *bigger_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) dma_addr_t dma_busaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) if (ha->ioctl_data && length <= ha->ioctl_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) /* there is no buffer or it's not big enough, allocate a new one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) bigger_buf = dma_alloc_coherent(&ha->pcidev->dev, length, &dma_busaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) if (bigger_buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) /* free the old memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) dma_free_coherent(&ha->pcidev->dev, ha->ioctl_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) ha->ioctl_data, ha->ioctl_busaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) /* use the new memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) ha->ioctl_data = (char *) bigger_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) ha->ioctl_len = length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) ha->ioctl_busaddr = dma_busaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) /* Routine Name: ips_make_passthru */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) /* Make a passthru command out of the info in the Scsi block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) ips_make_passthru(ips_ha_t *ha, struct scsi_cmnd *SC, ips_scb_t *scb, int intr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) ips_passthru_t *pt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) int length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) struct scatterlist *sg = scsi_sglist(SC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) METHOD_TRACE("ips_make_passthru", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) scsi_for_each_sg(SC, sg, scsi_sg_count(SC), i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) length += sg->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) if (length < sizeof (ips_passthru_t)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) /* wrong size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) DEBUG_VAR(1, "(%s%d) Passthru structure wrong size",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) ips_name, ha->host_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) return (IPS_FAILURE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) if (ips_alloc_passthru_buffer(ha, length)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) /* allocation failure! If ha->ioctl_data exists, use it to return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) some error codes. Return a failed command to the scsi layer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) if (ha->ioctl_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) pt = (ips_passthru_t *) ha->ioctl_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) ips_scmd_buf_read(SC, pt, sizeof (ips_passthru_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) pt->BasicStatus = 0x0B;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) pt->ExtendedStatus = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) ips_scmd_buf_write(SC, pt, sizeof (ips_passthru_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) return IPS_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) ha->ioctl_datasize = length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) ips_scmd_buf_read(SC, ha->ioctl_data, ha->ioctl_datasize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) pt = (ips_passthru_t *) ha->ioctl_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) * Some notes about the passthru interface used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) * IF the scsi op_code == 0x0d then we assume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) * that the data came along with/goes with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) * packet we received from the sg driver. In this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) * case the CmdBSize field of the pt structure is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) * used for the size of the buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) switch (pt->CoppCmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) case IPS_NUMCTRLS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) memcpy(ha->ioctl_data + sizeof (ips_passthru_t),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) &ips_num_controllers, sizeof (int));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) ips_scmd_buf_write(SC, ha->ioctl_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) sizeof (ips_passthru_t) + sizeof (int));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) SC->result = DID_OK << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) return (IPS_SUCCESS_IMM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) case IPS_COPPUSRCMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) case IPS_COPPIOCCMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) if (SC->cmnd[0] == IPS_IOCTL_COMMAND) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) if (length < (sizeof (ips_passthru_t) + pt->CmdBSize)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) /* wrong size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) DEBUG_VAR(1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) "(%s%d) Passthru structure wrong size",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) ips_name, ha->host_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) return (IPS_FAILURE);
^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) if (ha->pcidev->device == IPS_DEVICEID_COPPERHEAD &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) pt->CoppCP.cmd.flashfw.op_code ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) IPS_CMD_RW_BIOSFW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) ret = ips_flash_copperhead(ha, pt, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) ips_scmd_buf_write(SC, ha->ioctl_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) sizeof (ips_passthru_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) if (ips_usrcmd(ha, pt, scb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) return (IPS_SUCCESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) return (IPS_FAILURE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) } /* end switch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) return (IPS_FAILURE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) /* Routine Name: ips_flash_copperhead */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) /* Flash the BIOS/FW on a Copperhead style controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) ips_flash_copperhead(ips_ha_t * ha, ips_passthru_t * pt, ips_scb_t * scb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) int datasize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) /* Trombone is the only copperhead that can do packet flash, but only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) * for firmware. No one said it had to make sense. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) if (IPS_IS_TROMBONE(ha) && pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) if (ips_usrcmd(ha, pt, scb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) return IPS_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) return IPS_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) pt->BasicStatus = 0x0B;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) pt->ExtendedStatus = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) scb->scsi_cmd->result = DID_OK << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) /* IF it's OK to Use the "CD BOOT" Flash Buffer, then you can */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) /* avoid allocating a huge buffer per adapter ( which can fail ). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) if (pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) pt->CoppCP.cmd.flashfw.direction == IPS_ERASE_BIOS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) pt->BasicStatus = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) return ips_flash_bios(ha, pt, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) } else if (pt->CoppCP.cmd.flashfw.packet_num == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) if (ips_FlashData && !test_and_set_bit(0, &ips_FlashDataInUse)){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) ha->flash_data = ips_FlashData;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) ha->flash_busaddr = ips_flashbusaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) ha->flash_len = PAGE_SIZE << 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) ha->flash_datasize = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) } else if (!ha->flash_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) datasize = pt->CoppCP.cmd.flashfw.total_packets *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) pt->CoppCP.cmd.flashfw.count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) ha->flash_data = dma_alloc_coherent(&ha->pcidev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) datasize, &ha->flash_busaddr, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) if (!ha->flash_data){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) printk(KERN_WARNING "Unable to allocate a flash buffer\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) return IPS_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) ha->flash_datasize = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) ha->flash_len = datasize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) return IPS_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) if (pt->CoppCP.cmd.flashfw.count + ha->flash_datasize >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) ha->flash_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) ips_free_flash_copperhead(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) IPS_PRINTK(KERN_WARNING, ha->pcidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) "failed size sanity check\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) return IPS_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) if (!ha->flash_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) return IPS_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) pt->BasicStatus = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) memcpy(&ha->flash_data[ha->flash_datasize], pt + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) pt->CoppCP.cmd.flashfw.count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) ha->flash_datasize += pt->CoppCP.cmd.flashfw.count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) if (pt->CoppCP.cmd.flashfw.packet_num ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) pt->CoppCP.cmd.flashfw.total_packets - 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) if (pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) return ips_flash_bios(ha, pt, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) else if (pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) return ips_flash_firmware(ha, pt, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) return IPS_SUCCESS_IMM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) /* Routine Name: ips_flash_bios */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) /* flashes the bios of a copperhead adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) ips_flash_bios(ips_ha_t * ha, ips_passthru_t * pt, ips_scb_t * scb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) if (pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) pt->CoppCP.cmd.flashfw.direction == IPS_WRITE_BIOS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) if ((!ha->func.programbios) || (!ha->func.erasebios) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) (!ha->func.verifybios))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) if ((*ha->func.erasebios) (ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) DEBUG_VAR(1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) "(%s%d) flash bios failed - unable to erase flash",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) ips_name, ha->host_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) if ((*ha->func.programbios) (ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) ha->flash_data +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) IPS_BIOS_HEADER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) ha->flash_datasize -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) IPS_BIOS_HEADER, 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) DEBUG_VAR(1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) "(%s%d) flash bios failed - unable to flash",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) ips_name, ha->host_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) if ((*ha->func.verifybios) (ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) ha->flash_data +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) IPS_BIOS_HEADER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) ha->flash_datasize -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) IPS_BIOS_HEADER, 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) DEBUG_VAR(1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) "(%s%d) flash bios failed - unable to verify flash",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) ips_name, ha->host_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) ips_free_flash_copperhead(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) return IPS_SUCCESS_IMM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) } else if (pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) pt->CoppCP.cmd.flashfw.direction == IPS_ERASE_BIOS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) if (!ha->func.erasebios)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) if ((*ha->func.erasebios) (ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) DEBUG_VAR(1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) "(%s%d) flash bios failed - unable to erase flash",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) ips_name, ha->host_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) return IPS_SUCCESS_IMM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) pt->BasicStatus = 0x0B;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) pt->ExtendedStatus = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) ips_free_flash_copperhead(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) return IPS_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) /* Routine Name: ips_fill_scb_sg_single */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) /* Fill in a single scb sg_list element from an address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) /* return a -1 if a breakup occurred */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) ips_fill_scb_sg_single(ips_ha_t * ha, dma_addr_t busaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) ips_scb_t * scb, int indx, unsigned int e_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) int ret_val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) if ((scb->data_len + e_len) > ha->max_xfer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) e_len = ha->max_xfer - scb->data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) scb->breakup = indx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) ++scb->sg_break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) ret_val = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) scb->breakup = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) scb->sg_break = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) if (IPS_USE_ENH_SGLIST(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) scb->sg_list.enh_list[indx].address_lo =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) cpu_to_le32(lower_32_bits(busaddr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) scb->sg_list.enh_list[indx].address_hi =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) cpu_to_le32(upper_32_bits(busaddr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) scb->sg_list.enh_list[indx].length = cpu_to_le32(e_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) scb->sg_list.std_list[indx].address =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) cpu_to_le32(lower_32_bits(busaddr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) scb->sg_list.std_list[indx].length = cpu_to_le32(e_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) ++scb->sg_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) scb->data_len += e_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) return ret_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) /* Routine Name: ips_flash_firmware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) /* flashes the firmware of a copperhead adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) ips_flash_firmware(ips_ha_t * ha, ips_passthru_t * pt, ips_scb_t * scb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) IPS_SG_LIST sg_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) uint32_t cmd_busaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) if (pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) pt->CoppCP.cmd.flashfw.direction == IPS_WRITE_FW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) memset(&pt->CoppCP.cmd, 0, sizeof (IPS_HOST_COMMAND));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) pt->CoppCP.cmd.flashfw.op_code = IPS_CMD_DOWNLOAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) pt->CoppCP.cmd.flashfw.count = cpu_to_le32(ha->flash_datasize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) pt->BasicStatus = 0x0B;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) pt->ExtendedStatus = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) ips_free_flash_copperhead(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) return IPS_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) /* Save the S/G list pointer so it doesn't get clobbered */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) sg_list.list = scb->sg_list.list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) cmd_busaddr = scb->scb_busaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) /* copy in the CP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) memcpy(&scb->cmd, &pt->CoppCP.cmd, sizeof (IPS_IOCTL_CMD));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) /* FIX stuff that might be wrong */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) scb->sg_list.list = sg_list.list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) scb->scb_busaddr = cmd_busaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) scb->bus = scb->scsi_cmd->device->channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) scb->target_id = scb->scsi_cmd->device->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) scb->lun = scb->scsi_cmd->device->lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) scb->sg_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) scb->data_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) scb->flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) scb->op_code = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) scb->callback = ipsintr_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) scb->timeout = ips_cmd_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) scb->data_len = ha->flash_datasize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) scb->data_busaddr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) dma_map_single(&ha->pcidev->dev, ha->flash_data, scb->data_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) IPS_DMA_DIR(scb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) scb->flags |= IPS_SCB_MAP_SINGLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) scb->cmd.flashfw.command_id = IPS_COMMAND_ID(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) scb->cmd.flashfw.buffer_addr = cpu_to_le32(scb->data_busaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) if (pt->TimeOut)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) scb->timeout = pt->TimeOut;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) scb->scsi_cmd->result = DID_OK << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) return IPS_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) /* Routine Name: ips_free_flash_copperhead */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) /* release the memory resources used to hold the flash image */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) ips_free_flash_copperhead(ips_ha_t * ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) if (ha->flash_data == ips_FlashData)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) test_and_clear_bit(0, &ips_FlashDataInUse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) else if (ha->flash_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) dma_free_coherent(&ha->pcidev->dev, ha->flash_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) ha->flash_data, ha->flash_busaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) ha->flash_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) /* Routine Name: ips_usrcmd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) /* Process a user command and make it ready to send */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) ips_usrcmd(ips_ha_t * ha, ips_passthru_t * pt, ips_scb_t * scb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) IPS_SG_LIST sg_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) uint32_t cmd_busaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) METHOD_TRACE("ips_usrcmd", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) if ((!scb) || (!pt) || (!ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) /* Save the S/G list pointer so it doesn't get clobbered */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) sg_list.list = scb->sg_list.list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) cmd_busaddr = scb->scb_busaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) /* copy in the CP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) memcpy(&scb->cmd, &pt->CoppCP.cmd, sizeof (IPS_IOCTL_CMD));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) memcpy(&scb->dcdb, &pt->CoppCP.dcdb, sizeof (IPS_DCDB_TABLE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) /* FIX stuff that might be wrong */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) scb->sg_list.list = sg_list.list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) scb->scb_busaddr = cmd_busaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) scb->bus = scb->scsi_cmd->device->channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) scb->target_id = scb->scsi_cmd->device->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) scb->lun = scb->scsi_cmd->device->lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) scb->sg_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) scb->data_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) scb->flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) scb->op_code = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) scb->callback = ipsintr_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) scb->timeout = ips_cmd_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) /* we don't support DCDB/READ/WRITE Scatter Gather */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) if ((scb->cmd.basic_io.op_code == IPS_CMD_READ_SG) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) (scb->cmd.basic_io.op_code == IPS_CMD_WRITE_SG) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) (scb->cmd.basic_io.op_code == IPS_CMD_DCDB_SG))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) if (pt->CmdBSize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) scb->data_len = pt->CmdBSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) scb->data_busaddr = ha->ioctl_busaddr + sizeof (ips_passthru_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) scb->data_busaddr = 0L;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) scb->cmd.dcdb.dcdb_address = cpu_to_le32(scb->scb_busaddr +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) (unsigned long) &scb->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) dcdb -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) (unsigned long) scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) if (pt->CmdBSize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) scb->dcdb.buffer_pointer =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) cpu_to_le32(scb->data_busaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) scb->cmd.basic_io.sg_addr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) cpu_to_le32(scb->data_busaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) /* set timeouts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) if (pt->TimeOut) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) scb->timeout = pt->TimeOut;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) if (pt->TimeOut <= 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) scb->dcdb.cmd_attribute |= IPS_TIMEOUT10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) else if (pt->TimeOut <= 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) scb->dcdb.cmd_attribute |= IPS_TIMEOUT60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) /* assume success */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) scb->scsi_cmd->result = DID_OK << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) /* success */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974)
^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) /* Routine Name: ips_cleanup_passthru */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) /* Cleanup after a passthru command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) ips_cleanup_passthru(ips_ha_t * ha, ips_scb_t * scb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) ips_passthru_t *pt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) METHOD_TRACE("ips_cleanup_passthru", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) if ((!scb) || (!scb->scsi_cmd) || (!scsi_sglist(scb->scsi_cmd))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) DEBUG_VAR(1, "(%s%d) couldn't cleanup after passthru",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) ips_name, ha->host_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) pt = (ips_passthru_t *) ha->ioctl_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) /* Copy data back to the user */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB) /* Copy DCDB Back to Caller's Area */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) memcpy(&pt->CoppCP.dcdb, &scb->dcdb, sizeof (IPS_DCDB_TABLE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) pt->BasicStatus = scb->basic_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) pt->ExtendedStatus = scb->extended_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) pt->AdapterType = ha->ad_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) if (ha->pcidev->device == IPS_DEVICEID_COPPERHEAD &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) (scb->cmd.flashfw.op_code == IPS_CMD_DOWNLOAD ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) scb->cmd.flashfw.op_code == IPS_CMD_RW_BIOSFW))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) ips_free_flash_copperhead(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) ips_scmd_buf_write(scb->scsi_cmd, ha->ioctl_data, ha->ioctl_datasize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) /* Routine Name: ips_host_info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) /* The passthru interface for the driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) ips_host_info(ips_ha_t *ha, struct seq_file *m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) METHOD_TRACE("ips_host_info", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) seq_puts(m, "\nIBM ServeRAID General Information:\n\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) if ((le32_to_cpu(ha->nvram->signature) == IPS_NVRAM_P5_SIG) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) (le16_to_cpu(ha->nvram->adapter_type) != 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) seq_printf(m, "\tController Type : %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) ips_adapter_name[ha->ad_type - 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) seq_puts(m, "\tController Type : Unknown\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) if (ha->io_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) "\tIO region : 0x%x (%d bytes)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) ha->io_addr, ha->io_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) if (ha->mem_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) "\tMemory region : 0x%x (%d bytes)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) ha->mem_addr, ha->mem_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) "\tShared memory address : 0x%lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) (unsigned long)ha->mem_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) seq_printf(m, "\tIRQ number : %d\n", ha->pcidev->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) /* For the Next 3 lines Check for Binary 0 at the end and don't include it if it's there. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) /* That keeps everything happy for "text" operations on the proc file. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) if (le32_to_cpu(ha->nvram->signature) == IPS_NVRAM_P5_SIG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) if (ha->nvram->bios_low[3] == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) "\tBIOS Version : %c%c%c%c%c%c%c\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) ha->nvram->bios_high[0], ha->nvram->bios_high[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) ha->nvram->bios_high[2], ha->nvram->bios_high[3],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) ha->nvram->bios_low[0], ha->nvram->bios_low[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) ha->nvram->bios_low[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) "\tBIOS Version : %c%c%c%c%c%c%c%c\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) ha->nvram->bios_high[0], ha->nvram->bios_high[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) ha->nvram->bios_high[2], ha->nvram->bios_high[3],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) ha->nvram->bios_low[0], ha->nvram->bios_low[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) ha->nvram->bios_low[2], ha->nvram->bios_low[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) if (ha->enq->CodeBlkVersion[7] == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) "\tFirmware Version : %c%c%c%c%c%c%c\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) ha->enq->CodeBlkVersion[0], ha->enq->CodeBlkVersion[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) ha->enq->CodeBlkVersion[2], ha->enq->CodeBlkVersion[3],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) ha->enq->CodeBlkVersion[4], ha->enq->CodeBlkVersion[5],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) ha->enq->CodeBlkVersion[6]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) "\tFirmware Version : %c%c%c%c%c%c%c%c\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) ha->enq->CodeBlkVersion[0], ha->enq->CodeBlkVersion[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) ha->enq->CodeBlkVersion[2], ha->enq->CodeBlkVersion[3],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) ha->enq->CodeBlkVersion[4], ha->enq->CodeBlkVersion[5],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) ha->enq->CodeBlkVersion[6], ha->enq->CodeBlkVersion[7]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) if (ha->enq->BootBlkVersion[7] == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) "\tBoot Block Version : %c%c%c%c%c%c%c\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) ha->enq->BootBlkVersion[0], ha->enq->BootBlkVersion[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) ha->enq->BootBlkVersion[2], ha->enq->BootBlkVersion[3],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) ha->enq->BootBlkVersion[4], ha->enq->BootBlkVersion[5],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) ha->enq->BootBlkVersion[6]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) "\tBoot Block Version : %c%c%c%c%c%c%c%c\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) ha->enq->BootBlkVersion[0], ha->enq->BootBlkVersion[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) ha->enq->BootBlkVersion[2], ha->enq->BootBlkVersion[3],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) ha->enq->BootBlkVersion[4], ha->enq->BootBlkVersion[5],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) ha->enq->BootBlkVersion[6], ha->enq->BootBlkVersion[7]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) seq_printf(m, "\tDriver Version : %s%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) IPS_VERSION_HIGH, IPS_VERSION_LOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) seq_printf(m, "\tDriver Build : %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) IPS_BUILD_IDENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) seq_printf(m, "\tMax Physical Devices : %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) ha->enq->ucMaxPhysicalDevices);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) seq_printf(m, "\tMax Active Commands : %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) ha->max_cmds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) seq_printf(m, "\tCurrent Queued Commands : %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) ha->scb_waitlist.count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) seq_printf(m, "\tCurrent Active Commands : %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) ha->scb_activelist.count - ha->num_ioctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) seq_printf(m, "\tCurrent Queued PT Commands : %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) ha->copp_waitlist.count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) seq_printf(m, "\tCurrent Active PT Commands : %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) ha->num_ioctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) seq_putc(m, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) /* Routine Name: ips_identify_controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) /* Identify this controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) ips_identify_controller(ips_ha_t * ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) METHOD_TRACE("ips_identify_controller", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) switch (ha->pcidev->device) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) case IPS_DEVICEID_COPPERHEAD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) if (ha->pcidev->revision <= IPS_REVID_SERVERAID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) ha->ad_type = IPS_ADTYPE_SERVERAID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) } else if (ha->pcidev->revision == IPS_REVID_SERVERAID2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) ha->ad_type = IPS_ADTYPE_SERVERAID2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) } else if (ha->pcidev->revision == IPS_REVID_NAVAJO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) ha->ad_type = IPS_ADTYPE_NAVAJO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) } else if ((ha->pcidev->revision == IPS_REVID_SERVERAID2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) && (ha->slot_num == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) ha->ad_type = IPS_ADTYPE_KIOWA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) } else if ((ha->pcidev->revision >= IPS_REVID_CLARINETP1) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) (ha->pcidev->revision <= IPS_REVID_CLARINETP3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) if (ha->enq->ucMaxPhysicalDevices == 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) ha->ad_type = IPS_ADTYPE_SERVERAID3L;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) ha->ad_type = IPS_ADTYPE_SERVERAID3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) } else if ((ha->pcidev->revision >= IPS_REVID_TROMBONE32) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) (ha->pcidev->revision <= IPS_REVID_TROMBONE64)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) ha->ad_type = IPS_ADTYPE_SERVERAID4H;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) case IPS_DEVICEID_MORPHEUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) switch (ha->pcidev->subsystem_device) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) case IPS_SUBDEVICEID_4L:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) ha->ad_type = IPS_ADTYPE_SERVERAID4L;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) case IPS_SUBDEVICEID_4M:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) ha->ad_type = IPS_ADTYPE_SERVERAID4M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) case IPS_SUBDEVICEID_4MX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) ha->ad_type = IPS_ADTYPE_SERVERAID4MX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) case IPS_SUBDEVICEID_4LX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) ha->ad_type = IPS_ADTYPE_SERVERAID4LX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) case IPS_SUBDEVICEID_5I2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) ha->ad_type = IPS_ADTYPE_SERVERAID5I2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) case IPS_SUBDEVICEID_5I1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) ha->ad_type = IPS_ADTYPE_SERVERAID5I1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) case IPS_DEVICEID_MARCO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) switch (ha->pcidev->subsystem_device) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) case IPS_SUBDEVICEID_6M:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) ha->ad_type = IPS_ADTYPE_SERVERAID6M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) case IPS_SUBDEVICEID_6I:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) ha->ad_type = IPS_ADTYPE_SERVERAID6I;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) case IPS_SUBDEVICEID_7k:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) ha->ad_type = IPS_ADTYPE_SERVERAID7k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) case IPS_SUBDEVICEID_7M:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) ha->ad_type = IPS_ADTYPE_SERVERAID7M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) /* Routine Name: ips_get_bios_version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) /* Get the BIOS revision number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) ips_get_bios_version(ips_ha_t * ha, int intr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) ips_scb_t *scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) uint8_t major;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) uint8_t minor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) uint8_t subminor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) uint8_t *buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) METHOD_TRACE("ips_get_bios_version", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) major = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) minor = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) memcpy(ha->bios_version, " ?", 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) if (ha->pcidev->device == IPS_DEVICEID_COPPERHEAD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) if (IPS_USE_MEMIO(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) /* Memory Mapped I/O */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) /* test 1st byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) writel(0, ha->mem_ptr + IPS_REG_FLAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0x55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) writel(1, ha->mem_ptr + IPS_REG_FLAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0xAA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) /* Get Major version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) writel(0x1FF, ha->mem_ptr + IPS_REG_FLAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) major = readb(ha->mem_ptr + IPS_REG_FLDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) /* Get Minor version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) writel(0x1FE, ha->mem_ptr + IPS_REG_FLAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) minor = readb(ha->mem_ptr + IPS_REG_FLDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) /* Get SubMinor version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) writel(0x1FD, ha->mem_ptr + IPS_REG_FLAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) subminor = readb(ha->mem_ptr + IPS_REG_FLDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) /* Programmed I/O */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) /* test 1st byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) outl(0, ha->io_addr + IPS_REG_FLAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) outl(1, ha->io_addr + IPS_REG_FLAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) if (inb(ha->io_addr + IPS_REG_FLDP) != 0xAA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) /* Get Major version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) outl(0x1FF, ha->io_addr + IPS_REG_FLAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) major = inb(ha->io_addr + IPS_REG_FLDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) /* Get Minor version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) outl(0x1FE, ha->io_addr + IPS_REG_FLAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) minor = inb(ha->io_addr + IPS_REG_FLDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) /* Get SubMinor version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) outl(0x1FD, ha->io_addr + IPS_REG_FLAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) subminor = inb(ha->io_addr + IPS_REG_FLDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) /* Morpheus Family - Send Command to the card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) buffer = ha->ioctl_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) memset(buffer, 0, 0x1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) scb = &ha->scbs[ha->max_cmds - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) ips_init_scb(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) scb->timeout = ips_cmd_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) scb->cdb[0] = IPS_CMD_RW_BIOSFW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) scb->cmd.flashfw.op_code = IPS_CMD_RW_BIOSFW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) scb->cmd.flashfw.command_id = IPS_COMMAND_ID(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) scb->cmd.flashfw.type = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) scb->cmd.flashfw.direction = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) scb->cmd.flashfw.count = cpu_to_le32(0x800);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) scb->cmd.flashfw.total_packets = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) scb->cmd.flashfw.packet_num = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) scb->data_len = 0x1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) scb->cmd.flashfw.buffer_addr = ha->ioctl_busaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) /* issue the command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) if (((ret =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) ips_send_wait(ha, scb, ips_cmd_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) intr)) == IPS_FAILURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) || (ret == IPS_SUCCESS_IMM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) /* Error occurred */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) if ((buffer[0xC0] == 0x55) && (buffer[0xC1] == 0xAA)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) major = buffer[0x1ff + 0xC0]; /* Offset 0x1ff after the header (0xc0) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) minor = buffer[0x1fe + 0xC0]; /* Offset 0x1fe after the header (0xc0) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) subminor = buffer[0x1fd + 0xC0]; /* Offset 0x1fd after the header (0xc0) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) ha->bios_version[0] = hex_asc_upper_hi(major);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) ha->bios_version[1] = '.';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) ha->bios_version[2] = hex_asc_upper_lo(major);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) ha->bios_version[3] = hex_asc_upper_lo(subminor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) ha->bios_version[4] = '.';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) ha->bios_version[5] = hex_asc_upper_hi(minor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) ha->bios_version[6] = hex_asc_upper_lo(minor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) ha->bios_version[7] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) /* Routine Name: ips_hainit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) /* Initialize the controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) /* NOTE: Assumes to be called from with a lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) ips_hainit(ips_ha_t * ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) METHOD_TRACE("ips_hainit", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) if (!ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) if (ha->func.statinit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) (*ha->func.statinit) (ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) if (ha->func.enableint)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) (*ha->func.enableint) (ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) /* Send FFDC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) ha->reset_count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) ha->last_ffdc = ktime_get_real_seconds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) ips_ffdc_reset(ha, IPS_INTR_IORL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) if (!ips_read_config(ha, IPS_INTR_IORL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) IPS_PRINTK(KERN_WARNING, ha->pcidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) "unable to read config from controller.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) /* end if */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) if (!ips_read_adapter_status(ha, IPS_INTR_IORL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) IPS_PRINTK(KERN_WARNING, ha->pcidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) "unable to read controller status.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) /* Identify this controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) ips_identify_controller(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) if (!ips_read_subsystem_parameters(ha, IPS_INTR_IORL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) IPS_PRINTK(KERN_WARNING, ha->pcidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) "unable to read subsystem parameters.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) /* write nvram user page 5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) if (!ips_write_driver_status(ha, IPS_INTR_IORL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) IPS_PRINTK(KERN_WARNING, ha->pcidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) "unable to write driver info to controller.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) /* If there are Logical Drives and a Reset Occurred, then an EraseStripeLock is Needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) if ((ha->conf->ucLogDriveCount > 0) && (ha->requires_esl == 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) ips_clear_adapter(ha, IPS_INTR_IORL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) /* set limits on SID, LUN, BUS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) ha->ntargets = IPS_MAX_TARGETS + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) ha->nlun = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) ha->nbus = (ha->enq->ucMaxPhysicalDevices / IPS_MAX_TARGETS) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) switch (ha->conf->logical_drive[0].ucStripeSize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) ha->max_xfer = 0x10000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) ha->max_xfer = 0x20000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) case 6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) ha->max_xfer = 0x40000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) case 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) ha->max_xfer = 0x80000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) /* setup max concurrent commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) if (le32_to_cpu(ha->subsys->param[4]) & 0x1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) /* Use the new method */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) ha->max_cmds = ha->enq->ucConcurrentCmdCount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) /* use the old method */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) switch (ha->conf->logical_drive[0].ucStripeSize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) ha->max_cmds = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) ha->max_cmds = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) case 6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) ha->max_cmds = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) case 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) ha->max_cmds = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) /* Limit the Active Commands on a Lite Adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) if ((ha->ad_type == IPS_ADTYPE_SERVERAID3L) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) (ha->ad_type == IPS_ADTYPE_SERVERAID4L) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) (ha->ad_type == IPS_ADTYPE_SERVERAID4LX)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) if ((ha->max_cmds > MaxLiteCmds) && (MaxLiteCmds))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) ha->max_cmds = MaxLiteCmds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) /* set controller IDs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) ha->ha_id[0] = IPS_ADAPTER_ID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) for (i = 1; i < ha->nbus; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) ha->ha_id[i] = ha->conf->init_id[i - 1] & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) ha->dcdb_active[i - 1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) /* Routine Name: ips_next */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) /* Take the next command off the queue and send it to the controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) ips_next(ips_ha_t * ha, int intr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) ips_scb_t *scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) struct scsi_cmnd *SC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) struct scsi_cmnd *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) struct scsi_cmnd *q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) ips_copp_wait_item_t *item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) struct Scsi_Host *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) METHOD_TRACE("ips_next", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) if (!ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) host = ips_sh[ha->host_num];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) * Block access to the queue function so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) * this command won't time out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) if (intr == IPS_INTR_ON)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) spin_lock(host->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) if ((ha->subsys->param[3] & 0x300000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) && (ha->scb_activelist.count == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) time64_t now = ktime_get_real_seconds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) if (now - ha->last_ffdc > IPS_SECS_8HOURS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) ha->last_ffdc = now;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) ips_ffdc_time(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) * Send passthru commands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) * These have priority over normal I/O
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) * but shouldn't affect performance too much
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) * since we limit the number that can be active
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) * on the card at any one time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) while ((ha->num_ioctl < IPS_MAX_IOCTL) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) (ha->copp_waitlist.head) && (scb = ips_getscb(ha))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) item = ips_removeq_copp_head(&ha->copp_waitlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) ha->num_ioctl++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) if (intr == IPS_INTR_ON)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) spin_unlock(host->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) scb->scsi_cmd = item->scsi_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) kfree(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) ret = ips_make_passthru(ha, scb->scsi_cmd, scb, intr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) if (intr == IPS_INTR_ON)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) spin_lock(host->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) switch (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) case IPS_FAILURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) if (scb->scsi_cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) scb->scsi_cmd->result = DID_ERROR << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) scb->scsi_cmd->scsi_done(scb->scsi_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) ips_freescb(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) case IPS_SUCCESS_IMM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) if (scb->scsi_cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) scb->scsi_cmd->result = DID_OK << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) scb->scsi_cmd->scsi_done(scb->scsi_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) ips_freescb(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) } /* end case */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) if (ret != IPS_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) ha->num_ioctl--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) ret = ips_send_cmd(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) if (ret == IPS_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) ips_putq_scb_head(&ha->scb_activelist, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) ha->num_ioctl--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) switch (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) case IPS_FAILURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) if (scb->scsi_cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) scb->scsi_cmd->result = DID_ERROR << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) ips_freescb(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) case IPS_SUCCESS_IMM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) ips_freescb(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) } /* end case */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) * Send "Normal" I/O commands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) p = ha->scb_waitlist.head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) while ((p) && (scb = ips_getscb(ha))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) if ((scmd_channel(p) > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) && (ha->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) dcdb_active[scmd_channel(p) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) 1] & (1 << scmd_id(p)))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) ips_freescb(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) p = (struct scsi_cmnd *) p->host_scribble;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) q = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) SC = ips_removeq_wait(&ha->scb_waitlist, q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) if (intr == IPS_INTR_ON)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) spin_unlock(host->host_lock); /* Unlock HA after command is taken off queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) SC->result = DID_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) SC->host_scribble = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) scb->target_id = SC->device->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) scb->lun = SC->device->lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) scb->bus = SC->device->channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) scb->scsi_cmd = SC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) scb->breakup = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) scb->data_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) scb->callback = ipsintr_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) scb->timeout = ips_cmd_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) memset(&scb->cmd, 0, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) /* copy in the CDB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) memcpy(scb->cdb, SC->cmnd, SC->cmd_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) scb->sg_count = scsi_dma_map(SC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) BUG_ON(scb->sg_count < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) if (scb->sg_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) struct scatterlist *sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) scb->flags |= IPS_SCB_MAP_SG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) scsi_for_each_sg(SC, sg, scb->sg_count, i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) if (ips_fill_scb_sg_single
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) (ha, sg_dma_address(sg), scb, i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) sg_dma_len(sg)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) scb->dcdb.transfer_length = scb->data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) scb->data_busaddr = 0L;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) scb->sg_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) scb->data_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) scb->dcdb.transfer_length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) scb->dcdb.cmd_attribute =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) ips_command_direction[scb->scsi_cmd->cmnd[0]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) /* Allow a WRITE BUFFER Command to Have no Data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) /* This is Used by Tape Flash Utilites */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) if ((scb->scsi_cmd->cmnd[0] == WRITE_BUFFER) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) (scb->data_len == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) scb->dcdb.cmd_attribute = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) if (!(scb->dcdb.cmd_attribute & 0x3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) scb->dcdb.transfer_length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) if (scb->data_len >= IPS_MAX_XFER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) scb->dcdb.cmd_attribute |= IPS_TRANSFER64K;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) scb->dcdb.transfer_length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) if (intr == IPS_INTR_ON)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) spin_lock(host->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) ret = ips_send_cmd(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) switch (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) case IPS_SUCCESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) ips_putq_scb_head(&ha->scb_activelist, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) case IPS_FAILURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) if (scb->scsi_cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) scb->scsi_cmd->result = DID_ERROR << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) scb->scsi_cmd->scsi_done(scb->scsi_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) if (scb->bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) ha->dcdb_active[scb->bus - 1] &=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) ~(1 << scb->target_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) ips_freescb(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) case IPS_SUCCESS_IMM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) if (scb->scsi_cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) scb->scsi_cmd->scsi_done(scb->scsi_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) if (scb->bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) ha->dcdb_active[scb->bus - 1] &=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) ~(1 << scb->target_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) ips_freescb(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) } /* end case */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) p = (struct scsi_cmnd *) p->host_scribble;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) } /* end while */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) if (intr == IPS_INTR_ON)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) spin_unlock(host->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) /* Routine Name: ips_putq_scb_head */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) /* Add an item to the head of the queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) /* ASSUMED to be called from within the HA lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) ips_putq_scb_head(ips_scb_queue_t * queue, ips_scb_t * item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) METHOD_TRACE("ips_putq_scb_head", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) if (!item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) item->q_next = queue->head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) queue->head = item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) if (!queue->tail)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) queue->tail = item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) queue->count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) /* Routine Name: ips_removeq_scb_head */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) /* Remove the head of the queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) /* ASSUMED to be called from within the HA lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) static ips_scb_t *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) ips_removeq_scb_head(ips_scb_queue_t * queue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) ips_scb_t *item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) METHOD_TRACE("ips_removeq_scb_head", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) item = queue->head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) if (!item) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) return (NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) queue->head = item->q_next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) item->q_next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) if (queue->tail == item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) queue->tail = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) queue->count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) return (item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) /* Routine Name: ips_removeq_scb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) /* Remove an item from a queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) /* ASSUMED to be called from within the HA lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) static ips_scb_t *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) ips_removeq_scb(ips_scb_queue_t * queue, ips_scb_t * item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) ips_scb_t *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) METHOD_TRACE("ips_removeq_scb", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) if (!item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) return (NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) if (item == queue->head) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) return (ips_removeq_scb_head(queue));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) p = queue->head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) while ((p) && (item != p->q_next))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) p = p->q_next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) if (p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) /* found a match */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) p->q_next = item->q_next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) if (!item->q_next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) queue->tail = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) item->q_next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) queue->count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) return (item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) return (NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) /* Routine Name: ips_putq_wait_tail */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) /* Add an item to the tail of the queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) /* ASSUMED to be called from within the HA lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) static void ips_putq_wait_tail(ips_wait_queue_entry_t *queue, struct scsi_cmnd *item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) METHOD_TRACE("ips_putq_wait_tail", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) if (!item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) item->host_scribble = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) if (queue->tail)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) queue->tail->host_scribble = (char *) item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) queue->tail = item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) if (!queue->head)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) queue->head = item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) queue->count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) /* Routine Name: ips_removeq_wait_head */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) /* Remove the head of the queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) /* ASSUMED to be called from within the HA lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) static struct scsi_cmnd *ips_removeq_wait_head(ips_wait_queue_entry_t *queue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) struct scsi_cmnd *item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) METHOD_TRACE("ips_removeq_wait_head", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) item = queue->head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) if (!item) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) return (NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) queue->head = (struct scsi_cmnd *) item->host_scribble;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) item->host_scribble = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) if (queue->tail == item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) queue->tail = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) queue->count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) return (item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) /* Routine Name: ips_removeq_wait */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) /* Remove an item from a queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) /* ASSUMED to be called from within the HA lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) static struct scsi_cmnd *ips_removeq_wait(ips_wait_queue_entry_t *queue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) struct scsi_cmnd *item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) struct scsi_cmnd *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) METHOD_TRACE("ips_removeq_wait", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) if (!item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) return (NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) if (item == queue->head) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) return (ips_removeq_wait_head(queue));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) p = queue->head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) while ((p) && (item != (struct scsi_cmnd *) p->host_scribble))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) p = (struct scsi_cmnd *) p->host_scribble;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) if (p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) /* found a match */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) p->host_scribble = item->host_scribble;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) if (!item->host_scribble)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) queue->tail = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) item->host_scribble = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) queue->count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) return (item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) return (NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) /* Routine Name: ips_putq_copp_tail */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) /* Add an item to the tail of the queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) /* ASSUMED to be called from within the HA lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) ips_putq_copp_tail(ips_copp_queue_t * queue, ips_copp_wait_item_t * item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) METHOD_TRACE("ips_putq_copp_tail", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) if (!item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) item->next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) if (queue->tail)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) queue->tail->next = item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) queue->tail = item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) if (!queue->head)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) queue->head = item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) queue->count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) /* Routine Name: ips_removeq_copp_head */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) /* Remove the head of the queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) /* ASSUMED to be called from within the HA lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) static ips_copp_wait_item_t *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) ips_removeq_copp_head(ips_copp_queue_t * queue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) ips_copp_wait_item_t *item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) METHOD_TRACE("ips_removeq_copp_head", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) item = queue->head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) if (!item) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) return (NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) queue->head = item->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) item->next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) if (queue->tail == item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) queue->tail = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) queue->count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) return (item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) /* Routine Name: ips_removeq_copp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) /* Remove an item from a queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) /* ASSUMED to be called from within the HA lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) static ips_copp_wait_item_t *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) ips_removeq_copp(ips_copp_queue_t * queue, ips_copp_wait_item_t * item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) ips_copp_wait_item_t *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) METHOD_TRACE("ips_removeq_copp", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) if (!item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) return (NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) if (item == queue->head) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) return (ips_removeq_copp_head(queue));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) p = queue->head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) while ((p) && (item != p->next))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) p = p->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) if (p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) /* found a match */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) p->next = item->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) if (!item->next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) queue->tail = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) item->next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) queue->count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) return (item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) return (NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) /* Routine Name: ipsintr_blocking */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) /* Finalize an interrupt for internal commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) ipsintr_blocking(ips_ha_t * ha, ips_scb_t * scb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) METHOD_TRACE("ipsintr_blocking", 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) ips_freescb(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) if ((ha->waitflag == TRUE) && (ha->cmd_in_progress == scb->cdb[0])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) ha->waitflag = FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) /* Routine Name: ipsintr_done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) /* Finalize an interrupt for non-internal commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) ipsintr_done(ips_ha_t * ha, ips_scb_t * scb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) METHOD_TRACE("ipsintr_done", 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) if (!scb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) IPS_PRINTK(KERN_WARNING, ha->pcidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) "Spurious interrupt; scb NULL.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) if (scb->scsi_cmd == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) /* unexpected interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) IPS_PRINTK(KERN_WARNING, ha->pcidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) "Spurious interrupt; scsi_cmd not set.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) ips_done(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) /* Routine Name: ips_done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) /* Do housekeeping on completed commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) /* ASSUMED to be called form within the request lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) ips_done(ips_ha_t * ha, ips_scb_t * scb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) METHOD_TRACE("ips_done", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) if (!scb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) if ((scb->scsi_cmd) && (ips_is_passthru(scb->scsi_cmd))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) ips_cleanup_passthru(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) ha->num_ioctl--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) * Check to see if this command had too much
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) * data and had to be broke up. If so, queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) * the rest of the data and continue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) if ((scb->breakup) || (scb->sg_break)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) struct scatterlist *sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) int i, sg_dma_index, ips_sg_index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) /* we had a data breakup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) scb->data_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) sg = scsi_sglist(scb->scsi_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) /* Spin forward to last dma chunk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) sg_dma_index = scb->breakup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) for (i = 0; i < scb->breakup; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) sg = sg_next(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) /* Take care of possible partial on last chunk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) ips_fill_scb_sg_single(ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) sg_dma_address(sg),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) scb, ips_sg_index++,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) sg_dma_len(sg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) for (; sg_dma_index < scsi_sg_count(scb->scsi_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) sg_dma_index++, sg = sg_next(sg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) if (ips_fill_scb_sg_single
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) (ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) sg_dma_address(sg),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) scb, ips_sg_index++,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) sg_dma_len(sg)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) scb->dcdb.transfer_length = scb->data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) scb->dcdb.cmd_attribute |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) ips_command_direction[scb->scsi_cmd->cmnd[0]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) if (!(scb->dcdb.cmd_attribute & 0x3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) scb->dcdb.transfer_length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) if (scb->data_len >= IPS_MAX_XFER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) scb->dcdb.cmd_attribute |= IPS_TRANSFER64K;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) scb->dcdb.transfer_length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) ret = ips_send_cmd(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) switch (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) case IPS_FAILURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) if (scb->scsi_cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) scb->scsi_cmd->result = DID_ERROR << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) scb->scsi_cmd->scsi_done(scb->scsi_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) ips_freescb(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) case IPS_SUCCESS_IMM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) if (scb->scsi_cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) scb->scsi_cmd->result = DID_ERROR << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) scb->scsi_cmd->scsi_done(scb->scsi_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) ips_freescb(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) } /* end case */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) } /* end if passthru */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) if (scb->bus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) ha->dcdb_active[scb->bus - 1] &= ~(1 << scb->target_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) scb->scsi_cmd->scsi_done(scb->scsi_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) ips_freescb(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) /* Routine Name: ips_map_status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) /* Map Controller Error codes to Linux Error Codes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) ips_map_status(ips_ha_t * ha, ips_scb_t * scb, ips_stat_t * sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) int errcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) int device_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) uint32_t transfer_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) IPS_DCDB_TABLE_TAPE *tapeDCDB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) IPS_SCSI_INQ_DATA inquiryData;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) METHOD_TRACE("ips_map_status", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) if (scb->bus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) DEBUG_VAR(2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) "(%s%d) Physical device error (%d %d %d): %x %x, Sense Key: %x, ASC: %x, ASCQ: %x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) ips_name, ha->host_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) scb->scsi_cmd->device->channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) scb->scsi_cmd->device->id, scb->scsi_cmd->device->lun,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) scb->basic_status, scb->extended_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) scb->extended_status ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) IPS_ERR_CKCOND ? scb->dcdb.sense_info[2] & 0xf : 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) scb->extended_status ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) IPS_ERR_CKCOND ? scb->dcdb.sense_info[12] : 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) scb->extended_status ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) IPS_ERR_CKCOND ? scb->dcdb.sense_info[13] : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) /* default driver error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) errcode = DID_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) device_error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) switch (scb->basic_status & IPS_GSC_STATUS_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) case IPS_CMD_TIMEOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) errcode = DID_TIME_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) case IPS_INVAL_OPCO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) case IPS_INVAL_CMD_BLK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) case IPS_INVAL_PARM_BLK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) case IPS_LD_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) case IPS_CMD_CMPLT_WERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) case IPS_PHYS_DRV_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) switch (scb->extended_status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) case IPS_ERR_SEL_TO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) if (scb->bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) errcode = DID_NO_CONNECT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) case IPS_ERR_OU_RUN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) if ((scb->cmd.dcdb.op_code == IPS_CMD_EXTENDED_DCDB) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) (scb->cmd.dcdb.op_code ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) IPS_CMD_EXTENDED_DCDB_SG)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) tapeDCDB = (IPS_DCDB_TABLE_TAPE *) & scb->dcdb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) transfer_len = tapeDCDB->transfer_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) transfer_len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) (uint32_t) scb->dcdb.transfer_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) if ((scb->bus) && (transfer_len < scb->data_len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) /* Underrun - set default to no error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) errcode = DID_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) /* Restrict access to physical DASD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) if (scb->scsi_cmd->cmnd[0] == INQUIRY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) ips_scmd_buf_read(scb->scsi_cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) &inquiryData, sizeof (inquiryData));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) if ((inquiryData.DeviceType & 0x1f) == TYPE_DISK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) errcode = DID_TIME_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) errcode = DID_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) case IPS_ERR_RECOVERY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323) /* don't fail recovered errors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) if (scb->bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) errcode = DID_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) case IPS_ERR_HOST_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) case IPS_ERR_DEV_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) errcode = DID_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) case IPS_ERR_CKCOND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) if (scb->bus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) if ((scb->cmd.dcdb.op_code ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) IPS_CMD_EXTENDED_DCDB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) || (scb->cmd.dcdb.op_code ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) IPS_CMD_EXTENDED_DCDB_SG)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) tapeDCDB =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) (IPS_DCDB_TABLE_TAPE *) & scb->dcdb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) memcpy(scb->scsi_cmd->sense_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) tapeDCDB->sense_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) SCSI_SENSE_BUFFERSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) memcpy(scb->scsi_cmd->sense_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) scb->dcdb.sense_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) SCSI_SENSE_BUFFERSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) device_error = 2; /* check condition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353) errcode = DID_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358) errcode = DID_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) } /* end switch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) } /* end switch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) scb->scsi_cmd->result = device_error | (errcode << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) /* Routine Name: ips_send_wait */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) /* Send a command to the controller and wait for it to return */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) /* The FFDC Time Stamp use this function for the callback, but doesn't */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) /* actually need to wait. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) ips_send_wait(ips_ha_t * ha, ips_scb_t * scb, int timeout, int intr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) METHOD_TRACE("ips_send_wait", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) if (intr != IPS_FFDC) { /* Won't be Waiting if this is a Time Stamp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) ha->waitflag = TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) ha->cmd_in_progress = scb->cdb[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) scb->callback = ipsintr_blocking;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) ret = ips_send_cmd(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) if ((ret == IPS_FAILURE) || (ret == IPS_SUCCESS_IMM))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) return (ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) if (intr != IPS_FFDC) /* Don't Wait around if this is a Time Stamp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) ret = ips_wait(ha, timeout, intr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) return (ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) /* Routine Name: ips_scmd_buf_write */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) /* Write data to struct scsi_cmnd request_buffer at proper offsets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) ips_scmd_buf_write(struct scsi_cmnd *scmd, void *data, unsigned int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) scsi_sg_copy_from_buffer(scmd, data, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) /* Routine Name: ips_scmd_buf_read */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) /* Copy data from a struct scsi_cmnd to a new, linear buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) ips_scmd_buf_read(struct scsi_cmnd *scmd, void *data, unsigned int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) scsi_sg_copy_to_buffer(scmd, data, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439) /* Routine Name: ips_send_cmd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443) /* Map SCSI commands to ServeRAID commands for logical drives */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) ips_send_cmd(ips_ha_t * ha, ips_scb_t * scb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) char *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451) int device_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) IPS_DCDB_TABLE_TAPE *tapeDCDB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453) int TimeOut;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) METHOD_TRACE("ips_send_cmd", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) ret = IPS_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459) if (!scb->scsi_cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) /* internal command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) if (scb->bus > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) /* Controller commands can't be issued */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) /* to real devices -- fail them */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) if ((ha->waitflag == TRUE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) (ha->cmd_in_progress == scb->cdb[0])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) ha->waitflag = FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) } else if ((scb->bus == 0) && (!ips_is_passthru(scb->scsi_cmd))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) /* command to logical bus -- interpret */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474) ret = IPS_SUCCESS_IMM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) switch (scb->scsi_cmd->cmnd[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) case ALLOW_MEDIUM_REMOVAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478) case REZERO_UNIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) case ERASE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480) case WRITE_FILEMARKS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) case SPACE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) scb->scsi_cmd->result = DID_ERROR << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485) case START_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) scb->scsi_cmd->result = DID_OK << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489) case TEST_UNIT_READY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) case INQUIRY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491) if (scb->target_id == IPS_ADAPTER_ID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) * Either we have a TUR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) * or we have a SCSI inquiry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) if (scb->scsi_cmd->cmnd[0] == TEST_UNIT_READY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497) scb->scsi_cmd->result = DID_OK << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) if (scb->scsi_cmd->cmnd[0] == INQUIRY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500) IPS_SCSI_INQ_DATA inquiry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) memset(&inquiry, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) sizeof (IPS_SCSI_INQ_DATA));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) inquiry.DeviceType =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) IPS_SCSI_INQ_TYPE_PROCESSOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507) inquiry.DeviceTypeQualifier =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) IPS_SCSI_INQ_LU_CONNECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) inquiry.Version = IPS_SCSI_INQ_REV2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) inquiry.ResponseDataFormat =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511) IPS_SCSI_INQ_RD_REV2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) inquiry.AdditionalLength = 31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) inquiry.Flags[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) IPS_SCSI_INQ_Address16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) inquiry.Flags[1] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) IPS_SCSI_INQ_WBus16 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) IPS_SCSI_INQ_Sync;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518) memcpy(inquiry.VendorId, "IBM ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520) memcpy(inquiry.ProductId,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) "SERVERAID ", 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) memcpy(inquiry.ProductRevisionLevel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) "1.00", 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) ips_scmd_buf_write(scb->scsi_cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) &inquiry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527) sizeof (inquiry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) scb->scsi_cmd->result = DID_OK << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) scb->cmd.logical_info.op_code = IPS_CMD_GET_LD_INFO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) scb->cmd.logical_info.command_id = IPS_COMMAND_ID(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) scb->cmd.logical_info.reserved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) scb->cmd.logical_info.reserved2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536) scb->data_len = sizeof (IPS_LD_INFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) scb->data_busaddr = ha->logical_drive_info_dma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) scb->flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539) scb->cmd.logical_info.buffer_addr = scb->data_busaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) ret = IPS_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) case REQUEST_SENSE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546) ips_reqsen(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) scb->scsi_cmd->result = DID_OK << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) case READ_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) case WRITE_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552) if (!scb->sg_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553) scb->cmd.basic_io.op_code =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) (scb->scsi_cmd->cmnd[0] ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555) READ_6) ? IPS_CMD_READ : IPS_CMD_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556) scb->cmd.basic_io.enhanced_sg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) scb->cmd.basic_io.sg_addr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) cpu_to_le32(scb->data_busaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) scb->cmd.basic_io.op_code =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) (scb->scsi_cmd->cmnd[0] ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) READ_6) ? IPS_CMD_READ_SG :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) IPS_CMD_WRITE_SG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) scb->cmd.basic_io.enhanced_sg =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565) IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) scb->cmd.basic_io.sg_addr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567) cpu_to_le32(scb->sg_busaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570) scb->cmd.basic_io.segment_4G = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571) scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) scb->cmd.basic_io.log_drv = scb->target_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573) scb->cmd.basic_io.sg_count = scb->sg_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) if (scb->cmd.basic_io.lba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576) le32_add_cpu(&scb->cmd.basic_io.lba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577) le16_to_cpu(scb->cmd.basic_io.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) sector_count));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) scb->cmd.basic_io.lba =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581) (((scb->scsi_cmd->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) cmnd[1] & 0x1f) << 16) | (scb->scsi_cmd->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) cmnd[2] << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) (scb->scsi_cmd->cmnd[3]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586) scb->cmd.basic_io.sector_count =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) cpu_to_le16(scb->data_len / IPS_BLKSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) if (le16_to_cpu(scb->cmd.basic_io.sector_count) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) scb->cmd.basic_io.sector_count =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591) cpu_to_le16(256);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) ret = IPS_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) case READ_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) case WRITE_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) if (!scb->sg_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) scb->cmd.basic_io.op_code =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600) (scb->scsi_cmd->cmnd[0] ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601) READ_10) ? IPS_CMD_READ : IPS_CMD_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) scb->cmd.basic_io.enhanced_sg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) scb->cmd.basic_io.sg_addr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) cpu_to_le32(scb->data_busaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) scb->cmd.basic_io.op_code =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607) (scb->scsi_cmd->cmnd[0] ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) READ_10) ? IPS_CMD_READ_SG :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609) IPS_CMD_WRITE_SG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) scb->cmd.basic_io.enhanced_sg =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612) scb->cmd.basic_io.sg_addr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) cpu_to_le32(scb->sg_busaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) scb->cmd.basic_io.segment_4G = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617) scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618) scb->cmd.basic_io.log_drv = scb->target_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) scb->cmd.basic_io.sg_count = scb->sg_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) if (scb->cmd.basic_io.lba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) le32_add_cpu(&scb->cmd.basic_io.lba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) le16_to_cpu(scb->cmd.basic_io.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) sector_count));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626) scb->cmd.basic_io.lba =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) ((scb->scsi_cmd->cmnd[2] << 24) | (scb->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628) scsi_cmd->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629) cmnd[3]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630) << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) (scb->scsi_cmd->cmnd[4] << 8) | scb->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) scsi_cmd->cmnd[5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634) scb->cmd.basic_io.sector_count =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) cpu_to_le16(scb->data_len / IPS_BLKSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) if (cpu_to_le16(scb->cmd.basic_io.sector_count) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639) * This is a null condition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640) * we don't have to do anything
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641) * so just return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) scb->scsi_cmd->result = DID_OK << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645) ret = IPS_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) case RESERVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650) case RELEASE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651) scb->scsi_cmd->result = DID_OK << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) case MODE_SENSE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655) scb->cmd.basic_io.op_code = IPS_CMD_ENQUIRY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657) scb->cmd.basic_io.segment_4G = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658) scb->cmd.basic_io.enhanced_sg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659) scb->data_len = sizeof (*ha->enq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) scb->cmd.basic_io.sg_addr = ha->enq_busaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661) ret = IPS_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664) case READ_CAPACITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) scb->cmd.logical_info.op_code = IPS_CMD_GET_LD_INFO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666) scb->cmd.logical_info.command_id = IPS_COMMAND_ID(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) scb->cmd.logical_info.reserved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668) scb->cmd.logical_info.reserved2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669) scb->cmd.logical_info.reserved3 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670) scb->data_len = sizeof (IPS_LD_INFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671) scb->data_busaddr = ha->logical_drive_info_dma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672) scb->flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673) scb->cmd.logical_info.buffer_addr = scb->data_busaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674) ret = IPS_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677) case SEND_DIAGNOSTIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678) case REASSIGN_BLOCKS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679) case FORMAT_UNIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680) case SEEK_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681) case VERIFY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682) case READ_DEFECT_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) case READ_BUFFER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684) case WRITE_BUFFER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685) scb->scsi_cmd->result = DID_OK << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) /* Set the Return Info to appear like the Command was */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690) /* attempted, a Check Condition occurred, and Sense */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691) /* Data indicating an Invalid CDB OpCode is returned. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692) sp = (char *) scb->scsi_cmd->sense_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694) sp[0] = 0x70; /* Error Code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695) sp[2] = ILLEGAL_REQUEST; /* Sense Key 5 Illegal Req. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696) sp[7] = 0x0A; /* Additional Sense Length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697) sp[12] = 0x20; /* ASC = Invalid OpCode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698) sp[13] = 0x00; /* ASCQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700) device_error = 2; /* Indicate Check Condition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701) scb->scsi_cmd->result = device_error | (DID_OK << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703) } /* end switch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3705) /* end if */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706) if (ret == IPS_SUCCESS_IMM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707) return (ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3709) /* setup DCDB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3710) if (scb->bus > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712) /* If we already know the Device is Not there, no need to attempt a Command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713) /* This also protects an NT FailOver Controller from getting CDB's sent to it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) if (ha->conf->dev[scb->bus - 1][scb->target_id].ucState == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715) scb->scsi_cmd->result = DID_NO_CONNECT << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716) return (IPS_SUCCESS_IMM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719) ha->dcdb_active[scb->bus - 1] |= (1 << scb->target_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720) scb->cmd.dcdb.command_id = IPS_COMMAND_ID(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721) scb->cmd.dcdb.dcdb_address = cpu_to_le32(scb->scb_busaddr +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722) (unsigned long) &scb->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723) dcdb -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724) (unsigned long) scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725) scb->cmd.dcdb.reserved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726) scb->cmd.dcdb.reserved2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727) scb->cmd.dcdb.reserved3 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728) scb->cmd.dcdb.segment_4G = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729) scb->cmd.dcdb.enhanced_sg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731) TimeOut = scb->scsi_cmd->request->timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733) if (ha->subsys->param[4] & 0x00100000) { /* If NEW Tape DCDB is Supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734) if (!scb->sg_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735) scb->cmd.dcdb.op_code = IPS_CMD_EXTENDED_DCDB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737) scb->cmd.dcdb.op_code =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738) IPS_CMD_EXTENDED_DCDB_SG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739) scb->cmd.dcdb.enhanced_sg =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740) IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743) tapeDCDB = (IPS_DCDB_TABLE_TAPE *) & scb->dcdb; /* Use Same Data Area as Old DCDB Struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) tapeDCDB->device_address =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745) ((scb->bus - 1) << 4) | scb->target_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746) tapeDCDB->cmd_attribute |= IPS_DISCONNECT_ALLOWED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747) tapeDCDB->cmd_attribute &= ~IPS_TRANSFER64K; /* Always Turn OFF 64K Size Flag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749) if (TimeOut) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750) if (TimeOut < (10 * HZ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751) tapeDCDB->cmd_attribute |= IPS_TIMEOUT10; /* TimeOut is 10 Seconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752) else if (TimeOut < (60 * HZ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753) tapeDCDB->cmd_attribute |= IPS_TIMEOUT60; /* TimeOut is 60 Seconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754) else if (TimeOut < (1200 * HZ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755) tapeDCDB->cmd_attribute |= IPS_TIMEOUT20M; /* TimeOut is 20 Minutes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758) tapeDCDB->cdb_length = scb->scsi_cmd->cmd_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759) tapeDCDB->reserved_for_LUN = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760) tapeDCDB->transfer_length = scb->data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761) if (scb->cmd.dcdb.op_code == IPS_CMD_EXTENDED_DCDB_SG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762) tapeDCDB->buffer_pointer =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763) cpu_to_le32(scb->sg_busaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3765) tapeDCDB->buffer_pointer =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3766) cpu_to_le32(scb->data_busaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3767) tapeDCDB->sg_count = scb->sg_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768) tapeDCDB->sense_length = sizeof (tapeDCDB->sense_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769) tapeDCDB->scsi_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770) tapeDCDB->reserved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771) memcpy(tapeDCDB->scsi_cdb, scb->scsi_cmd->cmnd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772) scb->scsi_cmd->cmd_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774) if (!scb->sg_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775) scb->cmd.dcdb.op_code = IPS_CMD_DCDB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777) scb->cmd.dcdb.op_code = IPS_CMD_DCDB_SG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778) scb->cmd.dcdb.enhanced_sg =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779) IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782) scb->dcdb.device_address =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783) ((scb->bus - 1) << 4) | scb->target_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784) scb->dcdb.cmd_attribute |= IPS_DISCONNECT_ALLOWED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3786) if (TimeOut) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3787) if (TimeOut < (10 * HZ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3788) scb->dcdb.cmd_attribute |= IPS_TIMEOUT10; /* TimeOut is 10 Seconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3789) else if (TimeOut < (60 * HZ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790) scb->dcdb.cmd_attribute |= IPS_TIMEOUT60; /* TimeOut is 60 Seconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791) else if (TimeOut < (1200 * HZ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3792) scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M; /* TimeOut is 20 Minutes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3795) scb->dcdb.transfer_length = scb->data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3796) if (scb->dcdb.cmd_attribute & IPS_TRANSFER64K)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3797) scb->dcdb.transfer_length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798) if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB_SG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799) scb->dcdb.buffer_pointer =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800) cpu_to_le32(scb->sg_busaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802) scb->dcdb.buffer_pointer =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803) cpu_to_le32(scb->data_busaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804) scb->dcdb.cdb_length = scb->scsi_cmd->cmd_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805) scb->dcdb.sense_length = sizeof (scb->dcdb.sense_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806) scb->dcdb.sg_count = scb->sg_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807) scb->dcdb.reserved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808) memcpy(scb->dcdb.scsi_cdb, scb->scsi_cmd->cmnd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809) scb->scsi_cmd->cmd_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810) scb->dcdb.scsi_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811) scb->dcdb.reserved2[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812) scb->dcdb.reserved2[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813) scb->dcdb.reserved2[2] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817) return ((*ha->func.issue) (ha, scb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822) /* Routine Name: ips_chk_status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826) /* Check the status of commands to logical drives */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827) /* Assumed to be called with the HA lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3829) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3830) ips_chkstatus(ips_ha_t * ha, IPS_STATUS * pstatus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3831) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832) ips_scb_t *scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833) ips_stat_t *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834) uint8_t basic_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835) uint8_t ext_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836) int errcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837) IPS_SCSI_INQ_DATA inquiryData;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839) METHOD_TRACE("ips_chkstatus", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841) scb = &ha->scbs[pstatus->fields.command_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842) scb->basic_status = basic_status =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843) pstatus->fields.basic_status & IPS_BASIC_STATUS_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844) scb->extended_status = ext_status = pstatus->fields.extended_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) sp = &ha->sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847) sp->residue_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3848) sp->scb_addr = (void *) scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3850) /* Remove the item from the active queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3851) ips_removeq_scb(&ha->scb_activelist, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3853) if (!scb->scsi_cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3854) /* internal commands are handled in do_ipsintr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3855) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3857) DEBUG_VAR(2, "(%s%d) ips_chkstatus: cmd 0x%X id %d (%d %d %d)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3858) ips_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3859) ha->host_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3860) scb->cdb[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3861) scb->cmd.basic_io.command_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3862) scb->bus, scb->target_id, scb->lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3864) if ((scb->scsi_cmd) && (ips_is_passthru(scb->scsi_cmd)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3865) /* passthru - just returns the raw result */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3866) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3868) errcode = DID_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3870) if (((basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_SUCCESS) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3871) ((basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_RECOVERED_ERROR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3873) if (scb->bus == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3874) if ((basic_status & IPS_GSC_STATUS_MASK) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3875) IPS_CMD_RECOVERED_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3876) DEBUG_VAR(1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3877) "(%s%d) Recovered Logical Drive Error OpCode: %x, BSB: %x, ESB: %x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3878) ips_name, ha->host_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3879) scb->cmd.basic_io.op_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3880) basic_status, ext_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3881) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3883) switch (scb->scsi_cmd->cmnd[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3884) case ALLOW_MEDIUM_REMOVAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3885) case REZERO_UNIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3886) case ERASE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3887) case WRITE_FILEMARKS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3888) case SPACE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3889) errcode = DID_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3890) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3892) case START_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3893) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3895) case TEST_UNIT_READY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3896) if (!ips_online(ha, scb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3897) errcode = DID_TIME_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3899) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3901) case INQUIRY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3902) if (ips_online(ha, scb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3903) ips_inquiry(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3904) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3905) errcode = DID_TIME_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3906) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3907) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3909) case REQUEST_SENSE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3910) ips_reqsen(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3911) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3913) case READ_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3914) case WRITE_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3915) case READ_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3916) case WRITE_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3917) case RESERVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3918) case RELEASE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3919) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3921) case MODE_SENSE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3922) if (!ips_online(ha, scb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3923) || !ips_msense(ha, scb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3924) errcode = DID_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3926) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3928) case READ_CAPACITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3929) if (ips_online(ha, scb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3930) ips_rdcap(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3931) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3932) errcode = DID_TIME_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3933) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3934) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3936) case SEND_DIAGNOSTIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3937) case REASSIGN_BLOCKS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3938) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3940) case FORMAT_UNIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3941) errcode = DID_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3942) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3944) case SEEK_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3945) case VERIFY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3946) case READ_DEFECT_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3947) case READ_BUFFER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3948) case WRITE_BUFFER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3949) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3951) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3952) errcode = DID_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3953) } /* end switch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3955) scb->scsi_cmd->result = errcode << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3956) } else { /* bus == 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3957) /* restrict access to physical drives */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3958) if (scb->scsi_cmd->cmnd[0] == INQUIRY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3959) ips_scmd_buf_read(scb->scsi_cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3960) &inquiryData, sizeof (inquiryData));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3961) if ((inquiryData.DeviceType & 0x1f) == TYPE_DISK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3962) scb->scsi_cmd->result = DID_TIME_OUT << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3963) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3964) } /* else */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3965) } else { /* recovered error / success */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3966) if (scb->bus == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3967) DEBUG_VAR(1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3968) "(%s%d) Unrecovered Logical Drive Error OpCode: %x, BSB: %x, ESB: %x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3969) ips_name, ha->host_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3970) scb->cmd.basic_io.op_code, basic_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3971) ext_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3972) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3974) ips_map_status(ha, scb, sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3975) } /* else */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3976) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3978) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3979) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3980) /* Routine Name: ips_online */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3981) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3982) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3983) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3984) /* Determine if a logical drive is online */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3985) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3986) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3987) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3988) ips_online(ips_ha_t * ha, ips_scb_t * scb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3989) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3990) METHOD_TRACE("ips_online", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3992) if (scb->target_id >= IPS_MAX_LD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3993) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3995) if ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3996) memset(ha->logical_drive_info, 0, sizeof (IPS_LD_INFO));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3997) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3998) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4000) if (ha->logical_drive_info->drive_info[scb->target_id].state !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4001) IPS_LD_OFFLINE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4002) && ha->logical_drive_info->drive_info[scb->target_id].state !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4003) IPS_LD_FREE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4004) && ha->logical_drive_info->drive_info[scb->target_id].state !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4005) IPS_LD_CRS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4006) && ha->logical_drive_info->drive_info[scb->target_id].state !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4007) IPS_LD_SYS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4008) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4009) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4010) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4011) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4013) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4014) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4015) /* Routine Name: ips_inquiry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4016) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4017) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4018) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4019) /* Simulate an inquiry command to a logical drive */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4020) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4021) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4022) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4023) ips_inquiry(ips_ha_t * ha, ips_scb_t * scb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4024) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4025) IPS_SCSI_INQ_DATA inquiry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4027) METHOD_TRACE("ips_inquiry", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4029) memset(&inquiry, 0, sizeof (IPS_SCSI_INQ_DATA));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4031) inquiry.DeviceType = IPS_SCSI_INQ_TYPE_DASD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4032) inquiry.DeviceTypeQualifier = IPS_SCSI_INQ_LU_CONNECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4033) inquiry.Version = IPS_SCSI_INQ_REV2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4034) inquiry.ResponseDataFormat = IPS_SCSI_INQ_RD_REV2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4035) inquiry.AdditionalLength = 31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4036) inquiry.Flags[0] = IPS_SCSI_INQ_Address16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4037) inquiry.Flags[1] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4038) IPS_SCSI_INQ_WBus16 | IPS_SCSI_INQ_Sync | IPS_SCSI_INQ_CmdQue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4039) memcpy(inquiry.VendorId, "IBM ", 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4040) memcpy(inquiry.ProductId, "SERVERAID ", 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4041) memcpy(inquiry.ProductRevisionLevel, "1.00", 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4043) ips_scmd_buf_write(scb->scsi_cmd, &inquiry, sizeof (inquiry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4045) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4046) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4048) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4049) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4050) /* Routine Name: ips_rdcap */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4051) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4052) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4053) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4054) /* Simulate a read capacity command to a logical drive */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4055) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4056) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4057) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4058) ips_rdcap(ips_ha_t * ha, ips_scb_t * scb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4059) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4060) IPS_SCSI_CAPACITY cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4062) METHOD_TRACE("ips_rdcap", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4064) if (scsi_bufflen(scb->scsi_cmd) < 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4065) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4067) cap.lba =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4068) cpu_to_be32(le32_to_cpu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4069) (ha->logical_drive_info->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4070) drive_info[scb->target_id].sector_count) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4071) cap.len = cpu_to_be32((uint32_t) IPS_BLKSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4073) ips_scmd_buf_write(scb->scsi_cmd, &cap, sizeof (cap));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4075) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4076) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4078) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4079) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4080) /* Routine Name: ips_msense */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4081) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4082) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4083) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4084) /* Simulate a mode sense command to a logical drive */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4085) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4086) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4087) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4088) ips_msense(ips_ha_t * ha, ips_scb_t * scb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4089) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4090) uint16_t heads;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4091) uint16_t sectors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4092) uint32_t cylinders;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4093) IPS_SCSI_MODE_PAGE_DATA mdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4095) METHOD_TRACE("ips_msense", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4097) if (le32_to_cpu(ha->enq->ulDriveSize[scb->target_id]) > 0x400000 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4098) (ha->enq->ucMiscFlag & 0x8) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4099) heads = IPS_NORM_HEADS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4100) sectors = IPS_NORM_SECTORS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4101) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4102) heads = IPS_COMP_HEADS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4103) sectors = IPS_COMP_SECTORS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4106) cylinders =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4107) (le32_to_cpu(ha->enq->ulDriveSize[scb->target_id]) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4108) 1) / (heads * sectors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4110) memset(&mdata, 0, sizeof (IPS_SCSI_MODE_PAGE_DATA));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4112) mdata.hdr.BlockDescLength = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4114) switch (scb->scsi_cmd->cmnd[2] & 0x3f) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4115) case 0x03: /* page 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4116) mdata.pdata.pg3.PageCode = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4117) mdata.pdata.pg3.PageLength = sizeof (IPS_SCSI_MODE_PAGE3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4118) mdata.hdr.DataLength =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4119) 3 + mdata.hdr.BlockDescLength + mdata.pdata.pg3.PageLength;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4120) mdata.pdata.pg3.TracksPerZone = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4121) mdata.pdata.pg3.AltSectorsPerZone = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4122) mdata.pdata.pg3.AltTracksPerZone = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4123) mdata.pdata.pg3.AltTracksPerVolume = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4124) mdata.pdata.pg3.SectorsPerTrack = cpu_to_be16(sectors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4125) mdata.pdata.pg3.BytesPerSector = cpu_to_be16(IPS_BLKSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4126) mdata.pdata.pg3.Interleave = cpu_to_be16(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4127) mdata.pdata.pg3.TrackSkew = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4128) mdata.pdata.pg3.CylinderSkew = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4129) mdata.pdata.pg3.flags = IPS_SCSI_MP3_SoftSector;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4130) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4132) case 0x4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4133) mdata.pdata.pg4.PageCode = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4134) mdata.pdata.pg4.PageLength = sizeof (IPS_SCSI_MODE_PAGE4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4135) mdata.hdr.DataLength =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4136) 3 + mdata.hdr.BlockDescLength + mdata.pdata.pg4.PageLength;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4137) mdata.pdata.pg4.CylindersHigh =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4138) cpu_to_be16((cylinders >> 8) & 0xFFFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4139) mdata.pdata.pg4.CylindersLow = (cylinders & 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4140) mdata.pdata.pg4.Heads = heads;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4141) mdata.pdata.pg4.WritePrecompHigh = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4142) mdata.pdata.pg4.WritePrecompLow = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4143) mdata.pdata.pg4.ReducedWriteCurrentHigh = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4144) mdata.pdata.pg4.ReducedWriteCurrentLow = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4145) mdata.pdata.pg4.StepRate = cpu_to_be16(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4146) mdata.pdata.pg4.LandingZoneHigh = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4147) mdata.pdata.pg4.LandingZoneLow = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4148) mdata.pdata.pg4.flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4149) mdata.pdata.pg4.RotationalOffset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4150) mdata.pdata.pg4.MediumRotationRate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4151) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4152) case 0x8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4153) mdata.pdata.pg8.PageCode = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4154) mdata.pdata.pg8.PageLength = sizeof (IPS_SCSI_MODE_PAGE8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4155) mdata.hdr.DataLength =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4156) 3 + mdata.hdr.BlockDescLength + mdata.pdata.pg8.PageLength;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4157) /* everything else is left set to 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4158) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4160) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4161) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4162) } /* end switch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4164) ips_scmd_buf_write(scb->scsi_cmd, &mdata, sizeof (mdata));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4166) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4169) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4170) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4171) /* Routine Name: ips_reqsen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4172) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4173) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4174) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4175) /* Simulate a request sense command to a logical drive */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4176) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4177) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4178) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4179) ips_reqsen(ips_ha_t * ha, ips_scb_t * scb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4181) IPS_SCSI_REQSEN reqsen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4183) METHOD_TRACE("ips_reqsen", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4185) memset(&reqsen, 0, sizeof (IPS_SCSI_REQSEN));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4187) reqsen.ResponseCode =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4188) IPS_SCSI_REQSEN_VALID | IPS_SCSI_REQSEN_CURRENT_ERR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4189) reqsen.AdditionalLength = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4190) reqsen.AdditionalSenseCode = IPS_SCSI_REQSEN_NO_SENSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4191) reqsen.AdditionalSenseCodeQual = IPS_SCSI_REQSEN_NO_SENSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4193) ips_scmd_buf_write(scb->scsi_cmd, &reqsen, sizeof (reqsen));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4195) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4198) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4199) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4200) /* Routine Name: ips_free */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4201) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4202) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4203) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4204) /* Free any allocated space for this controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4205) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4206) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4207) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4208) ips_free(ips_ha_t * ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4211) METHOD_TRACE("ips_free", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4213) if (ha) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4214) if (ha->enq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4215) dma_free_coherent(&ha->pcidev->dev, sizeof(IPS_ENQ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4216) ha->enq, ha->enq_busaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4217) ha->enq = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4220) kfree(ha->conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4221) ha->conf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4223) if (ha->adapt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4224) dma_free_coherent(&ha->pcidev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4225) sizeof (IPS_ADAPTER) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4226) sizeof (IPS_IO_CMD), ha->adapt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4227) ha->adapt->hw_status_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4228) ha->adapt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4231) if (ha->logical_drive_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4232) dma_free_coherent(&ha->pcidev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4233) sizeof (IPS_LD_INFO),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4234) ha->logical_drive_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4235) ha->logical_drive_info_dma_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4236) ha->logical_drive_info = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4239) kfree(ha->nvram);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4240) ha->nvram = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4242) kfree(ha->subsys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4243) ha->subsys = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4245) if (ha->ioctl_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4246) dma_free_coherent(&ha->pcidev->dev, ha->ioctl_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4247) ha->ioctl_data, ha->ioctl_busaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4248) ha->ioctl_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4249) ha->ioctl_datasize = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4250) ha->ioctl_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4252) ips_deallocatescbs(ha, ha->max_cmds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4254) /* free memory mapped (if applicable) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4255) if (ha->mem_ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4256) iounmap(ha->ioremap_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4257) ha->ioremap_ptr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4258) ha->mem_ptr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4261) ha->mem_addr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4266) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4267) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4268) /* Routine Name: ips_deallocatescbs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4269) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4270) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4271) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4272) /* Free the command blocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4273) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4274) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4275) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4276) ips_deallocatescbs(ips_ha_t * ha, int cmds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4278) if (ha->scbs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4279) dma_free_coherent(&ha->pcidev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4280) IPS_SGLIST_SIZE(ha) * IPS_MAX_SG * cmds,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4281) ha->scbs->sg_list.list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4282) ha->scbs->sg_busaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4283) dma_free_coherent(&ha->pcidev->dev, sizeof (ips_scb_t) * cmds,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4284) ha->scbs, ha->scbs->scb_busaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4285) ha->scbs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4286) } /* end if */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4287) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4290) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4291) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4292) /* Routine Name: ips_allocatescbs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4293) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4294) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4295) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4296) /* Allocate the command blocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4297) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4298) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4299) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4300) ips_allocatescbs(ips_ha_t * ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4302) ips_scb_t *scb_p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4303) IPS_SG_LIST ips_sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4304) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4305) dma_addr_t command_dma, sg_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4307) METHOD_TRACE("ips_allocatescbs", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4309) /* Allocate memory for the SCBs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4310) ha->scbs = dma_alloc_coherent(&ha->pcidev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4311) ha->max_cmds * sizeof (ips_scb_t),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4312) &command_dma, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4313) if (ha->scbs == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4314) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4315) ips_sg.list = dma_alloc_coherent(&ha->pcidev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4316) IPS_SGLIST_SIZE(ha) * IPS_MAX_SG * ha->max_cmds,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4317) &sg_dma, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4318) if (ips_sg.list == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4319) dma_free_coherent(&ha->pcidev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4320) ha->max_cmds * sizeof (ips_scb_t), ha->scbs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4321) command_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4322) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4325) memset(ha->scbs, 0, ha->max_cmds * sizeof (ips_scb_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4327) for (i = 0; i < ha->max_cmds; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4328) scb_p = &ha->scbs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4329) scb_p->scb_busaddr = command_dma + sizeof (ips_scb_t) * i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4330) /* set up S/G list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4331) if (IPS_USE_ENH_SGLIST(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4332) scb_p->sg_list.enh_list =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4333) ips_sg.enh_list + i * IPS_MAX_SG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4334) scb_p->sg_busaddr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4335) sg_dma + IPS_SGLIST_SIZE(ha) * IPS_MAX_SG * i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4336) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4337) scb_p->sg_list.std_list =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4338) ips_sg.std_list + i * IPS_MAX_SG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4339) scb_p->sg_busaddr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4340) sg_dma + IPS_SGLIST_SIZE(ha) * IPS_MAX_SG * i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4343) /* add to the free list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4344) if (i < ha->max_cmds - 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4345) scb_p->q_next = ha->scb_freelist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4346) ha->scb_freelist = scb_p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4350) /* success */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4351) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4354) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4355) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4356) /* Routine Name: ips_init_scb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4357) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4358) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4359) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4360) /* Initialize a CCB to default values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4361) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4362) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4363) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4364) ips_init_scb(ips_ha_t * ha, ips_scb_t * scb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4365) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4366) IPS_SG_LIST sg_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4367) uint32_t cmd_busaddr, sg_busaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4368) METHOD_TRACE("ips_init_scb", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4370) if (scb == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4371) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4373) sg_list.list = scb->sg_list.list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4374) cmd_busaddr = scb->scb_busaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4375) sg_busaddr = scb->sg_busaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4376) /* zero fill */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4377) memset(scb, 0, sizeof (ips_scb_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4378) memset(ha->dummy, 0, sizeof (IPS_IO_CMD));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4380) /* Initialize dummy command bucket */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4381) ha->dummy->op_code = 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4382) ha->dummy->ccsar = cpu_to_le32(ha->adapt->hw_status_start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4383) + sizeof (IPS_ADAPTER));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4384) ha->dummy->command_id = IPS_MAX_CMDS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4386) /* set bus address of scb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4387) scb->scb_busaddr = cmd_busaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4388) scb->sg_busaddr = sg_busaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4389) scb->sg_list.list = sg_list.list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4391) /* Neptune Fix */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4392) scb->cmd.basic_io.cccr = cpu_to_le32((uint32_t) IPS_BIT_ILE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4393) scb->cmd.basic_io.ccsar = cpu_to_le32(ha->adapt->hw_status_start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4394) + sizeof (IPS_ADAPTER));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4397) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4398) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4399) /* Routine Name: ips_get_scb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4400) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4401) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4402) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4403) /* Initialize a CCB to default values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4404) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4405) /* ASSUMED to be called from within a lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4406) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4407) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4408) static ips_scb_t *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4409) ips_getscb(ips_ha_t * ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4410) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4411) ips_scb_t *scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4413) METHOD_TRACE("ips_getscb", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4415) if ((scb = ha->scb_freelist) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4417) return (NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4420) ha->scb_freelist = scb->q_next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4421) scb->flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4422) scb->q_next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4424) ips_init_scb(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4426) return (scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4429) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4430) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4431) /* Routine Name: ips_free_scb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4432) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4433) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4434) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4435) /* Return an unused CCB back to the free list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4436) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4437) /* ASSUMED to be called from within a lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4438) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4439) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4440) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4441) ips_freescb(ips_ha_t * ha, ips_scb_t * scb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4442) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4444) METHOD_TRACE("ips_freescb", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4445) if (scb->flags & IPS_SCB_MAP_SG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4446) scsi_dma_unmap(scb->scsi_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4447) else if (scb->flags & IPS_SCB_MAP_SINGLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4448) dma_unmap_single(&ha->pcidev->dev, scb->data_busaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4449) scb->data_len, IPS_DMA_DIR(scb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4451) /* check to make sure this is not our "special" scb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4452) if (IPS_COMMAND_ID(ha, scb) < (ha->max_cmds - 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4453) scb->q_next = ha->scb_freelist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4454) ha->scb_freelist = scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4458) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4459) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4460) /* Routine Name: ips_isinit_copperhead */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4461) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4462) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4463) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4464) /* Is controller initialized ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4465) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4466) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4467) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4468) ips_isinit_copperhead(ips_ha_t * ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4469) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4470) uint8_t scpr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4471) uint8_t isr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4473) METHOD_TRACE("ips_isinit_copperhead", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4475) isr = inb(ha->io_addr + IPS_REG_HISR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4476) scpr = inb(ha->io_addr + IPS_REG_SCPR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4478) if (((isr & IPS_BIT_EI) == 0) && ((scpr & IPS_BIT_EBM) == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4479) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4480) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4481) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4484) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4485) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4486) /* Routine Name: ips_isinit_copperhead_memio */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4487) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4488) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4489) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4490) /* Is controller initialized ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4491) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4492) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4493) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4494) ips_isinit_copperhead_memio(ips_ha_t * ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4495) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4496) uint8_t isr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4497) uint8_t scpr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4499) METHOD_TRACE("ips_is_init_copperhead_memio", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4501) isr = readb(ha->mem_ptr + IPS_REG_HISR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4502) scpr = readb(ha->mem_ptr + IPS_REG_SCPR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4504) if (((isr & IPS_BIT_EI) == 0) && ((scpr & IPS_BIT_EBM) == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4505) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4506) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4507) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4510) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4511) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4512) /* Routine Name: ips_isinit_morpheus */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4513) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4514) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4515) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4516) /* Is controller initialized ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4517) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4518) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4519) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4520) ips_isinit_morpheus(ips_ha_t * ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4521) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4522) uint32_t post;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4523) uint32_t bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4525) METHOD_TRACE("ips_is_init_morpheus", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4527) if (ips_isintr_morpheus(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4528) ips_flush_and_reset(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4530) post = readl(ha->mem_ptr + IPS_REG_I960_MSG0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4531) bits = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4533) if (post == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4534) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4535) else if (bits & 0x3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4536) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4537) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4538) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4541) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4542) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4543) /* Routine Name: ips_flush_and_reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4544) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4545) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4546) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4547) /* Perform cleanup ( FLUSH and RESET ) when the adapter is in an unknown */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4548) /* state ( was trying to INIT and an interrupt was already pending ) ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4549) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4550) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4551) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4552) ips_flush_and_reset(ips_ha_t *ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4553) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4554) ips_scb_t *scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4555) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4556) int time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4557) int done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4558) dma_addr_t command_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4560) /* Create a usuable SCB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4561) scb = dma_alloc_coherent(&ha->pcidev->dev, sizeof(ips_scb_t),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4562) &command_dma, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4563) if (scb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4564) memset(scb, 0, sizeof(ips_scb_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4565) ips_init_scb(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4566) scb->scb_busaddr = command_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4568) scb->timeout = ips_cmd_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4569) scb->cdb[0] = IPS_CMD_FLUSH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4571) scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4572) scb->cmd.flush_cache.command_id = IPS_MAX_CMDS; /* Use an ID that would otherwise not exist */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4573) scb->cmd.flush_cache.state = IPS_NORM_STATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4574) scb->cmd.flush_cache.reserved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4575) scb->cmd.flush_cache.reserved2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4576) scb->cmd.flush_cache.reserved3 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4577) scb->cmd.flush_cache.reserved4 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4579) ret = ips_send_cmd(ha, scb); /* Send the Flush Command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4581) if (ret == IPS_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4582) time = 60 * IPS_ONE_SEC; /* Max Wait time is 60 seconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4583) done = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4585) while ((time > 0) && (!done)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4586) done = ips_poll_for_flush_complete(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4587) /* This may look evil, but it's only done during extremely rare start-up conditions ! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4588) udelay(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4589) time--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4592) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4594) /* Now RESET and INIT the adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4595) (*ha->func.reset) (ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4597) dma_free_coherent(&ha->pcidev->dev, sizeof(ips_scb_t), scb, command_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4598) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4601) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4602) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4603) /* Routine Name: ips_poll_for_flush_complete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4604) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4605) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4606) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4607) /* Poll for the Flush Command issued by ips_flush_and_reset() to complete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4608) /* All other responses are just taken off the queue and ignored */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4609) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4610) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4611) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4612) ips_poll_for_flush_complete(ips_ha_t * ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4613) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4614) IPS_STATUS cstatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4616) while (TRUE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4617) cstatus.value = (*ha->func.statupd) (ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4619) if (cstatus.value == 0xffffffff) /* If No Interrupt to process */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4620) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4622) /* Success is when we see the Flush Command ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4623) if (cstatus.fields.command_id == IPS_MAX_CMDS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4624) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4627) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4630) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4631) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4632) /* Routine Name: ips_enable_int_copperhead */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4633) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4634) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4635) /* Turn on interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4636) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4637) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4638) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4639) ips_enable_int_copperhead(ips_ha_t * ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4640) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4641) METHOD_TRACE("ips_enable_int_copperhead", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4643) outb(ha->io_addr + IPS_REG_HISR, IPS_BIT_EI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4644) inb(ha->io_addr + IPS_REG_HISR); /*Ensure PCI Posting Completes*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4647) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4648) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4649) /* Routine Name: ips_enable_int_copperhead_memio */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4650) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4651) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4652) /* Turn on interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4653) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4654) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4655) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4656) ips_enable_int_copperhead_memio(ips_ha_t * ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4657) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4658) METHOD_TRACE("ips_enable_int_copperhead_memio", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4660) writeb(IPS_BIT_EI, ha->mem_ptr + IPS_REG_HISR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4661) readb(ha->mem_ptr + IPS_REG_HISR); /*Ensure PCI Posting Completes*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4664) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4665) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4666) /* Routine Name: ips_enable_int_morpheus */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4667) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4668) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4669) /* Turn on interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4670) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4671) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4672) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4673) ips_enable_int_morpheus(ips_ha_t * ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4674) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4675) uint32_t Oimr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4677) METHOD_TRACE("ips_enable_int_morpheus", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4679) Oimr = readl(ha->mem_ptr + IPS_REG_I960_OIMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4680) Oimr &= ~0x08;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4681) writel(Oimr, ha->mem_ptr + IPS_REG_I960_OIMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4682) readl(ha->mem_ptr + IPS_REG_I960_OIMR); /*Ensure PCI Posting Completes*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4685) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4686) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4687) /* Routine Name: ips_init_copperhead */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4688) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4689) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4690) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4691) /* Initialize a copperhead controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4692) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4693) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4694) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4695) ips_init_copperhead(ips_ha_t * ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4696) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4697) uint8_t Isr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4698) uint8_t Cbsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4699) uint8_t PostByte[IPS_MAX_POST_BYTES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4700) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4702) METHOD_TRACE("ips_init_copperhead", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4704) for (i = 0; i < IPS_MAX_POST_BYTES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4705) for (j = 0; j < 45; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4706) Isr = inb(ha->io_addr + IPS_REG_HISR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4707) if (Isr & IPS_BIT_GHI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4708) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4710) /* Delay for 1 Second */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4711) MDELAY(IPS_ONE_SEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4714) if (j >= 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4715) /* error occurred */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4716) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4718) PostByte[i] = inb(ha->io_addr + IPS_REG_ISPR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4719) outb(Isr, ha->io_addr + IPS_REG_HISR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4722) if (PostByte[0] < IPS_GOOD_POST_STATUS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4723) IPS_PRINTK(KERN_WARNING, ha->pcidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4724) "reset controller fails (post status %x %x).\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4725) PostByte[0], PostByte[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4727) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4730) for (i = 0; i < IPS_MAX_CONFIG_BYTES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4731) for (j = 0; j < 240; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4732) Isr = inb(ha->io_addr + IPS_REG_HISR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4733) if (Isr & IPS_BIT_GHI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4734) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4736) /* Delay for 1 Second */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4737) MDELAY(IPS_ONE_SEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4740) if (j >= 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4741) /* error occurred */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4742) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4744) inb(ha->io_addr + IPS_REG_ISPR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4745) outb(Isr, ha->io_addr + IPS_REG_HISR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4748) for (i = 0; i < 240; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4749) Cbsp = inb(ha->io_addr + IPS_REG_CBSP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4751) if ((Cbsp & IPS_BIT_OP) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4752) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4754) /* Delay for 1 Second */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4755) MDELAY(IPS_ONE_SEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4758) if (i >= 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4759) /* reset failed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4760) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4762) /* setup CCCR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4763) outl(0x1010, ha->io_addr + IPS_REG_CCCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4765) /* Enable busmastering */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4766) outb(IPS_BIT_EBM, ha->io_addr + IPS_REG_SCPR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4768) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4769) /* fix for anaconda64 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4770) outl(0, ha->io_addr + IPS_REG_NDAE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4772) /* Enable interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4773) outb(IPS_BIT_EI, ha->io_addr + IPS_REG_HISR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4775) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4778) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4779) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4780) /* Routine Name: ips_init_copperhead_memio */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4781) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4782) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4783) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4784) /* Initialize a copperhead controller with memory mapped I/O */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4785) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4786) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4787) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4788) ips_init_copperhead_memio(ips_ha_t * ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4789) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4790) uint8_t Isr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4791) uint8_t Cbsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4792) uint8_t PostByte[IPS_MAX_POST_BYTES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4793) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4795) METHOD_TRACE("ips_init_copperhead_memio", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4797) for (i = 0; i < IPS_MAX_POST_BYTES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4798) for (j = 0; j < 45; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4799) Isr = readb(ha->mem_ptr + IPS_REG_HISR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4800) if (Isr & IPS_BIT_GHI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4801) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4803) /* Delay for 1 Second */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4804) MDELAY(IPS_ONE_SEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4807) if (j >= 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4808) /* error occurred */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4809) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4811) PostByte[i] = readb(ha->mem_ptr + IPS_REG_ISPR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4812) writeb(Isr, ha->mem_ptr + IPS_REG_HISR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4815) if (PostByte[0] < IPS_GOOD_POST_STATUS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4816) IPS_PRINTK(KERN_WARNING, ha->pcidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4817) "reset controller fails (post status %x %x).\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4818) PostByte[0], PostByte[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4820) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4821) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4823) for (i = 0; i < IPS_MAX_CONFIG_BYTES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4824) for (j = 0; j < 240; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4825) Isr = readb(ha->mem_ptr + IPS_REG_HISR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4826) if (Isr & IPS_BIT_GHI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4827) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4829) /* Delay for 1 Second */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4830) MDELAY(IPS_ONE_SEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4833) if (j >= 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4834) /* error occurred */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4835) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4837) readb(ha->mem_ptr + IPS_REG_ISPR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4838) writeb(Isr, ha->mem_ptr + IPS_REG_HISR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4841) for (i = 0; i < 240; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4842) Cbsp = readb(ha->mem_ptr + IPS_REG_CBSP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4844) if ((Cbsp & IPS_BIT_OP) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4845) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4847) /* Delay for 1 Second */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4848) MDELAY(IPS_ONE_SEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4849) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4851) if (i >= 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4852) /* error occurred */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4853) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4855) /* setup CCCR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4856) writel(0x1010, ha->mem_ptr + IPS_REG_CCCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4858) /* Enable busmastering */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4859) writeb(IPS_BIT_EBM, ha->mem_ptr + IPS_REG_SCPR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4861) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4862) /* fix for anaconda64 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4863) writel(0, ha->mem_ptr + IPS_REG_NDAE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4865) /* Enable interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4866) writeb(IPS_BIT_EI, ha->mem_ptr + IPS_REG_HISR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4868) /* if we get here then everything went OK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4869) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4870) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4872) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4873) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4874) /* Routine Name: ips_init_morpheus */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4875) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4876) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4877) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4878) /* Initialize a morpheus controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4879) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4880) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4881) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4882) ips_init_morpheus(ips_ha_t * ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4883) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4884) uint32_t Post;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4885) uint32_t Config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4886) uint32_t Isr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4887) uint32_t Oimr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4888) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4890) METHOD_TRACE("ips_init_morpheus", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4892) /* Wait up to 45 secs for Post */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4893) for (i = 0; i < 45; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4894) Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4896) if (Isr & IPS_BIT_I960_MSG0I)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4897) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4899) /* Delay for 1 Second */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4900) MDELAY(IPS_ONE_SEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4903) if (i >= 45) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4904) /* error occurred */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4905) IPS_PRINTK(KERN_WARNING, ha->pcidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4906) "timeout waiting for post.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4908) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4909) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4911) Post = readl(ha->mem_ptr + IPS_REG_I960_MSG0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4913) if (Post == 0x4F00) { /* If Flashing the Battery PIC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4914) IPS_PRINTK(KERN_WARNING, ha->pcidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4915) "Flashing Battery PIC, Please wait ...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4917) /* Clear the interrupt bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4918) Isr = (uint32_t) IPS_BIT_I960_MSG0I;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4919) writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4921) for (i = 0; i < 120; i++) { /* Wait Up to 2 Min. for Completion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4922) Post = readl(ha->mem_ptr + IPS_REG_I960_MSG0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4923) if (Post != 0x4F00)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4924) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4925) /* Delay for 1 Second */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4926) MDELAY(IPS_ONE_SEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4929) if (i >= 120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4930) IPS_PRINTK(KERN_WARNING, ha->pcidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4931) "timeout waiting for Battery PIC Flash\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4932) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4933) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4937) /* Clear the interrupt bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4938) Isr = (uint32_t) IPS_BIT_I960_MSG0I;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4939) writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4941) if (Post < (IPS_GOOD_POST_STATUS << 8)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4942) IPS_PRINTK(KERN_WARNING, ha->pcidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4943) "reset controller fails (post status %x).\n", Post);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4945) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4946) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4948) /* Wait up to 240 secs for config bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4949) for (i = 0; i < 240; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4950) Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4952) if (Isr & IPS_BIT_I960_MSG1I)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4953) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4955) /* Delay for 1 Second */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4956) MDELAY(IPS_ONE_SEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4959) if (i >= 240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4960) /* error occurred */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4961) IPS_PRINTK(KERN_WARNING, ha->pcidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4962) "timeout waiting for config.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4964) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4965) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4967) Config = readl(ha->mem_ptr + IPS_REG_I960_MSG1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4969) /* Clear interrupt bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4970) Isr = (uint32_t) IPS_BIT_I960_MSG1I;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4971) writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4973) /* Turn on the interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4974) Oimr = readl(ha->mem_ptr + IPS_REG_I960_OIMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4975) Oimr &= ~0x8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4976) writel(Oimr, ha->mem_ptr + IPS_REG_I960_OIMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4978) /* if we get here then everything went OK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4980) /* Since we did a RESET, an EraseStripeLock may be needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4981) if (Post == 0xEF10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4982) if ((Config == 0x000F) || (Config == 0x0009))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4983) ha->requires_esl = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4986) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4987) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4989) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4990) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4991) /* Routine Name: ips_reset_copperhead */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4992) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4993) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4994) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4995) /* Reset the controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4996) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4997) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4998) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4999) ips_reset_copperhead(ips_ha_t * ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5001) int reset_counter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5003) METHOD_TRACE("ips_reset_copperhead", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5005) DEBUG_VAR(1, "(%s%d) ips_reset_copperhead: io addr: %x, irq: %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5006) ips_name, ha->host_num, ha->io_addr, ha->pcidev->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5008) reset_counter = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5010) while (reset_counter < 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5011) reset_counter++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5013) outb(IPS_BIT_RST, ha->io_addr + IPS_REG_SCPR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5015) /* Delay for 1 Second */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5016) MDELAY(IPS_ONE_SEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5018) outb(0, ha->io_addr + IPS_REG_SCPR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5020) /* Delay for 1 Second */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5021) MDELAY(IPS_ONE_SEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5023) if ((*ha->func.init) (ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5024) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5025) else if (reset_counter >= 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5027) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5028) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5029) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5031) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5032) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5034) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5035) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5036) /* Routine Name: ips_reset_copperhead_memio */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5037) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5038) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5039) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5040) /* Reset the controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5041) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5042) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5043) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5044) ips_reset_copperhead_memio(ips_ha_t * ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5045) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5046) int reset_counter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5048) METHOD_TRACE("ips_reset_copperhead_memio", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5050) DEBUG_VAR(1, "(%s%d) ips_reset_copperhead_memio: mem addr: %x, irq: %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5051) ips_name, ha->host_num, ha->mem_addr, ha->pcidev->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5053) reset_counter = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5055) while (reset_counter < 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5056) reset_counter++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5058) writeb(IPS_BIT_RST, ha->mem_ptr + IPS_REG_SCPR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5060) /* Delay for 1 Second */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5061) MDELAY(IPS_ONE_SEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5063) writeb(0, ha->mem_ptr + IPS_REG_SCPR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5065) /* Delay for 1 Second */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5066) MDELAY(IPS_ONE_SEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5068) if ((*ha->func.init) (ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5069) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5070) else if (reset_counter >= 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5072) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5073) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5074) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5076) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5077) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5079) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5080) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5081) /* Routine Name: ips_reset_morpheus */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5082) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5083) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5084) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5085) /* Reset the controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5086) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5087) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5088) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5089) ips_reset_morpheus(ips_ha_t * ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5090) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5091) int reset_counter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5092) uint8_t junk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5094) METHOD_TRACE("ips_reset_morpheus", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5096) DEBUG_VAR(1, "(%s%d) ips_reset_morpheus: mem addr: %x, irq: %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5097) ips_name, ha->host_num, ha->mem_addr, ha->pcidev->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5099) reset_counter = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5101) while (reset_counter < 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5102) reset_counter++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5104) writel(0x80000000, ha->mem_ptr + IPS_REG_I960_IDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5106) /* Delay for 5 Seconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5107) MDELAY(5 * IPS_ONE_SEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5109) /* Do a PCI config read to wait for adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5110) pci_read_config_byte(ha->pcidev, 4, &junk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5112) if ((*ha->func.init) (ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5113) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5114) else if (reset_counter >= 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5116) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5120) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5123) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5124) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5125) /* Routine Name: ips_statinit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5126) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5127) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5128) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5129) /* Initialize the status queues on the controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5130) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5131) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5132) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5133) ips_statinit(ips_ha_t * ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5135) uint32_t phys_status_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5137) METHOD_TRACE("ips_statinit", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5139) ha->adapt->p_status_start = ha->adapt->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5140) ha->adapt->p_status_end = ha->adapt->status + IPS_MAX_CMDS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5141) ha->adapt->p_status_tail = ha->adapt->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5143) phys_status_start = ha->adapt->hw_status_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5144) outl(phys_status_start, ha->io_addr + IPS_REG_SQSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5145) outl(phys_status_start + IPS_STATUS_Q_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5146) ha->io_addr + IPS_REG_SQER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5147) outl(phys_status_start + IPS_STATUS_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5148) ha->io_addr + IPS_REG_SQHR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5149) outl(phys_status_start, ha->io_addr + IPS_REG_SQTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5151) ha->adapt->hw_status_tail = phys_status_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5154) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5155) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5156) /* Routine Name: ips_statinit_memio */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5157) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5158) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5159) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5160) /* Initialize the status queues on the controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5161) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5162) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5163) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5164) ips_statinit_memio(ips_ha_t * ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5166) uint32_t phys_status_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5168) METHOD_TRACE("ips_statinit_memio", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5170) ha->adapt->p_status_start = ha->adapt->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5171) ha->adapt->p_status_end = ha->adapt->status + IPS_MAX_CMDS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5172) ha->adapt->p_status_tail = ha->adapt->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5174) phys_status_start = ha->adapt->hw_status_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5175) writel(phys_status_start, ha->mem_ptr + IPS_REG_SQSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5176) writel(phys_status_start + IPS_STATUS_Q_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5177) ha->mem_ptr + IPS_REG_SQER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5178) writel(phys_status_start + IPS_STATUS_SIZE, ha->mem_ptr + IPS_REG_SQHR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5179) writel(phys_status_start, ha->mem_ptr + IPS_REG_SQTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5181) ha->adapt->hw_status_tail = phys_status_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5184) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5185) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5186) /* Routine Name: ips_statupd_copperhead */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5187) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5188) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5189) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5190) /* Remove an element from the status queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5191) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5192) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5193) static uint32_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5194) ips_statupd_copperhead(ips_ha_t * ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5196) METHOD_TRACE("ips_statupd_copperhead", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5198) if (ha->adapt->p_status_tail != ha->adapt->p_status_end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5199) ha->adapt->p_status_tail++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5200) ha->adapt->hw_status_tail += sizeof (IPS_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5201) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5202) ha->adapt->p_status_tail = ha->adapt->p_status_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5203) ha->adapt->hw_status_tail = ha->adapt->hw_status_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5206) outl(ha->adapt->hw_status_tail,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5207) ha->io_addr + IPS_REG_SQTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5209) return (ha->adapt->p_status_tail->value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5212) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5213) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5214) /* Routine Name: ips_statupd_copperhead_memio */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5215) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5216) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5217) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5218) /* Remove an element from the status queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5219) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5220) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5221) static uint32_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5222) ips_statupd_copperhead_memio(ips_ha_t * ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5223) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5224) METHOD_TRACE("ips_statupd_copperhead_memio", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5226) if (ha->adapt->p_status_tail != ha->adapt->p_status_end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5227) ha->adapt->p_status_tail++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5228) ha->adapt->hw_status_tail += sizeof (IPS_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5229) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5230) ha->adapt->p_status_tail = ha->adapt->p_status_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5231) ha->adapt->hw_status_tail = ha->adapt->hw_status_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5234) writel(ha->adapt->hw_status_tail, ha->mem_ptr + IPS_REG_SQTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5236) return (ha->adapt->p_status_tail->value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5239) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5240) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5241) /* Routine Name: ips_statupd_morpheus */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5242) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5243) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5244) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5245) /* Remove an element from the status queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5246) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5247) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5248) static uint32_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5249) ips_statupd_morpheus(ips_ha_t * ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5251) uint32_t val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5253) METHOD_TRACE("ips_statupd_morpheus", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5255) val = readl(ha->mem_ptr + IPS_REG_I2O_OUTMSGQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5257) return (val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5260) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5261) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5262) /* Routine Name: ips_issue_copperhead */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5263) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5264) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5265) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5266) /* Send a command down to the controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5267) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5268) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5269) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5270) ips_issue_copperhead(ips_ha_t * ha, ips_scb_t * scb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5272) uint32_t TimeOut;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5273) uint32_t val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5275) METHOD_TRACE("ips_issue_copperhead", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5277) if (scb->scsi_cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5278) DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5279) ips_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5280) ha->host_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5281) scb->cdb[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5282) scb->cmd.basic_io.command_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5283) scb->bus, scb->target_id, scb->lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5284) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5285) DEBUG_VAR(2, KERN_NOTICE "(%s%d) ips_issue: logical cmd id %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5286) ips_name, ha->host_num, scb->cmd.basic_io.command_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5289) TimeOut = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5291) while ((val =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5292) le32_to_cpu(inl(ha->io_addr + IPS_REG_CCCR))) & IPS_BIT_SEM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5293) udelay(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5295) if (++TimeOut >= IPS_SEM_TIMEOUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5296) if (!(val & IPS_BIT_START_STOP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5297) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5299) IPS_PRINTK(KERN_WARNING, ha->pcidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5300) "ips_issue val [0x%x].\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5301) IPS_PRINTK(KERN_WARNING, ha->pcidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5302) "ips_issue semaphore chk timeout.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5304) return (IPS_FAILURE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5305) } /* end if */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5306) } /* end while */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5308) outl(scb->scb_busaddr, ha->io_addr + IPS_REG_CCSAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5309) outw(IPS_BIT_START_CMD, ha->io_addr + IPS_REG_CCCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5311) return (IPS_SUCCESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5314) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5315) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5316) /* Routine Name: ips_issue_copperhead_memio */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5317) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5318) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5319) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5320) /* Send a command down to the controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5321) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5322) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5323) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5324) ips_issue_copperhead_memio(ips_ha_t * ha, ips_scb_t * scb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5325) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5326) uint32_t TimeOut;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5327) uint32_t val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5329) METHOD_TRACE("ips_issue_copperhead_memio", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5331) if (scb->scsi_cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5332) DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5333) ips_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5334) ha->host_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5335) scb->cdb[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5336) scb->cmd.basic_io.command_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5337) scb->bus, scb->target_id, scb->lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5338) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5339) DEBUG_VAR(2, "(%s%d) ips_issue: logical cmd id %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5340) ips_name, ha->host_num, scb->cmd.basic_io.command_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5343) TimeOut = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5345) while ((val = readl(ha->mem_ptr + IPS_REG_CCCR)) & IPS_BIT_SEM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5346) udelay(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5348) if (++TimeOut >= IPS_SEM_TIMEOUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5349) if (!(val & IPS_BIT_START_STOP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5350) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5352) IPS_PRINTK(KERN_WARNING, ha->pcidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5353) "ips_issue val [0x%x].\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5354) IPS_PRINTK(KERN_WARNING, ha->pcidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5355) "ips_issue semaphore chk timeout.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5357) return (IPS_FAILURE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5358) } /* end if */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5359) } /* end while */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5361) writel(scb->scb_busaddr, ha->mem_ptr + IPS_REG_CCSAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5362) writel(IPS_BIT_START_CMD, ha->mem_ptr + IPS_REG_CCCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5364) return (IPS_SUCCESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5367) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5368) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5369) /* Routine Name: ips_issue_i2o */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5370) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5371) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5372) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5373) /* Send a command down to the controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5374) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5375) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5376) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5377) ips_issue_i2o(ips_ha_t * ha, ips_scb_t * scb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5378) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5380) METHOD_TRACE("ips_issue_i2o", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5382) if (scb->scsi_cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5383) DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5384) ips_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5385) ha->host_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5386) scb->cdb[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5387) scb->cmd.basic_io.command_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5388) scb->bus, scb->target_id, scb->lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5389) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5390) DEBUG_VAR(2, "(%s%d) ips_issue: logical cmd id %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5391) ips_name, ha->host_num, scb->cmd.basic_io.command_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5394) outl(scb->scb_busaddr, ha->io_addr + IPS_REG_I2O_INMSGQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5396) return (IPS_SUCCESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5399) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5400) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5401) /* Routine Name: ips_issue_i2o_memio */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5402) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5403) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5404) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5405) /* Send a command down to the controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5406) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5407) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5408) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5409) ips_issue_i2o_memio(ips_ha_t * ha, ips_scb_t * scb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5410) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5412) METHOD_TRACE("ips_issue_i2o_memio", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5414) if (scb->scsi_cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5415) DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5416) ips_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5417) ha->host_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5418) scb->cdb[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5419) scb->cmd.basic_io.command_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5420) scb->bus, scb->target_id, scb->lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5421) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5422) DEBUG_VAR(2, "(%s%d) ips_issue: logical cmd id %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5423) ips_name, ha->host_num, scb->cmd.basic_io.command_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5426) writel(scb->scb_busaddr, ha->mem_ptr + IPS_REG_I2O_INMSGQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5428) return (IPS_SUCCESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5431) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5432) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5433) /* Routine Name: ips_isintr_copperhead */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5434) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5435) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5436) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5437) /* Test to see if an interrupt is for us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5438) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5439) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5440) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5441) ips_isintr_copperhead(ips_ha_t * ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5442) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5443) uint8_t Isr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5445) METHOD_TRACE("ips_isintr_copperhead", 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5447) Isr = inb(ha->io_addr + IPS_REG_HISR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5449) if (Isr == 0xFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5450) /* ?!?! Nothing really there */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5451) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5453) if (Isr & IPS_BIT_SCE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5454) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5455) else if (Isr & (IPS_BIT_SQO | IPS_BIT_GHI)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5456) /* status queue overflow or GHI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5457) /* just clear the interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5458) outb(Isr, ha->io_addr + IPS_REG_HISR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5461) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5464) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5465) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5466) /* Routine Name: ips_isintr_copperhead_memio */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5467) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5468) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5469) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5470) /* Test to see if an interrupt is for us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5471) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5472) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5473) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5474) ips_isintr_copperhead_memio(ips_ha_t * ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5475) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5476) uint8_t Isr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5478) METHOD_TRACE("ips_isintr_memio", 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5480) Isr = readb(ha->mem_ptr + IPS_REG_HISR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5482) if (Isr == 0xFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5483) /* ?!?! Nothing really there */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5484) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5486) if (Isr & IPS_BIT_SCE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5487) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5488) else if (Isr & (IPS_BIT_SQO | IPS_BIT_GHI)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5489) /* status queue overflow or GHI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5490) /* just clear the interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5491) writeb(Isr, ha->mem_ptr + IPS_REG_HISR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5494) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5497) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5498) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5499) /* Routine Name: ips_isintr_morpheus */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5500) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5501) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5502) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5503) /* Test to see if an interrupt is for us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5504) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5505) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5506) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5507) ips_isintr_morpheus(ips_ha_t * ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5508) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5509) uint32_t Isr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5511) METHOD_TRACE("ips_isintr_morpheus", 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5513) Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5515) if (Isr & IPS_BIT_I2O_OPQI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5516) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5517) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5518) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5521) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5522) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5523) /* Routine Name: ips_wait */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5524) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5525) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5526) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5527) /* Wait for a command to complete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5528) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5529) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5530) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5531) ips_wait(ips_ha_t * ha, int time, int intr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5532) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5533) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5534) int done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5536) METHOD_TRACE("ips_wait", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5538) ret = IPS_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5539) done = FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5541) time *= IPS_ONE_SEC; /* convert seconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5543) while ((time > 0) && (!done)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5544) if (intr == IPS_INTR_ON) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5545) if (ha->waitflag == FALSE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5546) ret = IPS_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5547) done = TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5548) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5550) } else if (intr == IPS_INTR_IORL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5551) if (ha->waitflag == FALSE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5552) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5553) * controller generated an interrupt to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5554) * acknowledge completion of the command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5555) * and ips_intr() has serviced the interrupt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5556) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5557) ret = IPS_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5558) done = TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5559) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5562) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5563) * NOTE: we already have the io_request_lock so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5564) * even if we get an interrupt it won't get serviced
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5565) * until after we finish.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5566) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5568) (*ha->func.intr) (ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5571) /* This looks like a very evil loop, but it only does this during start-up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5572) udelay(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5573) time--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5576) return (ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5579) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5580) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5581) /* Routine Name: ips_write_driver_status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5582) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5583) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5584) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5585) /* Write OS/Driver version to Page 5 of the nvram on the controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5586) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5587) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5588) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5589) ips_write_driver_status(ips_ha_t * ha, int intr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5590) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5591) METHOD_TRACE("ips_write_driver_status", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5593) if (!ips_readwrite_page5(ha, FALSE, intr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5594) IPS_PRINTK(KERN_WARNING, ha->pcidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5595) "unable to read NVRAM page 5.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5597) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5600) /* check to make sure the page has a valid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5601) /* signature */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5602) if (le32_to_cpu(ha->nvram->signature) != IPS_NVRAM_P5_SIG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5603) DEBUG_VAR(1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5604) "(%s%d) NVRAM page 5 has an invalid signature: %X.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5605) ips_name, ha->host_num, ha->nvram->signature);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5606) ha->nvram->signature = IPS_NVRAM_P5_SIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5609) DEBUG_VAR(2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5610) "(%s%d) Ad Type: %d, Ad Slot: %d, BIOS: %c%c%c%c %c%c%c%c.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5611) ips_name, ha->host_num, le16_to_cpu(ha->nvram->adapter_type),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5612) ha->nvram->adapter_slot, ha->nvram->bios_high[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5613) ha->nvram->bios_high[1], ha->nvram->bios_high[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5614) ha->nvram->bios_high[3], ha->nvram->bios_low[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5615) ha->nvram->bios_low[1], ha->nvram->bios_low[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5616) ha->nvram->bios_low[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5618) ips_get_bios_version(ha, intr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5620) /* change values (as needed) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5621) ha->nvram->operating_system = IPS_OS_LINUX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5622) ha->nvram->adapter_type = ha->ad_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5623) memcpy((char *) ha->nvram->driver_high, IPS_VERSION_HIGH, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5624) memcpy((char *) ha->nvram->driver_low, IPS_VERSION_LOW, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5625) memcpy((char *) ha->nvram->bios_high, ha->bios_version, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5626) memcpy((char *) ha->nvram->bios_low, ha->bios_version + 4, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5628) ha->nvram->versioning = 0; /* Indicate the Driver Does Not Support Versioning */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5630) /* now update the page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5631) if (!ips_readwrite_page5(ha, TRUE, intr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5632) IPS_PRINTK(KERN_WARNING, ha->pcidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5633) "unable to write NVRAM page 5.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5635) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5638) /* IF NVRAM Page 5 is OK, Use it for Slot Number Info Because Linux Doesn't Do Slots */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5639) ha->slot_num = ha->nvram->adapter_slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5641) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5644) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5645) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5646) /* Routine Name: ips_read_adapter_status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5647) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5648) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5649) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5650) /* Do an Inquiry command to the adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5651) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5652) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5653) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5654) ips_read_adapter_status(ips_ha_t * ha, int intr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5655) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5656) ips_scb_t *scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5657) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5659) METHOD_TRACE("ips_read_adapter_status", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5661) scb = &ha->scbs[ha->max_cmds - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5663) ips_init_scb(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5665) scb->timeout = ips_cmd_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5666) scb->cdb[0] = IPS_CMD_ENQUIRY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5668) scb->cmd.basic_io.op_code = IPS_CMD_ENQUIRY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5669) scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5670) scb->cmd.basic_io.sg_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5671) scb->cmd.basic_io.lba = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5672) scb->cmd.basic_io.sector_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5673) scb->cmd.basic_io.log_drv = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5674) scb->data_len = sizeof (*ha->enq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5675) scb->cmd.basic_io.sg_addr = ha->enq_busaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5677) /* send command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5678) if (((ret =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5679) ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5680) || (ret == IPS_SUCCESS_IMM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5681) || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5682) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5684) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5687) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5688) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5689) /* Routine Name: ips_read_subsystem_parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5690) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5691) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5692) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5693) /* Read subsystem parameters from the adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5694) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5695) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5696) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5697) ips_read_subsystem_parameters(ips_ha_t * ha, int intr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5698) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5699) ips_scb_t *scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5700) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5702) METHOD_TRACE("ips_read_subsystem_parameters", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5704) scb = &ha->scbs[ha->max_cmds - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5706) ips_init_scb(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5708) scb->timeout = ips_cmd_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5709) scb->cdb[0] = IPS_CMD_GET_SUBSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5711) scb->cmd.basic_io.op_code = IPS_CMD_GET_SUBSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5712) scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5713) scb->cmd.basic_io.sg_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5714) scb->cmd.basic_io.lba = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5715) scb->cmd.basic_io.sector_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5716) scb->cmd.basic_io.log_drv = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5717) scb->data_len = sizeof (*ha->subsys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5718) scb->cmd.basic_io.sg_addr = ha->ioctl_busaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5720) /* send command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5721) if (((ret =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5722) ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5723) || (ret == IPS_SUCCESS_IMM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5724) || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5725) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5727) memcpy(ha->subsys, ha->ioctl_data, sizeof(*ha->subsys));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5728) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5731) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5732) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5733) /* Routine Name: ips_read_config */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5734) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5735) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5736) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5737) /* Read the configuration on the adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5738) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5739) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5740) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5741) ips_read_config(ips_ha_t * ha, int intr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5742) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5743) ips_scb_t *scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5744) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5745) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5747) METHOD_TRACE("ips_read_config", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5749) /* set defaults for initiator IDs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5750) for (i = 0; i < 4; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5751) ha->conf->init_id[i] = 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5753) scb = &ha->scbs[ha->max_cmds - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5755) ips_init_scb(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5757) scb->timeout = ips_cmd_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5758) scb->cdb[0] = IPS_CMD_READ_CONF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5760) scb->cmd.basic_io.op_code = IPS_CMD_READ_CONF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5761) scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5762) scb->data_len = sizeof (*ha->conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5763) scb->cmd.basic_io.sg_addr = ha->ioctl_busaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5765) /* send command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5766) if (((ret =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5767) ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5768) || (ret == IPS_SUCCESS_IMM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5769) || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5771) memset(ha->conf, 0, sizeof (IPS_CONF));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5773) /* reset initiator IDs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5774) for (i = 0; i < 4; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5775) ha->conf->init_id[i] = 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5777) /* Allow Completed with Errors, so JCRM can access the Adapter to fix the problems */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5778) if ((scb->basic_status & IPS_GSC_STATUS_MASK) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5779) IPS_CMD_CMPLT_WERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5780) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5782) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5785) memcpy(ha->conf, ha->ioctl_data, sizeof(*ha->conf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5786) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5789) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5790) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5791) /* Routine Name: ips_readwrite_page5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5792) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5793) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5794) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5795) /* Read nvram page 5 from the adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5796) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5797) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5798) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5799) ips_readwrite_page5(ips_ha_t * ha, int write, int intr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5800) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5801) ips_scb_t *scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5802) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5804) METHOD_TRACE("ips_readwrite_page5", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5806) scb = &ha->scbs[ha->max_cmds - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5808) ips_init_scb(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5810) scb->timeout = ips_cmd_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5811) scb->cdb[0] = IPS_CMD_RW_NVRAM_PAGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5813) scb->cmd.nvram.op_code = IPS_CMD_RW_NVRAM_PAGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5814) scb->cmd.nvram.command_id = IPS_COMMAND_ID(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5815) scb->cmd.nvram.page = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5816) scb->cmd.nvram.write = write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5817) scb->cmd.nvram.reserved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5818) scb->cmd.nvram.reserved2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5819) scb->data_len = sizeof (*ha->nvram);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5820) scb->cmd.nvram.buffer_addr = ha->ioctl_busaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5821) if (write)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5822) memcpy(ha->ioctl_data, ha->nvram, sizeof(*ha->nvram));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5824) /* issue the command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5825) if (((ret =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5826) ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5827) || (ret == IPS_SUCCESS_IMM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5828) || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5830) memset(ha->nvram, 0, sizeof (IPS_NVRAM_P5));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5832) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5833) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5834) if (!write)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5835) memcpy(ha->nvram, ha->ioctl_data, sizeof(*ha->nvram));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5836) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5837) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5839) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5840) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5841) /* Routine Name: ips_clear_adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5842) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5843) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5844) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5845) /* Clear the stripe lock tables */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5846) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5847) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5848) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5849) ips_clear_adapter(ips_ha_t * ha, int intr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5850) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5851) ips_scb_t *scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5852) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5854) METHOD_TRACE("ips_clear_adapter", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5856) scb = &ha->scbs[ha->max_cmds - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5858) ips_init_scb(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5860) scb->timeout = ips_reset_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5861) scb->cdb[0] = IPS_CMD_CONFIG_SYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5863) scb->cmd.config_sync.op_code = IPS_CMD_CONFIG_SYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5864) scb->cmd.config_sync.command_id = IPS_COMMAND_ID(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5865) scb->cmd.config_sync.channel = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5866) scb->cmd.config_sync.source_target = IPS_POCL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5867) scb->cmd.config_sync.reserved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5868) scb->cmd.config_sync.reserved2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5869) scb->cmd.config_sync.reserved3 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5871) /* issue command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5872) if (((ret =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5873) ips_send_wait(ha, scb, ips_reset_timeout, intr)) == IPS_FAILURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5874) || (ret == IPS_SUCCESS_IMM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5875) || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5876) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5878) /* send unlock stripe command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5879) ips_init_scb(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5881) scb->cdb[0] = IPS_CMD_ERROR_TABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5882) scb->timeout = ips_reset_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5884) scb->cmd.unlock_stripe.op_code = IPS_CMD_ERROR_TABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5885) scb->cmd.unlock_stripe.command_id = IPS_COMMAND_ID(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5886) scb->cmd.unlock_stripe.log_drv = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5887) scb->cmd.unlock_stripe.control = IPS_CSL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5888) scb->cmd.unlock_stripe.reserved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5889) scb->cmd.unlock_stripe.reserved2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5890) scb->cmd.unlock_stripe.reserved3 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5892) /* issue command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5893) if (((ret =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5894) ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5895) || (ret == IPS_SUCCESS_IMM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5896) || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5897) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5899) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5900) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5902) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5903) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5904) /* Routine Name: ips_ffdc_reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5905) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5906) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5907) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5908) /* FFDC: write reset info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5909) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5910) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5911) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5912) ips_ffdc_reset(ips_ha_t * ha, int intr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5913) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5914) ips_scb_t *scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5916) METHOD_TRACE("ips_ffdc_reset", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5918) scb = &ha->scbs[ha->max_cmds - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5920) ips_init_scb(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5922) scb->timeout = ips_cmd_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5923) scb->cdb[0] = IPS_CMD_FFDC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5924) scb->cmd.ffdc.op_code = IPS_CMD_FFDC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5925) scb->cmd.ffdc.command_id = IPS_COMMAND_ID(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5926) scb->cmd.ffdc.reset_count = ha->reset_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5927) scb->cmd.ffdc.reset_type = 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5929) /* convert time to what the card wants */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5930) ips_fix_ffdc_time(ha, scb, ha->last_ffdc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5932) /* issue command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5933) ips_send_wait(ha, scb, ips_cmd_timeout, intr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5934) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5936) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5937) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5938) /* Routine Name: ips_ffdc_time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5939) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5940) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5941) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5942) /* FFDC: write time info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5943) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5944) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5945) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5946) ips_ffdc_time(ips_ha_t * ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5947) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5948) ips_scb_t *scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5950) METHOD_TRACE("ips_ffdc_time", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5952) DEBUG_VAR(1, "(%s%d) Sending time update.", ips_name, ha->host_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5954) scb = &ha->scbs[ha->max_cmds - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5956) ips_init_scb(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5958) scb->timeout = ips_cmd_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5959) scb->cdb[0] = IPS_CMD_FFDC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5960) scb->cmd.ffdc.op_code = IPS_CMD_FFDC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5961) scb->cmd.ffdc.command_id = IPS_COMMAND_ID(ha, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5962) scb->cmd.ffdc.reset_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5963) scb->cmd.ffdc.reset_type = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5965) /* convert time to what the card wants */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5966) ips_fix_ffdc_time(ha, scb, ha->last_ffdc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5968) /* issue command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5969) ips_send_wait(ha, scb, ips_cmd_timeout, IPS_FFDC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5970) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5972) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5973) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5974) /* Routine Name: ips_fix_ffdc_time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5975) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5976) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5977) /* Adjust time_t to what the card wants */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5978) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5979) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5980) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5981) ips_fix_ffdc_time(ips_ha_t * ha, ips_scb_t * scb, time64_t current_time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5982) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5983) struct tm tm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5985) METHOD_TRACE("ips_fix_ffdc_time", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5987) time64_to_tm(current_time, 0, &tm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5989) scb->cmd.ffdc.hour = tm.tm_hour;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5990) scb->cmd.ffdc.minute = tm.tm_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5991) scb->cmd.ffdc.second = tm.tm_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5992) scb->cmd.ffdc.yearH = (tm.tm_year + 1900) / 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5993) scb->cmd.ffdc.yearL = tm.tm_year % 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5994) scb->cmd.ffdc.month = tm.tm_mon + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5995) scb->cmd.ffdc.day = tm.tm_mday;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5998) /****************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5999) * BIOS Flash Routines *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6000) ****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6002) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6003) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6004) /* Routine Name: ips_erase_bios */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6005) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6006) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6007) /* Erase the BIOS on the adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6008) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6009) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6010) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6011) ips_erase_bios(ips_ha_t * ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6012) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6013) int timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6014) uint8_t status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6016) METHOD_TRACE("ips_erase_bios", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6018) status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6020) /* Clear the status register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6021) outl(0, ha->io_addr + IPS_REG_FLAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6022) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6023) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6025) outb(0x50, ha->io_addr + IPS_REG_FLDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6026) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6027) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6029) /* Erase Setup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6030) outb(0x20, ha->io_addr + IPS_REG_FLDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6031) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6032) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6034) /* Erase Confirm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6035) outb(0xD0, ha->io_addr + IPS_REG_FLDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6036) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6037) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6039) /* Erase Status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6040) outb(0x70, ha->io_addr + IPS_REG_FLDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6041) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6042) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6044) timeout = 80000; /* 80 seconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6046) while (timeout > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6047) if (ha->pcidev->revision == IPS_REVID_TROMBONE64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6048) outl(0, ha->io_addr + IPS_REG_FLAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6049) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6050) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6052) status = inb(ha->io_addr + IPS_REG_FLDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6054) if (status & 0x80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6055) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6057) MDELAY(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6058) timeout--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6059) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6061) /* check for timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6062) if (timeout <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6063) /* timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6065) /* try to suspend the erase */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6066) outb(0xB0, ha->io_addr + IPS_REG_FLDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6067) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6068) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6070) /* wait for 10 seconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6071) timeout = 10000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6072) while (timeout > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6073) if (ha->pcidev->revision == IPS_REVID_TROMBONE64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6074) outl(0, ha->io_addr + IPS_REG_FLAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6075) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6076) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6078) status = inb(ha->io_addr + IPS_REG_FLDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6080) if (status & 0xC0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6081) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6083) MDELAY(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6084) timeout--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6085) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6087) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6088) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6090) /* check for valid VPP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6091) if (status & 0x08)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6092) /* VPP failure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6093) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6095) /* check for successful flash */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6096) if (status & 0x30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6097) /* sequence error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6098) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6100) /* Otherwise, we were successful */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6101) /* clear status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6102) outb(0x50, ha->io_addr + IPS_REG_FLDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6103) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6104) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6106) /* enable reads */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6107) outb(0xFF, ha->io_addr + IPS_REG_FLDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6108) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6109) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6111) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6114) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6115) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6116) /* Routine Name: ips_erase_bios_memio */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6117) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6118) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6119) /* Erase the BIOS on the adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6120) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6121) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6122) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6123) ips_erase_bios_memio(ips_ha_t * ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6125) int timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6126) uint8_t status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6128) METHOD_TRACE("ips_erase_bios_memio", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6130) status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6132) /* Clear the status register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6133) writel(0, ha->mem_ptr + IPS_REG_FLAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6134) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6135) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6137) writeb(0x50, ha->mem_ptr + IPS_REG_FLDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6138) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6139) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6141) /* Erase Setup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6142) writeb(0x20, ha->mem_ptr + IPS_REG_FLDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6143) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6144) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6146) /* Erase Confirm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6147) writeb(0xD0, ha->mem_ptr + IPS_REG_FLDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6148) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6149) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6151) /* Erase Status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6152) writeb(0x70, ha->mem_ptr + IPS_REG_FLDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6153) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6154) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6156) timeout = 80000; /* 80 seconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6158) while (timeout > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6159) if (ha->pcidev->revision == IPS_REVID_TROMBONE64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6160) writel(0, ha->mem_ptr + IPS_REG_FLAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6161) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6164) status = readb(ha->mem_ptr + IPS_REG_FLDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6166) if (status & 0x80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6167) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6169) MDELAY(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6170) timeout--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6173) /* check for timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6174) if (timeout <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6175) /* timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6177) /* try to suspend the erase */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6178) writeb(0xB0, ha->mem_ptr + IPS_REG_FLDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6179) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6180) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6182) /* wait for 10 seconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6183) timeout = 10000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6184) while (timeout > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6185) if (ha->pcidev->revision == IPS_REVID_TROMBONE64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6186) writel(0, ha->mem_ptr + IPS_REG_FLAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6187) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6190) status = readb(ha->mem_ptr + IPS_REG_FLDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6192) if (status & 0xC0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6193) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6195) MDELAY(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6196) timeout--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6199) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6202) /* check for valid VPP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6203) if (status & 0x08)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6204) /* VPP failure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6205) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6207) /* check for successful flash */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6208) if (status & 0x30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6209) /* sequence error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6210) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6212) /* Otherwise, we were successful */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6213) /* clear status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6214) writeb(0x50, ha->mem_ptr + IPS_REG_FLDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6215) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6216) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6218) /* enable reads */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6219) writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6220) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6221) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6223) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6226) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6227) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6228) /* Routine Name: ips_program_bios */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6229) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6230) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6231) /* Program the BIOS on the adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6232) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6233) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6234) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6235) ips_program_bios(ips_ha_t * ha, char *buffer, uint32_t buffersize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6236) uint32_t offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6238) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6239) int timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6240) uint8_t status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6242) METHOD_TRACE("ips_program_bios", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6244) status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6246) for (i = 0; i < buffersize; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6247) /* write a byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6248) outl(i + offset, ha->io_addr + IPS_REG_FLAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6249) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6250) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6252) outb(0x40, ha->io_addr + IPS_REG_FLDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6253) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6254) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6256) outb(buffer[i], ha->io_addr + IPS_REG_FLDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6257) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6258) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6260) /* wait up to one second */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6261) timeout = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6262) while (timeout > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6263) if (ha->pcidev->revision == IPS_REVID_TROMBONE64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6264) outl(0, ha->io_addr + IPS_REG_FLAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6265) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6268) status = inb(ha->io_addr + IPS_REG_FLDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6270) if (status & 0x80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6271) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6273) MDELAY(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6274) timeout--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6277) if (timeout == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6278) /* timeout error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6279) outl(0, ha->io_addr + IPS_REG_FLAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6280) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6281) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6283) outb(0xFF, ha->io_addr + IPS_REG_FLDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6284) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6285) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6287) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6290) /* check the status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6291) if (status & 0x18) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6292) /* programming error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6293) outl(0, ha->io_addr + IPS_REG_FLAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6294) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6295) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6297) outb(0xFF, ha->io_addr + IPS_REG_FLDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6298) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6299) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6301) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6303) } /* end for */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6305) /* Enable reading */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6306) outl(0, ha->io_addr + IPS_REG_FLAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6307) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6308) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6310) outb(0xFF, ha->io_addr + IPS_REG_FLDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6311) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6312) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6314) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6317) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6318) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6319) /* Routine Name: ips_program_bios_memio */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6320) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6321) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6322) /* Program the BIOS on the adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6323) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6324) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6325) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6326) ips_program_bios_memio(ips_ha_t * ha, char *buffer, uint32_t buffersize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6327) uint32_t offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6329) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6330) int timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6331) uint8_t status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6333) METHOD_TRACE("ips_program_bios_memio", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6335) status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6337) for (i = 0; i < buffersize; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6338) /* write a byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6339) writel(i + offset, ha->mem_ptr + IPS_REG_FLAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6340) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6341) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6343) writeb(0x40, ha->mem_ptr + IPS_REG_FLDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6344) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6345) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6347) writeb(buffer[i], ha->mem_ptr + IPS_REG_FLDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6348) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6349) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6351) /* wait up to one second */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6352) timeout = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6353) while (timeout > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6354) if (ha->pcidev->revision == IPS_REVID_TROMBONE64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6355) writel(0, ha->mem_ptr + IPS_REG_FLAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6356) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6359) status = readb(ha->mem_ptr + IPS_REG_FLDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6361) if (status & 0x80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6362) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6364) MDELAY(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6365) timeout--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6368) if (timeout == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6369) /* timeout error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6370) writel(0, ha->mem_ptr + IPS_REG_FLAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6371) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6372) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6374) writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6375) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6376) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6378) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6381) /* check the status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6382) if (status & 0x18) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6383) /* programming error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6384) writel(0, ha->mem_ptr + IPS_REG_FLAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6385) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6386) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6388) writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6389) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6390) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6392) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6394) } /* end for */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6396) /* Enable reading */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6397) writel(0, ha->mem_ptr + IPS_REG_FLAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6398) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6399) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6401) writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6402) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6403) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6405) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6408) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6409) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6410) /* Routine Name: ips_verify_bios */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6411) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6412) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6413) /* Verify the BIOS on the adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6414) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6415) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6416) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6417) ips_verify_bios(ips_ha_t * ha, char *buffer, uint32_t buffersize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6418) uint32_t offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6419) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6420) uint8_t checksum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6421) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6423) METHOD_TRACE("ips_verify_bios", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6425) /* test 1st byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6426) outl(0, ha->io_addr + IPS_REG_FLAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6427) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6428) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6430) if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6431) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6433) outl(1, ha->io_addr + IPS_REG_FLAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6434) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6435) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6436) if (inb(ha->io_addr + IPS_REG_FLDP) != 0xAA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6437) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6439) checksum = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6440) for (i = 2; i < buffersize; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6442) outl(i + offset, ha->io_addr + IPS_REG_FLAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6443) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6444) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6446) checksum = (uint8_t) checksum + inb(ha->io_addr + IPS_REG_FLDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6449) if (checksum != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6450) /* failure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6451) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6452) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6453) /* success */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6454) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6457) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6458) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6459) /* Routine Name: ips_verify_bios_memio */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6460) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6461) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6462) /* Verify the BIOS on the adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6463) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6464) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6465) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6466) ips_verify_bios_memio(ips_ha_t * ha, char *buffer, uint32_t buffersize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6467) uint32_t offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6468) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6469) uint8_t checksum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6470) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6472) METHOD_TRACE("ips_verify_bios_memio", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6474) /* test 1st byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6475) writel(0, ha->mem_ptr + IPS_REG_FLAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6476) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6477) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6479) if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0x55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6480) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6482) writel(1, ha->mem_ptr + IPS_REG_FLAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6483) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6484) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6485) if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0xAA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6486) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6488) checksum = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6489) for (i = 2; i < buffersize; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6491) writel(i + offset, ha->mem_ptr + IPS_REG_FLAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6492) if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6493) udelay(25); /* 25 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6495) checksum =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6496) (uint8_t) checksum + readb(ha->mem_ptr + IPS_REG_FLDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6499) if (checksum != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6500) /* failure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6501) return (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6502) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6503) /* success */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6504) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6507) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6508) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6509) /* Routine Name: ips_abort_init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6510) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6511) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6512) /* cleanup routine for a failed adapter initialization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6513) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6514) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6515) ips_abort_init(ips_ha_t * ha, int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6516) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6517) ha->active = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6518) ips_free(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6519) ips_ha[index] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6520) ips_sh[index] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6521) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6524) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6525) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6526) /* Routine Name: ips_shift_controllers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6527) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6528) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6529) /* helper function for ordering adapters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6530) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6531) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6532) ips_shift_controllers(int lowindex, int highindex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6533) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6534) ips_ha_t *ha_sav = ips_ha[highindex];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6535) struct Scsi_Host *sh_sav = ips_sh[highindex];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6536) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6538) for (i = highindex; i > lowindex; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6539) ips_ha[i] = ips_ha[i - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6540) ips_sh[i] = ips_sh[i - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6541) ips_ha[i]->host_num = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6543) ha_sav->host_num = lowindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6544) ips_ha[lowindex] = ha_sav;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6545) ips_sh[lowindex] = sh_sav;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6548) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6549) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6550) /* Routine Name: ips_order_controllers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6551) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6552) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6553) /* place controllers is the "proper" boot order */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6554) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6555) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6556) ips_order_controllers(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6557) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6558) int i, j, tmp, position = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6559) IPS_NVRAM_P5 *nvram;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6560) if (!ips_ha[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6561) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6562) nvram = ips_ha[0]->nvram;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6564) if (nvram->adapter_order[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6565) for (i = 1; i <= nvram->adapter_order[0]; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6566) for (j = position; j < ips_num_controllers; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6567) switch (ips_ha[j]->ad_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6568) case IPS_ADTYPE_SERVERAID6M:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6569) case IPS_ADTYPE_SERVERAID7M:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6570) if (nvram->adapter_order[i] == 'M') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6571) ips_shift_controllers(position,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6572) j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6573) position++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6575) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6576) case IPS_ADTYPE_SERVERAID4L:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6577) case IPS_ADTYPE_SERVERAID4M:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6578) case IPS_ADTYPE_SERVERAID4MX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6579) case IPS_ADTYPE_SERVERAID4LX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6580) if (nvram->adapter_order[i] == 'N') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6581) ips_shift_controllers(position,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6582) j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6583) position++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6585) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6586) case IPS_ADTYPE_SERVERAID6I:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6587) case IPS_ADTYPE_SERVERAID5I2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6588) case IPS_ADTYPE_SERVERAID5I1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6589) case IPS_ADTYPE_SERVERAID7k:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6590) if (nvram->adapter_order[i] == 'S') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6591) ips_shift_controllers(position,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6592) j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6593) position++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6595) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6596) case IPS_ADTYPE_SERVERAID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6597) case IPS_ADTYPE_SERVERAID2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6598) case IPS_ADTYPE_NAVAJO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6599) case IPS_ADTYPE_KIOWA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6600) case IPS_ADTYPE_SERVERAID3L:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6601) case IPS_ADTYPE_SERVERAID3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6602) case IPS_ADTYPE_SERVERAID4H:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6603) if (nvram->adapter_order[i] == 'A') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6604) ips_shift_controllers(position,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6605) j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6606) position++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6608) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6609) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6610) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6614) /* if adapter_order[0], then ordering is complete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6615) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6617) /* old bios, use older ordering */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6618) tmp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6619) for (i = position; i < ips_num_controllers; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6620) if (ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID5I2 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6621) ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID5I1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6622) ips_shift_controllers(position, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6623) position++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6624) tmp = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6627) /* if there were no 5I cards, then don't do any extra ordering */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6628) if (!tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6629) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6630) for (i = position; i < ips_num_controllers; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6631) if (ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID4L ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6632) ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID4M ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6633) ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID4LX ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6634) ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID4MX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6635) ips_shift_controllers(position, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6636) position++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6640) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6643) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6644) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6645) /* Routine Name: ips_register_scsi */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6646) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6647) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6648) /* perform any registration and setup with the scsi layer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6649) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6650) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6651) ips_register_scsi(int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6652) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6653) struct Scsi_Host *sh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6654) ips_ha_t *ha, *oldha = ips_ha[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6655) sh = scsi_host_alloc(&ips_driver_template, sizeof (ips_ha_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6656) if (!sh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6657) IPS_PRINTK(KERN_WARNING, oldha->pcidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6658) "Unable to register controller with SCSI subsystem\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6659) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6661) ha = IPS_HA(sh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6662) memcpy(ha, oldha, sizeof (ips_ha_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6663) free_irq(oldha->pcidev->irq, oldha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6664) /* Install the interrupt handler with the new ha */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6665) if (request_irq(ha->pcidev->irq, do_ipsintr, IRQF_SHARED, ips_name, ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6666) IPS_PRINTK(KERN_WARNING, ha->pcidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6667) "Unable to install interrupt handler\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6668) goto err_out_sh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6669) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6671) kfree(oldha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6673) /* Store away needed values for later use */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6674) sh->unique_id = (ha->io_addr) ? ha->io_addr : ha->mem_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6675) sh->sg_tablesize = sh->hostt->sg_tablesize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6676) sh->can_queue = sh->hostt->can_queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6677) sh->cmd_per_lun = sh->hostt->cmd_per_lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6678) sh->max_sectors = 128;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6680) sh->max_id = ha->ntargets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6681) sh->max_lun = ha->nlun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6682) sh->max_channel = ha->nbus - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6683) sh->can_queue = ha->max_cmds - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6685) if (scsi_add_host(sh, &ha->pcidev->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6686) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6688) ips_sh[index] = sh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6689) ips_ha[index] = ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6691) scsi_scan_host(sh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6693) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6695) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6696) free_irq(ha->pcidev->irq, ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6697) err_out_sh:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6698) scsi_host_put(sh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6699) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6702) /*---------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6703) /* Routine Name: ips_remove_device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6704) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6705) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6706) /* Remove one Adapter ( Hot Plugging ) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6707) /*---------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6708) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6709) ips_remove_device(struct pci_dev *pci_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6710) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6711) struct Scsi_Host *sh = pci_get_drvdata(pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6713) pci_set_drvdata(pci_dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6715) ips_release(sh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6717) pci_release_regions(pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6718) pci_disable_device(pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6721) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6722) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6723) /* Routine Name: ips_module_init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6724) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6725) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6726) /* function called on module load */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6727) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6728) static int __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6729) ips_module_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6730) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6731) #if !defined(__i386__) && !defined(__ia64__) && !defined(__x86_64__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6732) printk(KERN_ERR "ips: This driver has only been tested on the x86/ia64/x86_64 platforms\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6733) add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_STILL_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6734) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6736) if (pci_register_driver(&ips_pci_driver) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6737) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6738) ips_driver_template.module = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6739) ips_order_controllers();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6740) if (!ips_detect(&ips_driver_template)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6741) pci_unregister_driver(&ips_pci_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6742) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6744) register_reboot_notifier(&ips_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6745) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6748) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6749) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6750) /* Routine Name: ips_module_exit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6751) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6752) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6753) /* function called on module unload */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6754) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6755) static void __exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6756) ips_module_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6757) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6758) pci_unregister_driver(&ips_pci_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6759) unregister_reboot_notifier(&ips_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6760) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6762) module_init(ips_module_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6763) module_exit(ips_module_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6765) /*---------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6766) /* Routine Name: ips_insert_device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6767) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6768) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6769) /* Add One Adapter ( Hot Plug ) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6770) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6771) /* Return Value: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6772) /* 0 if Successful, else non-zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6773) /*---------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6774) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6775) ips_insert_device(struct pci_dev *pci_dev, const struct pci_device_id *ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6776) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6777) int index = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6778) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6780) METHOD_TRACE("ips_insert_device", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6781) rc = pci_enable_device(pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6782) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6783) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6785) rc = pci_request_regions(pci_dev, "ips");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6786) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6787) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6789) rc = ips_init_phase1(pci_dev, &index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6790) if (rc == SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6791) rc = ips_init_phase2(index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6793) if (ips_hotplug)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6794) if (ips_register_scsi(index)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6795) ips_free(ips_ha[index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6796) rc = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6799) if (rc == SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6800) ips_num_controllers++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6802) ips_next_controller = ips_num_controllers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6804) if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6805) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6806) goto err_out_regions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6807) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6809) pci_set_drvdata(pci_dev, ips_sh[index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6810) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6812) err_out_regions:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6813) pci_release_regions(pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6814) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6815) pci_disable_device(pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6816) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6817) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6819) /*---------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6820) /* Routine Name: ips_init_phase1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6821) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6822) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6823) /* Adapter Initialization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6824) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6825) /* Return Value: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6826) /* 0 if Successful, else non-zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6827) /*---------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6828) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6829) ips_init_phase1(struct pci_dev *pci_dev, int *indexPtr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6830) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6831) ips_ha_t *ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6832) uint32_t io_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6833) uint32_t mem_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6834) uint32_t io_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6835) uint32_t mem_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6836) int j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6837) int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6838) dma_addr_t dma_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6839) char __iomem *ioremap_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6840) char __iomem *mem_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6841) uint32_t IsDead;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6843) METHOD_TRACE("ips_init_phase1", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6844) index = IPS_MAX_ADAPTERS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6845) for (j = 0; j < IPS_MAX_ADAPTERS; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6846) if (ips_ha[j] == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6847) index = j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6848) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6849) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6850) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6852) if (index >= IPS_MAX_ADAPTERS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6853) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6855) /* Init MEM/IO addresses to 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6856) mem_addr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6857) io_addr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6858) mem_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6859) io_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6861) for (j = 0; j < 2; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6862) if (!pci_resource_start(pci_dev, j))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6863) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6865) if (pci_resource_flags(pci_dev, j) & IORESOURCE_IO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6866) io_addr = pci_resource_start(pci_dev, j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6867) io_len = pci_resource_len(pci_dev, j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6868) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6869) mem_addr = pci_resource_start(pci_dev, j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6870) mem_len = pci_resource_len(pci_dev, j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6874) /* setup memory mapped area (if applicable) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6875) if (mem_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6876) uint32_t base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6877) uint32_t offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6879) base = mem_addr & PAGE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6880) offs = mem_addr - base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6881) ioremap_ptr = ioremap(base, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6882) if (!ioremap_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6883) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6884) mem_ptr = ioremap_ptr + offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6885) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6886) ioremap_ptr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6887) mem_ptr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6890) /* found a controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6891) ha = kzalloc(sizeof (ips_ha_t), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6892) if (ha == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6893) IPS_PRINTK(KERN_WARNING, pci_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6894) "Unable to allocate temporary ha struct\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6895) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6896) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6898) ips_sh[index] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6899) ips_ha[index] = ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6900) ha->active = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6902) /* Store info in HA structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6903) ha->io_addr = io_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6904) ha->io_len = io_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6905) ha->mem_addr = mem_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6906) ha->mem_len = mem_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6907) ha->mem_ptr = mem_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6908) ha->ioremap_ptr = ioremap_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6909) ha->host_num = (uint32_t) index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6910) ha->slot_num = PCI_SLOT(pci_dev->devfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6911) ha->pcidev = pci_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6913) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6914) * Set the pci_dev's dma_mask. Not all adapters support 64bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6915) * addressing so don't enable it if the adapter can't support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6916) * it! Also, don't use 64bit addressing if dma addresses
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6917) * are guaranteed to be < 4G.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6918) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6919) if (sizeof(dma_addr_t) > 4 && IPS_HAS_ENH_SGLIST(ha) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6920) !dma_set_mask(&ha->pcidev->dev, DMA_BIT_MASK(64))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6921) (ha)->flags |= IPS_HA_ENH_SG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6922) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6923) if (dma_set_mask(&ha->pcidev->dev, DMA_BIT_MASK(32)) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6924) printk(KERN_WARNING "Unable to set DMA Mask\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6925) return ips_abort_init(ha, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6926) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6928) if(ips_cd_boot && !ips_FlashData){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6929) ips_FlashData = dma_alloc_coherent(&pci_dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6930) PAGE_SIZE << 7, &ips_flashbusaddr, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6933) ha->enq = dma_alloc_coherent(&pci_dev->dev, sizeof (IPS_ENQ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6934) &ha->enq_busaddr, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6935) if (!ha->enq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6936) IPS_PRINTK(KERN_WARNING, pci_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6937) "Unable to allocate host inquiry structure\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6938) return ips_abort_init(ha, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6939) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6941) ha->adapt = dma_alloc_coherent(&pci_dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6942) sizeof (IPS_ADAPTER) + sizeof (IPS_IO_CMD),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6943) &dma_address, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6944) if (!ha->adapt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6945) IPS_PRINTK(KERN_WARNING, pci_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6946) "Unable to allocate host adapt & dummy structures\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6947) return ips_abort_init(ha, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6949) ha->adapt->hw_status_start = dma_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6950) ha->dummy = (void *) (ha->adapt + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6954) ha->logical_drive_info = dma_alloc_coherent(&pci_dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6955) sizeof (IPS_LD_INFO), &dma_address, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6956) if (!ha->logical_drive_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6957) IPS_PRINTK(KERN_WARNING, pci_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6958) "Unable to allocate logical drive info structure\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6959) return ips_abort_init(ha, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6960) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6961) ha->logical_drive_info_dma_addr = dma_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6964) ha->conf = kmalloc(sizeof (IPS_CONF), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6966) if (!ha->conf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6967) IPS_PRINTK(KERN_WARNING, pci_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6968) "Unable to allocate host conf structure\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6969) return ips_abort_init(ha, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6970) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6972) ha->nvram = kmalloc(sizeof (IPS_NVRAM_P5), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6974) if (!ha->nvram) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6975) IPS_PRINTK(KERN_WARNING, pci_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6976) "Unable to allocate host NVRAM structure\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6977) return ips_abort_init(ha, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6978) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6980) ha->subsys = kmalloc(sizeof (IPS_SUBSYS), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6982) if (!ha->subsys) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6983) IPS_PRINTK(KERN_WARNING, pci_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6984) "Unable to allocate host subsystem structure\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6985) return ips_abort_init(ha, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6986) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6988) /* the ioctl buffer is now used during adapter initialization, so its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6989) * successful allocation is now required */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6990) if (ips_ioctlsize < PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6991) ips_ioctlsize = PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6993) ha->ioctl_data = dma_alloc_coherent(&pci_dev->dev, ips_ioctlsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6994) &ha->ioctl_busaddr, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6995) ha->ioctl_len = ips_ioctlsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6996) if (!ha->ioctl_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6997) IPS_PRINTK(KERN_WARNING, pci_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6998) "Unable to allocate IOCTL data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6999) return ips_abort_init(ha, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7000) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7002) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7003) * Setup Functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7004) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7005) ips_setup_funclist(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7007) if ((IPS_IS_MORPHEUS(ha)) || (IPS_IS_MARCO(ha))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7008) /* If Morpheus appears dead, reset it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7009) IsDead = readl(ha->mem_ptr + IPS_REG_I960_MSG1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7010) if (IsDead == 0xDEADBEEF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7011) ips_reset_morpheus(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7012) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7013) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7015) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7016) * Initialize the card if it isn't already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7017) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7019) if (!(*ha->func.isinit) (ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7020) if (!(*ha->func.init) (ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7021) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7022) * Initialization failed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7023) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7024) IPS_PRINTK(KERN_WARNING, pci_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7025) "Unable to initialize controller\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7026) return ips_abort_init(ha, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7027) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7028) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7030) *indexPtr = index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7031) return SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7032) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7034) /*---------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7035) /* Routine Name: ips_init_phase2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7036) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7037) /* Routine Description: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7038) /* Adapter Initialization Phase 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7039) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7040) /* Return Value: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7041) /* 0 if Successful, else non-zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7042) /*---------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7043) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7044) ips_init_phase2(int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7045) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7046) ips_ha_t *ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7048) ha = ips_ha[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7050) METHOD_TRACE("ips_init_phase2", 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7051) if (!ha->active) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7052) ips_ha[index] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7053) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7056) /* Install the interrupt handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7057) if (request_irq(ha->pcidev->irq, do_ipsintr, IRQF_SHARED, ips_name, ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7058) IPS_PRINTK(KERN_WARNING, ha->pcidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7059) "Unable to install interrupt handler\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7060) return ips_abort_init(ha, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7061) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7063) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7064) * Allocate a temporary SCB for initialization
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7065) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7066) ha->max_cmds = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7067) if (!ips_allocatescbs(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7068) IPS_PRINTK(KERN_WARNING, ha->pcidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7069) "Unable to allocate a CCB\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7070) free_irq(ha->pcidev->irq, ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7071) return ips_abort_init(ha, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7072) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7074) if (!ips_hainit(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7075) IPS_PRINTK(KERN_WARNING, ha->pcidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7076) "Unable to initialize controller\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7077) free_irq(ha->pcidev->irq, ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7078) return ips_abort_init(ha, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7079) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7080) /* Free the temporary SCB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7081) ips_deallocatescbs(ha, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7083) /* allocate CCBs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7084) if (!ips_allocatescbs(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7085) IPS_PRINTK(KERN_WARNING, ha->pcidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7086) "Unable to allocate CCBs\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7087) free_irq(ha->pcidev->irq, ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7088) return ips_abort_init(ha, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7089) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7091) return SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7092) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7094) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7095) MODULE_DESCRIPTION("IBM ServeRAID Adapter Driver " IPS_VER_STRING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7096) MODULE_VERSION(IPS_VER_STRING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7099) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7100) * Overrides for Emacs so that we almost follow Linus's tabbing style.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7101) * Emacs will notice this stuff at the end of the file and automatically
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7102) * adjust the settings for this buffer only. This must remain at the end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7103) * of the file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7104) * ---------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7105) * Local variables:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7106) * c-indent-level: 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7107) * c-brace-imaginary-offset: 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7108) * c-brace-offset: -2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7109) * c-argdecl-indent: 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7110) * c-label-offset: -2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7111) * c-continued-statement-offset: 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7112) * c-continued-brace-offset: 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7113) * indent-tabs-mode: nil
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7114) * tab-width: 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7115) * End:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7116) */