| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* | 
 | 2 |  *      eata.c - Low-level driver for EATA/DMA SCSI host adapters. | 
 | 3 |  * | 
 | 4 |  *      03 Jun 2003 Rev. 8.10 for linux-2.5.70 | 
 | 5 |  *        + Update for new IRQ API. | 
 | 6 |  *        + Use "goto" when appropriate. | 
 | 7 |  *        + Drop eata.h. | 
 | 8 |  *        + Update for new module_param API. | 
 | 9 |  *        + Module parameters  can now be specified only in the | 
 | 10 |  *          same format as the kernel boot options. | 
 | 11 |  * | 
 | 12 |  *             boot option    old module param  | 
 | 13 |  *             -----------    ------------------ | 
 | 14 |  *             addr,...       io_port=addr,... | 
 | 15 |  *             lc:[y|n]       linked_comm=[1|0] | 
 | 16 |  *             mq:xx          max_queue_depth=xx | 
 | 17 |  *             tm:[0|1|2]     tag_mode=[0|1|2] | 
 | 18 |  *             et:[y|n]       ext_tran=[1|0] | 
 | 19 |  *             rs:[y|n]       rev_scan=[1|0] | 
 | 20 |  *             ip:[y|n]       isa_probe=[1|0] | 
 | 21 |  *             ep:[y|n]       eisa_probe=[1|0] | 
 | 22 |  *             pp:[y|n]       pci_probe=[1|0] | 
 | 23 |  * | 
 | 24 |  *          A valid example using the new parameter format is: | 
 | 25 |  *          modprobe eata "eata=0x7410,0x230,lc:y,tm:0,mq:4,ep:n" | 
 | 26 |  * | 
 | 27 |  *          which is equivalent to the old format: | 
 | 28 |  *          modprobe eata io_port=0x7410,0x230 linked_comm=1 tag_mode=0 \ | 
 | 29 |  *                        max_queue_depth=4 eisa_probe=0 | 
 | 30 |  * | 
 | 31 |  *      12 Feb 2003 Rev. 8.04 for linux 2.5.60 | 
 | 32 |  *        + Release irq before calling scsi_register. | 
 | 33 |  * | 
 | 34 |  *      12 Nov 2002 Rev. 8.02 for linux 2.5.47 | 
 | 35 |  *        + Release driver_lock before calling scsi_register. | 
 | 36 |  * | 
 | 37 |  *      11 Nov 2002 Rev. 8.01 for linux 2.5.47 | 
 | 38 |  *        + Fixed bios_param and scsicam_bios_param calling parameters. | 
 | 39 |  * | 
 | 40 |  *      28 Oct 2002 Rev. 8.00 for linux 2.5.44-ac4 | 
 | 41 |  *        + Use new tcq and adjust_queue_depth api. | 
 | 42 |  *        + New command line option (tm:[0-2]) to choose the type of tags: | 
 | 43 |  *          0 -> disable tagging ; 1 -> simple tags  ; 2 -> ordered tags. | 
 | 44 |  *          Default is tm:0 (tagged commands disabled). | 
 | 45 |  *          For compatibility the "tc:" option is an alias of the "tm:" | 
 | 46 |  *          option; tc:n is equivalent to tm:0 and tc:y is equivalent to | 
 | 47 |  *          tm:1. | 
 | 48 |  *        + The tagged_comm module parameter has been removed, use tag_mode | 
 | 49 |  *          instead, equivalent to the "tm:" boot option. | 
 | 50 |  * | 
 | 51 |  *      10 Oct 2002 Rev. 7.70 for linux 2.5.42 | 
 | 52 |  *        + Foreport from revision 6.70. | 
 | 53 |  * | 
 | 54 |  *      25 Jun 2002 Rev. 6.70 for linux 2.4.19 | 
 | 55 |  *        + This release is the first one tested on a Big Endian platform: | 
 | 56 |  *          fixed endian-ness problem due to bitfields; | 
 | 57 |  *          fixed endian-ness problem in read_pio. | 
 | 58 |  *        + Added new options for selectively probing ISA, EISA and PCI bus: | 
 | 59 |  * | 
 | 60 |  *          Boot option   Parameter name    Default according to | 
 | 61 |  * | 
 | 62 |  *          ip:[y|n]      isa_probe=[1|0]   CONFIG_ISA  defined | 
 | 63 |  *          ep:[y|n]      eisa_probe=[1|0]  CONFIG_EISA defined | 
 | 64 |  *          pp:[y|n]      pci_probe=[1|0]   CONFIG_PCI  defined | 
 | 65 |  * | 
 | 66 |  *          The default action is to perform probing if the corrisponding | 
 | 67 |  *          bus is configured and to skip probing otherwise. | 
 | 68 |  * | 
 | 69 |  *        + If pci_probe is in effect and a list of I/O  ports is specified | 
 | 70 |  *          as parameter or boot option, pci_enable_device() is performed | 
 | 71 |  *          on all pci devices matching PCI_CLASS_STORAGE_SCSI. | 
 | 72 |  * | 
 | 73 |  *      21 Feb 2002 Rev. 6.52 for linux 2.4.18 | 
 | 74 |  *        + Backport from rev. 7.22 (use io_request_lock). | 
 | 75 |  * | 
 | 76 |  *      20 Feb 2002 Rev. 7.22 for linux 2.5.5 | 
 | 77 |  *        + Remove any reference to virt_to_bus(). | 
 | 78 |  *        + Fix pio hang while detecting multiple HBAs. | 
 | 79 |  *        + Fixed a board detection bug: in a system with | 
 | 80 |  *          multiple ISA/EISA boards, all but the first one | 
 | 81 |  *          were erroneously detected as PCI. | 
 | 82 |  * | 
 | 83 |  *      01 Jan 2002 Rev. 7.20 for linux 2.5.1 | 
 | 84 |  *        + Use the dynamic DMA mapping API. | 
 | 85 |  * | 
 | 86 |  *      19 Dec 2001 Rev. 7.02 for linux 2.5.1 | 
 | 87 |  *        + Use SCpnt->sc_data_direction if set. | 
 | 88 |  *        + Use sglist.page instead of sglist.address. | 
 | 89 |  * | 
 | 90 |  *      11 Dec 2001 Rev. 7.00 for linux 2.5.1 | 
 | 91 |  *        + Use host->host_lock instead of io_request_lock. | 
 | 92 |  * | 
 | 93 |  *       1 May 2001 Rev. 6.05 for linux 2.4.4 | 
 | 94 |  *        + Clean up all pci related routines. | 
 | 95 |  *        + Fix data transfer direction for opcode SEND_CUE_SHEET (0x5d) | 
 | 96 |  * | 
 | 97 |  *      30 Jan 2001 Rev. 6.04 for linux 2.4.1 | 
 | 98 |  *        + Call pci_resource_start after pci_enable_device. | 
 | 99 |  * | 
 | 100 |  *      25 Jan 2001 Rev. 6.03 for linux 2.4.0 | 
 | 101 |  *        + "check_region" call replaced by "request_region". | 
 | 102 |  * | 
 | 103 |  *      22 Nov 2000 Rev. 6.02 for linux 2.4.0-test11 | 
 | 104 |  *        + Return code checked when calling pci_enable_device. | 
 | 105 |  *        + Removed old scsi error handling support. | 
 | 106 |  *        + The obsolete boot option flag eh:n is silently ignored. | 
 | 107 |  *        + Removed error messages while a disk drive is powered up at | 
 | 108 |  *          boot time. | 
 | 109 |  *        + Improved boot messages: all tagged capable device are | 
 | 110 |  *          indicated as "tagged" or "soft-tagged" : | 
 | 111 |  *          - "soft-tagged"  means that the driver is trying to do its | 
 | 112 |  *            own tagging (i.e. the tc:y option is in effect); | 
 | 113 |  *          - "tagged" means that the device supports tagged commands, | 
 | 114 |  *            but the driver lets the HBA be responsible for tagging | 
 | 115 |  *            support. | 
 | 116 |  * | 
 | 117 |  *      16 Sep 1999 Rev. 5.11 for linux 2.2.12 and 2.3.18 | 
 | 118 |  *        + Updated to the new __setup interface for boot command line options. | 
 | 119 |  *        + When loaded as a module, accepts the new parameter boot_options | 
 | 120 |  *          which value is a string with the same format of the kernel boot | 
 | 121 |  *          command line options. A valid example is: | 
 | 122 |  *          modprobe eata 'boot_options="0x7410,0x230,lc:y,tc:n,mq:4"' | 
 | 123 |  * | 
 | 124 |  *       9 Sep 1999 Rev. 5.10 for linux 2.2.12 and 2.3.17 | 
 | 125 |  *        + 64bit cleanup for Linux/Alpha platform support | 
 | 126 |  *          (contribution from H.J. Lu). | 
 | 127 |  * | 
 | 128 |  *      22 Jul 1999 Rev. 5.00 for linux 2.2.10 and 2.3.11 | 
 | 129 |  *        + Removed pre-2.2 source code compatibility. | 
 | 130 |  *        + Added call to pci_set_master. | 
 | 131 |  * | 
 | 132 |  *      26 Jul 1998 Rev. 4.33 for linux 2.0.35 and 2.1.111 | 
 | 133 |  *        + Added command line option (rs:[y|n]) to reverse the scan order | 
 | 134 |  *          of PCI boards. The default is rs:y, which reverses the BIOS order | 
 | 135 |  *          while registering PCI boards. The default value rs:y generates | 
 | 136 |  *          the same order of all previous revisions of this driver. | 
 | 137 |  *          Pls. note that "BIOS order" might have been reversed itself | 
 | 138 |  *          after the 2.1.9x PCI modifications in the linux kernel. | 
 | 139 |  *          The rs value is ignored when the explicit list of addresses | 
 | 140 |  *          is used by the "eata=port0,port1,..." command line option. | 
 | 141 |  *        + Added command line option (et:[y|n]) to force use of extended | 
 | 142 |  *          translation (255 heads, 63 sectors) as disk geometry. | 
 | 143 |  *          The default is et:n, which uses the disk geometry returned | 
 | 144 |  *          by scsicam_bios_param. The default value et:n is compatible with | 
 | 145 |  *          all previous revisions of this driver. | 
 | 146 |  * | 
 | 147 |  *      28 May 1998 Rev. 4.32 for linux 2.0.33 and 2.1.104 | 
 | 148 |  *          Increased busy timeout from 10 msec. to 200 msec. while | 
 | 149 |  *          processing interrupts. | 
 | 150 |  * | 
 | 151 |  *      16 May 1998 Rev. 4.31 for linux 2.0.33 and 2.1.102 | 
 | 152 |  *          Improved abort handling during the eh recovery process. | 
 | 153 |  * | 
 | 154 |  *      13 May 1998 Rev. 4.30 for linux 2.0.33 and 2.1.101 | 
 | 155 |  *          The driver is now fully SMP safe, including the | 
 | 156 |  *          abort and reset routines. | 
 | 157 |  *          Added command line options (eh:[y|n]) to choose between | 
 | 158 |  *          new_eh_code and the old scsi code. | 
 | 159 |  *          If linux version >= 2.1.101 the default is eh:y, while the eh | 
 | 160 |  *          option is ignored for previous releases and the old scsi code | 
 | 161 |  *          is used. | 
 | 162 |  * | 
 | 163 |  *      18 Apr 1998 Rev. 4.20 for linux 2.0.33 and 2.1.97 | 
 | 164 |  *          Reworked interrupt handler. | 
 | 165 |  * | 
 | 166 |  *      11 Apr 1998 rev. 4.05 for linux 2.0.33 and 2.1.95 | 
 | 167 |  *          Major reliability improvement: when a batch with overlapping | 
 | 168 |  *          requests is detected, requests are queued one at a time | 
 | 169 |  *          eliminating any possible board or drive reordering. | 
 | 170 |  * | 
 | 171 |  *      10 Apr 1998 rev. 4.04 for linux 2.0.33 and 2.1.95 | 
 | 172 |  *          Improved SMP support (if linux version >= 2.1.95). | 
 | 173 |  * | 
 | 174 |  *       9 Apr 1998 rev. 4.03 for linux 2.0.33 and 2.1.94 | 
 | 175 |  *          Added support for new PCI code and IO-APIC remapping of irqs. | 
 | 176 |  *          Performance improvement: when sequential i/o is detected, | 
 | 177 |  *          always use direct sort instead of reverse sort. | 
 | 178 |  * | 
 | 179 |  *       4 Apr 1998 rev. 4.02 for linux 2.0.33 and 2.1.92 | 
 | 180 |  *          io_port is now unsigned long. | 
 | 181 |  * | 
 | 182 |  *      17 Mar 1998 rev. 4.01 for linux 2.0.33 and 2.1.88 | 
 | 183 |  *          Use new scsi error handling code (if linux version >= 2.1.88). | 
 | 184 |  *          Use new interrupt code. | 
 | 185 |  * | 
 | 186 |  *      12 Sep 1997 rev. 3.11 for linux 2.0.30 and 2.1.55 | 
 | 187 |  *          Use of udelay inside the wait loops to avoid timeout | 
 | 188 |  *          problems with fast cpus. | 
 | 189 |  *          Removed check about useless calls to the interrupt service | 
 | 190 |  *          routine (reported on SMP systems only). | 
 | 191 |  *          At initialization time "sorted/unsorted" is displayed instead | 
 | 192 |  *          of "linked/unlinked" to reinforce the fact that "linking" is | 
 | 193 |  *          nothing but "elevator sorting" in the actual implementation. | 
 | 194 |  * | 
 | 195 |  *      17 May 1997 rev. 3.10 for linux 2.0.30 and 2.1.38 | 
 | 196 |  *          Use of serial_number_at_timeout in abort and reset processing. | 
 | 197 |  *          Use of the __initfunc and __initdata macro in setup code. | 
 | 198 |  *          Minor cleanups in the list_statistics code. | 
 | 199 |  *          Increased controller busy timeout in order to better support | 
 | 200 |  *          slow SCSI devices. | 
 | 201 |  * | 
 | 202 |  *      24 Feb 1997 rev. 3.00 for linux 2.0.29 and 2.1.26 | 
 | 203 |  *          When loading as a module, parameter passing is now supported | 
 | 204 |  *          both in 2.0 and in 2.1 style. | 
 | 205 |  *          Fixed data transfer direction for some SCSI opcodes. | 
 | 206 |  *          Immediate acknowledge to request sense commands. | 
 | 207 |  *          Linked commands to each disk device are now reordered by elevator | 
 | 208 |  *          sorting. Rare cases in which reordering of write requests could | 
 | 209 |  *          cause wrong results are managed. | 
 | 210 |  *          Fixed spurious timeouts caused by long simple queue tag sequences. | 
 | 211 |  *          New command line option (tm:[0-3]) to choose the type of tags: | 
 | 212 |  *          0 -> mixed (default); 1 -> simple; 2 -> head; 3 -> ordered. | 
 | 213 |  * | 
 | 214 |  *      18 Jan 1997 rev. 2.60 for linux 2.1.21 and 2.0.28 | 
 | 215 |  *          Added command line options to enable/disable linked commands | 
 | 216 |  *          (lc:[y|n]), tagged commands (tc:[y|n]) and to set the max queue | 
 | 217 |  *          depth (mq:xx). Default is "eata=lc:n,tc:n,mq:16". | 
 | 218 |  *          Improved command linking. | 
 | 219 |  *          Documented how to setup RAID-0 with DPT SmartRAID boards. | 
 | 220 |  * | 
 | 221 |  *       8 Jan 1997 rev. 2.50 for linux 2.1.20 and 2.0.27 | 
 | 222 |  *          Added linked command support. | 
 | 223 |  *          Improved detection of PCI boards using ISA base addresses. | 
 | 224 |  * | 
 | 225 |  *       3 Dec 1996 rev. 2.40 for linux 2.1.14 and 2.0.27 | 
 | 226 |  *          Added support for tagged commands and queue depth adjustment. | 
 | 227 |  * | 
 | 228 |  *      22 Nov 1996 rev. 2.30 for linux 2.1.12 and 2.0.26 | 
 | 229 |  *          When CONFIG_PCI is defined, BIOS32 is used to include in the | 
 | 230 |  *          list of i/o ports to be probed all the PCI SCSI controllers. | 
 | 231 |  *          The list of i/o ports to be probed can be overwritten by the | 
 | 232 |  *          "eata=port0,port1,...." boot command line option. | 
 | 233 |  *          Scatter/gather lists are now allocated by a number of kmalloc | 
 | 234 |  *          calls, in order to avoid the previous size limit of 64Kb. | 
 | 235 |  * | 
 | 236 |  *      16 Nov 1996 rev. 2.20 for linux 2.1.10 and 2.0.25 | 
 | 237 |  *          Added support for EATA 2.0C, PCI, multichannel and wide SCSI. | 
 | 238 |  * | 
 | 239 |  *      27 Sep 1996 rev. 2.12 for linux 2.1.0 | 
 | 240 |  *          Portability cleanups (virtual/bus addressing, little/big endian | 
 | 241 |  *          support). | 
 | 242 |  * | 
 | 243 |  *      09 Jul 1996 rev. 2.11 for linux 2.0.4 | 
 | 244 |  *          Number of internal retries is now limited. | 
 | 245 |  * | 
 | 246 |  *      16 Apr 1996 rev. 2.10 for linux 1.3.90 | 
 | 247 |  *          New argument "reset_flags" to the reset routine. | 
 | 248 |  * | 
 | 249 |  *       6 Jul 1995 rev. 2.01 for linux 1.3.7 | 
 | 250 |  *          Update required by the new /proc/scsi support. | 
 | 251 |  * | 
 | 252 |  *      11 Mar 1995 rev. 2.00 for linux 1.2.0 | 
 | 253 |  *          Fixed a bug which prevented media change detection for removable | 
 | 254 |  *          disk drives. | 
 | 255 |  * | 
 | 256 |  *      23 Feb 1995 rev. 1.18 for linux 1.1.94 | 
 | 257 |  *          Added a check for scsi_register returning NULL. | 
 | 258 |  * | 
 | 259 |  *      11 Feb 1995 rev. 1.17 for linux 1.1.91 | 
 | 260 |  *          Now DEBUG_RESET is disabled by default. | 
 | 261 |  *          Register a board even if it does not assert DMA protocol support | 
 | 262 |  *          (DPT SK2011B does not report correctly the dmasup bit). | 
 | 263 |  * | 
 | 264 |  *       9 Feb 1995 rev. 1.16 for linux 1.1.90 | 
 | 265 |  *          Use host->wish_block instead of host->block. | 
 | 266 |  *          New list of Data Out SCSI commands. | 
 | 267 |  * | 
 | 268 |  *       8 Feb 1995 rev. 1.15 for linux 1.1.89 | 
 | 269 |  *          Cleared target_time_out counter while performing a reset. | 
 | 270 |  *          All external symbols renamed to avoid possible name conflicts. | 
 | 271 |  * | 
 | 272 |  *      28 Jan 1995 rev. 1.14 for linux 1.1.86 | 
 | 273 |  *          Added module support. | 
 | 274 |  *          Log and do a retry when a disk drive returns a target status | 
 | 275 |  *          different from zero on a recovered error. | 
 | 276 |  * | 
 | 277 |  *      24 Jan 1995 rev. 1.13 for linux 1.1.85 | 
 | 278 |  *          Use optimized board configuration, with a measured performance | 
 | 279 |  *          increase in the range 10%-20% on i/o throughput. | 
 | 280 |  * | 
 | 281 |  *      16 Jan 1995 rev. 1.12 for linux 1.1.81 | 
 | 282 |  *          Fix mscp structure comments (no functional change). | 
 | 283 |  *          Display a message if check_region detects a port address | 
 | 284 |  *          already in use. | 
 | 285 |  * | 
 | 286 |  *      17 Dec 1994 rev. 1.11 for linux 1.1.74 | 
 | 287 |  *          Use the scsicam_bios_param routine. This allows an easy | 
 | 288 |  *          migration path from disk partition tables created using | 
 | 289 |  *          different SCSI drivers and non optimal disk geometry. | 
 | 290 |  * | 
 | 291 |  *      15 Dec 1994 rev. 1.10 for linux 1.1.74 | 
 | 292 |  *          Added support for ISA EATA boards (DPT PM2011, DPT PM2021). | 
 | 293 |  *          The host->block flag is set for all the detected ISA boards. | 
 | 294 |  *          The detect routine no longer enforces LEVEL triggering | 
 | 295 |  *          for EISA boards, it just prints a warning message. | 
 | 296 |  * | 
 | 297 |  *      30 Nov 1994 rev. 1.09 for linux 1.1.68 | 
 | 298 |  *          Redo i/o on target status CHECK_CONDITION for TYPE_DISK only. | 
 | 299 |  *          Added optional support for using a single board at a time. | 
 | 300 |  * | 
 | 301 |  *      18 Nov 1994 rev. 1.08 for linux 1.1.64 | 
 | 302 |  *          Forces sg_tablesize = 64 and can_queue = 64 if these | 
 | 303 |  *          values are not correctly detected (DPT PM2012). | 
 | 304 |  * | 
 | 305 |  *      14 Nov 1994 rev. 1.07 for linux 1.1.63  Final BETA release. | 
 | 306 |  *      04 Aug 1994 rev. 1.00 for linux 1.1.39  First BETA release. | 
 | 307 |  * | 
 | 308 |  * | 
 | 309 |  *          This driver is based on the CAM (Common Access Method Committee) | 
 | 310 |  *          EATA (Enhanced AT Bus Attachment) rev. 2.0A, using DMA protocol. | 
 | 311 |  * | 
 | 312 |  *  Copyright (C) 1994-2003 Dario Ballabio (ballabio_dario@emc.com) | 
 | 313 |  * | 
 | 314 |  *  Alternate email: dario.ballabio@inwind.it, dario.ballabio@tiscalinet.it | 
 | 315 |  * | 
 | 316 |  *  Redistribution and use in source and binary forms, with or without | 
 | 317 |  *  modification, are permitted provided that redistributions of source | 
 | 318 |  *  code retain the above copyright notice and this comment without | 
 | 319 |  *  modification. | 
 | 320 |  * | 
 | 321 |  */ | 
 | 322 |  | 
 | 323 | /* | 
 | 324 |  * | 
 | 325 |  *  Here is a brief description of the DPT SCSI host adapters. | 
 | 326 |  *  All these boards provide an EATA/DMA compatible programming interface | 
 | 327 |  *  and are fully supported by this driver in any configuration, including | 
 | 328 |  *  multiple SCSI channels: | 
 | 329 |  * | 
 | 330 |  *  PM2011B/9X -  Entry Level ISA | 
 | 331 |  *  PM2021A/9X -  High Performance ISA | 
 | 332 |  *  PM2012A       Old EISA | 
 | 333 |  *  PM2012B       Old EISA | 
 | 334 |  *  PM2022A/9X -  Entry Level EISA | 
 | 335 |  *  PM2122A/9X -  High Performance EISA | 
 | 336 |  *  PM2322A/9X -  Extra High Performance EISA | 
 | 337 |  *  PM3021     -  SmartRAID Adapter for ISA | 
 | 338 |  *  PM3222     -  SmartRAID Adapter for EISA (PM3222W is 16-bit wide SCSI) | 
 | 339 |  *  PM3224     -  SmartRAID Adapter for PCI  (PM3224W is 16-bit wide SCSI) | 
 | 340 |  *  PM33340UW  -  SmartRAID Adapter for PCI  ultra wide multichannel | 
 | 341 |  * | 
 | 342 |  *  The above list is just an indication: as a matter of fact all DPT | 
 | 343 |  *  boards using the EATA/DMA protocol are supported by this driver, | 
 | 344 |  *  since they use exactely the same programming interface. | 
 | 345 |  * | 
 | 346 |  *  The DPT PM2001 provides only the EATA/PIO interface and hence is not | 
 | 347 |  *  supported by this driver. | 
 | 348 |  * | 
 | 349 |  *  This code has been tested with up to 3 Distributed Processing Technology | 
 | 350 |  *  PM2122A/9X (DPT SCSI BIOS v002.D1, firmware v05E.0) EISA controllers, | 
 | 351 |  *  in any combination of private and shared IRQ. | 
 | 352 |  *  PCI support has been tested using up to 2 DPT PM3224W (DPT SCSI BIOS | 
 | 353 |  *  v003.D0, firmware v07G.0). | 
 | 354 |  * | 
 | 355 |  *  DPT SmartRAID boards support "Hardware Array" - a group of disk drives | 
 | 356 |  *  which are all members of the same RAID-0, RAID-1 or RAID-5 array implemented | 
 | 357 |  *  in host adapter hardware. Hardware Arrays are fully compatible with this | 
 | 358 |  *  driver, since they look to it as a single disk drive. | 
 | 359 |  * | 
 | 360 |  *  WARNING: to create a RAID-0 "Hardware Array" you must select "Other Unix" | 
 | 361 |  *  as the current OS in the DPTMGR "Initial System Installation" menu. | 
 | 362 |  *  Otherwise RAID-0 is generated as an "Array Group" (i.e. software RAID-0), | 
 | 363 |  *  which is not supported by the actual SCSI subsystem. | 
 | 364 |  *  To get the "Array Group" functionality, the Linux MD driver must be used | 
 | 365 |  *  instead of the DPT "Array Group" feature. | 
 | 366 |  * | 
 | 367 |  *  Multiple ISA, EISA and PCI boards can be configured in the same system. | 
 | 368 |  *  It is suggested to put all the EISA boards on the same IRQ level, all | 
 | 369 |  *  the PCI  boards on another IRQ level, while ISA boards cannot share | 
 | 370 |  *  interrupts. | 
 | 371 |  * | 
 | 372 |  *  If you configure multiple boards on the same IRQ, the interrupt must | 
 | 373 |  *  be _level_ triggered (not _edge_ triggered). | 
 | 374 |  * | 
 | 375 |  *  This driver detects EATA boards by probes at fixed port addresses, | 
 | 376 |  *  so no BIOS32 or PCI BIOS support is required. | 
 | 377 |  *  The suggested way to detect a generic EATA PCI board is to force on it | 
 | 378 |  *  any unused EISA address, even if there are other controllers on the EISA | 
 | 379 |  *  bus, or even if you system has no EISA bus at all. | 
 | 380 |  *  Do not force any ISA address on EATA PCI boards. | 
 | 381 |  * | 
 | 382 |  *  If PCI bios support is configured into the kernel, BIOS32 is used to | 
 | 383 |  *  include in the list of i/o ports to be probed all the PCI SCSI controllers. | 
 | 384 |  * | 
 | 385 |  *  Due to a DPT BIOS "feature", it might not be possible to force an EISA | 
 | 386 |  *  address on more than a single DPT PCI board, so in this case you have to | 
 | 387 |  *  let the PCI BIOS assign the addresses. | 
 | 388 |  * | 
 | 389 |  *  The sequence of detection probes is: | 
 | 390 |  * | 
 | 391 |  *  - ISA 0x1F0; | 
 | 392 |  *  - PCI SCSI controllers (only if BIOS32 is available); | 
 | 393 |  *  - EISA/PCI 0x1C88 through 0xFC88 (corresponding to EISA slots 1 to 15); | 
 | 394 |  *  - ISA  0x170, 0x230, 0x330. | 
 | 395 |  * | 
 | 396 |  *  The above list of detection probes can be totally replaced by the | 
 | 397 |  *  boot command line option: "eata=port0,port1,port2,...", where the | 
 | 398 |  *  port0, port1... arguments are ISA/EISA/PCI addresses to be probed. | 
 | 399 |  *  For example using "eata=0x7410,0x7450,0x230", the driver probes | 
 | 400 |  *  only the two PCI addresses 0x7410 and 0x7450 and the ISA address 0x230, | 
 | 401 |  *  in this order; "eata=0" totally disables this driver. | 
 | 402 |  * | 
 | 403 |  *  After the optional list of detection probes, other possible command line | 
 | 404 |  *  options are: | 
 | 405 |  * | 
 | 406 |  *  et:y  force use of extended translation (255 heads, 63 sectors); | 
 | 407 |  *  et:n  use disk geometry detected by scsicam_bios_param; | 
 | 408 |  *  rs:y  reverse scan order while detecting PCI boards; | 
 | 409 |  *  rs:n  use BIOS order while detecting PCI boards; | 
 | 410 |  *  lc:y  enables linked commands; | 
 | 411 |  *  lc:n  disables linked commands; | 
 | 412 |  *  tm:0  disables tagged commands (same as tc:n); | 
 | 413 |  *  tm:1  use simple queue tags (same as tc:y); | 
 | 414 |  *  tm:2  use ordered queue tags (same as tc:2); | 
 | 415 |  *  mq:xx set the max queue depth to the value xx (2 <= xx <= 32). | 
 | 416 |  * | 
 | 417 |  *  The default value is: "eata=lc:n,mq:16,tm:0,et:n,rs:n". | 
 | 418 |  *  An example using the list of detection probes could be: | 
 | 419 |  *  "eata=0x7410,0x230,lc:y,tm:2,mq:4,et:n". | 
 | 420 |  * | 
 | 421 |  *  When loading as a module, parameters can be specified as well. | 
 | 422 |  *  The above example would be (use 1 in place of y and 0 in place of n): | 
 | 423 |  * | 
 | 424 |  *  modprobe eata io_port=0x7410,0x230 linked_comm=1 \ | 
 | 425 |  *                max_queue_depth=4 ext_tran=0 tag_mode=2 \ | 
 | 426 |  *                rev_scan=1 | 
 | 427 |  * | 
 | 428 |  *  ---------------------------------------------------------------------------- | 
 | 429 |  *  In this implementation, linked commands are designed to work with any DISK | 
 | 430 |  *  or CD-ROM, since this linking has only the intent of clustering (time-wise) | 
 | 431 |  *  and reordering by elevator sorting commands directed to each device, | 
 | 432 |  *  without any relation with the actual SCSI protocol between the controller | 
 | 433 |  *  and the device. | 
 | 434 |  *  If Q is the queue depth reported at boot time for each device (also named | 
 | 435 |  *  cmds/lun) and Q > 2, whenever there is already an active command to the | 
 | 436 |  *  device all other commands to the same device  (up to Q-1) are kept waiting | 
 | 437 |  *  in the elevator sorting queue. When the active command completes, the | 
 | 438 |  *  commands in this queue are sorted by sector address. The sort is chosen | 
 | 439 |  *  between increasing or decreasing by minimizing the seek distance between | 
 | 440 |  *  the sector of the commands just completed and the sector of the first | 
 | 441 |  *  command in the list to be sorted. | 
 | 442 |  *  Trivial math assures that the unsorted average seek distance when doing | 
 | 443 |  *  random seeks over S sectors is S/3. | 
 | 444 |  *  When (Q-1) requests are uniformly distributed over S sectors, the average | 
 | 445 |  *  distance between two adjacent requests is S/((Q-1) + 1), so the sorted | 
 | 446 |  *  average seek distance for (Q-1) random requests over S sectors is S/Q. | 
 | 447 |  *  The elevator sorting hence divides the seek distance by a factor Q/3. | 
 | 448 |  *  The above pure geometric remarks are valid in all cases and the | 
 | 449 |  *  driver effectively reduces the seek distance by the predicted factor | 
 | 450 |  *  when there are Q concurrent read i/o operations on the device, but this | 
 | 451 |  *  does not necessarily results in a noticeable performance improvement: | 
 | 452 |  *  your mileage may vary.... | 
 | 453 |  * | 
 | 454 |  *  Note: command reordering inside a batch of queued commands could cause | 
 | 455 |  *        wrong results only if there is at least one write request and the | 
 | 456 |  *        intersection (sector-wise) of all requests is not empty. | 
 | 457 |  *        When the driver detects a batch including overlapping requests | 
 | 458 |  *        (a really rare event) strict serial (pid) order is enforced. | 
 | 459 |  *  ---------------------------------------------------------------------------- | 
 | 460 |  *  The extended translation option (et:y) is useful when using large physical | 
 | 461 |  *  disks/arrays. It could also be useful when switching between Adaptec boards | 
 | 462 |  *  and DPT boards without reformatting the disk. | 
 | 463 |  *  When a boot disk is partitioned with extended translation, in order to | 
 | 464 |  *  be able to boot it with a DPT board is could be necessary to add to | 
 | 465 |  *  lilo.conf additional commands as in the following example: | 
 | 466 |  * | 
 | 467 |  *  fix-table | 
 | 468 |  *  disk=/dev/sda bios=0x80 sectors=63 heads=128 cylindres=546 | 
 | 469 |  * | 
 | 470 |  *  where the above geometry should be replaced with the one reported at | 
 | 471 |  *  power up by the DPT controller. | 
 | 472 |  *  ---------------------------------------------------------------------------- | 
 | 473 |  * | 
 | 474 |  *  The boards are named EATA0, EATA1,... according to the detection order. | 
 | 475 |  * | 
 | 476 |  *  In order to support multiple ISA boards in a reliable way, | 
 | 477 |  *  the driver sets host->wish_block = 1 for all ISA boards. | 
 | 478 |  */ | 
 | 479 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 480 | #include <linux/string.h> | 
 | 481 | #include <linux/kernel.h> | 
 | 482 | #include <linux/ioport.h> | 
 | 483 | #include <linux/delay.h> | 
 | 484 | #include <linux/proc_fs.h> | 
 | 485 | #include <linux/blkdev.h> | 
 | 486 | #include <linux/interrupt.h> | 
 | 487 | #include <linux/stat.h> | 
 | 488 | #include <linux/pci.h> | 
 | 489 | #include <linux/init.h> | 
 | 490 | #include <linux/ctype.h> | 
 | 491 | #include <linux/spinlock.h> | 
| Matthias Gehre | 910638a | 2006-03-28 01:56:48 -0800 | [diff] [blame] | 492 | #include <linux/dma-mapping.h> | 
| Tejun Heo | 5a0e3ad | 2010-03-24 17:04:11 +0900 | [diff] [blame] | 493 | #include <linux/slab.h> | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 494 | #include <asm/byteorder.h> | 
 | 495 | #include <asm/dma.h> | 
 | 496 | #include <asm/io.h> | 
 | 497 | #include <asm/irq.h> | 
 | 498 |  | 
 | 499 | #include <scsi/scsi.h> | 
 | 500 | #include <scsi/scsi_cmnd.h> | 
 | 501 | #include <scsi/scsi_device.h> | 
 | 502 | #include <scsi/scsi_host.h> | 
 | 503 | #include <scsi/scsi_tcq.h> | 
 | 504 | #include <scsi/scsicam.h> | 
 | 505 |  | 
 | 506 | static int eata2x_detect(struct scsi_host_template *); | 
 | 507 | static int eata2x_release(struct Scsi_Host *); | 
 | 508 | static int eata2x_queuecommand(struct scsi_cmnd *, | 
 | 509 | 			       void (*done) (struct scsi_cmnd *)); | 
 | 510 | static int eata2x_eh_abort(struct scsi_cmnd *); | 
 | 511 | static int eata2x_eh_host_reset(struct scsi_cmnd *); | 
 | 512 | static int eata2x_bios_param(struct scsi_device *, struct block_device *, | 
 | 513 | 			     sector_t, int *); | 
 | 514 | static int eata2x_slave_configure(struct scsi_device *); | 
 | 515 |  | 
 | 516 | static struct scsi_host_template driver_template = { | 
 | 517 | 	.name = "EATA/DMA 2.0x rev. 8.10.00 ", | 
 | 518 | 	.detect = eata2x_detect, | 
 | 519 | 	.release = eata2x_release, | 
 | 520 | 	.queuecommand = eata2x_queuecommand, | 
 | 521 | 	.eh_abort_handler = eata2x_eh_abort, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 522 | 	.eh_host_reset_handler = eata2x_eh_host_reset, | 
 | 523 | 	.bios_param = eata2x_bios_param, | 
 | 524 | 	.slave_configure = eata2x_slave_configure, | 
 | 525 | 	.this_id = 7, | 
 | 526 | 	.unchecked_isa_dma = 1, | 
| FUJITA Tomonori | 9cb83c7 | 2007-10-16 11:24:32 +0200 | [diff] [blame] | 527 | 	.use_clustering = ENABLE_CLUSTERING, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 528 | }; | 
 | 529 |  | 
 | 530 | #if !defined(__BIG_ENDIAN_BITFIELD) && !defined(__LITTLE_ENDIAN_BITFIELD) | 
 | 531 | #error "Adjust your <asm/byteorder.h> defines" | 
 | 532 | #endif | 
 | 533 |  | 
 | 534 | /* Subversion values */ | 
 | 535 | #define ISA  0 | 
 | 536 | #define ESA 1 | 
 | 537 |  | 
 | 538 | #undef  FORCE_CONFIG | 
 | 539 |  | 
 | 540 | #undef  DEBUG_LINKED_COMMANDS | 
 | 541 | #undef  DEBUG_DETECT | 
 | 542 | #undef  DEBUG_PCI_DETECT | 
 | 543 | #undef  DEBUG_INTERRUPT | 
 | 544 | #undef  DEBUG_RESET | 
 | 545 | #undef  DEBUG_GENERATE_ERRORS | 
 | 546 | #undef  DEBUG_GENERATE_ABORTS | 
 | 547 | #undef  DEBUG_GEOMETRY | 
 | 548 |  | 
 | 549 | #define MAX_ISA 4 | 
 | 550 | #define MAX_VESA 0 | 
 | 551 | #define MAX_EISA 15 | 
 | 552 | #define MAX_PCI 16 | 
 | 553 | #define MAX_BOARDS (MAX_ISA + MAX_VESA + MAX_EISA + MAX_PCI) | 
 | 554 | #define MAX_CHANNEL 4 | 
 | 555 | #define MAX_LUN 32 | 
 | 556 | #define MAX_TARGET 32 | 
 | 557 | #define MAX_MAILBOXES 64 | 
 | 558 | #define MAX_SGLIST 64 | 
 | 559 | #define MAX_LARGE_SGLIST 122 | 
 | 560 | #define MAX_INTERNAL_RETRIES 64 | 
 | 561 | #define MAX_CMD_PER_LUN 2 | 
 | 562 | #define MAX_TAGGED_CMD_PER_LUN (MAX_MAILBOXES - MAX_CMD_PER_LUN) | 
 | 563 |  | 
 | 564 | #define SKIP ULONG_MAX | 
 | 565 | #define FREE 0 | 
 | 566 | #define IN_USE   1 | 
 | 567 | #define LOCKED   2 | 
 | 568 | #define IN_RESET 3 | 
 | 569 | #define IGNORE   4 | 
 | 570 | #define READY    5 | 
 | 571 | #define ABORTING 6 | 
 | 572 | #define NO_DMA  0xff | 
 | 573 | #define MAXLOOP  10000 | 
 | 574 | #define TAG_DISABLED 0 | 
 | 575 | #define TAG_SIMPLE   1 | 
 | 576 | #define TAG_ORDERED  2 | 
 | 577 |  | 
 | 578 | #define REG_CMD         7 | 
 | 579 | #define REG_STATUS      7 | 
 | 580 | #define REG_AUX_STATUS  8 | 
 | 581 | #define REG_DATA        0 | 
 | 582 | #define REG_DATA2       1 | 
 | 583 | #define REG_SEE         6 | 
 | 584 | #define REG_LOW         2 | 
 | 585 | #define REG_LM          3 | 
 | 586 | #define REG_MID         4 | 
 | 587 | #define REG_MSB         5 | 
 | 588 | #define REGION_SIZE     9UL | 
 | 589 | #define MAX_ISA_ADDR    0x03ff | 
 | 590 | #define MIN_EISA_ADDR   0x1c88 | 
 | 591 | #define MAX_EISA_ADDR   0xfc88 | 
 | 592 | #define BSY_ASSERTED      0x80 | 
 | 593 | #define DRQ_ASSERTED      0x08 | 
 | 594 | #define ABSY_ASSERTED     0x01 | 
 | 595 | #define IRQ_ASSERTED      0x02 | 
 | 596 | #define READ_CONFIG_PIO   0xf0 | 
 | 597 | #define SET_CONFIG_PIO    0xf1 | 
 | 598 | #define SEND_CP_PIO       0xf2 | 
 | 599 | #define RECEIVE_SP_PIO    0xf3 | 
 | 600 | #define TRUNCATE_XFR_PIO  0xf4 | 
 | 601 | #define RESET_PIO         0xf9 | 
 | 602 | #define READ_CONFIG_DMA   0xfd | 
 | 603 | #define SET_CONFIG_DMA    0xfe | 
 | 604 | #define SEND_CP_DMA       0xff | 
 | 605 | #define ASOK              0x00 | 
 | 606 | #define ASST              0x01 | 
 | 607 |  | 
 | 608 | #define YESNO(a) ((a) ? 'y' : 'n') | 
 | 609 | #define TLDEV(type) ((type) == TYPE_DISK || (type) == TYPE_ROM) | 
 | 610 |  | 
 | 611 | /* "EATA", in Big Endian format */ | 
 | 612 | #define EATA_SIG_BE 0x45415441 | 
 | 613 |  | 
 | 614 | /* Number of valid bytes in the board config structure for EATA 2.0x */ | 
 | 615 | #define EATA_2_0A_SIZE 28 | 
 | 616 | #define EATA_2_0B_SIZE 30 | 
 | 617 | #define EATA_2_0C_SIZE 34 | 
 | 618 |  | 
 | 619 | /* Board info structure */ | 
 | 620 | struct eata_info { | 
 | 621 | 	u_int32_t data_len;	/* Number of valid bytes after this field */ | 
 | 622 | 	u_int32_t sign;		/* ASCII "EATA" signature */ | 
 | 623 |  | 
 | 624 | #if defined(__BIG_ENDIAN_BITFIELD) | 
 | 625 | 	unchar version	: 4, | 
 | 626 | 	       		: 4; | 
 | 627 | 	unchar haaval	: 1, | 
 | 628 | 	       ata	: 1, | 
 | 629 | 	       drqvld	: 1, | 
 | 630 | 	       dmasup	: 1, | 
 | 631 | 	       morsup	: 1, | 
 | 632 | 	       trnxfr	: 1, | 
 | 633 | 	       tarsup	: 1, | 
 | 634 | 	       ocsena	: 1; | 
 | 635 | #else | 
 | 636 | 	unchar		: 4,	/* unused low nibble */ | 
 | 637 | 	 	version	: 4;	/* EATA version, should be 0x1 */ | 
 | 638 | 	unchar ocsena	: 1,	/* Overlap Command Support Enabled */ | 
 | 639 | 	       tarsup	: 1,	/* Target Mode Supported */ | 
 | 640 | 	       trnxfr	: 1,	/* Truncate Transfer Cmd NOT Necessary */ | 
 | 641 | 	       morsup	: 1,	/* More Supported */ | 
 | 642 | 	       dmasup	: 1,	/* DMA Supported */ | 
 | 643 | 	       drqvld	: 1,	/* DRQ Index (DRQX) is valid */ | 
 | 644 | 	       ata	: 1,	/* This is an ATA device */ | 
 | 645 | 	       haaval	: 1;	/* Host Adapter Address Valid */ | 
 | 646 | #endif | 
 | 647 |  | 
 | 648 | 	ushort cp_pad_len;	/* Number of pad bytes after cp_len */ | 
 | 649 | 	unchar host_addr[4];	/* Host Adapter SCSI ID for channels 3, 2, 1, 0 */ | 
 | 650 | 	u_int32_t cp_len;	/* Number of valid bytes in cp */ | 
 | 651 | 	u_int32_t sp_len;	/* Number of valid bytes in sp */ | 
 | 652 | 	ushort queue_size;	/* Max number of cp that can be queued */ | 
 | 653 | 	ushort unused; | 
 | 654 | 	ushort scatt_size;	/* Max number of entries in scatter/gather table */ | 
 | 655 |  | 
 | 656 | #if defined(__BIG_ENDIAN_BITFIELD) | 
 | 657 | 	unchar drqx	: 2, | 
 | 658 | 	       second	: 1, | 
 | 659 | 	       irq_tr	: 1, | 
 | 660 | 	       irq	: 4; | 
 | 661 | 	unchar sync; | 
 | 662 | 	unchar		: 4, | 
 | 663 | 	       res1	: 1, | 
 | 664 | 	       large_sg	: 1, | 
 | 665 | 	       forcaddr	: 1, | 
 | 666 | 	       isaena	: 1; | 
 | 667 | 	unchar max_chan	: 3, | 
 | 668 | 	       max_id	: 5; | 
 | 669 | 	unchar max_lun; | 
 | 670 | 	unchar eisa	: 1, | 
 | 671 | 	       pci	: 1, | 
 | 672 | 	       idquest	: 1, | 
 | 673 | 	       m1	: 1, | 
 | 674 | 	       		: 4; | 
 | 675 | #else | 
 | 676 | 	unchar irq	: 4,	/* Interrupt Request assigned to this controller */ | 
 | 677 | 	       irq_tr	: 1,	/* 0 for edge triggered, 1 for level triggered */ | 
 | 678 | 	       second	: 1,	/* 1 if this is a secondary (not primary) controller */ | 
 | 679 | 	       drqx	: 2;	/* DRQ Index (0=DMA0, 1=DMA7, 2=DMA6, 3=DMA5) */ | 
 | 680 | 	unchar sync;		/* 1 if scsi target id 7...0 is running sync scsi */ | 
 | 681 |  | 
 | 682 | 	/* Structure extension defined in EATA 2.0B */ | 
 | 683 | 	unchar isaena	: 1,	/* ISA i/o addressing is disabled/enabled */ | 
 | 684 | 	       forcaddr	: 1,	/* Port address has been forced */ | 
 | 685 | 	       large_sg	: 1,	/* 1 if large SG lists are supported */ | 
 | 686 | 	       res1	: 1, | 
 | 687 | 	       		: 4; | 
 | 688 | 	unchar max_id	: 5,	/* Max SCSI target ID number */ | 
 | 689 | 	       max_chan	: 3;	/* Max SCSI channel number on this board */ | 
 | 690 |  | 
 | 691 | 	/* Structure extension defined in EATA 2.0C */ | 
 | 692 | 	unchar max_lun;		/* Max SCSI LUN number */ | 
 | 693 | 	unchar | 
 | 694 | 			: 4, | 
 | 695 | 	       m1	: 1,	/* This is a PCI with an M1 chip installed */ | 
 | 696 | 	       idquest	: 1,	/* RAIDNUM returned is questionable */ | 
 | 697 | 	       pci	: 1,	/* This board is PCI */ | 
 | 698 | 	       eisa	: 1;	/* This board is EISA */ | 
 | 699 | #endif | 
 | 700 |  | 
 | 701 | 	unchar raidnum;		/* Uniquely identifies this HBA in a system */ | 
 | 702 | 	unchar notused; | 
 | 703 |  | 
 | 704 | 	ushort ipad[247]; | 
 | 705 | }; | 
 | 706 |  | 
 | 707 | /* Board config structure */ | 
 | 708 | struct eata_config { | 
 | 709 | 	ushort len;		/* Number of bytes following this field */ | 
 | 710 |  | 
 | 711 | #if defined(__BIG_ENDIAN_BITFIELD) | 
 | 712 | 	unchar		: 4, | 
 | 713 | 	       tarena	: 1, | 
 | 714 | 	       mdpena	: 1, | 
 | 715 | 	       ocena	: 1, | 
 | 716 | 	       edis	: 1; | 
 | 717 | #else | 
 | 718 | 	unchar edis	: 1,	/* Disable EATA interface after config command */ | 
 | 719 | 	       ocena	: 1,	/* Overlapped Commands Enabled */ | 
 | 720 | 	       mdpena	: 1,	/* Transfer all Modified Data Pointer Messages */ | 
 | 721 | 	       tarena	: 1,	/* Target Mode Enabled for this controller */ | 
 | 722 | 	       		: 4; | 
 | 723 | #endif | 
 | 724 | 	unchar cpad[511]; | 
 | 725 | }; | 
 | 726 |  | 
 | 727 | /* Returned status packet structure */ | 
 | 728 | struct mssp { | 
 | 729 | #if defined(__BIG_ENDIAN_BITFIELD) | 
 | 730 | 	unchar eoc	: 1, | 
 | 731 | 	       adapter_status : 7; | 
 | 732 | #else | 
 | 733 | 	unchar adapter_status : 7,	/* State related to current command */ | 
 | 734 | 	       eoc	: 1;		/* End Of Command (1 = command completed) */ | 
 | 735 | #endif | 
 | 736 | 	unchar target_status;	/* SCSI status received after data transfer */ | 
 | 737 | 	unchar unused[2]; | 
 | 738 | 	u_int32_t inv_res_len;	/* Number of bytes not transferred */ | 
 | 739 | 	u_int32_t cpp_index;	/* Index of address set in cp */ | 
 | 740 | 	char mess[12]; | 
 | 741 | }; | 
 | 742 |  | 
 | 743 | struct sg_list { | 
 | 744 | 	unsigned int address;	/* Segment Address */ | 
 | 745 | 	unsigned int num_bytes;	/* Segment Length */ | 
 | 746 | }; | 
 | 747 |  | 
 | 748 | /* MailBox SCSI Command Packet */ | 
 | 749 | struct mscp { | 
 | 750 | #if defined(__BIG_ENDIAN_BITFIELD) | 
 | 751 | 	unchar din	: 1, | 
 | 752 | 	       dout	: 1, | 
 | 753 | 	       interp	: 1, | 
 | 754 | 	       		: 1, | 
 | 755 | 		sg	: 1, | 
 | 756 | 		reqsen	:1, | 
 | 757 | 		init	: 1, | 
 | 758 | 		sreset	: 1; | 
 | 759 | 	unchar sense_len; | 
 | 760 | 	unchar unused[3]; | 
 | 761 | 	unchar		: 7, | 
 | 762 | 	       fwnest	: 1; | 
 | 763 | 	unchar		: 5, | 
 | 764 | 	       hbaci	: 1, | 
 | 765 | 	       iat	: 1, | 
 | 766 | 	       phsunit	: 1; | 
 | 767 | 	unchar channel	: 3, | 
 | 768 | 	       target	: 5; | 
 | 769 | 	unchar one	: 1, | 
 | 770 | 	       dispri	: 1, | 
 | 771 | 	       luntar	: 1, | 
 | 772 | 	       lun	: 5; | 
 | 773 | #else | 
 | 774 | 	unchar sreset	:1,	/* SCSI Bus Reset Signal should be asserted */ | 
 | 775 | 	       init	:1,	/* Re-initialize controller and self test */ | 
 | 776 | 	       reqsen	:1,	/* Transfer Request Sense Data to addr using DMA */ | 
 | 777 | 	       sg	:1,	/* Use Scatter/Gather */ | 
 | 778 | 	       		:1, | 
 | 779 | 	       interp	:1,	/* The controller interprets cp, not the target */ | 
 | 780 | 	       dout	:1,	/* Direction of Transfer is Out (Host to Target) */ | 
 | 781 | 	       din	:1;	/* Direction of Transfer is In (Target to Host) */ | 
 | 782 | 	unchar sense_len;	/* Request Sense Length */ | 
 | 783 | 	unchar unused[3]; | 
 | 784 | 	unchar fwnest	: 1,	/* Send command to a component of an Array Group */ | 
 | 785 | 			: 7; | 
 | 786 | 	unchar phsunit	: 1,	/* Send to Target Physical Unit (bypass RAID) */ | 
 | 787 | 	       iat	: 1,	/* Inhibit Address Translation */ | 
 | 788 | 	       hbaci	: 1,	/* Inhibit HBA Caching for this command */ | 
 | 789 | 	       		: 5; | 
 | 790 | 	unchar target	: 5,	/* SCSI target ID */ | 
 | 791 | 	       channel	: 3;	/* SCSI channel number */ | 
 | 792 | 	unchar lun	: 5,	/* SCSI logical unit number */ | 
 | 793 | 	       luntar	: 1,	/* This cp is for Target (not LUN) */ | 
 | 794 | 	       dispri	: 1,	/* Disconnect Privilege granted */ | 
 | 795 | 	       one	: 1;	/* 1 */ | 
 | 796 | #endif | 
 | 797 |  | 
 | 798 | 	unchar mess[3];		/* Massage to/from Target */ | 
 | 799 | 	unchar cdb[12];		/* Command Descriptor Block */ | 
 | 800 | 	u_int32_t data_len;	/* If sg=0 Data Length, if sg=1 sglist length */ | 
 | 801 | 	u_int32_t cpp_index;	/* Index of address to be returned in sp */ | 
 | 802 | 	u_int32_t data_address;	/* If sg=0 Data Address, if sg=1 sglist address */ | 
 | 803 | 	u_int32_t sp_dma_addr;	/* Address where sp is DMA'ed when cp completes */ | 
 | 804 | 	u_int32_t sense_addr;	/* Address where Sense Data is DMA'ed on error */ | 
 | 805 |  | 
 | 806 | 	/* Additional fields begin here. */ | 
 | 807 | 	struct scsi_cmnd *SCpnt; | 
 | 808 |  | 
 | 809 | 	/* All the cp structure is zero filled by queuecommand except the | 
 | 810 | 	   following CP_TAIL_SIZE bytes, initialized by detect */ | 
 | 811 | 	dma_addr_t cp_dma_addr;	/* dma handle for this cp structure */ | 
 | 812 | 	struct sg_list *sglist;	/* pointer to the allocated SG list */ | 
 | 813 | }; | 
 | 814 |  | 
 | 815 | #define CP_TAIL_SIZE (sizeof(struct sglist *) + sizeof(dma_addr_t)) | 
 | 816 |  | 
 | 817 | struct hostdata { | 
 | 818 | 	struct mscp cp[MAX_MAILBOXES];	/* Mailboxes for this board */ | 
 | 819 | 	unsigned int cp_stat[MAX_MAILBOXES];	/* FREE, IN_USE, LOCKED, IN_RESET */ | 
 | 820 | 	unsigned int last_cp_used;	/* Index of last mailbox used */ | 
 | 821 | 	unsigned int iocount;	/* Total i/o done for this board */ | 
 | 822 | 	int board_number;	/* Number of this board */ | 
 | 823 | 	char board_name[16];	/* Name of this board */ | 
 | 824 | 	int in_reset;		/* True if board is doing a reset */ | 
 | 825 | 	int target_to[MAX_TARGET][MAX_CHANNEL];	/* N. of timeout errors on target */ | 
 | 826 | 	int target_redo[MAX_TARGET][MAX_CHANNEL];	/* If 1 redo i/o on target */ | 
 | 827 | 	unsigned int retries;	/* Number of internal retries */ | 
 | 828 | 	unsigned long last_retried_pid;	/* Pid of last retried command */ | 
 | 829 | 	unsigned char subversion;	/* Bus type, either ISA or EISA/PCI */ | 
 | 830 | 	unsigned char protocol_rev;	/* EATA 2.0 rev., 'A' or 'B' or 'C' */ | 
 | 831 | 	unsigned char is_pci;	/* 1 is bus type is PCI */ | 
 | 832 | 	struct pci_dev *pdev;	/* pdev for PCI bus, NULL otherwise */ | 
 | 833 | 	struct mssp *sp_cpu_addr;	/* cpu addr for DMA buffer sp */ | 
 | 834 | 	dma_addr_t sp_dma_addr;	/* dma handle for DMA buffer sp */ | 
 | 835 | 	struct mssp sp;		/* Local copy of sp buffer */ | 
 | 836 | }; | 
 | 837 |  | 
 | 838 | static struct Scsi_Host *sh[MAX_BOARDS]; | 
 | 839 | static const char *driver_name = "EATA"; | 
 | 840 | static char sha[MAX_BOARDS]; | 
 | 841 | static DEFINE_SPINLOCK(driver_lock); | 
 | 842 |  | 
 | 843 | /* Initialize num_boards so that ihdlr can work while detect is in progress */ | 
 | 844 | static unsigned int num_boards = MAX_BOARDS; | 
 | 845 |  | 
 | 846 | static unsigned long io_port[] = { | 
 | 847 |  | 
 | 848 | 	/* Space for MAX_INT_PARAM ports usable while loading as a module */ | 
 | 849 | 	SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, | 
 | 850 | 	SKIP, SKIP, | 
 | 851 |  | 
 | 852 | 	/* First ISA */ | 
 | 853 | 	0x1f0, | 
 | 854 |  | 
 | 855 | 	/* Space for MAX_PCI ports possibly reported by PCI_BIOS */ | 
 | 856 | 	SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, | 
 | 857 | 	SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, | 
 | 858 |  | 
 | 859 | 	/* MAX_EISA ports */ | 
 | 860 | 	0x1c88, 0x2c88, 0x3c88, 0x4c88, 0x5c88, 0x6c88, 0x7c88, 0x8c88, | 
 | 861 | 	0x9c88, 0xac88, 0xbc88, 0xcc88, 0xdc88, 0xec88, 0xfc88, | 
 | 862 |  | 
 | 863 | 	/* Other (MAX_ISA - 1) ports */ | 
 | 864 | 	0x170, 0x230, 0x330, | 
 | 865 |  | 
 | 866 | 	/* End of list */ | 
 | 867 | 	0x0 | 
 | 868 | }; | 
 | 869 |  | 
 | 870 | /* Device is Big Endian */ | 
 | 871 | #define H2DEV(x)   cpu_to_be32(x) | 
 | 872 | #define DEV2H(x)   be32_to_cpu(x) | 
 | 873 | #define H2DEV16(x) cpu_to_be16(x) | 
 | 874 | #define DEV2H16(x) be16_to_cpu(x) | 
 | 875 |  | 
 | 876 | /* But transfer orientation from the 16 bit data register is Little Endian */ | 
 | 877 | #define REG2H(x)   le16_to_cpu(x) | 
 | 878 |  | 
| David Howells | 7d12e78 | 2006-10-05 14:55:46 +0100 | [diff] [blame] | 879 | static irqreturn_t do_interrupt_handler(int, void *); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 880 | static void flush_dev(struct scsi_device *, unsigned long, struct hostdata *, | 
 | 881 | 		      unsigned int); | 
 | 882 | static int do_trace = 0; | 
 | 883 | static int setup_done = 0; | 
 | 884 | static int link_statistics; | 
 | 885 | static int ext_tran = 0; | 
 | 886 | static int rev_scan = 1; | 
 | 887 |  | 
 | 888 | #if defined(CONFIG_SCSI_EATA_TAGGED_QUEUE) | 
 | 889 | static int tag_mode = TAG_SIMPLE; | 
 | 890 | #else | 
 | 891 | static int tag_mode = TAG_DISABLED; | 
 | 892 | #endif | 
 | 893 |  | 
 | 894 | #if defined(CONFIG_SCSI_EATA_LINKED_COMMANDS) | 
 | 895 | static int linked_comm = 1; | 
 | 896 | #else | 
 | 897 | static int linked_comm = 0; | 
 | 898 | #endif | 
 | 899 |  | 
 | 900 | #if defined(CONFIG_SCSI_EATA_MAX_TAGS) | 
 | 901 | static int max_queue_depth = CONFIG_SCSI_EATA_MAX_TAGS; | 
 | 902 | #else | 
 | 903 | static int max_queue_depth = MAX_CMD_PER_LUN; | 
 | 904 | #endif | 
 | 905 |  | 
 | 906 | #if defined(CONFIG_ISA) | 
 | 907 | static int isa_probe = 1; | 
 | 908 | #else | 
 | 909 | static int isa_probe = 0; | 
 | 910 | #endif | 
 | 911 |  | 
 | 912 | #if defined(CONFIG_EISA) | 
 | 913 | static int eisa_probe = 1; | 
 | 914 | #else | 
 | 915 | static int eisa_probe = 0; | 
 | 916 | #endif | 
 | 917 |  | 
 | 918 | #if defined(CONFIG_PCI) | 
 | 919 | static int pci_probe = 1; | 
 | 920 | #else | 
 | 921 | static int pci_probe = 0; | 
 | 922 | #endif | 
 | 923 |  | 
 | 924 | #define MAX_INT_PARAM 10 | 
 | 925 | #define MAX_BOOT_OPTIONS_SIZE 256 | 
 | 926 | static char boot_options[MAX_BOOT_OPTIONS_SIZE]; | 
 | 927 |  | 
 | 928 | #if defined(MODULE) | 
 | 929 | #include <linux/module.h> | 
 | 930 | #include <linux/moduleparam.h> | 
 | 931 |  | 
 | 932 | module_param_string(eata, boot_options, MAX_BOOT_OPTIONS_SIZE, 0); | 
 | 933 | MODULE_PARM_DESC(eata, " equivalent to the \"eata=...\" kernel boot option." | 
 | 934 | 		 "            Example: modprobe eata \"eata=0x7410,0x230,lc:y,tm:0,mq:4,ep:n\""); | 
 | 935 | MODULE_AUTHOR("Dario Ballabio"); | 
 | 936 | MODULE_LICENSE("GPL"); | 
 | 937 | MODULE_DESCRIPTION("EATA/DMA SCSI Driver"); | 
 | 938 |  | 
 | 939 | #endif | 
 | 940 |  | 
 | 941 | static int eata2x_slave_configure(struct scsi_device *dev) | 
 | 942 | { | 
 | 943 | 	int tqd, utqd; | 
 | 944 | 	char *tag_suffix, *link_suffix; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 945 |  | 
 | 946 | 	utqd = MAX_CMD_PER_LUN; | 
 | 947 | 	tqd = max_queue_depth; | 
 | 948 |  | 
 | 949 | 	if (TLDEV(dev->type) && dev->tagged_supported) { | 
 | 950 | 		if (tag_mode == TAG_SIMPLE) { | 
 | 951 | 			scsi_adjust_queue_depth(dev, MSG_SIMPLE_TAG, tqd); | 
 | 952 | 			tag_suffix = ", simple tags"; | 
 | 953 | 		} else if (tag_mode == TAG_ORDERED) { | 
 | 954 | 			scsi_adjust_queue_depth(dev, MSG_ORDERED_TAG, tqd); | 
 | 955 | 			tag_suffix = ", ordered tags"; | 
 | 956 | 		} else { | 
 | 957 | 			scsi_adjust_queue_depth(dev, 0, tqd); | 
 | 958 | 			tag_suffix = ", no tags"; | 
 | 959 | 		} | 
 | 960 | 	} else if (TLDEV(dev->type) && linked_comm) { | 
 | 961 | 		scsi_adjust_queue_depth(dev, 0, tqd); | 
 | 962 | 		tag_suffix = ", untagged"; | 
 | 963 | 	} else { | 
 | 964 | 		scsi_adjust_queue_depth(dev, 0, utqd); | 
 | 965 | 		tag_suffix = ""; | 
 | 966 | 	} | 
 | 967 |  | 
 | 968 | 	if (TLDEV(dev->type) && linked_comm && dev->queue_depth > 2) | 
 | 969 | 		link_suffix = ", sorted"; | 
 | 970 | 	else if (TLDEV(dev->type)) | 
 | 971 | 		link_suffix = ", unsorted"; | 
 | 972 | 	else | 
 | 973 | 		link_suffix = ""; | 
 | 974 |  | 
| Jeff Garzik | 017560f | 2005-10-24 18:04:36 -0400 | [diff] [blame] | 975 | 	sdev_printk(KERN_INFO, dev, | 
 | 976 | 		"cmds/lun %d%s%s.\n", | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 977 | 	       dev->queue_depth, link_suffix, tag_suffix); | 
 | 978 |  | 
 | 979 | 	return 0; | 
 | 980 | } | 
 | 981 |  | 
 | 982 | static int wait_on_busy(unsigned long iobase, unsigned int loop) | 
 | 983 | { | 
 | 984 | 	while (inb(iobase + REG_AUX_STATUS) & ABSY_ASSERTED) { | 
 | 985 | 		udelay(1L); | 
 | 986 | 		if (--loop == 0) | 
 | 987 | 			return 1; | 
 | 988 | 	} | 
 | 989 | 	return 0; | 
 | 990 | } | 
 | 991 |  | 
 | 992 | static int do_dma(unsigned long iobase, unsigned long addr, unchar cmd) | 
 | 993 | { | 
 | 994 | 	unsigned char *byaddr; | 
 | 995 | 	unsigned long devaddr; | 
 | 996 |  | 
 | 997 | 	if (wait_on_busy(iobase, (addr ? MAXLOOP * 100 : MAXLOOP))) | 
 | 998 | 		return 1; | 
 | 999 |  | 
 | 1000 | 	if (addr) { | 
 | 1001 | 		devaddr = H2DEV(addr); | 
 | 1002 | 		byaddr = (unsigned char *)&devaddr; | 
 | 1003 | 		outb(byaddr[3], iobase + REG_LOW); | 
 | 1004 | 		outb(byaddr[2], iobase + REG_LM); | 
 | 1005 | 		outb(byaddr[1], iobase + REG_MID); | 
 | 1006 | 		outb(byaddr[0], iobase + REG_MSB); | 
 | 1007 | 	} | 
 | 1008 |  | 
 | 1009 | 	outb(cmd, iobase + REG_CMD); | 
 | 1010 | 	return 0; | 
 | 1011 | } | 
 | 1012 |  | 
 | 1013 | static int read_pio(unsigned long iobase, ushort * start, ushort * end) | 
 | 1014 | { | 
 | 1015 | 	unsigned int loop = MAXLOOP; | 
 | 1016 | 	ushort *p; | 
 | 1017 |  | 
 | 1018 | 	for (p = start; p <= end; p++) { | 
 | 1019 | 		while (!(inb(iobase + REG_STATUS) & DRQ_ASSERTED)) { | 
 | 1020 | 			udelay(1L); | 
 | 1021 | 			if (--loop == 0) | 
 | 1022 | 				return 1; | 
 | 1023 | 		} | 
 | 1024 | 		loop = MAXLOOP; | 
 | 1025 | 		*p = REG2H(inw(iobase)); | 
 | 1026 | 	} | 
 | 1027 |  | 
 | 1028 | 	return 0; | 
 | 1029 | } | 
 | 1030 |  | 
 | 1031 | static struct pci_dev *get_pci_dev(unsigned long port_base) | 
 | 1032 | { | 
 | 1033 | #if defined(CONFIG_PCI) | 
 | 1034 | 	unsigned int addr; | 
 | 1035 | 	struct pci_dev *dev = NULL; | 
 | 1036 |  | 
 | 1037 | 	while ((dev = pci_get_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) { | 
 | 1038 | 		addr = pci_resource_start(dev, 0); | 
 | 1039 |  | 
 | 1040 | #if defined(DEBUG_PCI_DETECT) | 
 | 1041 | 		printk("%s: get_pci_dev, bus %d, devfn 0x%x, addr 0x%x.\n", | 
 | 1042 | 		       driver_name, dev->bus->number, dev->devfn, addr); | 
 | 1043 | #endif | 
 | 1044 |  | 
 | 1045 | 		/* we are in so much trouble for a pci hotplug system with this driver | 
 | 1046 | 		 * anyway, so doing this at least lets people unload the driver and not | 
 | 1047 | 		 * cause memory problems, but in general this is a bad thing to do (this | 
 | 1048 | 		 * driver needs to be converted to the proper PCI api someday... */ | 
 | 1049 | 		pci_dev_put(dev); | 
 | 1050 | 		if (addr + PCI_BASE_ADDRESS_0 == port_base) | 
 | 1051 | 			return dev; | 
 | 1052 | 	} | 
 | 1053 | #endif				/* end CONFIG_PCI */ | 
 | 1054 | 	return NULL; | 
 | 1055 | } | 
 | 1056 |  | 
 | 1057 | static void enable_pci_ports(void) | 
 | 1058 | { | 
 | 1059 | #if defined(CONFIG_PCI) | 
 | 1060 | 	struct pci_dev *dev = NULL; | 
 | 1061 |  | 
 | 1062 | 	while ((dev = pci_get_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) { | 
 | 1063 | #if defined(DEBUG_PCI_DETECT) | 
 | 1064 | 		printk("%s: enable_pci_ports, bus %d, devfn 0x%x.\n", | 
 | 1065 | 		       driver_name, dev->bus->number, dev->devfn); | 
 | 1066 | #endif | 
 | 1067 |  | 
 | 1068 | 		if (pci_enable_device(dev)) | 
 | 1069 | 			printk | 
 | 1070 | 			    ("%s: warning, pci_enable_device failed, bus %d devfn 0x%x.\n", | 
 | 1071 | 			     driver_name, dev->bus->number, dev->devfn); | 
 | 1072 | 	} | 
 | 1073 |  | 
 | 1074 | #endif				/* end CONFIG_PCI */ | 
 | 1075 | } | 
 | 1076 |  | 
 | 1077 | static int port_detect(unsigned long port_base, unsigned int j, | 
 | 1078 | 		struct scsi_host_template *tpnt) | 
 | 1079 | { | 
 | 1080 | 	unsigned char irq, dma_channel, subversion, i, is_pci = 0; | 
 | 1081 | 	unsigned char protocol_rev; | 
 | 1082 | 	struct eata_info info; | 
 | 1083 | 	char *bus_type, dma_name[16]; | 
 | 1084 | 	struct pci_dev *pdev; | 
 | 1085 | 	/* Allowed DMA channels for ISA (0 indicates reserved) */ | 
 | 1086 | 	unsigned char dma_channel_table[4] = { 5, 6, 7, 0 }; | 
 | 1087 | 	struct Scsi_Host *shost; | 
 | 1088 | 	struct hostdata *ha; | 
 | 1089 | 	char name[16]; | 
 | 1090 |  | 
 | 1091 | 	sprintf(name, "%s%d", driver_name, j); | 
 | 1092 |  | 
 | 1093 | 	if (!request_region(port_base, REGION_SIZE, driver_name)) { | 
 | 1094 | #if defined(DEBUG_DETECT) | 
 | 1095 | 		printk("%s: address 0x%03lx in use, skipping probe.\n", name, | 
 | 1096 | 		       port_base); | 
 | 1097 | #endif | 
 | 1098 | 		goto fail; | 
 | 1099 | 	} | 
 | 1100 |  | 
 | 1101 | 	spin_lock_irq(&driver_lock); | 
 | 1102 |  | 
 | 1103 | 	if (do_dma(port_base, 0, READ_CONFIG_PIO)) { | 
 | 1104 | #if defined(DEBUG_DETECT) | 
 | 1105 | 		printk("%s: detect, do_dma failed at 0x%03lx.\n", name, | 
 | 1106 | 		       port_base); | 
 | 1107 | #endif | 
 | 1108 | 		goto freelock; | 
 | 1109 | 	} | 
 | 1110 |  | 
 | 1111 | 	/* Read the info structure */ | 
 | 1112 | 	if (read_pio(port_base, (ushort *) & info, (ushort *) & info.ipad[0])) { | 
 | 1113 | #if defined(DEBUG_DETECT) | 
 | 1114 | 		printk("%s: detect, read_pio failed at 0x%03lx.\n", name, | 
 | 1115 | 		       port_base); | 
 | 1116 | #endif | 
 | 1117 | 		goto freelock; | 
 | 1118 | 	} | 
 | 1119 |  | 
 | 1120 | 	info.data_len = DEV2H(info.data_len); | 
 | 1121 | 	info.sign = DEV2H(info.sign); | 
 | 1122 | 	info.cp_pad_len = DEV2H16(info.cp_pad_len); | 
 | 1123 | 	info.cp_len = DEV2H(info.cp_len); | 
 | 1124 | 	info.sp_len = DEV2H(info.sp_len); | 
 | 1125 | 	info.scatt_size = DEV2H16(info.scatt_size); | 
 | 1126 | 	info.queue_size = DEV2H16(info.queue_size); | 
 | 1127 |  | 
 | 1128 | 	/* Check the controller "EATA" signature */ | 
 | 1129 | 	if (info.sign != EATA_SIG_BE) { | 
 | 1130 | #if defined(DEBUG_DETECT) | 
 | 1131 | 		printk("%s: signature 0x%04x discarded.\n", name, info.sign); | 
 | 1132 | #endif | 
 | 1133 | 		goto freelock; | 
 | 1134 | 	} | 
 | 1135 |  | 
 | 1136 | 	if (info.data_len < EATA_2_0A_SIZE) { | 
 | 1137 | 		printk | 
 | 1138 | 		    ("%s: config structure size (%d bytes) too short, detaching.\n", | 
 | 1139 | 		     name, info.data_len); | 
 | 1140 | 		goto freelock; | 
 | 1141 | 	} else if (info.data_len == EATA_2_0A_SIZE) | 
 | 1142 | 		protocol_rev = 'A'; | 
 | 1143 | 	else if (info.data_len == EATA_2_0B_SIZE) | 
 | 1144 | 		protocol_rev = 'B'; | 
 | 1145 | 	else | 
 | 1146 | 		protocol_rev = 'C'; | 
 | 1147 |  | 
 | 1148 | 	if (protocol_rev != 'A' && info.forcaddr) { | 
 | 1149 | 		printk("%s: warning, port address has been forced.\n", name); | 
 | 1150 | 		bus_type = "PCI"; | 
 | 1151 | 		is_pci = 1; | 
 | 1152 | 		subversion = ESA; | 
 | 1153 | 	} else if (port_base > MAX_EISA_ADDR | 
 | 1154 | 		   || (protocol_rev == 'C' && info.pci)) { | 
 | 1155 | 		bus_type = "PCI"; | 
 | 1156 | 		is_pci = 1; | 
 | 1157 | 		subversion = ESA; | 
 | 1158 | 	} else if (port_base >= MIN_EISA_ADDR | 
 | 1159 | 		   || (protocol_rev == 'C' && info.eisa)) { | 
 | 1160 | 		bus_type = "EISA"; | 
 | 1161 | 		subversion = ESA; | 
 | 1162 | 	} else if (protocol_rev == 'C' && !info.eisa && !info.pci) { | 
 | 1163 | 		bus_type = "ISA"; | 
 | 1164 | 		subversion = ISA; | 
 | 1165 | 	} else if (port_base > MAX_ISA_ADDR) { | 
 | 1166 | 		bus_type = "PCI"; | 
 | 1167 | 		is_pci = 1; | 
 | 1168 | 		subversion = ESA; | 
 | 1169 | 	} else { | 
 | 1170 | 		bus_type = "ISA"; | 
 | 1171 | 		subversion = ISA; | 
 | 1172 | 	} | 
 | 1173 |  | 
 | 1174 | 	if (!info.haaval || info.ata) { | 
 | 1175 | 		printk | 
 | 1176 | 		    ("%s: address 0x%03lx, unusable %s board (%d%d), detaching.\n", | 
 | 1177 | 		     name, port_base, bus_type, info.haaval, info.ata); | 
 | 1178 | 		goto freelock; | 
 | 1179 | 	} | 
 | 1180 |  | 
 | 1181 | 	if (info.drqvld) { | 
 | 1182 | 		if (subversion == ESA) | 
 | 1183 | 			printk("%s: warning, weird %s board using DMA.\n", name, | 
 | 1184 | 			       bus_type); | 
 | 1185 |  | 
 | 1186 | 		subversion = ISA; | 
 | 1187 | 		dma_channel = dma_channel_table[3 - info.drqx]; | 
 | 1188 | 	} else { | 
 | 1189 | 		if (subversion == ISA) | 
 | 1190 | 			printk("%s: warning, weird %s board not using DMA.\n", | 
 | 1191 | 			       name, bus_type); | 
 | 1192 |  | 
 | 1193 | 		subversion = ESA; | 
 | 1194 | 		dma_channel = NO_DMA; | 
 | 1195 | 	} | 
 | 1196 |  | 
 | 1197 | 	if (!info.dmasup) | 
 | 1198 | 		printk("%s: warning, DMA protocol support not asserted.\n", | 
 | 1199 | 		       name); | 
 | 1200 |  | 
 | 1201 | 	irq = info.irq; | 
 | 1202 |  | 
 | 1203 | 	if (subversion == ESA && !info.irq_tr) | 
 | 1204 | 		printk | 
 | 1205 | 		    ("%s: warning, LEVEL triggering is suggested for IRQ %u.\n", | 
 | 1206 | 		     name, irq); | 
 | 1207 |  | 
 | 1208 | 	if (is_pci) { | 
 | 1209 | 		pdev = get_pci_dev(port_base); | 
 | 1210 | 		if (!pdev) | 
 | 1211 | 			printk | 
 | 1212 | 			    ("%s: warning, failed to get pci_dev structure.\n", | 
 | 1213 | 			     name); | 
 | 1214 | 	} else | 
 | 1215 | 		pdev = NULL; | 
 | 1216 |  | 
 | 1217 | 	if (pdev && (irq != pdev->irq)) { | 
 | 1218 | 		printk("%s: IRQ %u mapped to IO-APIC IRQ %u.\n", name, irq, | 
 | 1219 | 		       pdev->irq); | 
 | 1220 | 		irq = pdev->irq; | 
 | 1221 | 	} | 
 | 1222 |  | 
 | 1223 | 	/* Board detected, allocate its IRQ */ | 
 | 1224 | 	if (request_irq(irq, do_interrupt_handler, | 
| Thomas Gleixner | 1d6f359 | 2006-07-01 19:29:42 -0700 | [diff] [blame] | 1225 | 			IRQF_DISABLED | ((subversion == ESA) ? IRQF_SHARED : 0), | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1226 | 			driver_name, (void *)&sha[j])) { | 
 | 1227 | 		printk("%s: unable to allocate IRQ %u, detaching.\n", name, | 
 | 1228 | 		       irq); | 
 | 1229 | 		goto freelock; | 
 | 1230 | 	} | 
 | 1231 |  | 
 | 1232 | 	if (subversion == ISA && request_dma(dma_channel, driver_name)) { | 
 | 1233 | 		printk("%s: unable to allocate DMA channel %u, detaching.\n", | 
 | 1234 | 		       name, dma_channel); | 
 | 1235 | 		goto freeirq; | 
 | 1236 | 	} | 
 | 1237 | #if defined(FORCE_CONFIG) | 
 | 1238 | 	{ | 
 | 1239 | 		struct eata_config *cf; | 
 | 1240 | 		dma_addr_t cf_dma_addr; | 
 | 1241 |  | 
 | 1242 | 		cf = pci_alloc_consistent(pdev, sizeof(struct eata_config), | 
 | 1243 | 					  &cf_dma_addr); | 
 | 1244 |  | 
 | 1245 | 		if (!cf) { | 
 | 1246 | 			printk | 
 | 1247 | 			    ("%s: config, pci_alloc_consistent failed, detaching.\n", | 
 | 1248 | 			     name); | 
 | 1249 | 			goto freedma; | 
 | 1250 | 		} | 
 | 1251 |  | 
 | 1252 | 		/* Set board configuration */ | 
 | 1253 | 		memset((char *)cf, 0, sizeof(struct eata_config)); | 
 | 1254 | 		cf->len = (ushort) H2DEV16((ushort) 510); | 
 | 1255 | 		cf->ocena = 1; | 
 | 1256 |  | 
 | 1257 | 		if (do_dma(port_base, cf_dma_addr, SET_CONFIG_DMA)) { | 
 | 1258 | 			printk | 
 | 1259 | 			    ("%s: busy timeout sending configuration, detaching.\n", | 
 | 1260 | 			     name); | 
 | 1261 | 			pci_free_consistent(pdev, sizeof(struct eata_config), | 
 | 1262 | 					    cf, cf_dma_addr); | 
 | 1263 | 			goto freedma; | 
 | 1264 | 		} | 
 | 1265 |  | 
 | 1266 | 	} | 
 | 1267 | #endif | 
 | 1268 |  | 
 | 1269 | 	spin_unlock_irq(&driver_lock); | 
 | 1270 | 	sh[j] = shost = scsi_register(tpnt, sizeof(struct hostdata)); | 
 | 1271 | 	spin_lock_irq(&driver_lock); | 
 | 1272 |  | 
 | 1273 | 	if (shost == NULL) { | 
 | 1274 | 		printk("%s: unable to register host, detaching.\n", name); | 
 | 1275 | 		goto freedma; | 
 | 1276 | 	} | 
 | 1277 |  | 
 | 1278 | 	shost->io_port = port_base; | 
 | 1279 | 	shost->unique_id = port_base; | 
 | 1280 | 	shost->n_io_port = REGION_SIZE; | 
 | 1281 | 	shost->dma_channel = dma_channel; | 
 | 1282 | 	shost->irq = irq; | 
 | 1283 | 	shost->sg_tablesize = (ushort) info.scatt_size; | 
 | 1284 | 	shost->this_id = (ushort) info.host_addr[3]; | 
 | 1285 | 	shost->can_queue = (ushort) info.queue_size; | 
 | 1286 | 	shost->cmd_per_lun = MAX_CMD_PER_LUN; | 
 | 1287 |  | 
 | 1288 | 	ha = (struct hostdata *)shost->hostdata; | 
 | 1289 | 	 | 
 | 1290 | 	memset(ha, 0, sizeof(struct hostdata)); | 
 | 1291 | 	ha->subversion = subversion; | 
 | 1292 | 	ha->protocol_rev = protocol_rev; | 
 | 1293 | 	ha->is_pci = is_pci; | 
 | 1294 | 	ha->pdev = pdev; | 
 | 1295 | 	ha->board_number = j; | 
 | 1296 |  | 
 | 1297 | 	if (ha->subversion == ESA) | 
 | 1298 | 		shost->unchecked_isa_dma = 0; | 
 | 1299 | 	else { | 
 | 1300 | 		unsigned long flags; | 
 | 1301 | 		shost->unchecked_isa_dma = 1; | 
 | 1302 |  | 
 | 1303 | 		flags = claim_dma_lock(); | 
 | 1304 | 		disable_dma(dma_channel); | 
 | 1305 | 		clear_dma_ff(dma_channel); | 
 | 1306 | 		set_dma_mode(dma_channel, DMA_MODE_CASCADE); | 
 | 1307 | 		enable_dma(dma_channel); | 
 | 1308 | 		release_dma_lock(flags); | 
 | 1309 |  | 
 | 1310 | 	} | 
 | 1311 |  | 
 | 1312 | 	strcpy(ha->board_name, name); | 
 | 1313 |  | 
 | 1314 | 	/* DPT PM2012 does not allow to detect sg_tablesize correctly */ | 
 | 1315 | 	if (shost->sg_tablesize > MAX_SGLIST || shost->sg_tablesize < 2) { | 
 | 1316 | 		printk("%s: detect, wrong n. of SG lists %d, fixed.\n", | 
 | 1317 | 		       ha->board_name, shost->sg_tablesize); | 
 | 1318 | 		shost->sg_tablesize = MAX_SGLIST; | 
 | 1319 | 	} | 
 | 1320 |  | 
 | 1321 | 	/* DPT PM2012 does not allow to detect can_queue correctly */ | 
 | 1322 | 	if (shost->can_queue > MAX_MAILBOXES || shost->can_queue < 2) { | 
 | 1323 | 		printk("%s: detect, wrong n. of mbox %d, fixed.\n", | 
 | 1324 | 		       ha->board_name, shost->can_queue); | 
 | 1325 | 		shost->can_queue = MAX_MAILBOXES; | 
 | 1326 | 	} | 
 | 1327 |  | 
 | 1328 | 	if (protocol_rev != 'A') { | 
 | 1329 | 		if (info.max_chan > 0 && info.max_chan < MAX_CHANNEL) | 
 | 1330 | 			shost->max_channel = info.max_chan; | 
 | 1331 |  | 
 | 1332 | 		if (info.max_id > 7 && info.max_id < MAX_TARGET) | 
 | 1333 | 			shost->max_id = info.max_id + 1; | 
 | 1334 |  | 
 | 1335 | 		if (info.large_sg && shost->sg_tablesize == MAX_SGLIST) | 
 | 1336 | 			shost->sg_tablesize = MAX_LARGE_SGLIST; | 
 | 1337 | 	} | 
 | 1338 |  | 
 | 1339 | 	if (protocol_rev == 'C') { | 
 | 1340 | 		if (info.max_lun > 7 && info.max_lun < MAX_LUN) | 
 | 1341 | 			shost->max_lun = info.max_lun + 1; | 
 | 1342 | 	} | 
 | 1343 |  | 
 | 1344 | 	if (dma_channel == NO_DMA) | 
 | 1345 | 		sprintf(dma_name, "%s", "BMST"); | 
 | 1346 | 	else | 
 | 1347 | 		sprintf(dma_name, "DMA %u", dma_channel); | 
 | 1348 |  | 
 | 1349 | 	spin_unlock_irq(&driver_lock); | 
 | 1350 |  | 
 | 1351 | 	for (i = 0; i < shost->can_queue; i++) | 
 | 1352 | 		ha->cp[i].cp_dma_addr = pci_map_single(ha->pdev, | 
 | 1353 | 							  &ha->cp[i], | 
 | 1354 | 							  sizeof(struct mscp), | 
 | 1355 | 							  PCI_DMA_BIDIRECTIONAL); | 
 | 1356 |  | 
 | 1357 | 	for (i = 0; i < shost->can_queue; i++) { | 
 | 1358 | 		size_t sz = shost->sg_tablesize *sizeof(struct sg_list); | 
| Al Viro | c53033f | 2005-10-21 03:22:08 -0400 | [diff] [blame] | 1359 | 		gfp_t gfp_mask = (shost->unchecked_isa_dma ? GFP_DMA : 0) | GFP_ATOMIC; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1360 | 		ha->cp[i].sglist = kmalloc(sz, gfp_mask); | 
 | 1361 | 		if (!ha->cp[i].sglist) { | 
 | 1362 | 			printk | 
 | 1363 | 			    ("%s: kmalloc SGlist failed, mbox %d, detaching.\n", | 
 | 1364 | 			     ha->board_name, i); | 
 | 1365 | 			goto release; | 
 | 1366 | 		} | 
 | 1367 | 	} | 
 | 1368 |  | 
 | 1369 | 	if (!(ha->sp_cpu_addr = pci_alloc_consistent(ha->pdev, | 
 | 1370 | 							sizeof(struct mssp), | 
 | 1371 | 							&ha->sp_dma_addr))) { | 
 | 1372 | 		printk("%s: pci_alloc_consistent failed, detaching.\n", ha->board_name); | 
 | 1373 | 		goto release; | 
 | 1374 | 	} | 
 | 1375 |  | 
 | 1376 | 	if (max_queue_depth > MAX_TAGGED_CMD_PER_LUN) | 
 | 1377 | 		max_queue_depth = MAX_TAGGED_CMD_PER_LUN; | 
 | 1378 |  | 
 | 1379 | 	if (max_queue_depth < MAX_CMD_PER_LUN) | 
 | 1380 | 		max_queue_depth = MAX_CMD_PER_LUN; | 
 | 1381 |  | 
 | 1382 | 	if (tag_mode != TAG_DISABLED && tag_mode != TAG_SIMPLE) | 
 | 1383 | 		tag_mode = TAG_ORDERED; | 
 | 1384 |  | 
 | 1385 | 	if (j == 0) { | 
 | 1386 | 		printk | 
 | 1387 | 		    ("EATA/DMA 2.0x: Copyright (C) 1994-2003 Dario Ballabio.\n"); | 
 | 1388 | 		printk | 
 | 1389 | 		    ("%s config options -> tm:%d, lc:%c, mq:%d, rs:%c, et:%c, " | 
 | 1390 | 		     "ip:%c, ep:%c, pp:%c.\n", driver_name, tag_mode, | 
 | 1391 | 		     YESNO(linked_comm), max_queue_depth, YESNO(rev_scan), | 
 | 1392 | 		     YESNO(ext_tran), YESNO(isa_probe), YESNO(eisa_probe), | 
 | 1393 | 		     YESNO(pci_probe)); | 
 | 1394 | 	} | 
 | 1395 |  | 
 | 1396 | 	printk("%s: 2.0%c, %s 0x%03lx, IRQ %u, %s, SG %d, MB %d.\n", | 
 | 1397 | 	       ha->board_name, ha->protocol_rev, bus_type, | 
 | 1398 | 	       (unsigned long)shost->io_port, shost->irq, dma_name, | 
 | 1399 | 	       shost->sg_tablesize, shost->can_queue); | 
 | 1400 |  | 
 | 1401 | 	if (shost->max_id > 8 || shost->max_lun > 8) | 
 | 1402 | 		printk | 
 | 1403 | 		    ("%s: wide SCSI support enabled, max_id %u, max_lun %u.\n", | 
 | 1404 | 		     ha->board_name, shost->max_id, shost->max_lun); | 
 | 1405 |  | 
 | 1406 | 	for (i = 0; i <= shost->max_channel; i++) | 
 | 1407 | 		printk("%s: SCSI channel %u enabled, host target ID %d.\n", | 
 | 1408 | 		       ha->board_name, i, info.host_addr[3 - i]); | 
 | 1409 |  | 
 | 1410 | #if defined(DEBUG_DETECT) | 
 | 1411 | 	printk("%s: Vers. 0x%x, ocs %u, tar %u, trnxfr %u, more %u, SYNC 0x%x, " | 
 | 1412 | 	       "sec. %u, infol %d, cpl %d spl %d.\n", name, info.version, | 
 | 1413 | 	       info.ocsena, info.tarsup, info.trnxfr, info.morsup, info.sync, | 
 | 1414 | 	       info.second, info.data_len, info.cp_len, info.sp_len); | 
 | 1415 |  | 
 | 1416 | 	if (protocol_rev == 'B' || protocol_rev == 'C') | 
 | 1417 | 		printk("%s: isaena %u, forcaddr %u, max_id %u, max_chan %u, " | 
 | 1418 | 		       "large_sg %u, res1 %u.\n", name, info.isaena, | 
 | 1419 | 		       info.forcaddr, info.max_id, info.max_chan, info.large_sg, | 
 | 1420 | 		       info.res1); | 
 | 1421 |  | 
 | 1422 | 	if (protocol_rev == 'C') | 
 | 1423 | 		printk("%s: max_lun %u, m1 %u, idquest %u, pci %u, eisa %u, " | 
 | 1424 | 		       "raidnum %u.\n", name, info.max_lun, info.m1, | 
 | 1425 | 		       info.idquest, info.pci, info.eisa, info.raidnum); | 
 | 1426 | #endif | 
 | 1427 |  | 
 | 1428 | 	if (ha->pdev) { | 
 | 1429 | 		pci_set_master(ha->pdev); | 
| Yang Hongyang | 284901a | 2009-04-06 19:01:15 -0700 | [diff] [blame] | 1430 | 		if (pci_set_dma_mask(ha->pdev, DMA_BIT_MASK(32))) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1431 | 			printk("%s: warning, pci_set_dma_mask failed.\n", | 
 | 1432 | 			       ha->board_name); | 
 | 1433 | 	} | 
 | 1434 |  | 
 | 1435 | 	return 1; | 
 | 1436 |  | 
 | 1437 |       freedma: | 
 | 1438 | 	if (subversion == ISA) | 
 | 1439 | 		free_dma(dma_channel); | 
 | 1440 |       freeirq: | 
 | 1441 | 	free_irq(irq, &sha[j]); | 
 | 1442 |       freelock: | 
 | 1443 | 	spin_unlock_irq(&driver_lock); | 
 | 1444 | 	release_region(port_base, REGION_SIZE); | 
 | 1445 |       fail: | 
 | 1446 | 	return 0; | 
 | 1447 |  | 
 | 1448 |       release: | 
 | 1449 | 	eata2x_release(shost); | 
 | 1450 | 	return 0; | 
 | 1451 | } | 
 | 1452 |  | 
 | 1453 | static void internal_setup(char *str, int *ints) | 
 | 1454 | { | 
 | 1455 | 	int i, argc = ints[0]; | 
 | 1456 | 	char *cur = str, *pc; | 
 | 1457 |  | 
 | 1458 | 	if (argc > 0) { | 
 | 1459 | 		if (argc > MAX_INT_PARAM) | 
 | 1460 | 			argc = MAX_INT_PARAM; | 
 | 1461 |  | 
 | 1462 | 		for (i = 0; i < argc; i++) | 
 | 1463 | 			io_port[i] = ints[i + 1]; | 
 | 1464 |  | 
 | 1465 | 		io_port[i] = 0; | 
 | 1466 | 		setup_done = 1; | 
 | 1467 | 	} | 
 | 1468 |  | 
 | 1469 | 	while (cur && (pc = strchr(cur, ':'))) { | 
 | 1470 | 		int val = 0, c = *++pc; | 
 | 1471 |  | 
 | 1472 | 		if (c == 'n' || c == 'N') | 
 | 1473 | 			val = 0; | 
 | 1474 | 		else if (c == 'y' || c == 'Y') | 
 | 1475 | 			val = 1; | 
 | 1476 | 		else | 
 | 1477 | 			val = (int)simple_strtoul(pc, NULL, 0); | 
 | 1478 |  | 
 | 1479 | 		if (!strncmp(cur, "lc:", 3)) | 
 | 1480 | 			linked_comm = val; | 
 | 1481 | 		else if (!strncmp(cur, "tm:", 3)) | 
 | 1482 | 			tag_mode = val; | 
 | 1483 | 		else if (!strncmp(cur, "tc:", 3)) | 
 | 1484 | 			tag_mode = val; | 
 | 1485 | 		else if (!strncmp(cur, "mq:", 3)) | 
 | 1486 | 			max_queue_depth = val; | 
 | 1487 | 		else if (!strncmp(cur, "ls:", 3)) | 
 | 1488 | 			link_statistics = val; | 
 | 1489 | 		else if (!strncmp(cur, "et:", 3)) | 
 | 1490 | 			ext_tran = val; | 
 | 1491 | 		else if (!strncmp(cur, "rs:", 3)) | 
 | 1492 | 			rev_scan = val; | 
 | 1493 | 		else if (!strncmp(cur, "ip:", 3)) | 
 | 1494 | 			isa_probe = val; | 
 | 1495 | 		else if (!strncmp(cur, "ep:", 3)) | 
 | 1496 | 			eisa_probe = val; | 
 | 1497 | 		else if (!strncmp(cur, "pp:", 3)) | 
 | 1498 | 			pci_probe = val; | 
 | 1499 |  | 
 | 1500 | 		if ((cur = strchr(cur, ','))) | 
 | 1501 | 			++cur; | 
 | 1502 | 	} | 
 | 1503 |  | 
 | 1504 | 	return; | 
 | 1505 | } | 
 | 1506 |  | 
 | 1507 | static int option_setup(char *str) | 
 | 1508 | { | 
 | 1509 | 	int ints[MAX_INT_PARAM]; | 
 | 1510 | 	char *cur = str; | 
 | 1511 | 	int i = 1; | 
 | 1512 |  | 
| Roel Kluin | 8fe7916 | 2009-12-08 14:08:57 -0800 | [diff] [blame] | 1513 | 	while (cur && isdigit(*cur) && i < MAX_INT_PARAM) { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1514 | 		ints[i++] = simple_strtoul(cur, NULL, 0); | 
 | 1515 |  | 
 | 1516 | 		if ((cur = strchr(cur, ',')) != NULL) | 
 | 1517 | 			cur++; | 
 | 1518 | 	} | 
 | 1519 |  | 
 | 1520 | 	ints[0] = i - 1; | 
 | 1521 | 	internal_setup(cur, ints); | 
 | 1522 | 	return 1; | 
 | 1523 | } | 
 | 1524 |  | 
 | 1525 | static void add_pci_ports(void) | 
 | 1526 | { | 
 | 1527 | #if defined(CONFIG_PCI) | 
 | 1528 | 	unsigned int addr, k; | 
 | 1529 | 	struct pci_dev *dev = NULL; | 
 | 1530 |  | 
 | 1531 | 	for (k = 0; k < MAX_PCI; k++) { | 
 | 1532 |  | 
 | 1533 | 		if (!(dev = pci_get_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) | 
 | 1534 | 			break; | 
 | 1535 |  | 
 | 1536 | 		if (pci_enable_device(dev)) { | 
 | 1537 | #if defined(DEBUG_PCI_DETECT) | 
 | 1538 | 			printk | 
 | 1539 | 			    ("%s: detect, bus %d, devfn 0x%x, pci_enable_device failed.\n", | 
 | 1540 | 			     driver_name, dev->bus->number, dev->devfn); | 
 | 1541 | #endif | 
 | 1542 |  | 
 | 1543 | 			continue; | 
 | 1544 | 		} | 
 | 1545 |  | 
 | 1546 | 		addr = pci_resource_start(dev, 0); | 
 | 1547 |  | 
 | 1548 | #if defined(DEBUG_PCI_DETECT) | 
 | 1549 | 		printk("%s: detect, seq. %d, bus %d, devfn 0x%x, addr 0x%x.\n", | 
 | 1550 | 		       driver_name, k, dev->bus->number, dev->devfn, addr); | 
 | 1551 | #endif | 
 | 1552 |  | 
 | 1553 | 		/* Order addresses according to rev_scan value */ | 
 | 1554 | 		io_port[MAX_INT_PARAM + (rev_scan ? (MAX_PCI - k) : (1 + k))] = | 
 | 1555 | 		    addr + PCI_BASE_ADDRESS_0; | 
 | 1556 | 	} | 
 | 1557 |  | 
 | 1558 | 	pci_dev_put(dev); | 
 | 1559 | #endif				/* end CONFIG_PCI */ | 
 | 1560 | } | 
 | 1561 |  | 
 | 1562 | static int eata2x_detect(struct scsi_host_template *tpnt) | 
 | 1563 | { | 
 | 1564 | 	unsigned int j = 0, k; | 
 | 1565 |  | 
 | 1566 | 	tpnt->proc_name = "eata2x"; | 
 | 1567 |  | 
 | 1568 | 	if (strlen(boot_options)) | 
 | 1569 | 		option_setup(boot_options); | 
 | 1570 |  | 
 | 1571 | #if defined(MODULE) | 
 | 1572 | 	/* io_port could have been modified when loading as a module */ | 
 | 1573 | 	if (io_port[0] != SKIP) { | 
 | 1574 | 		setup_done = 1; | 
 | 1575 | 		io_port[MAX_INT_PARAM] = 0; | 
 | 1576 | 	} | 
 | 1577 | #endif | 
 | 1578 |  | 
 | 1579 | 	for (k = MAX_INT_PARAM; io_port[k]; k++) | 
 | 1580 | 		if (io_port[k] == SKIP) | 
 | 1581 | 			continue; | 
 | 1582 | 		else if (io_port[k] <= MAX_ISA_ADDR) { | 
 | 1583 | 			if (!isa_probe) | 
 | 1584 | 				io_port[k] = SKIP; | 
 | 1585 | 		} else if (io_port[k] >= MIN_EISA_ADDR | 
 | 1586 | 			   && io_port[k] <= MAX_EISA_ADDR) { | 
 | 1587 | 			if (!eisa_probe) | 
 | 1588 | 				io_port[k] = SKIP; | 
 | 1589 | 		} | 
 | 1590 |  | 
 | 1591 | 	if (pci_probe) { | 
 | 1592 | 		if (!setup_done) | 
 | 1593 | 			add_pci_ports(); | 
 | 1594 | 		else | 
 | 1595 | 			enable_pci_ports(); | 
 | 1596 | 	} | 
 | 1597 |  | 
 | 1598 | 	for (k = 0; io_port[k]; k++) { | 
 | 1599 |  | 
 | 1600 | 		if (io_port[k] == SKIP) | 
 | 1601 | 			continue; | 
 | 1602 |  | 
 | 1603 | 		if (j < MAX_BOARDS && port_detect(io_port[k], j, tpnt)) | 
 | 1604 | 			j++; | 
 | 1605 | 	} | 
 | 1606 |  | 
 | 1607 | 	num_boards = j; | 
 | 1608 | 	return j; | 
 | 1609 | } | 
 | 1610 |  | 
 | 1611 | static void map_dma(unsigned int i, struct hostdata *ha) | 
 | 1612 | { | 
| FUJITA Tomonori | 58e2a02 | 2007-05-14 20:21:16 +0900 | [diff] [blame] | 1613 | 	unsigned int k, pci_dir; | 
 | 1614 | 	int count; | 
 | 1615 | 	struct scatterlist *sg; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1616 | 	struct mscp *cpp; | 
 | 1617 | 	struct scsi_cmnd *SCpnt; | 
 | 1618 |  | 
 | 1619 | 	cpp = &ha->cp[i]; | 
 | 1620 | 	SCpnt = cpp->SCpnt; | 
 | 1621 | 	pci_dir = SCpnt->sc_data_direction; | 
 | 1622 |  | 
 | 1623 | 	if (SCpnt->sense_buffer) | 
 | 1624 | 		cpp->sense_addr = | 
 | 1625 | 		    H2DEV(pci_map_single(ha->pdev, SCpnt->sense_buffer, | 
| FUJITA Tomonori | b80ca4f | 2008-01-13 15:46:13 +0900 | [diff] [blame] | 1626 | 			   SCSI_SENSE_BUFFERSIZE, PCI_DMA_FROMDEVICE)); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1627 |  | 
| FUJITA Tomonori | b80ca4f | 2008-01-13 15:46:13 +0900 | [diff] [blame] | 1628 | 	cpp->sense_len = SCSI_SENSE_BUFFERSIZE; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1629 |  | 
| FUJITA Tomonori | 20c09df | 2008-12-23 04:01:35 +0900 | [diff] [blame] | 1630 | 	if (!scsi_sg_count(SCpnt)) { | 
 | 1631 | 		cpp->data_len = 0; | 
 | 1632 | 		return; | 
 | 1633 | 	} | 
 | 1634 |  | 
 | 1635 | 	count = pci_map_sg(ha->pdev, scsi_sglist(SCpnt), scsi_sg_count(SCpnt), | 
 | 1636 | 			   pci_dir); | 
 | 1637 | 	BUG_ON(!count); | 
 | 1638 |  | 
| FUJITA Tomonori | 58e2a02 | 2007-05-14 20:21:16 +0900 | [diff] [blame] | 1639 | 	scsi_for_each_sg(SCpnt, sg, count, k) { | 
 | 1640 | 		cpp->sglist[k].address = H2DEV(sg_dma_address(sg)); | 
 | 1641 | 		cpp->sglist[k].num_bytes = H2DEV(sg_dma_len(sg)); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1642 | 	} | 
 | 1643 |  | 
 | 1644 | 	cpp->sg = 1; | 
 | 1645 | 	cpp->data_address = H2DEV(pci_map_single(ha->pdev, cpp->sglist, | 
| FUJITA Tomonori | 58e2a02 | 2007-05-14 20:21:16 +0900 | [diff] [blame] | 1646 | 						 scsi_sg_count(SCpnt) * | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1647 | 						 sizeof(struct sg_list), | 
 | 1648 | 						 pci_dir)); | 
| FUJITA Tomonori | 58e2a02 | 2007-05-14 20:21:16 +0900 | [diff] [blame] | 1649 | 	cpp->data_len = H2DEV((scsi_sg_count(SCpnt) * sizeof(struct sg_list))); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1650 | } | 
 | 1651 |  | 
 | 1652 | static void unmap_dma(unsigned int i, struct hostdata *ha) | 
 | 1653 | { | 
 | 1654 | 	unsigned int pci_dir; | 
 | 1655 | 	struct mscp *cpp; | 
 | 1656 | 	struct scsi_cmnd *SCpnt; | 
 | 1657 |  | 
 | 1658 | 	cpp = &ha->cp[i]; | 
 | 1659 | 	SCpnt = cpp->SCpnt; | 
 | 1660 | 	pci_dir = SCpnt->sc_data_direction; | 
 | 1661 |  | 
 | 1662 | 	if (DEV2H(cpp->sense_addr)) | 
 | 1663 | 		pci_unmap_single(ha->pdev, DEV2H(cpp->sense_addr), | 
 | 1664 | 				 DEV2H(cpp->sense_len), PCI_DMA_FROMDEVICE); | 
 | 1665 |  | 
| FUJITA Tomonori | 20c09df | 2008-12-23 04:01:35 +0900 | [diff] [blame] | 1666 | 	if (scsi_sg_count(SCpnt)) | 
 | 1667 | 		pci_unmap_sg(ha->pdev, scsi_sglist(SCpnt), scsi_sg_count(SCpnt), | 
 | 1668 | 			     pci_dir); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1669 |  | 
 | 1670 | 	if (!DEV2H(cpp->data_len)) | 
 | 1671 | 		pci_dir = PCI_DMA_BIDIRECTIONAL; | 
 | 1672 |  | 
 | 1673 | 	if (DEV2H(cpp->data_address)) | 
 | 1674 | 		pci_unmap_single(ha->pdev, DEV2H(cpp->data_address), | 
 | 1675 | 				 DEV2H(cpp->data_len), pci_dir); | 
 | 1676 | } | 
 | 1677 |  | 
 | 1678 | static void sync_dma(unsigned int i, struct hostdata *ha) | 
 | 1679 | { | 
 | 1680 | 	unsigned int pci_dir; | 
 | 1681 | 	struct mscp *cpp; | 
 | 1682 | 	struct scsi_cmnd *SCpnt; | 
 | 1683 |  | 
 | 1684 | 	cpp = &ha->cp[i]; | 
 | 1685 | 	SCpnt = cpp->SCpnt; | 
 | 1686 | 	pci_dir = SCpnt->sc_data_direction; | 
 | 1687 |  | 
 | 1688 | 	if (DEV2H(cpp->sense_addr)) | 
 | 1689 | 		pci_dma_sync_single_for_cpu(ha->pdev, DEV2H(cpp->sense_addr), | 
 | 1690 | 					    DEV2H(cpp->sense_len), | 
 | 1691 | 					    PCI_DMA_FROMDEVICE); | 
 | 1692 |  | 
| FUJITA Tomonori | 58e2a02 | 2007-05-14 20:21:16 +0900 | [diff] [blame] | 1693 | 	if (scsi_sg_count(SCpnt)) | 
 | 1694 | 		pci_dma_sync_sg_for_cpu(ha->pdev, scsi_sglist(SCpnt), | 
 | 1695 | 					scsi_sg_count(SCpnt), pci_dir); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1696 |  | 
 | 1697 | 	if (!DEV2H(cpp->data_len)) | 
 | 1698 | 		pci_dir = PCI_DMA_BIDIRECTIONAL; | 
 | 1699 |  | 
 | 1700 | 	if (DEV2H(cpp->data_address)) | 
 | 1701 | 		pci_dma_sync_single_for_cpu(ha->pdev, | 
 | 1702 | 					    DEV2H(cpp->data_address), | 
 | 1703 | 					    DEV2H(cpp->data_len), pci_dir); | 
 | 1704 | } | 
 | 1705 |  | 
 | 1706 | static void scsi_to_dev_dir(unsigned int i, struct hostdata *ha) | 
 | 1707 | { | 
 | 1708 | 	unsigned int k; | 
 | 1709 |  | 
 | 1710 | 	static const unsigned char data_out_cmds[] = { | 
 | 1711 | 		0x0a, 0x2a, 0x15, 0x55, 0x04, 0x07, 0x18, 0x1d, 0x24, 0x2e, | 
 | 1712 | 		0x30, 0x31, 0x32, 0x38, 0x39, 0x3a, 0x3b, 0x3d, 0x3f, 0x40, | 
 | 1713 | 		0x41, 0x4c, 0xaa, 0xae, 0xb0, 0xb1, 0xb2, 0xb6, 0xea, 0x1b, 0x5d | 
 | 1714 | 	}; | 
 | 1715 |  | 
 | 1716 | 	static const unsigned char data_none_cmds[] = { | 
 | 1717 | 		0x01, 0x0b, 0x10, 0x11, 0x13, 0x16, 0x17, 0x19, 0x2b, 0x1e, | 
 | 1718 | 		0x2c, 0xac, 0x2f, 0xaf, 0x33, 0xb3, 0x35, 0x36, 0x45, 0x47, | 
 | 1719 | 		0x48, 0x49, 0xa9, 0x4b, 0xa5, 0xa6, 0xb5, 0x00 | 
 | 1720 | 	}; | 
 | 1721 |  | 
 | 1722 | 	struct mscp *cpp; | 
 | 1723 | 	struct scsi_cmnd *SCpnt; | 
 | 1724 |  | 
 | 1725 | 	cpp = &ha->cp[i]; | 
 | 1726 | 	SCpnt = cpp->SCpnt; | 
 | 1727 |  | 
 | 1728 | 	if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) { | 
 | 1729 | 		cpp->din = 1; | 
 | 1730 | 		cpp->dout = 0; | 
 | 1731 | 		return; | 
 | 1732 | 	} else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) { | 
 | 1733 | 		cpp->din = 0; | 
 | 1734 | 		cpp->dout = 1; | 
 | 1735 | 		return; | 
 | 1736 | 	} else if (SCpnt->sc_data_direction == DMA_NONE) { | 
 | 1737 | 		cpp->din = 0; | 
 | 1738 | 		cpp->dout = 0; | 
 | 1739 | 		return; | 
 | 1740 | 	} | 
 | 1741 |  | 
 | 1742 | 	if (SCpnt->sc_data_direction != DMA_BIDIRECTIONAL) | 
 | 1743 | 		panic("%s: qcomm, invalid SCpnt->sc_data_direction.\n", | 
 | 1744 | 				ha->board_name); | 
 | 1745 |  | 
 | 1746 | 	for (k = 0; k < ARRAY_SIZE(data_out_cmds); k++) | 
 | 1747 | 		if (SCpnt->cmnd[0] == data_out_cmds[k]) { | 
 | 1748 | 			cpp->dout = 1; | 
 | 1749 | 			break; | 
 | 1750 | 		} | 
 | 1751 |  | 
 | 1752 | 	if ((cpp->din = !cpp->dout)) | 
 | 1753 | 		for (k = 0; k < ARRAY_SIZE(data_none_cmds); k++) | 
 | 1754 | 			if (SCpnt->cmnd[0] == data_none_cmds[k]) { | 
 | 1755 | 				cpp->din = 0; | 
 | 1756 | 				break; | 
 | 1757 | 			} | 
 | 1758 |  | 
 | 1759 | } | 
 | 1760 |  | 
 | 1761 | static int eata2x_queuecommand(struct scsi_cmnd *SCpnt, | 
 | 1762 | 			       void (*done) (struct scsi_cmnd *)) | 
 | 1763 | { | 
 | 1764 | 	struct Scsi_Host *shost = SCpnt->device->host; | 
 | 1765 | 	struct hostdata *ha = (struct hostdata *)shost->hostdata; | 
 | 1766 | 	unsigned int i, k; | 
 | 1767 | 	struct mscp *cpp; | 
 | 1768 |  | 
 | 1769 | 	if (SCpnt->host_scribble) | 
 | 1770 | 		panic("%s: qcomm, pid %ld, SCpnt %p already active.\n", | 
| Matthew Wilcox | 12a4416 | 2007-09-18 19:54:43 -0600 | [diff] [blame] | 1771 | 		      ha->board_name, SCpnt->serial_number, SCpnt); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1772 |  | 
 | 1773 | 	/* i is the mailbox number, look for the first free mailbox | 
 | 1774 | 	   starting from last_cp_used */ | 
 | 1775 | 	i = ha->last_cp_used + 1; | 
 | 1776 |  | 
 | 1777 | 	for (k = 0; k < shost->can_queue; k++, i++) { | 
 | 1778 | 		if (i >= shost->can_queue) | 
 | 1779 | 			i = 0; | 
 | 1780 | 		if (ha->cp_stat[i] == FREE) { | 
 | 1781 | 			ha->last_cp_used = i; | 
 | 1782 | 			break; | 
 | 1783 | 		} | 
 | 1784 | 	} | 
 | 1785 |  | 
 | 1786 | 	if (k == shost->can_queue) { | 
 | 1787 | 		printk("%s: qcomm, no free mailbox.\n", ha->board_name); | 
 | 1788 | 		return 1; | 
 | 1789 | 	} | 
 | 1790 |  | 
 | 1791 | 	/* Set pointer to control packet structure */ | 
 | 1792 | 	cpp = &ha->cp[i]; | 
 | 1793 |  | 
 | 1794 | 	memset(cpp, 0, sizeof(struct mscp) - CP_TAIL_SIZE); | 
 | 1795 |  | 
 | 1796 | 	/* Set pointer to status packet structure, Big Endian format */ | 
 | 1797 | 	cpp->sp_dma_addr = H2DEV(ha->sp_dma_addr); | 
 | 1798 |  | 
 | 1799 | 	SCpnt->scsi_done = done; | 
 | 1800 | 	cpp->cpp_index = i; | 
 | 1801 | 	SCpnt->host_scribble = (unsigned char *)&cpp->cpp_index; | 
 | 1802 |  | 
 | 1803 | 	if (do_trace) | 
| Jeff Garzik | 017560f | 2005-10-24 18:04:36 -0400 | [diff] [blame] | 1804 | 		scmd_printk(KERN_INFO, SCpnt, | 
| Matthew Wilcox | 12a4416 | 2007-09-18 19:54:43 -0600 | [diff] [blame] | 1805 | 			"qcomm, mbox %d, pid %ld.\n", i, SCpnt->serial_number); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1806 |  | 
 | 1807 | 	cpp->reqsen = 1; | 
 | 1808 | 	cpp->dispri = 1; | 
 | 1809 | #if 0 | 
 | 1810 | 	if (SCpnt->device->type == TYPE_TAPE) | 
 | 1811 | 		cpp->hbaci = 1; | 
 | 1812 | #endif | 
 | 1813 | 	cpp->one = 1; | 
 | 1814 | 	cpp->channel = SCpnt->device->channel; | 
 | 1815 | 	cpp->target = SCpnt->device->id; | 
 | 1816 | 	cpp->lun = SCpnt->device->lun; | 
 | 1817 | 	cpp->SCpnt = SCpnt; | 
 | 1818 | 	memcpy(cpp->cdb, SCpnt->cmnd, SCpnt->cmd_len); | 
 | 1819 |  | 
 | 1820 | 	/* Use data transfer direction SCpnt->sc_data_direction */ | 
 | 1821 | 	scsi_to_dev_dir(i, ha); | 
 | 1822 |  | 
 | 1823 | 	/* Map DMA buffers and SG list */ | 
 | 1824 | 	map_dma(i, ha); | 
 | 1825 |  | 
 | 1826 | 	if (linked_comm && SCpnt->device->queue_depth > 2 | 
 | 1827 | 	    && TLDEV(SCpnt->device->type)) { | 
 | 1828 | 		ha->cp_stat[i] = READY; | 
| Tejun Heo | 83096eb | 2009-05-07 22:24:39 +0900 | [diff] [blame] | 1829 | 		flush_dev(SCpnt->device, blk_rq_pos(SCpnt->request), ha, 0); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1830 | 		return 0; | 
 | 1831 | 	} | 
 | 1832 |  | 
 | 1833 | 	/* Send control packet to the board */ | 
 | 1834 | 	if (do_dma(shost->io_port, cpp->cp_dma_addr, SEND_CP_DMA)) { | 
 | 1835 | 		unmap_dma(i, ha); | 
 | 1836 | 		SCpnt->host_scribble = NULL; | 
| Jeff Garzik | 017560f | 2005-10-24 18:04:36 -0400 | [diff] [blame] | 1837 | 		scmd_printk(KERN_INFO, SCpnt, | 
| Matthew Wilcox | 12a4416 | 2007-09-18 19:54:43 -0600 | [diff] [blame] | 1838 | 			"qcomm, pid %ld, adapter busy.\n", SCpnt->serial_number); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1839 | 		return 1; | 
 | 1840 | 	} | 
 | 1841 |  | 
 | 1842 | 	ha->cp_stat[i] = IN_USE; | 
 | 1843 | 	return 0; | 
 | 1844 | } | 
 | 1845 |  | 
 | 1846 | static int eata2x_eh_abort(struct scsi_cmnd *SCarg) | 
 | 1847 | { | 
 | 1848 | 	struct Scsi_Host *shost = SCarg->device->host; | 
 | 1849 | 	struct hostdata *ha = (struct hostdata *)shost->hostdata; | 
 | 1850 | 	unsigned int i; | 
 | 1851 |  | 
 | 1852 | 	if (SCarg->host_scribble == NULL) { | 
| Jeff Garzik | 017560f | 2005-10-24 18:04:36 -0400 | [diff] [blame] | 1853 | 		scmd_printk(KERN_INFO, SCarg, | 
| Matthew Wilcox | 12a4416 | 2007-09-18 19:54:43 -0600 | [diff] [blame] | 1854 | 			"abort, pid %ld inactive.\n", SCarg->serial_number); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1855 | 		return SUCCESS; | 
 | 1856 | 	} | 
 | 1857 |  | 
 | 1858 | 	i = *(unsigned int *)SCarg->host_scribble; | 
| Jeff Garzik | 017560f | 2005-10-24 18:04:36 -0400 | [diff] [blame] | 1859 | 	scmd_printk(KERN_WARNING, SCarg, | 
| Matthew Wilcox | 12a4416 | 2007-09-18 19:54:43 -0600 | [diff] [blame] | 1860 | 		"abort, mbox %d, pid %ld.\n", i, SCarg->serial_number); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1861 |  | 
 | 1862 | 	if (i >= shost->can_queue) | 
 | 1863 | 		panic("%s: abort, invalid SCarg->host_scribble.\n", ha->board_name); | 
 | 1864 |  | 
 | 1865 | 	if (wait_on_busy(shost->io_port, MAXLOOP)) { | 
 | 1866 | 		printk("%s: abort, timeout error.\n", ha->board_name); | 
 | 1867 | 		return FAILED; | 
 | 1868 | 	} | 
 | 1869 |  | 
 | 1870 | 	if (ha->cp_stat[i] == FREE) { | 
 | 1871 | 		printk("%s: abort, mbox %d is free.\n", ha->board_name, i); | 
 | 1872 | 		return SUCCESS; | 
 | 1873 | 	} | 
 | 1874 |  | 
 | 1875 | 	if (ha->cp_stat[i] == IN_USE) { | 
 | 1876 | 		printk("%s: abort, mbox %d is in use.\n", ha->board_name, i); | 
 | 1877 |  | 
 | 1878 | 		if (SCarg != ha->cp[i].SCpnt) | 
 | 1879 | 			panic("%s: abort, mbox %d, SCarg %p, cp SCpnt %p.\n", | 
 | 1880 | 			      ha->board_name, i, SCarg, ha->cp[i].SCpnt); | 
 | 1881 |  | 
 | 1882 | 		if (inb(shost->io_port + REG_AUX_STATUS) & IRQ_ASSERTED) | 
 | 1883 | 			printk("%s: abort, mbox %d, interrupt pending.\n", | 
 | 1884 | 			       ha->board_name, i); | 
 | 1885 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1886 | 		return FAILED; | 
 | 1887 | 	} | 
 | 1888 |  | 
 | 1889 | 	if (ha->cp_stat[i] == IN_RESET) { | 
 | 1890 | 		printk("%s: abort, mbox %d is in reset.\n", ha->board_name, i); | 
 | 1891 | 		return FAILED; | 
 | 1892 | 	} | 
 | 1893 |  | 
 | 1894 | 	if (ha->cp_stat[i] == LOCKED) { | 
 | 1895 | 		printk("%s: abort, mbox %d is locked.\n", ha->board_name, i); | 
 | 1896 | 		return SUCCESS; | 
 | 1897 | 	} | 
 | 1898 |  | 
 | 1899 | 	if (ha->cp_stat[i] == READY || ha->cp_stat[i] == ABORTING) { | 
 | 1900 | 		unmap_dma(i, ha); | 
 | 1901 | 		SCarg->result = DID_ABORT << 16; | 
 | 1902 | 		SCarg->host_scribble = NULL; | 
 | 1903 | 		ha->cp_stat[i] = FREE; | 
 | 1904 | 		printk("%s, abort, mbox %d ready, DID_ABORT, pid %ld done.\n", | 
| Matthew Wilcox | 12a4416 | 2007-09-18 19:54:43 -0600 | [diff] [blame] | 1905 | 		       ha->board_name, i, SCarg->serial_number); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1906 | 		SCarg->scsi_done(SCarg); | 
 | 1907 | 		return SUCCESS; | 
 | 1908 | 	} | 
 | 1909 |  | 
 | 1910 | 	panic("%s: abort, mbox %d, invalid cp_stat.\n", ha->board_name, i); | 
 | 1911 | } | 
 | 1912 |  | 
 | 1913 | static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg) | 
 | 1914 | { | 
 | 1915 | 	unsigned int i, time, k, c, limit = 0; | 
 | 1916 | 	int arg_done = 0; | 
 | 1917 | 	struct scsi_cmnd *SCpnt; | 
 | 1918 | 	struct Scsi_Host *shost = SCarg->device->host; | 
 | 1919 | 	struct hostdata *ha = (struct hostdata *)shost->hostdata; | 
 | 1920 |  | 
| Jeff Garzik | 017560f | 2005-10-24 18:04:36 -0400 | [diff] [blame] | 1921 | 	scmd_printk(KERN_INFO, SCarg, | 
| Matthew Wilcox | 12a4416 | 2007-09-18 19:54:43 -0600 | [diff] [blame] | 1922 | 		"reset, enter, pid %ld.\n", SCarg->serial_number); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1923 |  | 
| Jeff Garzik  | df0ae24 | 2005-05-28 07:57:14 -0400 | [diff] [blame] | 1924 | 	spin_lock_irq(shost->host_lock); | 
 | 1925 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1926 | 	if (SCarg->host_scribble == NULL) | 
| Matthew Wilcox | 12a4416 | 2007-09-18 19:54:43 -0600 | [diff] [blame] | 1927 | 		printk("%s: reset, pid %ld inactive.\n", ha->board_name, SCarg->serial_number); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1928 |  | 
 | 1929 | 	if (ha->in_reset) { | 
 | 1930 | 		printk("%s: reset, exit, already in reset.\n", ha->board_name); | 
| Jeff Garzik  | df0ae24 | 2005-05-28 07:57:14 -0400 | [diff] [blame] | 1931 | 		spin_unlock_irq(shost->host_lock); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1932 | 		return FAILED; | 
 | 1933 | 	} | 
 | 1934 |  | 
 | 1935 | 	if (wait_on_busy(shost->io_port, MAXLOOP)) { | 
 | 1936 | 		printk("%s: reset, exit, timeout error.\n", ha->board_name); | 
| Jeff Garzik  | df0ae24 | 2005-05-28 07:57:14 -0400 | [diff] [blame] | 1937 | 		spin_unlock_irq(shost->host_lock); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1938 | 		return FAILED; | 
 | 1939 | 	} | 
 | 1940 |  | 
 | 1941 | 	ha->retries = 0; | 
 | 1942 |  | 
 | 1943 | 	for (c = 0; c <= shost->max_channel; c++) | 
 | 1944 | 		for (k = 0; k < shost->max_id; k++) { | 
 | 1945 | 			ha->target_redo[k][c] = 1; | 
 | 1946 | 			ha->target_to[k][c] = 0; | 
 | 1947 | 		} | 
 | 1948 |  | 
 | 1949 | 	for (i = 0; i < shost->can_queue; i++) { | 
 | 1950 |  | 
 | 1951 | 		if (ha->cp_stat[i] == FREE) | 
 | 1952 | 			continue; | 
 | 1953 |  | 
 | 1954 | 		if (ha->cp_stat[i] == LOCKED) { | 
 | 1955 | 			ha->cp_stat[i] = FREE; | 
 | 1956 | 			printk("%s: reset, locked mbox %d forced free.\n", | 
 | 1957 | 			       ha->board_name, i); | 
 | 1958 | 			continue; | 
 | 1959 | 		} | 
 | 1960 |  | 
 | 1961 | 		if (!(SCpnt = ha->cp[i].SCpnt)) | 
 | 1962 | 			panic("%s: reset, mbox %d, SCpnt == NULL.\n", ha->board_name, i); | 
 | 1963 |  | 
 | 1964 | 		if (ha->cp_stat[i] == READY || ha->cp_stat[i] == ABORTING) { | 
 | 1965 | 			ha->cp_stat[i] = ABORTING; | 
 | 1966 | 			printk("%s: reset, mbox %d aborting, pid %ld.\n", | 
| Matthew Wilcox | 12a4416 | 2007-09-18 19:54:43 -0600 | [diff] [blame] | 1967 | 			       ha->board_name, i, SCpnt->serial_number); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1968 | 		} | 
 | 1969 |  | 
 | 1970 | 		else { | 
 | 1971 | 			ha->cp_stat[i] = IN_RESET; | 
 | 1972 | 			printk("%s: reset, mbox %d in reset, pid %ld.\n", | 
| Matthew Wilcox | 12a4416 | 2007-09-18 19:54:43 -0600 | [diff] [blame] | 1973 | 			       ha->board_name, i, SCpnt->serial_number); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1974 | 		} | 
 | 1975 |  | 
 | 1976 | 		if (SCpnt->host_scribble == NULL) | 
 | 1977 | 			panic("%s: reset, mbox %d, garbled SCpnt.\n", ha->board_name, i); | 
 | 1978 |  | 
 | 1979 | 		if (*(unsigned int *)SCpnt->host_scribble != i) | 
 | 1980 | 			panic("%s: reset, mbox %d, index mismatch.\n", ha->board_name, i); | 
 | 1981 |  | 
 | 1982 | 		if (SCpnt->scsi_done == NULL) | 
 | 1983 | 			panic("%s: reset, mbox %d, SCpnt->scsi_done == NULL.\n", | 
 | 1984 | 			      ha->board_name, i); | 
 | 1985 |  | 
 | 1986 | 		if (SCpnt == SCarg) | 
 | 1987 | 			arg_done = 1; | 
 | 1988 | 	} | 
 | 1989 |  | 
 | 1990 | 	if (do_dma(shost->io_port, 0, RESET_PIO)) { | 
 | 1991 | 		printk("%s: reset, cannot reset, timeout error.\n", ha->board_name); | 
| Jeff Garzik  | df0ae24 | 2005-05-28 07:57:14 -0400 | [diff] [blame] | 1992 | 		spin_unlock_irq(shost->host_lock); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1993 | 		return FAILED; | 
 | 1994 | 	} | 
 | 1995 |  | 
 | 1996 | 	printk("%s: reset, board reset done, enabling interrupts.\n", ha->board_name); | 
 | 1997 |  | 
 | 1998 | #if defined(DEBUG_RESET) | 
 | 1999 | 	do_trace = 1; | 
 | 2000 | #endif | 
 | 2001 |  | 
 | 2002 | 	ha->in_reset = 1; | 
 | 2003 |  | 
 | 2004 | 	spin_unlock_irq(shost->host_lock); | 
| Jeff Garzik  | df0ae24 | 2005-05-28 07:57:14 -0400 | [diff] [blame] | 2005 |  | 
 | 2006 | 	/* FIXME: use a sleep instead */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 2007 | 	time = jiffies; | 
 | 2008 | 	while ((jiffies - time) < (10 * HZ) && limit++ < 200000) | 
 | 2009 | 		udelay(100L); | 
| Jeff Garzik  | df0ae24 | 2005-05-28 07:57:14 -0400 | [diff] [blame] | 2010 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 2011 | 	spin_lock_irq(shost->host_lock); | 
 | 2012 |  | 
 | 2013 | 	printk("%s: reset, interrupts disabled, loops %d.\n", ha->board_name, limit); | 
 | 2014 |  | 
 | 2015 | 	for (i = 0; i < shost->can_queue; i++) { | 
 | 2016 |  | 
 | 2017 | 		if (ha->cp_stat[i] == IN_RESET) { | 
 | 2018 | 			SCpnt = ha->cp[i].SCpnt; | 
 | 2019 | 			unmap_dma(i, ha); | 
 | 2020 | 			SCpnt->result = DID_RESET << 16; | 
 | 2021 | 			SCpnt->host_scribble = NULL; | 
 | 2022 |  | 
 | 2023 | 			/* This mailbox is still waiting for its interrupt */ | 
 | 2024 | 			ha->cp_stat[i] = LOCKED; | 
 | 2025 |  | 
 | 2026 | 			printk | 
 | 2027 | 			    ("%s, reset, mbox %d locked, DID_RESET, pid %ld done.\n", | 
| Matthew Wilcox | 12a4416 | 2007-09-18 19:54:43 -0600 | [diff] [blame] | 2028 | 			     ha->board_name, i, SCpnt->serial_number); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 2029 | 		} | 
 | 2030 |  | 
 | 2031 | 		else if (ha->cp_stat[i] == ABORTING) { | 
 | 2032 | 			SCpnt = ha->cp[i].SCpnt; | 
 | 2033 | 			unmap_dma(i, ha); | 
 | 2034 | 			SCpnt->result = DID_RESET << 16; | 
 | 2035 | 			SCpnt->host_scribble = NULL; | 
 | 2036 |  | 
 | 2037 | 			/* This mailbox was never queued to the adapter */ | 
 | 2038 | 			ha->cp_stat[i] = FREE; | 
 | 2039 |  | 
 | 2040 | 			printk | 
 | 2041 | 			    ("%s, reset, mbox %d aborting, DID_RESET, pid %ld done.\n", | 
| Matthew Wilcox | 12a4416 | 2007-09-18 19:54:43 -0600 | [diff] [blame] | 2042 | 			     ha->board_name, i, SCpnt->serial_number); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 2043 | 		} | 
 | 2044 |  | 
 | 2045 | 		else | 
 | 2046 | 			/* Any other mailbox has already been set free by interrupt */ | 
 | 2047 | 			continue; | 
 | 2048 |  | 
 | 2049 | 		SCpnt->scsi_done(SCpnt); | 
 | 2050 | 	} | 
 | 2051 |  | 
 | 2052 | 	ha->in_reset = 0; | 
 | 2053 | 	do_trace = 0; | 
 | 2054 |  | 
 | 2055 | 	if (arg_done) | 
| Matthew Wilcox | 12a4416 | 2007-09-18 19:54:43 -0600 | [diff] [blame] | 2056 | 		printk("%s: reset, exit, pid %ld done.\n", ha->board_name, SCarg->serial_number); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 2057 | 	else | 
 | 2058 | 		printk("%s: reset, exit.\n", ha->board_name); | 
 | 2059 |  | 
| Jeff Garzik  | df0ae24 | 2005-05-28 07:57:14 -0400 | [diff] [blame] | 2060 | 	spin_unlock_irq(shost->host_lock); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 2061 | 	return SUCCESS; | 
 | 2062 | } | 
 | 2063 |  | 
 | 2064 | int eata2x_bios_param(struct scsi_device *sdev, struct block_device *bdev, | 
 | 2065 | 		      sector_t capacity, int *dkinfo) | 
 | 2066 | { | 
 | 2067 | 	unsigned int size = capacity; | 
 | 2068 |  | 
 | 2069 | 	if (ext_tran || (scsicam_bios_param(bdev, capacity, dkinfo) < 0)) { | 
 | 2070 | 		dkinfo[0] = 255; | 
 | 2071 | 		dkinfo[1] = 63; | 
 | 2072 | 		dkinfo[2] = size / (dkinfo[0] * dkinfo[1]); | 
 | 2073 | 	} | 
 | 2074 | #if defined (DEBUG_GEOMETRY) | 
 | 2075 | 	printk("%s: bios_param, head=%d, sec=%d, cyl=%d.\n", driver_name, | 
 | 2076 | 	       dkinfo[0], dkinfo[1], dkinfo[2]); | 
 | 2077 | #endif | 
 | 2078 |  | 
 | 2079 | 	return 0; | 
 | 2080 | } | 
 | 2081 |  | 
 | 2082 | static void sort(unsigned long sk[], unsigned int da[], unsigned int n, | 
 | 2083 | 		 unsigned int rev) | 
 | 2084 | { | 
 | 2085 | 	unsigned int i, j, k, y; | 
 | 2086 | 	unsigned long x; | 
 | 2087 |  | 
 | 2088 | 	for (i = 0; i < n - 1; i++) { | 
 | 2089 | 		k = i; | 
 | 2090 |  | 
 | 2091 | 		for (j = k + 1; j < n; j++) | 
 | 2092 | 			if (rev) { | 
 | 2093 | 				if (sk[j] > sk[k]) | 
 | 2094 | 					k = j; | 
 | 2095 | 			} else { | 
 | 2096 | 				if (sk[j] < sk[k]) | 
 | 2097 | 					k = j; | 
 | 2098 | 			} | 
 | 2099 |  | 
 | 2100 | 		if (k != i) { | 
 | 2101 | 			x = sk[k]; | 
 | 2102 | 			sk[k] = sk[i]; | 
 | 2103 | 			sk[i] = x; | 
 | 2104 | 			y = da[k]; | 
 | 2105 | 			da[k] = da[i]; | 
 | 2106 | 			da[i] = y; | 
 | 2107 | 		} | 
 | 2108 | 	} | 
 | 2109 |  | 
 | 2110 | 	return; | 
 | 2111 | } | 
 | 2112 |  | 
 | 2113 | static int reorder(struct hostdata *ha, unsigned long cursec, | 
 | 2114 | 		   unsigned int ihdlr, unsigned int il[], unsigned int n_ready) | 
 | 2115 | { | 
 | 2116 | 	struct scsi_cmnd *SCpnt; | 
 | 2117 | 	struct mscp *cpp; | 
 | 2118 | 	unsigned int k, n; | 
 | 2119 | 	unsigned int rev = 0, s = 1, r = 1; | 
 | 2120 | 	unsigned int input_only = 1, overlap = 0; | 
 | 2121 | 	unsigned long sl[n_ready], pl[n_ready], ll[n_ready]; | 
 | 2122 | 	unsigned long maxsec = 0, minsec = ULONG_MAX, seek = 0, iseek = 0; | 
 | 2123 | 	unsigned long ioseek = 0; | 
 | 2124 |  | 
 | 2125 | 	static unsigned int flushcount = 0, batchcount = 0, sortcount = 0; | 
 | 2126 | 	static unsigned int readycount = 0, ovlcount = 0, inputcount = 0; | 
 | 2127 | 	static unsigned int readysorted = 0, revcount = 0; | 
 | 2128 | 	static unsigned long seeksorted = 0, seeknosort = 0; | 
 | 2129 |  | 
 | 2130 | 	if (link_statistics && !(++flushcount % link_statistics)) | 
 | 2131 | 		printk("fc %d bc %d ic %d oc %d rc %d rs %d sc %d re %d" | 
 | 2132 | 		       " av %ldK as %ldK.\n", flushcount, batchcount, | 
 | 2133 | 		       inputcount, ovlcount, readycount, readysorted, sortcount, | 
 | 2134 | 		       revcount, seeknosort / (readycount + 1), | 
 | 2135 | 		       seeksorted / (readycount + 1)); | 
 | 2136 |  | 
 | 2137 | 	if (n_ready <= 1) | 
 | 2138 | 		return 0; | 
 | 2139 |  | 
 | 2140 | 	for (n = 0; n < n_ready; n++) { | 
 | 2141 | 		k = il[n]; | 
 | 2142 | 		cpp = &ha->cp[k]; | 
 | 2143 | 		SCpnt = cpp->SCpnt; | 
 | 2144 |  | 
 | 2145 | 		if (!cpp->din) | 
 | 2146 | 			input_only = 0; | 
 | 2147 |  | 
| Tejun Heo | 83096eb | 2009-05-07 22:24:39 +0900 | [diff] [blame] | 2148 | 		if (blk_rq_pos(SCpnt->request) < minsec) | 
 | 2149 | 			minsec = blk_rq_pos(SCpnt->request); | 
 | 2150 | 		if (blk_rq_pos(SCpnt->request) > maxsec) | 
 | 2151 | 			maxsec = blk_rq_pos(SCpnt->request); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 2152 |  | 
| Tejun Heo | 83096eb | 2009-05-07 22:24:39 +0900 | [diff] [blame] | 2153 | 		sl[n] = blk_rq_pos(SCpnt->request); | 
 | 2154 | 		ioseek += blk_rq_sectors(SCpnt->request); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 2155 |  | 
 | 2156 | 		if (!n) | 
 | 2157 | 			continue; | 
 | 2158 |  | 
 | 2159 | 		if (sl[n] < sl[n - 1]) | 
 | 2160 | 			s = 0; | 
 | 2161 | 		if (sl[n] > sl[n - 1]) | 
 | 2162 | 			r = 0; | 
 | 2163 |  | 
 | 2164 | 		if (link_statistics) { | 
 | 2165 | 			if (sl[n] > sl[n - 1]) | 
 | 2166 | 				seek += sl[n] - sl[n - 1]; | 
 | 2167 | 			else | 
 | 2168 | 				seek += sl[n - 1] - sl[n]; | 
 | 2169 | 		} | 
 | 2170 |  | 
 | 2171 | 	} | 
 | 2172 |  | 
 | 2173 | 	if (link_statistics) { | 
 | 2174 | 		if (cursec > sl[0]) | 
 | 2175 | 			seek += cursec - sl[0]; | 
 | 2176 | 		else | 
 | 2177 | 			seek += sl[0] - cursec; | 
 | 2178 | 	} | 
 | 2179 |  | 
 | 2180 | 	if (cursec > ((maxsec + minsec) / 2)) | 
 | 2181 | 		rev = 1; | 
 | 2182 |  | 
 | 2183 | 	if (ioseek > ((maxsec - minsec) / 2)) | 
 | 2184 | 		rev = 0; | 
 | 2185 |  | 
 | 2186 | 	if (!((rev && r) || (!rev && s))) | 
 | 2187 | 		sort(sl, il, n_ready, rev); | 
 | 2188 |  | 
 | 2189 | 	if (!input_only) | 
 | 2190 | 		for (n = 0; n < n_ready; n++) { | 
 | 2191 | 			k = il[n]; | 
 | 2192 | 			cpp = &ha->cp[k]; | 
 | 2193 | 			SCpnt = cpp->SCpnt; | 
| Tejun Heo | 83096eb | 2009-05-07 22:24:39 +0900 | [diff] [blame] | 2194 | 			ll[n] = blk_rq_sectors(SCpnt->request); | 
| Matthew Wilcox | 12a4416 | 2007-09-18 19:54:43 -0600 | [diff] [blame] | 2195 | 			pl[n] = SCpnt->serial_number; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 2196 |  | 
 | 2197 | 			if (!n) | 
 | 2198 | 				continue; | 
 | 2199 |  | 
 | 2200 | 			if ((sl[n] == sl[n - 1]) | 
 | 2201 | 			    || (!rev && ((sl[n - 1] + ll[n - 1]) > sl[n])) | 
 | 2202 | 			    || (rev && ((sl[n] + ll[n]) > sl[n - 1]))) | 
 | 2203 | 				overlap = 1; | 
 | 2204 | 		} | 
 | 2205 |  | 
 | 2206 | 	if (overlap) | 
 | 2207 | 		sort(pl, il, n_ready, 0); | 
 | 2208 |  | 
 | 2209 | 	if (link_statistics) { | 
 | 2210 | 		if (cursec > sl[0]) | 
 | 2211 | 			iseek = cursec - sl[0]; | 
 | 2212 | 		else | 
 | 2213 | 			iseek = sl[0] - cursec; | 
 | 2214 | 		batchcount++; | 
 | 2215 | 		readycount += n_ready; | 
 | 2216 | 		seeknosort += seek / 1024; | 
 | 2217 | 		if (input_only) | 
 | 2218 | 			inputcount++; | 
 | 2219 | 		if (overlap) { | 
 | 2220 | 			ovlcount++; | 
 | 2221 | 			seeksorted += iseek / 1024; | 
 | 2222 | 		} else | 
 | 2223 | 			seeksorted += (iseek + maxsec - minsec) / 1024; | 
 | 2224 | 		if (rev && !r) { | 
 | 2225 | 			revcount++; | 
 | 2226 | 			readysorted += n_ready; | 
 | 2227 | 		} | 
 | 2228 | 		if (!rev && !s) { | 
 | 2229 | 			sortcount++; | 
 | 2230 | 			readysorted += n_ready; | 
 | 2231 | 		} | 
 | 2232 | 	} | 
 | 2233 | #if defined(DEBUG_LINKED_COMMANDS) | 
 | 2234 | 	if (link_statistics && (overlap || !(flushcount % link_statistics))) | 
 | 2235 | 		for (n = 0; n < n_ready; n++) { | 
 | 2236 | 			k = il[n]; | 
 | 2237 | 			cpp = &ha->cp[k]; | 
 | 2238 | 			SCpnt = cpp->SCpnt; | 
| Jeff Garzik | 017560f | 2005-10-24 18:04:36 -0400 | [diff] [blame] | 2239 | 			scmd_printk(KERN_INFO, SCpnt, | 
| Tejun Heo | 83096eb | 2009-05-07 22:24:39 +0900 | [diff] [blame] | 2240 | 			    "%s pid %ld mb %d fc %d nr %d sec %ld ns %u" | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 2241 | 			     " cur %ld s:%c r:%c rev:%c in:%c ov:%c xd %d.\n", | 
 | 2242 | 			     (ihdlr ? "ihdlr" : "qcomm"), | 
| Matthew Wilcox | 12a4416 | 2007-09-18 19:54:43 -0600 | [diff] [blame] | 2243 | 			     SCpnt->serial_number, k, flushcount, | 
| Tejun Heo | 83096eb | 2009-05-07 22:24:39 +0900 | [diff] [blame] | 2244 | 			     n_ready, blk_rq_pos(SCpnt->request), | 
 | 2245 | 			     blk_rq_sectors(SCpnt->request), cursec, YESNO(s), | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 2246 | 			     YESNO(r), YESNO(rev), YESNO(input_only), | 
 | 2247 | 			     YESNO(overlap), cpp->din); | 
 | 2248 | 		} | 
 | 2249 | #endif | 
 | 2250 | 	return overlap; | 
 | 2251 | } | 
 | 2252 |  | 
 | 2253 | static void flush_dev(struct scsi_device *dev, unsigned long cursec, | 
 | 2254 | 		      struct hostdata *ha, unsigned int ihdlr) | 
 | 2255 | { | 
 | 2256 | 	struct scsi_cmnd *SCpnt; | 
 | 2257 | 	struct mscp *cpp; | 
 | 2258 | 	unsigned int k, n, n_ready = 0, il[MAX_MAILBOXES]; | 
 | 2259 |  | 
 | 2260 | 	for (k = 0; k < dev->host->can_queue; k++) { | 
 | 2261 |  | 
 | 2262 | 		if (ha->cp_stat[k] != READY && ha->cp_stat[k] != IN_USE) | 
 | 2263 | 			continue; | 
 | 2264 |  | 
 | 2265 | 		cpp = &ha->cp[k]; | 
 | 2266 | 		SCpnt = cpp->SCpnt; | 
 | 2267 |  | 
 | 2268 | 		if (SCpnt->device != dev) | 
 | 2269 | 			continue; | 
 | 2270 |  | 
 | 2271 | 		if (ha->cp_stat[k] == IN_USE) | 
 | 2272 | 			return; | 
 | 2273 |  | 
 | 2274 | 		il[n_ready++] = k; | 
 | 2275 | 	} | 
 | 2276 |  | 
 | 2277 | 	if (reorder(ha, cursec, ihdlr, il, n_ready)) | 
 | 2278 | 		n_ready = 1; | 
 | 2279 |  | 
 | 2280 | 	for (n = 0; n < n_ready; n++) { | 
 | 2281 | 		k = il[n]; | 
 | 2282 | 		cpp = &ha->cp[k]; | 
 | 2283 | 		SCpnt = cpp->SCpnt; | 
 | 2284 |  | 
 | 2285 | 		if (do_dma(dev->host->io_port, cpp->cp_dma_addr, SEND_CP_DMA)) { | 
| Jeff Garzik | 017560f | 2005-10-24 18:04:36 -0400 | [diff] [blame] | 2286 | 			scmd_printk(KERN_INFO, SCpnt, | 
 | 2287 | 			    "%s, pid %ld, mbox %d, adapter" | 
 | 2288 | 			     " busy, will abort.\n", | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 2289 | 			     (ihdlr ? "ihdlr" : "qcomm"), | 
| Matthew Wilcox | 12a4416 | 2007-09-18 19:54:43 -0600 | [diff] [blame] | 2290 | 			     SCpnt->serial_number, k); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 2291 | 			ha->cp_stat[k] = ABORTING; | 
 | 2292 | 			continue; | 
 | 2293 | 		} | 
 | 2294 |  | 
 | 2295 | 		ha->cp_stat[k] = IN_USE; | 
 | 2296 | 	} | 
 | 2297 | } | 
 | 2298 |  | 
| Jeff Garzik | e19166d | 2008-04-18 19:22:52 -0400 | [diff] [blame] | 2299 | static irqreturn_t ihdlr(struct Scsi_Host *shost) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 2300 | { | 
 | 2301 | 	struct scsi_cmnd *SCpnt; | 
 | 2302 | 	unsigned int i, k, c, status, tstatus, reg; | 
 | 2303 | 	struct mssp *spp; | 
 | 2304 | 	struct mscp *cpp; | 
 | 2305 | 	struct hostdata *ha = (struct hostdata *)shost->hostdata; | 
| Jeff Garzik | e19166d | 2008-04-18 19:22:52 -0400 | [diff] [blame] | 2306 | 	int irq = shost->irq; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 2307 |  | 
 | 2308 | 	/* Check if this board need to be serviced */ | 
 | 2309 | 	if (!(inb(shost->io_port + REG_AUX_STATUS) & IRQ_ASSERTED)) | 
 | 2310 | 		goto none; | 
 | 2311 |  | 
 | 2312 | 	ha->iocount++; | 
 | 2313 |  | 
 | 2314 | 	if (do_trace) | 
 | 2315 | 		printk("%s: ihdlr, enter, irq %d, count %d.\n", ha->board_name, irq, | 
 | 2316 | 		       ha->iocount); | 
 | 2317 |  | 
 | 2318 | 	/* Check if this board is still busy */ | 
 | 2319 | 	if (wait_on_busy(shost->io_port, 20 * MAXLOOP)) { | 
 | 2320 | 		reg = inb(shost->io_port + REG_STATUS); | 
 | 2321 | 		printk | 
 | 2322 | 		    ("%s: ihdlr, busy timeout error,  irq %d, reg 0x%x, count %d.\n", | 
 | 2323 | 		     ha->board_name, irq, reg, ha->iocount); | 
 | 2324 | 		goto none; | 
 | 2325 | 	} | 
 | 2326 |  | 
 | 2327 | 	spp = &ha->sp; | 
 | 2328 |  | 
 | 2329 | 	/* Make a local copy just before clearing the interrupt indication */ | 
 | 2330 | 	memcpy(spp, ha->sp_cpu_addr, sizeof(struct mssp)); | 
 | 2331 |  | 
 | 2332 | 	/* Clear the completion flag and cp pointer on the dynamic copy of sp */ | 
 | 2333 | 	memset(ha->sp_cpu_addr, 0, sizeof(struct mssp)); | 
 | 2334 |  | 
 | 2335 | 	/* Read the status register to clear the interrupt indication */ | 
 | 2336 | 	reg = inb(shost->io_port + REG_STATUS); | 
 | 2337 |  | 
 | 2338 | #if defined (DEBUG_INTERRUPT) | 
 | 2339 | 	{ | 
 | 2340 | 		unsigned char *bytesp; | 
 | 2341 | 		int cnt; | 
 | 2342 | 		bytesp = (unsigned char *)spp; | 
 | 2343 | 		if (ha->iocount < 200) { | 
 | 2344 | 			printk("sp[] ="); | 
 | 2345 | 			for (cnt = 0; cnt < 15; cnt++) | 
 | 2346 | 				printk(" 0x%x", bytesp[cnt]); | 
 | 2347 | 			printk("\n"); | 
 | 2348 | 		} | 
 | 2349 | 	} | 
 | 2350 | #endif | 
 | 2351 |  | 
 | 2352 | 	/* Reject any sp with supspect data */ | 
 | 2353 | 	if (spp->eoc == 0 && ha->iocount > 1) | 
 | 2354 | 		printk | 
 | 2355 | 		    ("%s: ihdlr, spp->eoc == 0, irq %d, reg 0x%x, count %d.\n", | 
 | 2356 | 		     ha->board_name, irq, reg, ha->iocount); | 
 | 2357 | 	if (spp->cpp_index < 0 || spp->cpp_index >= shost->can_queue) | 
 | 2358 | 		printk | 
 | 2359 | 		    ("%s: ihdlr, bad spp->cpp_index %d, irq %d, reg 0x%x, count %d.\n", | 
 | 2360 | 		     ha->board_name, spp->cpp_index, irq, reg, ha->iocount); | 
 | 2361 | 	if (spp->eoc == 0 || spp->cpp_index < 0 | 
 | 2362 | 	    || spp->cpp_index >= shost->can_queue) | 
 | 2363 | 		goto handled; | 
 | 2364 |  | 
 | 2365 | 	/* Find the mailbox to be serviced on this board */ | 
 | 2366 | 	i = spp->cpp_index; | 
 | 2367 |  | 
 | 2368 | 	cpp = &(ha->cp[i]); | 
 | 2369 |  | 
 | 2370 | #if defined(DEBUG_GENERATE_ABORTS) | 
 | 2371 | 	if ((ha->iocount > 500) && ((ha->iocount % 500) < 3)) | 
 | 2372 | 		goto handled; | 
 | 2373 | #endif | 
 | 2374 |  | 
 | 2375 | 	if (ha->cp_stat[i] == IGNORE) { | 
 | 2376 | 		ha->cp_stat[i] = FREE; | 
 | 2377 | 		goto handled; | 
 | 2378 | 	} else if (ha->cp_stat[i] == LOCKED) { | 
 | 2379 | 		ha->cp_stat[i] = FREE; | 
 | 2380 | 		printk("%s: ihdlr, mbox %d unlocked, count %d.\n", ha->board_name, i, | 
 | 2381 | 		       ha->iocount); | 
 | 2382 | 		goto handled; | 
 | 2383 | 	} else if (ha->cp_stat[i] == FREE) { | 
 | 2384 | 		printk("%s: ihdlr, mbox %d is free, count %d.\n", ha->board_name, i, | 
 | 2385 | 		       ha->iocount); | 
 | 2386 | 		goto handled; | 
 | 2387 | 	} else if (ha->cp_stat[i] == IN_RESET) | 
 | 2388 | 		printk("%s: ihdlr, mbox %d is in reset.\n", ha->board_name, i); | 
 | 2389 | 	else if (ha->cp_stat[i] != IN_USE) | 
 | 2390 | 		panic("%s: ihdlr, mbox %d, invalid cp_stat: %d.\n", | 
 | 2391 | 		      ha->board_name, i, ha->cp_stat[i]); | 
 | 2392 |  | 
 | 2393 | 	ha->cp_stat[i] = FREE; | 
 | 2394 | 	SCpnt = cpp->SCpnt; | 
 | 2395 |  | 
 | 2396 | 	if (SCpnt == NULL) | 
 | 2397 | 		panic("%s: ihdlr, mbox %d, SCpnt == NULL.\n", ha->board_name, i); | 
 | 2398 |  | 
 | 2399 | 	if (SCpnt->host_scribble == NULL) | 
 | 2400 | 		panic("%s: ihdlr, mbox %d, pid %ld, SCpnt %p garbled.\n", ha->board_name, | 
| Matthew Wilcox | 12a4416 | 2007-09-18 19:54:43 -0600 | [diff] [blame] | 2401 | 		      i, SCpnt->serial_number, SCpnt); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 2402 |  | 
 | 2403 | 	if (*(unsigned int *)SCpnt->host_scribble != i) | 
 | 2404 | 		panic("%s: ihdlr, mbox %d, pid %ld, index mismatch %d.\n", | 
| Matthew Wilcox | 12a4416 | 2007-09-18 19:54:43 -0600 | [diff] [blame] | 2405 | 		      ha->board_name, i, SCpnt->serial_number, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 2406 | 		      *(unsigned int *)SCpnt->host_scribble); | 
 | 2407 |  | 
 | 2408 | 	sync_dma(i, ha); | 
 | 2409 |  | 
 | 2410 | 	if (linked_comm && SCpnt->device->queue_depth > 2 | 
 | 2411 | 	    && TLDEV(SCpnt->device->type)) | 
| Tejun Heo | 83096eb | 2009-05-07 22:24:39 +0900 | [diff] [blame] | 2412 | 		flush_dev(SCpnt->device, blk_rq_pos(SCpnt->request), ha, 1); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 2413 |  | 
 | 2414 | 	tstatus = status_byte(spp->target_status); | 
 | 2415 |  | 
 | 2416 | #if defined(DEBUG_GENERATE_ERRORS) | 
 | 2417 | 	if ((ha->iocount > 500) && ((ha->iocount % 200) < 2)) | 
 | 2418 | 		spp->adapter_status = 0x01; | 
 | 2419 | #endif | 
 | 2420 |  | 
 | 2421 | 	switch (spp->adapter_status) { | 
 | 2422 | 	case ASOK:		/* status OK */ | 
 | 2423 |  | 
 | 2424 | 		/* Forces a reset if a disk drive keeps returning BUSY */ | 
 | 2425 | 		if (tstatus == BUSY && SCpnt->device->type != TYPE_TAPE) | 
 | 2426 | 			status = DID_ERROR << 16; | 
 | 2427 |  | 
 | 2428 | 		/* If there was a bus reset, redo operation on each target */ | 
 | 2429 | 		else if (tstatus != GOOD && SCpnt->device->type == TYPE_DISK | 
 | 2430 | 			 && ha->target_redo[SCpnt->device->id][SCpnt-> | 
 | 2431 | 								  device-> | 
 | 2432 | 								  channel]) | 
 | 2433 | 			status = DID_BUS_BUSY << 16; | 
 | 2434 |  | 
 | 2435 | 		/* Works around a flaw in scsi.c */ | 
 | 2436 | 		else if (tstatus == CHECK_CONDITION | 
 | 2437 | 			 && SCpnt->device->type == TYPE_DISK | 
 | 2438 | 			 && (SCpnt->sense_buffer[2] & 0xf) == RECOVERED_ERROR) | 
 | 2439 | 			status = DID_BUS_BUSY << 16; | 
 | 2440 |  | 
 | 2441 | 		else | 
 | 2442 | 			status = DID_OK << 16; | 
 | 2443 |  | 
 | 2444 | 		if (tstatus == GOOD) | 
 | 2445 | 			ha->target_redo[SCpnt->device->id][SCpnt->device-> | 
 | 2446 | 							      channel] = 0; | 
 | 2447 |  | 
 | 2448 | 		if (spp->target_status && SCpnt->device->type == TYPE_DISK && | 
 | 2449 | 		    (!(tstatus == CHECK_CONDITION && ha->iocount <= 1000 && | 
 | 2450 | 		       (SCpnt->sense_buffer[2] & 0xf) == NOT_READY))) | 
 | 2451 | 			printk("%s: ihdlr, target %d.%d:%d, pid %ld, " | 
 | 2452 | 			       "target_status 0x%x, sense key 0x%x.\n", | 
 | 2453 | 			       ha->board_name, | 
 | 2454 | 			       SCpnt->device->channel, SCpnt->device->id, | 
| Matthew Wilcox | 12a4416 | 2007-09-18 19:54:43 -0600 | [diff] [blame] | 2455 | 			       SCpnt->device->lun, SCpnt->serial_number, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 2456 | 			       spp->target_status, SCpnt->sense_buffer[2]); | 
 | 2457 |  | 
 | 2458 | 		ha->target_to[SCpnt->device->id][SCpnt->device->channel] = 0; | 
 | 2459 |  | 
| Matthew Wilcox | 12a4416 | 2007-09-18 19:54:43 -0600 | [diff] [blame] | 2460 | 		if (ha->last_retried_pid == SCpnt->serial_number) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 2461 | 			ha->retries = 0; | 
 | 2462 |  | 
 | 2463 | 		break; | 
 | 2464 | 	case ASST:		/* Selection Time Out */ | 
 | 2465 | 	case 0x02:		/* Command Time Out   */ | 
 | 2466 |  | 
 | 2467 | 		if (ha->target_to[SCpnt->device->id][SCpnt->device->channel] > 1) | 
 | 2468 | 			status = DID_ERROR << 16; | 
 | 2469 | 		else { | 
 | 2470 | 			status = DID_TIME_OUT << 16; | 
 | 2471 | 			ha->target_to[SCpnt->device->id][SCpnt->device-> | 
 | 2472 | 							    channel]++; | 
 | 2473 | 		} | 
 | 2474 |  | 
 | 2475 | 		break; | 
 | 2476 |  | 
 | 2477 | 		/* Perform a limited number of internal retries */ | 
 | 2478 | 	case 0x03:		/* SCSI Bus Reset Received */ | 
 | 2479 | 	case 0x04:		/* Initial Controller Power-up */ | 
 | 2480 |  | 
 | 2481 | 		for (c = 0; c <= shost->max_channel; c++) | 
 | 2482 | 			for (k = 0; k < shost->max_id; k++) | 
 | 2483 | 				ha->target_redo[k][c] = 1; | 
 | 2484 |  | 
 | 2485 | 		if (SCpnt->device->type != TYPE_TAPE | 
 | 2486 | 		    && ha->retries < MAX_INTERNAL_RETRIES) { | 
 | 2487 |  | 
 | 2488 | #if defined(DID_SOFT_ERROR) | 
 | 2489 | 			status = DID_SOFT_ERROR << 16; | 
 | 2490 | #else | 
 | 2491 | 			status = DID_BUS_BUSY << 16; | 
 | 2492 | #endif | 
 | 2493 |  | 
 | 2494 | 			ha->retries++; | 
| Matthew Wilcox | 12a4416 | 2007-09-18 19:54:43 -0600 | [diff] [blame] | 2495 | 			ha->last_retried_pid = SCpnt->serial_number; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 2496 | 		} else | 
 | 2497 | 			status = DID_ERROR << 16; | 
 | 2498 |  | 
 | 2499 | 		break; | 
 | 2500 | 	case 0x05:		/* Unexpected Bus Phase */ | 
 | 2501 | 	case 0x06:		/* Unexpected Bus Free */ | 
 | 2502 | 	case 0x07:		/* Bus Parity Error */ | 
 | 2503 | 	case 0x08:		/* SCSI Hung */ | 
 | 2504 | 	case 0x09:		/* Unexpected Message Reject */ | 
 | 2505 | 	case 0x0a:		/* SCSI Bus Reset Stuck */ | 
 | 2506 | 	case 0x0b:		/* Auto Request-Sense Failed */ | 
 | 2507 | 	case 0x0c:		/* Controller Ram Parity Error */ | 
 | 2508 | 	default: | 
 | 2509 | 		status = DID_ERROR << 16; | 
 | 2510 | 		break; | 
 | 2511 | 	} | 
 | 2512 |  | 
 | 2513 | 	SCpnt->result = status | spp->target_status; | 
 | 2514 |  | 
 | 2515 | #if defined(DEBUG_INTERRUPT) | 
 | 2516 | 	if (SCpnt->result || do_trace) | 
 | 2517 | #else | 
 | 2518 | 	if ((spp->adapter_status != ASOK && ha->iocount > 1000) || | 
 | 2519 | 	    (spp->adapter_status != ASOK && | 
 | 2520 | 	     spp->adapter_status != ASST && ha->iocount <= 1000) || | 
 | 2521 | 	    do_trace || msg_byte(spp->target_status)) | 
 | 2522 | #endif | 
| Jeff Garzik | 017560f | 2005-10-24 18:04:36 -0400 | [diff] [blame] | 2523 | 		scmd_printk(KERN_INFO, SCpnt, "ihdlr, mbox %2d, err 0x%x:%x," | 
 | 2524 | 		       " pid %ld, reg 0x%x, count %d.\n", | 
 | 2525 | 		       i, spp->adapter_status, spp->target_status, | 
| Matthew Wilcox | 12a4416 | 2007-09-18 19:54:43 -0600 | [diff] [blame] | 2526 | 		       SCpnt->serial_number, reg, ha->iocount); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 2527 |  | 
 | 2528 | 	unmap_dma(i, ha); | 
 | 2529 |  | 
 | 2530 | 	/* Set the command state to inactive */ | 
 | 2531 | 	SCpnt->host_scribble = NULL; | 
 | 2532 |  | 
 | 2533 | 	SCpnt->scsi_done(SCpnt); | 
 | 2534 |  | 
 | 2535 | 	if (do_trace) | 
 | 2536 | 		printk("%s: ihdlr, exit, irq %d, count %d.\n", ha->board_name, | 
 | 2537 | 				irq, ha->iocount); | 
 | 2538 |  | 
 | 2539 |       handled: | 
 | 2540 | 	return IRQ_HANDLED; | 
 | 2541 |       none: | 
 | 2542 | 	return IRQ_NONE; | 
 | 2543 | } | 
 | 2544 |  | 
| Jeff Garzik | e19166d | 2008-04-18 19:22:52 -0400 | [diff] [blame] | 2545 | static irqreturn_t do_interrupt_handler(int dummy, void *shap) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 2546 | { | 
 | 2547 | 	struct Scsi_Host *shost; | 
 | 2548 | 	unsigned int j; | 
 | 2549 | 	unsigned long spin_flags; | 
 | 2550 | 	irqreturn_t ret; | 
 | 2551 |  | 
 | 2552 | 	/* Check if the interrupt must be processed by this handler */ | 
 | 2553 | 	if ((j = (unsigned int)((char *)shap - sha)) >= num_boards) | 
 | 2554 | 		return IRQ_NONE; | 
 | 2555 | 	shost = sh[j]; | 
 | 2556 |  | 
 | 2557 | 	spin_lock_irqsave(shost->host_lock, spin_flags); | 
| Jeff Garzik | e19166d | 2008-04-18 19:22:52 -0400 | [diff] [blame] | 2558 | 	ret = ihdlr(shost); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 2559 | 	spin_unlock_irqrestore(shost->host_lock, spin_flags); | 
 | 2560 | 	return ret; | 
 | 2561 | } | 
 | 2562 |  | 
 | 2563 | static int eata2x_release(struct Scsi_Host *shost) | 
 | 2564 | { | 
 | 2565 | 	struct hostdata *ha = (struct hostdata *)shost->hostdata; | 
 | 2566 | 	unsigned int i; | 
 | 2567 |  | 
 | 2568 | 	for (i = 0; i < shost->can_queue; i++) | 
| Jesper Juhl | c9475cb | 2005-11-07 01:01:26 -0800 | [diff] [blame] | 2569 | 		kfree((&ha->cp[i])->sglist); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 2570 |  | 
 | 2571 | 	for (i = 0; i < shost->can_queue; i++) | 
 | 2572 | 		pci_unmap_single(ha->pdev, ha->cp[i].cp_dma_addr, | 
 | 2573 | 				 sizeof(struct mscp), PCI_DMA_BIDIRECTIONAL); | 
 | 2574 |  | 
 | 2575 | 	if (ha->sp_cpu_addr) | 
 | 2576 | 		pci_free_consistent(ha->pdev, sizeof(struct mssp), | 
 | 2577 | 				    ha->sp_cpu_addr, ha->sp_dma_addr); | 
 | 2578 |  | 
 | 2579 | 	free_irq(shost->irq, &sha[ha->board_number]); | 
 | 2580 |  | 
 | 2581 | 	if (shost->dma_channel != NO_DMA) | 
 | 2582 | 		free_dma(shost->dma_channel); | 
 | 2583 |  | 
 | 2584 | 	release_region(shost->io_port, shost->n_io_port); | 
 | 2585 | 	scsi_unregister(shost); | 
 | 2586 | 	return 0; | 
 | 2587 | } | 
 | 2588 |  | 
 | 2589 | #include "scsi_module.c" | 
 | 2590 |  | 
 | 2591 | #ifndef MODULE | 
 | 2592 | __setup("eata=", option_setup); | 
 | 2593 | #endif				/* end MODULE */ |