File: /usr/src/linux/drivers/scsi/ips.c

1     /*****************************************************************************/
2     /* ips.c -- driver for the IBM ServeRAID controller                          */
3     /*                                                                           */
4     /* Written By: Keith Mitchell, IBM Corporation                               */
5     /*                                                                           */
6     /* Copyright (C) 1999 IBM Corporation                                        */
7     /*                                                                           */
8     /* This program is free software; you can redistribute it and/or modify      */
9     /* it under the terms of the GNU General Public License as published by      */
10     /* the Free Software Foundation; either version 2 of the License, or         */
11     /* (at your option) any later version.                                       */
12     /*                                                                           */
13     /* This program is distributed in the hope that it will be useful,           */
14     /* but WITHOUT ANY WARRANTY; without even the implied warranty of            */
15     /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             */
16     /* GNU General Public License for more details.                              */
17     /*                                                                           */
18     /* NO WARRANTY                                                               */
19     /* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR        */
20     /* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT      */
21     /* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,      */
22     /* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is    */
23     /* solely responsible for determining the appropriateness of using and       */
24     /* distributing the Program and assumes all risks associated with its        */
25     /* exercise of rights under this Agreement, including but not limited to     */
26     /* the risks and costs of program errors, damage to or loss of data,         */
27     /* programs or equipment, and unavailability or interruption of operations.  */
28     /*                                                                           */
29     /* DISCLAIMER OF LIABILITY                                                   */
30     /* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY   */
31     /* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL        */
32     /* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND   */
33     /* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR     */
34     /* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE    */
35     /* USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED  */
36     /* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES             */
37     /*                                                                           */
38     /* You should have received a copy of the GNU General Public License         */
39     /* along with this program; if not, write to the Free Software               */
40     /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
41     /*                                                                           */
42     /* Bugs/Comments/Suggestions should be mailed to:                            */
43     /*      ipslinux@us.ibm.com                                                  */
44     /*                                                                           */
45     /*****************************************************************************/
46     
47     /*****************************************************************************/
48     /* Change Log                                                                */
49     /*                                                                           */
50     /* 0.99.02  - Breakup commands that are bigger than 8 * the stripe size      */
51     /* 0.99.03  - Make interrupt routine handle all completed request on the     */
52     /*            adapter not just the first one                                 */
53     /*          - Make sure passthru commands get woken up if we run out of      */
54     /*            SCBs                                                           */
55     /*          - Send all of the commands on the queue at once rather than      */
56     /*            one at a time since the card will support it.                  */
57     /* 0.99.04  - Fix race condition in the passthru mechanism -- this required  */
58     /*            the interface to the utilities to change                       */
59     /*          - Fix error recovery code                                        */
60     /* 0.99.05  - Fix an oops when we get certain passthru commands              */
61     /* 1.00.00  - Initial Public Release                                         */
62     /*            Functionally equivalent to 0.99.05                             */
63     /* 3.60.00  - Bump max commands to 128 for use with ServeRAID firmware 3.60  */
64     /*          - Change version to 3.60 to coincide with ServeRAID release      */
65     /*            numbering.                                                     */
66     /* 3.60.01  - Remove bogus error check in passthru routine                   */
67     /* 3.60.02  - Make DCDB direction based on lookup table                      */
68     /*          - Only allow one DCDB command to a SCSI ID at a time             */
69     /* 4.00.00  - Add support for ServeRAID 4                                    */
70     /* 4.00.01  - Add support for First Failure Data Capture                     */
71     /* 4.00.02  - Fix problem with PT DCDB with no buffer                        */
72     /* 4.00.03  - Add alternative passthru interface                             */
73     /*          - Add ability to flash ServeRAID BIOS                            */
74     /* 4.00.04  - Rename structures/constants to be prefixed with IPS_           */
75     /* 4.00.05  - Remove wish_block from init routine                            */
76     /*          - Use linux/spinlock.h instead of asm/spinlock.h for kernels     */
77     /*            2.3.18 and later                                               */
78     /*          - Sync with other changes from the 2.3 kernels                   */
79     /* 4.00.06  - Fix timeout with initial FFDC command                          */
80     /* 4.00.06a - Port to 2.4 (trivial) -- Christoph Hellwig <hch@caldera.de>    */
81     /* 4.10.00  - Add support for ServeRAID 4M/4L                                */
82     /* 4.10.13  - Fix for dynamic unload and proc file system                    */
83     /* 4.20.03  - Rename version to coincide with new release schedules          */
84     /*            Performance fixes                                              */
85     /*            Fix truncation of /proc files with cat                         */
86     /*            Merge in changes through kernel 2.4.0test1ac21                 */
87     /* 4.20.13  - Fix some failure cases / reset code                            */
88     /*          - Hook into the reboot_notifier to flush the controller cache    */
89     /* 4.50.01  - Fix problem when there is a hole in logical drive numbering   */
90     /* 4.70.09  - Use a Common ( Large Buffer ) for Flashing from the JCRM CD    */
91     /*          - Add IPSSEND Flash Support                                      */
92     /*          - Set Sense Data for Unknown SCSI Command                        */
93     /*          - Use Slot Number from NVRAM Page 5                              */
94     /*          - Restore caller's DCDB Structure                                */
95     /* 4.70.12  - Corrective actions for bad controller ( during initialization )*/
96     /* 4.70.13  - Don't Send CDB's if we already know the device is not present  */
97     /*          - Don't release HA Lock in ips_next() until SC taken off queue   */
98     /*          - Unregister SCSI device in ips_release()                        */
99     /* 4.70.15  - Fix Breakup for very large ( non-SG ) requests in ips_done()   */
100     /* 4.71.00  - Change all memory allocations to not use GFP_DMA flag          */
101     /*            Code Clean-Up for 2.4.x kernel                                 */
102     /* 4.72.00  - Allow for a Scatter-Gather Element to exceed MAX_XFER Size     */
103     /*                                                                           */
104     /*****************************************************************************/
105     
106     /*
107      * Conditional Compilation directives for this driver:
108      *
109      * IPS_DEBUG            - Turn on debugging info
110      *
111      *
112      * Parameters:
113      *
114      * debug:<number>       - Set debug level to <number>
115      *                        NOTE: only works when IPS_DEBUG compile directive
116      *                              is used.
117      *
118      *       1              - Normal debug messages
119      *       2              - Verbose debug messages
120      *       11             - Method trace (non interrupt)
121      *       12             - Method trace (includes interrupt)
122      *
123      * noreset              - Don't reset the controller
124      * nocmdline            - Turn off passthru support
125      * noi2o                - Don't use I2O Queues (ServeRAID 4 only)
126      * nommap               - Don't use memory mapped I/O
127      * ioctlsize            - Initial size of the IOCTL buffer
128      */
129     
130     #include <asm/io.h>
131     #include <asm/byteorder.h>
132     #include <linux/stddef.h>
133     #include <linux/version.h>
134     #include <linux/string.h>
135     #include <linux/errno.h>
136     #include <linux/kernel.h>
137     #include <linux/ioport.h> 
138     #include <linux/slab.h>
139     #include <linux/vmalloc.h>
140     #include <linux/delay.h>
141     #include <linux/sched.h>
142     #include <linux/pci.h>
143     #include <linux/proc_fs.h>
144     #include <linux/reboot.h>
145     #include <linux/tqueue.h>
146     #include <linux/interrupt.h>
147     
148     #include <linux/blk.h>
149     #include <linux/types.h>
150     
151     #ifndef NO_IPS_CMDLINE
152     #include <scsi/sg.h>
153     #endif
154     
155     #include "sd.h"
156     #include "scsi.h"
157     #include "hosts.h"
158     #include "ips.h"
159     
160     #include <linux/module.h>
161     
162     #include <linux/stat.h>
163     #include <linux/config.h>
164     
165     #if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,18)
166     #include <linux/spinlock.h>
167     #else
168     #include <asm/spinlock.h>
169     #endif
170     
171     #if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,13)
172     #include <linux/init.h>
173     #endif
174     
175     #include <linux/smp.h>
176     
177     #ifdef MODULE
178        static char *ips = NULL;
179        MODULE_PARM(ips, "s");
180     #endif
181     
182     /*
183      * DRIVER_VER
184      */
185     #define IPS_VERSION_HIGH        "4.72"
186     #define IPS_VERSION_LOW         ".00 "
187     
188     
189     #if LINUX_VERSION_CODE < LinuxVersionCode(2,3,27)
190     struct proc_dir_entry proc_scsi_ips = {
191        0,
192        3, "ips",
193        S_IFDIR | S_IRUGO | S_IXUGO, 2
194     };
195     #endif
196     
197     #if !defined(__i386__)
198        #error "This driver has only been tested on the x86 platform"
199     #endif
200     
201     #if LINUX_VERSION_CODE < LinuxVersionCode(2,2,0)
202        #error "This driver only works with kernel 2.2.0 and later"
203     #endif
204     
205     #if !defined(NO_IPS_CMDLINE) && ((SG_BIG_BUFF < 8192) || !defined(SG_BIG_BUFF))
206        #error "To use the command-line interface you need to define SG_BIG_BUFF"
207     #endif
208     
209     #ifdef IPS_DEBUG
210        #define METHOD_TRACE(s, i)    if (ips_debug >= (i+10)) printk(KERN_NOTICE s "\n");
211        #define DEBUG(i, s)           if (ips_debug >= i) printk(KERN_NOTICE s "\n");
212        #define DEBUG_VAR(i, s, v...) if (ips_debug >= i) printk(KERN_NOTICE s "\n", v);
213     #else
214        #define METHOD_TRACE(s, i)
215        #define DEBUG(i, s)
216        #define DEBUG_VAR(i, s, v...)
217     #endif
218     
219     /*
220      * global variables
221      */
222     static const char * ips_name = "ips";
223     static struct Scsi_Host * ips_sh[IPS_MAX_ADAPTERS];  /* Array of host controller structures */
224     static ips_ha_t * ips_ha[IPS_MAX_ADAPTERS];          /* Array of HA structures */
225     static unsigned int ips_next_controller = 0;
226     static unsigned int ips_num_controllers = 0;
227     static unsigned int ips_released_controllers = 0;
228     static int          ips_cmd_timeout = 60;
229     static int          ips_reset_timeout = 60 * 5;
230     static int          ips_force_memio = 1;             /* Always use Memory Mapped I/O    */
231     static int          ips_force_i2o = 1;               /* Always use I2O command delivery */
232     static int          ips_resetcontroller = 1;         /* Reset the controller            */
233     static int          ips_cmdline = 1;                 /* Support for passthru            */
234     static int          ips_ioctlsize = IPS_IOCTL_SIZE;  /* Size of the ioctl buffer        */
235     static int          ips_cd_boot = 0;                 /* Booting from ServeRAID Manager CD */
236     static char        *ips_FlashData = NULL;            /* CD Boot - Flash Data Buffer      */
237     static int          ips_FlashDataInUse = 0;          /* CD Boot - Flash Data In Use Flag */
238     
239     #ifdef IPS_DEBUG
240     static int          ips_debug = 0;                   /* Debug mode                      */
241     #endif
242     
243     /*
244      * Necessary forward function protoypes
245      */
246     static int ips_halt(struct notifier_block *nb, ulong event, void *buf);
247     
248     #define MAX_ADAPTER_NAME 11
249     
250     static char ips_adapter_name[][30] = {
251        "ServeRAID",
252        "ServeRAID II",
253        "ServeRAID on motherboard",
254        "ServeRAID on motherboard",
255        "ServeRAID 3H",
256        "ServeRAID 3L",
257        "ServeRAID 4H",
258        "ServeRAID 4M",
259        "ServeRAID 4L",
260        "ServeRAID 4Mx",
261        "ServeRAID 4Lx"
262     };
263     
264     static struct notifier_block ips_notifier = {
265        ips_halt, NULL, 0
266     };
267     
268     /*
269      * Direction table
270      */
271     static char ips_command_direction[] = {
272     IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_IN,   IPS_DATA_IN,   IPS_DATA_OUT,
273     IPS_DATA_IN,   IPS_DATA_IN,   IPS_DATA_OUT,  IPS_DATA_IN,   IPS_DATA_UNK,
274     IPS_DATA_OUT,  IPS_DATA_OUT,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
275     IPS_DATA_IN,   IPS_DATA_NONE, IPS_DATA_IN,   IPS_DATA_IN,   IPS_DATA_OUT,
276     IPS_DATA_IN,   IPS_DATA_OUT,  IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_OUT,
277     IPS_DATA_NONE, IPS_DATA_IN,   IPS_DATA_NONE, IPS_DATA_IN,   IPS_DATA_OUT,
278     IPS_DATA_NONE, IPS_DATA_UNK,  IPS_DATA_IN,   IPS_DATA_UNK,  IPS_DATA_IN,
279     IPS_DATA_UNK,  IPS_DATA_OUT,  IPS_DATA_IN,   IPS_DATA_UNK,  IPS_DATA_UNK,
280     IPS_DATA_IN,   IPS_DATA_IN,   IPS_DATA_OUT,  IPS_DATA_NONE, IPS_DATA_UNK,
281     IPS_DATA_IN,   IPS_DATA_OUT,  IPS_DATA_OUT,  IPS_DATA_OUT,  IPS_DATA_OUT,
282     IPS_DATA_OUT,  IPS_DATA_NONE, IPS_DATA_IN,   IPS_DATA_NONE, IPS_DATA_NONE,
283     IPS_DATA_IN,   IPS_DATA_OUT,  IPS_DATA_OUT,  IPS_DATA_OUT,  IPS_DATA_OUT,
284     IPS_DATA_IN,   IPS_DATA_OUT,  IPS_DATA_IN,   IPS_DATA_OUT,  IPS_DATA_OUT,
285     IPS_DATA_OUT,  IPS_DATA_IN,   IPS_DATA_IN,   IPS_DATA_IN,   IPS_DATA_NONE,
286     IPS_DATA_UNK,  IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_UNK,
287     IPS_DATA_NONE, IPS_DATA_OUT,  IPS_DATA_IN,   IPS_DATA_UNK,  IPS_DATA_UNK,
288     IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
289     IPS_DATA_OUT,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
290     IPS_DATA_IN,   IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
291     IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
292     IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
293     IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
294     IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
295     IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
296     IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
297     IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
298     IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
299     IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
300     IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
301     IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
302     IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
303     IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
304     IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
305     IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_UNK,  IPS_DATA_IN,   IPS_DATA_NONE,
306     IPS_DATA_OUT,  IPS_DATA_UNK,  IPS_DATA_NONE, IPS_DATA_UNK,  IPS_DATA_OUT,
307     IPS_DATA_OUT,  IPS_DATA_OUT,  IPS_DATA_OUT,  IPS_DATA_OUT,  IPS_DATA_NONE,
308     IPS_DATA_UNK,  IPS_DATA_IN,   IPS_DATA_OUT,  IPS_DATA_IN,   IPS_DATA_IN,
309     IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
310     IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
311     IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
312     IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
313     IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
314     IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
315     IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
316     IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
317     IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
318     IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_OUT,
319     IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
320     IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
321     IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,
322     IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK,  IPS_DATA_UNK
323     };
324     
325     /*
326      * Function prototypes
327      */
328     int ips_detect(Scsi_Host_Template *);
329     int ips_release(struct Scsi_Host *);
330     int ips_eh_abort(Scsi_Cmnd *);
331     int ips_eh_reset(Scsi_Cmnd *);
332     int ips_queue(Scsi_Cmnd *, void (*) (Scsi_Cmnd *));
333     int ips_biosparam(Disk *, kdev_t, int *);
334     const char * ips_info(struct Scsi_Host *);
335     void do_ipsintr(int, void *, struct pt_regs *);
336     static int ips_hainit(ips_ha_t *);
337     static int ips_map_status(ips_ha_t *, ips_scb_t *, ips_stat_t *);
338     static int ips_send(ips_ha_t *, ips_scb_t *, ips_scb_callback);
339     static int ips_send_wait(ips_ha_t *, ips_scb_t *, int, int);
340     static int ips_send_cmd(ips_ha_t *, ips_scb_t *);
341     static int ips_online(ips_ha_t *, ips_scb_t *);
342     static int ips_inquiry(ips_ha_t *, ips_scb_t *);
343     static int ips_rdcap(ips_ha_t *, ips_scb_t *);
344     static int ips_msense(ips_ha_t *, ips_scb_t *);
345     static int ips_reqsen(ips_ha_t *, ips_scb_t *);
346     static int ips_allocatescbs(ips_ha_t *);
347     static int ips_reset_copperhead(ips_ha_t *);
348     static int ips_reset_copperhead_memio(ips_ha_t *);
349     static int ips_reset_morpheus(ips_ha_t *);
350     static int ips_issue_copperhead(ips_ha_t *, ips_scb_t *);
351     static int ips_issue_copperhead_memio(ips_ha_t *, ips_scb_t *);
352     static int ips_issue_i2o(ips_ha_t *, ips_scb_t *);
353     static int ips_issue_i2o_memio(ips_ha_t *, ips_scb_t *);
354     static int ips_isintr_copperhead(ips_ha_t *);
355     static int ips_isintr_copperhead_memio(ips_ha_t *);
356     static int ips_isintr_morpheus(ips_ha_t *);
357     static int ips_wait(ips_ha_t *, int, int);
358     static int ips_write_driver_status(ips_ha_t *, int);
359     static int ips_read_adapter_status(ips_ha_t *, int);
360     static int ips_read_subsystem_parameters(ips_ha_t *, int);
361     static int ips_read_config(ips_ha_t *, int);
362     static int ips_clear_adapter(ips_ha_t *, int);
363     static int ips_readwrite_page5(ips_ha_t *, int, int);
364     static int ips_init_copperhead(ips_ha_t *);
365     static int ips_init_copperhead_memio(ips_ha_t *);
366     static int ips_init_morpheus(ips_ha_t *);
367     static int ips_isinit_copperhead(ips_ha_t *);
368     static int ips_isinit_copperhead_memio(ips_ha_t *);
369     static int ips_isinit_morpheus(ips_ha_t *);
370     static u32 ips_statupd_copperhead(ips_ha_t *);
371     static u32 ips_statupd_copperhead_memio(ips_ha_t *);
372     static u32 ips_statupd_morpheus(ips_ha_t *);
373     static void ips_flash_bios_section(void *);
374     static void ips_flash_bios_segment(void *);
375     static void ips_scheduled_flash_bios(void *);
376     static void ips_create_nvrampage5(ips_ha_t *, IPS_NVRAM_P5 *);
377     static void ips_get_bios_version(ips_ha_t *, int);
378     static void ips_identify_controller(ips_ha_t *);
379     static void ips_select_queue_depth(struct Scsi_Host *, Scsi_Device *);
380     static void ips_chkstatus(ips_ha_t *, IPS_STATUS *);
381     static void ips_enable_int_copperhead(ips_ha_t *);
382     static void ips_enable_int_copperhead_memio(ips_ha_t *);
383     static void ips_enable_int_morpheus(ips_ha_t *);
384     static void ips_intr_copperhead(ips_ha_t *);
385     static void ips_intr_morpheus(ips_ha_t *);
386     static void ips_next(ips_ha_t *, int);
387     static void ipsintr_blocking(ips_ha_t *, struct ips_scb *);
388     static void ipsintr_done(ips_ha_t *, struct ips_scb *);
389     static void ips_done(ips_ha_t *, ips_scb_t *);
390     static void ips_free(ips_ha_t *);
391     static void ips_init_scb(ips_ha_t *, ips_scb_t *);
392     static void ips_freescb(ips_ha_t *, ips_scb_t *);
393     static void ips_statinit(ips_ha_t *);
394     static void ips_statinit_memio(ips_ha_t *);
395     static void ips_fix_ffdc_time(ips_ha_t *, ips_scb_t *, time_t);
396     static void ips_ffdc_reset(ips_ha_t *, int);
397     static void ips_ffdc_time(ips_ha_t *, int);
398     static ips_scb_t * ips_getscb(ips_ha_t *);
399     static inline void ips_putq_scb_head(ips_scb_queue_t *, ips_scb_t *);
400     static inline void ips_putq_scb_tail(ips_scb_queue_t *, ips_scb_t *);
401     static inline ips_scb_t * ips_removeq_scb_head(ips_scb_queue_t *);
402     static inline ips_scb_t * ips_removeq_scb(ips_scb_queue_t *, ips_scb_t *);
403     static inline void ips_putq_wait_head(ips_wait_queue_t *, Scsi_Cmnd *);
404     static inline void ips_putq_wait_tail(ips_wait_queue_t *, Scsi_Cmnd *);
405     static inline Scsi_Cmnd * ips_removeq_wait_head(ips_wait_queue_t *);
406     static inline Scsi_Cmnd * ips_removeq_wait(ips_wait_queue_t *, Scsi_Cmnd *);
407     static inline void ips_putq_copp_head(ips_copp_queue_t *, ips_copp_wait_item_t *);
408     static inline void ips_putq_copp_tail(ips_copp_queue_t *, ips_copp_wait_item_t *);
409     static inline ips_copp_wait_item_t * ips_removeq_copp(ips_copp_queue_t *, ips_copp_wait_item_t *);
410     static inline ips_copp_wait_item_t * ips_removeq_copp_head(ips_copp_queue_t *);
411     static int ips_erase_bios(ips_ha_t *);
412     static int ips_program_bios(ips_ha_t *, char *, u32, u32);
413     static int ips_verify_bios(ips_ha_t *, char *, u32, u32);
414     static int ips_erase_bios_memio(ips_ha_t *);
415     static int ips_program_bios_memio(ips_ha_t *, char *, u32, u32);
416     static int ips_verify_bios_memio(ips_ha_t *, char *, u32, u32);
417     
418     #ifndef NO_IPS_CMDLINE
419     static int ips_is_passthru(Scsi_Cmnd *);
420     static int ips_make_passthru(ips_ha_t *, Scsi_Cmnd *, ips_scb_t *, int);
421     static int ips_usrcmd(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
422     static int ips_newusrcmd(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
423     static void ips_cleanup_passthru(ips_ha_t *, ips_scb_t *);
424     #endif
425     
426     int  ips_proc_info(char *, char **, off_t, int, int, int);
427     static int ips_host_info(ips_ha_t *, char *, off_t, int);
428     static void copy_mem_info(IPS_INFOSTR *, char *, int);
429     static int copy_info(IPS_INFOSTR *, char *, ...);
430     
431     /*--------------------------------------------------------------------------*/
432     /* Exported Functions                                                       */
433     /*--------------------------------------------------------------------------*/
434     
435     /****************************************************************************/
436     /*                                                                          */
437     /* Routine Name: ips_setup                                                  */
438     /*                                                                          */
439     /* Routine Description:                                                     */
440     /*                                                                          */
441     /*   setup parameters to the driver                                         */
442     /*                                                                          */
443     /****************************************************************************/
444     #if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,13)
445     static int
446     ips_setup(char *ips_str) {
447     #else
448     void
449     ips_setup(char *ips_str, int *dummy) {
450     #endif
451        int        i;
452        char      *p;
453        char      *key;
454        char      *value;
455        char       tokens[3] = {',', '.', 0};
456        IPS_OPTION options[] = {
457           {"noreset", &ips_resetcontroller, 0},
458     #ifdef IPS_DEBUG
459           {"debug", &ips_debug, 1},
460     #endif
461           {"noi2o", &ips_force_i2o, 0},
462           {"nommap", &ips_force_memio, 0},
463           {"nocmdline", &ips_cmdline, 0},
464           {"ioctlsize", &ips_ioctlsize, IPS_IOCTL_SIZE},
465           {"cdboot", &ips_cd_boot, 0},
466        };
467     
468        METHOD_TRACE("ips_setup", 1);
469     
470        for (key = strtok(ips_str, tokens); key; key = strtok(NULL, tokens)) {
471           p = key;
472     
473           /* Search for value */
474           while ((p) && (*p != ':'))
475              p++;
476     
477           if (p) {
478              *p = '\0';
479              value = p+1;
480           } else
481              value = NULL;
482     
483           /*
484            * We now have key/value pairs.
485            * Update the variables
486            */
487           for (i = 0; i < (sizeof(options) / sizeof(options[0])); i++) {
488              if (strnicmp(key, options[i].option_name, strlen(ips_str)) == 0) {
489                 if (value)
490                    *options[i].option_flag = simple_strtoul(value, NULL, 0);
491                 else
492                    *options[i].option_flag = options[i].option_value;
493     
494                 break;
495              }
496           }
497        }
498     #if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,13)
499        return (1);
500     #endif
501     }
502     
503     #if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,13)
504     __setup("ips=", ips_setup);
505     #endif
506     
507     /****************************************************************************/
508     /*                                                                          */
509     /* Routine Name: ips_detect                                                 */
510     /*                                                                          */
511     /* Routine Description:                                                     */
512     /*                                                                          */
513     /*   Detect and initialize the driver                                       */
514     /*                                                                          */
515     /* NOTE: this routine is called under the io_request_lock spinlock          */
516     /*                                                                          */
517     /****************************************************************************/
518     int
519     ips_detect(Scsi_Host_Template *SHT) {
520        struct Scsi_Host *sh;
521        ips_ha_t         *ha;
522        u32               io_addr;
523        u32               mem_addr;
524        u32               io_len;
525        u32               mem_len;
526        u16               planer;
527        u8                revision_id;
528        u8                bus;
529        u8                func;
530        u8                irq;
531        u16               deviceID[2];
532        u16               subdevice_id;
533        int               i;
534        int               j;
535        u32               count;
536        char             *ioremap_ptr;
537        char             *mem_ptr;
538        struct pci_dev   *dev[2];
539        struct pci_dev   *morpheus = NULL;
540        struct pci_dev   *trombone = NULL;
541     #if LINUX_VERSION_CODE < LinuxVersionCode(2,3,14)
542        u32               currbar;
543        u32               maskbar;
544        u8                barnum;
545     #endif
546     
547        METHOD_TRACE("ips_detect", 1);
548     
549     #ifdef MODULE
550        if (ips)
551     #if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,13)
552           ips_setup(ips);
553     #else
554           ips_setup(ips, NULL);
555     #endif
556     #endif
557     
558        /* If Booting from the ServeRAID Manager CD, Allocate a large Flash  */
559        /* Buffer ( so we won't need to allocate one for each adapter ).     */
560         if ( ips_cd_boot ) {                                                            
561           ips_FlashData = ( char * ) __get_free_pages( GFP_KERNEL, 7 ); 
562           if (ips_FlashData == NULL) {
563              /* The validity of this pointer is checked in ips_make_passthru() before it is used */
564              printk( KERN_WARNING "ERROR: Can't Allocate Large Buffer for Flashing\n" );
565           }
566        }                                                                               
567     
568        SHT->proc_info = ips_proc_info;
569     #if LINUX_VERSION_CODE < LinuxVersionCode(2,3,27)
570        SHT->proc_dir = &proc_scsi_ips;
571     #else
572        SHT->proc_name = "ips";
573     #endif
574     
575     #if defined(CONFIG_PCI)
576     
577        /* initalize number of controllers */
578        ips_num_controllers = 0;
579        ips_next_controller = 0;
580        ips_released_controllers = 0;
581     
582        if (!pci_present())
583           return (0);
584     
585        morpheus = pci_find_device(IPS_VENDORID, IPS_DEVICEID_MORPHEUS, morpheus);
586        trombone = pci_find_device(IPS_VENDORID, IPS_DEVICEID_COPPERHEAD, trombone);
587     
588        /* determine which controller to probe first */
589        if (!morpheus) {
590           /* we only have trombone */
591           dev[0] = trombone;
592           dev[1] = NULL;
593           deviceID[0] = IPS_DEVICEID_COPPERHEAD;
594        } else if (!trombone) {
595           /* we only have morpheus */
596           dev[0] = morpheus;
597           dev[1] = NULL;
598           deviceID[0] = IPS_DEVICEID_MORPHEUS;
599        } else {
600           /* we have both in the system */
601           if (trombone->bus < morpheus->bus) {
602              dev[0] = trombone;
603              dev[1] = morpheus;
604              deviceID[0] = IPS_DEVICEID_COPPERHEAD;
605              deviceID[1] = IPS_DEVICEID_MORPHEUS;
606           } else if (trombone->bus > morpheus->bus) {
607              dev[0] = morpheus;
608              dev[1] = trombone;
609              deviceID[0] = IPS_DEVICEID_MORPHEUS;
610              deviceID[1] = IPS_DEVICEID_COPPERHEAD;
611           } else {
612              /* further detection required */
613              if (trombone->devfn < morpheus->devfn) {
614                 dev[0] = trombone;
615                 dev[1] = morpheus;
616                 deviceID[0] = IPS_DEVICEID_COPPERHEAD;
617                 deviceID[1] = IPS_DEVICEID_MORPHEUS;
618              } else {
619                 dev[0] = morpheus;
620                 dev[1] = trombone;
621                 deviceID[0] = IPS_DEVICEID_MORPHEUS;
622                 deviceID[1] = IPS_DEVICEID_COPPERHEAD;
623              }
624           }
625        }
626     
627        /* Now scan the controllers */
628        for (i = 0; i < 2; i++) {
629           if (!dev[i])
630              break;
631     
632           do {
633              if (ips_next_controller >= IPS_MAX_ADAPTERS)
634                 break;
635     
636     #if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
637              if (pci_enable_device(dev[i]))
638                 break;
639     #endif
640     
641              /* stuff that we get in dev */
642              irq = dev[i]->irq;
643              bus = dev[i]->bus->number;
644              func = dev[i]->devfn;
645     
646              /* Init MEM/IO addresses to 0 */
647              mem_addr = 0;
648              io_addr = 0;
649              mem_len = 0;
650              io_len = 0;
651     
652              for (j = 0; j < 2; j++) {
653     #if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
654                 if (!pci_resource_start(dev[i], j))
655                    break;
656     
657                 if (pci_resource_flags(dev[i], j) & IORESOURCE_IO) {
658                    io_addr = pci_resource_start(dev[i], j);
659                    io_len = pci_resource_len(dev[i], j);
660                 } else {
661                    mem_addr = pci_resource_start(dev[i], j);
662                    mem_len = pci_resource_len(dev[i], j);
663                 }
664     #elif LINUX_VERSION_CODE >= LinuxVersionCode(2,3,14)
665                 if (!dev[i]->resource[j].start)
666                    break;
667     
668                 if ((dev[i]->resource[j].start & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) {
669                    io_addr = dev[i]->resource[j].start;
670                    io_len = dev[i]->resource[j].end - dev[i]->resource[j].start + 1;
671                 } else {
672                    mem_addr = dev[i]->resource[j].start;
673                    mem_len = dev[i]->resource[j].end - dev[i]->resource[j].start + 1;
674                 }
675     #else
676                 if (!dev[i]->base_address[j])
677                    break;
678     
679                 if ((dev[i]->base_address[j] & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) {
680                    barnum = PCI_BASE_ADDRESS_0 + (j * 4);
681                    io_addr = dev[i]->base_address[j] & PCI_BASE_ADDRESS_IO_MASK;
682     
683                    /* Get Size */
684                    pci_read_config_dword(dev[i], barnum, &currbar);
685                    pci_write_config_dword(dev[i], barnum, ~0);
686                    pci_read_config_dword(dev[i], barnum, &maskbar);
687                    pci_write_config_dword(dev[i], barnum, currbar);
688     
689                    io_len = ~(maskbar & PCI_BASE_ADDRESS_IO_MASK) + 1;
690                 } else {
691                    barnum = PCI_BASE_ADDRESS_0 + (j * 4);
692                    mem_addr = dev[i]->base_address[j] & PCI_BASE_ADDRESS_MEM_MASK;
693     
694                    /* Get Size */
695                    pci_read_config_dword(dev[i], barnum, &currbar);
696                    pci_write_config_dword(dev[i], barnum, ~0);
697                    pci_read_config_dword(dev[i], barnum, &maskbar);
698                    pci_write_config_dword(dev[i], barnum, currbar);
699     
700                    mem_len = ~(maskbar & PCI_BASE_ADDRESS_MEM_MASK) + 1;
701                 }
702     #endif
703              }
704     
705              /* setup memory mapped area (if applicable) */
706              if (mem_addr) {
707                 u32 base;
708                 u32 offs;
709     
710                 DEBUG_VAR(1, "(%s%d) detect, Memory region %x, size: %d",
711                           ips_name, ips_next_controller, mem_addr, mem_len);
712     
713     #if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,17)
714                 if (check_mem_region(mem_addr, mem_len)) {
715                    /* Couldn't allocate io space */
716                    printk(KERN_WARNING "(%s%d) couldn't allocate IO space %x len %d.\n",
717                           ips_name, ips_next_controller, io_addr, io_len);
718     
719                    ips_next_controller++;
720     
721                    continue;
722                 }
723     
724                 request_mem_region(mem_addr, mem_len, "ips");
725     #endif
726     
727                 base = mem_addr & PAGE_MASK;
728                 offs = mem_addr - base;
729     
730                 ioremap_ptr = ioremap(base, PAGE_SIZE);
731                 mem_ptr = ioremap_ptr + offs;
732              } else {
733                 ioremap_ptr = NULL;
734                 mem_ptr = NULL;
735              }
736     
737              /* setup I/O mapped area (if applicable) */
738              if (io_addr) {
739                 DEBUG_VAR(1, "(%s%d) detect, IO region %x, size: %d",
740                           ips_name, ips_next_controller, io_addr, io_len);
741     
742                 if (check_region(io_addr, io_len)) {
743                    /* Couldn't allocate io space */
744                    printk(KERN_WARNING "(%s%d) couldn't allocate IO space %x len %d.\n",
745                           ips_name, ips_next_controller, io_addr, io_len);
746     
747                    ips_next_controller++;
748     
749                    continue;
750                 }
751     
752                 request_region(io_addr, io_len, "ips");
753              }
754     
755              /* get planer status */
756              if (pci_read_config_word(dev[i], 0x04, &planer)) {
757                 printk(KERN_WARNING "(%s%d) can't get planer status.\n",
758                        ips_name, ips_next_controller);
759     
760                 ips_next_controller++;
761     
762                 continue;
763              }
764     
765              /* check to see if an onboard planer controller is disabled */
766              if (!(planer & 0x000C)) {
767     
768                 DEBUG_VAR(1, "(%s%d) detect, Onboard ServeRAID disabled by BIOS",
769                           ips_name, ips_next_controller);
770     
771                 ips_next_controller++;
772     
773                 continue;
774              }
775     
776              DEBUG_VAR(1, "(%s%d) detect bus %d, func %x, irq %d, io %x, mem: %x, ptr: %x",
777                        ips_name, ips_next_controller, bus, func, irq, io_addr, mem_addr, (u32) mem_ptr);
778     
779              /* get the revision ID */
780              if (pci_read_config_byte(dev[i], 0x08, &revision_id)) {
781                 printk(KERN_WARNING "(%s%d) can't get revision id.\n",
782                        ips_name, ips_next_controller);
783     
784                 ips_next_controller++;
785     
786                 continue;
787              }
788     
789     #if LINUX_VERSION_CODE < LinuxVersionCode(2,3,15)
790              /* get the subdevice id */
791              if (pci_read_config_word(dev[i], 0x2e, &subdevice_id)) {
792                 printk(KERN_WARNING "(%s%d) can't get subdevice id.\n",
793                        ips_name, ips_next_controller);
794     
795                 ips_next_controller++;
796     
797                 continue;
798              }
799     #else
800              subdevice_id = dev[i]->subsystem_device;
801     #endif
802     
803              /* found a controller */
804              sh = scsi_register(SHT, sizeof(ips_ha_t));
805     
806              if (sh == NULL) {
807                 printk(KERN_WARNING "(%s%d) Unable to register controller with SCSI subsystem - skipping controller\n",
808                        ips_name, ips_next_controller);
809     
810                 ips_next_controller++;
811     
812                 continue;
813              }
814     
815              ha = IPS_HA(sh);
816              memset(ha, 0, sizeof(ips_ha_t));
817     
818              /* Initialize spin lock */
819              spin_lock_init(&ha->scb_lock);
820              spin_lock_init(&ha->copp_lock);
821              spin_lock_init(&ha->ips_lock);
822              spin_lock_init(&ha->copp_waitlist.lock);
823              spin_lock_init(&ha->scb_waitlist.lock);
824              spin_lock_init(&ha->scb_activelist.lock);
825     
826              ips_sh[ips_next_controller] = sh;
827              ips_ha[ips_next_controller] = ha;
828              ips_num_controllers++;
829              ha->active = 1;
830     
831              ha->enq = kmalloc(sizeof(IPS_ENQ), GFP_ATOMIC);
832     
833              if (!ha->enq) {
834                 printk(KERN_WARNING "(%s%d) Unable to allocate host inquiry structure - skipping contoller\n",
835                        ips_name, ips_next_controller);
836     
837                 ha->active = 0;
838                 ips_free(ha);
839                 scsi_unregister(sh);
840                 ips_ha[ips_next_controller] = 0;
841                 ips_sh[ips_next_controller] = 0;
842                 ips_next_controller++;
843                 ips_num_controllers--;
844     
845                 continue;
846              }
847     
848              ha->adapt = kmalloc(sizeof(IPS_ADAPTER), GFP_ATOMIC);
849     
850              if (!ha->adapt) {
851                 printk(KERN_WARNING "(%s%d) Unable to allocate host adapt structure - skipping controller\n",
852                        ips_name, ips_next_controller);
853     
854                 ha->active = 0;
855                 ips_free(ha);
856                 scsi_unregister(sh);
857                 ips_ha[ips_next_controller] = 0;
858                 ips_sh[ips_next_controller] = 0;
859                 ips_next_controller++;
860                 ips_num_controllers--;
861     
862                 continue;
863              }
864     
865              ha->conf = kmalloc(sizeof(IPS_CONF), GFP_ATOMIC);
866     
867              if (!ha->conf) {
868                 printk(KERN_WARNING "(%s%d) Unable to allocate host conf structure - skipping controller\n",
869                        ips_name, ips_next_controller);
870     
871                 ha->active = 0;
872                 ips_free(ha);
873                 scsi_unregister(sh);
874                 ips_ha[ips_next_controller] = 0;
875                 ips_sh[ips_next_controller] = 0;
876                 ips_next_controller++;
877                 ips_num_controllers--;
878     
879                 continue;
880              }
881     
882              ha->nvram = kmalloc(sizeof(IPS_NVRAM_P5), GFP_ATOMIC);
883     
884              if (!ha->nvram) {
885                 printk(KERN_WARNING "(%s%d) Unable to allocate host nvram structure - skipping controller\n",
886                        ips_name, ips_next_controller);
887     
888                 ha->active = 0;
889                 ips_free(ha);
890                 scsi_unregister(sh);
891                 ips_ha[ips_next_controller] = 0;
892                 ips_sh[ips_next_controller] = 0;
893                 ips_next_controller++;
894                 ips_num_controllers--;
895     
896                 continue;
897              }
898     
899              ha->subsys = kmalloc(sizeof(IPS_SUBSYS), GFP_ATOMIC);
900     
901              if (!ha->subsys) {
902                 printk(KERN_WARNING "(%s%d) Unable to allocate host subsystem structure - skipping controller\n",
903                        ips_name, ips_next_controller);
904     
905                 ha->active = 0;
906                 ips_free(ha);
907                 scsi_unregister(sh);
908                 ips_ha[ips_next_controller] = 0;
909                 ips_sh[ips_next_controller] = 0;
910                 ips_next_controller++;
911                 ips_num_controllers--;
912     
913                 continue;
914              }
915     
916              ha->dummy = kmalloc(sizeof(IPS_IO_CMD), GFP_ATOMIC);
917     
918              if (!ha->dummy) {
919                 printk(KERN_WARNING "(%s%d) Unable to allocate host dummy structure - skipping controller\n",
920                        ips_name, ips_next_controller);
921     
922                 ha->active = 0;
923                 ips_free(ha);
924                 scsi_unregister(sh);
925                 ips_ha[ips_next_controller] = 0;
926                 ips_sh[ips_next_controller] = 0;
927                 ips_next_controller++;
928                 ips_num_controllers--;
929     
930                 continue;
931              }
932     
933              for (count = PAGE_SIZE, ha->ioctl_order = 0;
934                   count < ips_ioctlsize;
935                   ha->ioctl_order++, count <<= 1);
936     
937              ha->ioctl_data = (char *) __get_free_pages(GFP_KERNEL, ha->ioctl_order);
938              ha->ioctl_datasize = count;
939     
940              if (!ha->ioctl_data) {
941                 printk(KERN_WARNING "(%s%d) Unable to allocate ioctl data\n",
942                        ips_name, ips_next_controller);
943     
944                 ha->ioctl_data = NULL;
945                 ha->ioctl_order = 0;
946                 ha->ioctl_datasize = 0;
947              }
948     
949              /* Store away needed values for later use */
950              sh->io_port = io_addr;
951              sh->n_io_port = io_addr ? 255 : 0;
952              sh->unique_id = (io_addr) ? io_addr : mem_addr;
953              sh->irq = irq;
954              sh->select_queue_depths = ips_select_queue_depth;
955              sh->sg_tablesize = sh->hostt->sg_tablesize;
956              sh->can_queue = sh->hostt->can_queue;
957              sh->cmd_per_lun = sh->hostt->cmd_per_lun;
958              sh->unchecked_isa_dma = sh->hostt->unchecked_isa_dma;
959              sh->use_clustering = sh->hostt->use_clustering;
960     /***** Implement the following if it gets into a future kernel
961     #if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,4)
962              sh->max_sectors = 128;
963     #endif
964     ******/
965     
966     #if LINUX_VERSION_CODE < LinuxVersionCode(2,3,32)
967              sh->wish_block = FALSE;
968     #endif
969     
970              /* Store info in HA structure */
971              ha->irq = irq;
972              ha->io_addr = io_addr;
973              ha->io_len = io_len;
974              ha->mem_addr = mem_addr;
975              ha->mem_len = mem_len;
976              ha->mem_ptr = mem_ptr;
977              ha->ioremap_ptr = ioremap_ptr;
978              ha->host_num = ips_next_controller;
979              ha->revision_id = revision_id;
980              ha->slot_num = PCI_SLOT(dev[i]->devfn);
981              ha->device_id = deviceID[i];
982              ha->subdevice_id = subdevice_id;
983              ha->pcidev = dev[i];
984     
985              /*
986               * Setup Functions
987               */
988              if (IPS_IS_MORPHEUS(ha)) {
989                 /* morpheus */
990                 ha->func.isintr = ips_isintr_morpheus;
991                 ha->func.isinit = ips_isinit_morpheus;
992                 ha->func.issue = ips_issue_i2o_memio;
993                 ha->func.init = ips_init_morpheus;
994                 ha->func.statupd = ips_statupd_morpheus;
995                 ha->func.reset = ips_reset_morpheus;
996                 ha->func.intr = ips_intr_morpheus;
997                 ha->func.enableint = ips_enable_int_morpheus;
998              } else if (IPS_USE_MEMIO(ha)) {
999                 /* copperhead w/MEMIO */
1000                 ha->func.isintr = ips_isintr_copperhead_memio;
1001                 ha->func.isinit = ips_isinit_copperhead_memio;
1002                 ha->func.init = ips_init_copperhead_memio;
1003                 ha->func.statupd = ips_statupd_copperhead_memio;
1004                 ha->func.statinit = ips_statinit_memio;
1005                 ha->func.reset = ips_reset_copperhead_memio;
1006                 ha->func.intr = ips_intr_copperhead;
1007                 ha->func.erasebios = ips_erase_bios_memio;
1008                 ha->func.programbios = ips_program_bios_memio;
1009                 ha->func.verifybios = ips_verify_bios_memio;
1010                 ha->func.enableint = ips_enable_int_copperhead_memio;
1011     
1012                 if (IPS_USE_I2O_DELIVER(ha))
1013                    ha->func.issue = ips_issue_i2o_memio;
1014                 else
1015                    ha->func.issue = ips_issue_copperhead_memio;
1016              } else {
1017                 /* copperhead */
1018                 ha->func.isintr = ips_isintr_copperhead;
1019                 ha->func.isinit = ips_isinit_copperhead;
1020                 ha->func.init = ips_init_copperhead;
1021                 ha->func.statupd = ips_statupd_copperhead;
1022                 ha->func.statinit = ips_statinit;
1023                 ha->func.reset = ips_reset_copperhead;
1024                 ha->func.intr = ips_intr_copperhead;
1025                 ha->func.erasebios = ips_erase_bios;
1026                 ha->func.programbios = ips_program_bios;
1027                 ha->func.verifybios = ips_verify_bios;
1028                 ha->func.enableint = ips_enable_int_copperhead;
1029     
1030                 if (IPS_USE_I2O_DELIVER(ha))
1031                    ha->func.issue = ips_issue_i2o;
1032                 else
1033                    ha->func.issue = ips_issue_copperhead;
1034              }
1035     
1036              /*
1037               * Initialize the card if it isn't already
1038               */
1039              if (!(*ha->func.isinit)(ha)) {
1040                 if (!(*ha->func.init)(ha)) {
1041                    /*
1042                     * Initialization failed
1043                     */
1044                    printk(KERN_WARNING "(%s%d) unable to initialize controller - skipping controller\n",
1045                           ips_name, ips_next_controller);
1046     
1047                    ha->active = 0;
1048                    ips_free(ha);
1049                    scsi_unregister(sh);
1050                    ips_ha[ips_next_controller] = 0;
1051                    ips_sh[ips_next_controller] = 0;
1052                    ips_next_controller++;
1053                    ips_num_controllers--;
1054     
1055                    continue;
1056                 }
1057              }
1058     
1059              /* install the interrupt handler */
1060              if (request_irq(irq, do_ipsintr, SA_SHIRQ, ips_name, ha)) {
1061                 printk(KERN_WARNING "(%s%d) unable to install interrupt handler - skipping controller\n",
1062                        ips_name, ips_next_controller);
1063     
1064                 ha->active = 0;
1065                 ips_free(ha);
1066                 scsi_unregister(sh);
1067                 ips_ha[ips_next_controller] = 0;
1068                 ips_sh[ips_next_controller] = 0;
1069                 ips_next_controller++;
1070                 ips_num_controllers--;
1071     
1072                 continue;
1073              }
1074     
1075              /*
1076               * Allocate a temporary SCB for initialization
1077               */
1078              ha->scbs = (ips_scb_t *) kmalloc(sizeof(ips_scb_t), GFP_ATOMIC);
1079              if (!ha->scbs) {
1080                 /* couldn't allocate a temp SCB */
1081                 printk(KERN_WARNING "(%s%d) unable to allocate CCBs - skipping contoller\n",
1082                        ips_name, ips_next_controller);
1083     
1084                 ha->active = 0;
1085                 ips_free(ha);
1086                 scsi_unregister(sh);
1087                 ips_ha[ips_next_controller] = 0;
1088                 ips_sh[ips_next_controller] = 0;
1089                 free_irq(ha->irq, ha);
1090                 ips_next_controller++;
1091                 ips_num_controllers--;
1092     
1093                 continue;
1094              }
1095     
1096              memset(ha->scbs, 0, sizeof(ips_scb_t));
1097              ha->scbs->sg_list = (IPS_SG_LIST *) kmalloc(sizeof(IPS_SG_LIST) * IPS_MAX_SG, GFP_ATOMIC);
1098              if (!ha->scbs->sg_list) {
1099                 /* couldn't allocate a temp SCB S/G list */
1100                 printk(KERN_WARNING "(%s%d) unable to allocate CCBs - skipping contoller\n",
1101                        ips_name, ips_next_controller);
1102     
1103                 ha->active = 0;
1104                 ips_free(ha);
1105                 scsi_unregister(sh);
1106                 ips_ha[ips_next_controller] = 0;
1107                 ips_sh[ips_next_controller] = 0;
1108                 free_irq(ha->irq, ha);
1109                 ips_next_controller++;
1110                 ips_num_controllers--;
1111     
1112                 continue;
1113              }
1114     
1115              ha->max_cmds = 1;
1116     
1117              ips_next_controller++;
1118           } while ((dev[i] = pci_find_device(IPS_VENDORID, deviceID[i], dev[i])));
1119        }
1120     
1121        /*
1122         * Do Phase 2 Initialization
1123         * Controller init
1124         */
1125        for (i = 0; i < ips_next_controller; i++) {
1126     
1127           if (ips_ha[i] == 0) {
1128              printk(KERN_WARNING "(%s%d) ignoring bad controller\n",
1129                     ips_name, i);
1130              continue;
1131           }
1132     
1133           ha = ips_ha[i];
1134           sh = ips_sh[i];
1135     
1136           if (!ha->active) {
1137              scsi_unregister(sh);
1138              ips_ha[i] = NULL;
1139              ips_sh[i] = NULL;
1140     
1141              continue;
1142           }
1143     
1144           if (!ips_hainit(ha)) {
1145              printk(KERN_WARNING "(%s%d) unable to initialize controller - skipping\n",
1146                     ips_name, i);
1147     
1148              ha->active = 0;
1149              ips_free(ha);
1150              free_irq(ha->irq, ha);
1151              scsi_unregister(sh);
1152              ips_ha[i] = NULL;
1153              ips_sh[i] = NULL;
1154              ips_num_controllers--;
1155     
1156              continue;
1157           }
1158     
1159           /*
1160            * Free the temporary SCB
1161            */
1162           kfree(ha->scbs->sg_list);
1163           kfree(ha->scbs);
1164           ha->scbs = NULL;
1165     
1166           /* allocate CCBs */
1167           if (!ips_allocatescbs(ha)) {
1168              printk(KERN_WARNING "(%s%d) unable to allocate CCBs - skipping contoller\n",
1169                     ips_name, i);
1170     
1171              ha->active = 0;
1172              ips_free(ha);
1173              free_irq(ha->irq, ha);
1174              scsi_unregister(sh);
1175              ips_ha[i] = NULL;
1176              ips_sh[i] = NULL;
1177              ips_num_controllers--;
1178     
1179              continue;
1180           }
1181     
1182           /* finish setting values */
1183           sh->max_id = ha->ntargets;
1184           sh->max_lun = ha->nlun;
1185           sh->max_channel = ha->nbus - 1;
1186           sh->can_queue = ha->max_cmds-1;
1187        }
1188     
1189        if (ips_num_controllers > 0)
1190           register_reboot_notifier(&ips_notifier);
1191     
1192        return (ips_num_controllers);
1193     
1194     #else
1195     
1196        /* No PCI -- No ServeRAID */
1197        return (0);
1198     #endif /* CONFIG_PCI */
1199     }
1200     
1201     /****************************************************************************/
1202     /*                                                                          */
1203     /* Routine Name: ips_release                                                */
1204     /*                                                                          */
1205     /* Routine Description:                                                     */
1206     /*                                                                          */
1207     /*   Remove a driver                                                        */
1208     /*                                                                          */
1209     /****************************************************************************/
1210     int
1211     ips_release(struct Scsi_Host *sh) {
1212        ips_scb_t *scb;
1213        ips_ha_t  *ha;
1214        int        i;
1215     
1216        METHOD_TRACE("ips_release", 1);
1217     
1218        for (i = 0; i < IPS_MAX_ADAPTERS && ips_sh[i] != sh; i++);
1219     
1220        if (i == IPS_MAX_ADAPTERS)
1221           panic("(%s) release, invalid Scsi_Host pointer.\n",
1222                 ips_name);
1223     
1224        ha = IPS_HA(sh);
1225     
1226        if (!ha)
1227           return (FALSE);
1228     
1229        /* flush the cache on the controller */
1230        scb = &ha->scbs[ha->max_cmds-1];
1231     
1232        ips_init_scb(ha, scb);
1233     
1234        scb->timeout = ips_cmd_timeout;
1235        scb->cdb[0] = IPS_CMD_FLUSH;
1236     
1237        scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH;
1238        scb->cmd.flush_cache.command_id = IPS_COMMAND_ID(ha, scb);
1239        scb->cmd.flush_cache.state = IPS_NORM_STATE;
1240        scb->cmd.flush_cache.reserved = 0;
1241        scb->cmd.flush_cache.reserved2 = 0;
1242        scb->cmd.flush_cache.reserved3 = 0;
1243        scb->cmd.flush_cache.reserved4 = 0;
1244     
1245        printk("(%s%d) Flushing Cache.\n", ips_name, ha->host_num);
1246     
1247        /* send command */
1248        if (ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_ON) == IPS_FAILURE)
1249           printk("(%s%d) Incomplete Flush.\n", ips_name, ha->host_num);
1250     
1251        printk("(%s%d) Flushing Complete.\n", ips_name, ha->host_num);
1252     
1253        ips_sh[i] = NULL;
1254        ips_ha[i] = NULL;
1255     
1256        /* free extra memory */
1257        ips_free(ha);
1258     
1259        /* Free I/O Region */
1260        if (ha->io_addr)
1261           release_region(ha->io_addr, ha->io_len);
1262     
1263     #if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,17)
1264        if (ha->mem_addr)
1265           release_mem_region(ha->mem_addr, ha->mem_len);
1266     #endif
1267     
1268        /* free IRQ */
1269        free_irq(ha->irq, ha);
1270     
1271        scsi_unregister(sh);
1272     
1273        ips_released_controllers++;
1274     
1275        if (ips_num_controllers == ips_released_controllers)
1276           unregister_reboot_notifier(&ips_notifier);
1277     
1278        return (FALSE);
1279     }
1280     
1281     /****************************************************************************/
1282     /*                                                                          */
1283     /* Routine Name: ips_halt                                                   */
1284     /*                                                                          */
1285     /* Routine Description:                                                     */
1286     /*                                                                          */
1287     /*   Perform cleanup when the system reboots                                */
1288     /*                                                                          */
1289     /****************************************************************************/
1290     static int
1291     ips_halt(struct notifier_block *nb, ulong event, void *buf) {
1292        ips_scb_t *scb;
1293        ips_ha_t  *ha;
1294        int        i;
1295     
1296        if ((event != SYS_RESTART) && (event != SYS_HALT) &&
1297            (event != SYS_POWER_OFF))
1298           return (NOTIFY_DONE);
1299     
1300        for (i = 0; i < ips_next_controller; i++) {
1301           ha = (ips_ha_t *) ips_ha[i];
1302     
1303           if (!ha)
1304              continue;
1305     
1306           if (!ha->active)
1307              continue;
1308     
1309           /* flush the cache on the controller */
1310           scb = &ha->scbs[ha->max_cmds-1];
1311     
1312           ips_init_scb(ha, scb);
1313     
1314           scb->timeout = ips_cmd_timeout;
1315           scb->cdb[0] = IPS_CMD_FLUSH;
1316     
1317           scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH;
1318           scb->cmd.flush_cache.command_id = IPS_COMMAND_ID(ha, scb);
1319           scb->cmd.flush_cache.state = IPS_NORM_STATE;
1320           scb->cmd.flush_cache.reserved = 0;
1321           scb->cmd.flush_cache.reserved2 = 0;
1322           scb->cmd.flush_cache.reserved3 = 0;
1323           scb->cmd.flush_cache.reserved4 = 0;
1324     
1325           printk("(%s%d) Flushing Cache.\n", ips_name, ha->host_num);
1326     
1327           /* send command */
1328           if (ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_ON) == IPS_FAILURE)
1329              printk("(%s%d) Incomplete Flush.\n", ips_name, ha->host_num);
1330           else
1331              printk("(%s%d) Flushing Complete.\n", ips_name, ha->host_num);
1332        }
1333     
1334        unregister_reboot_notifier(&ips_notifier);
1335        return (NOTIFY_OK);
1336     }
1337     
1338     /****************************************************************************/
1339     /*                                                                          */
1340     /* Routine Name: ips_eh_abort                                               */
1341     /*                                                                          */
1342     /* Routine Description:                                                     */
1343     /*                                                                          */
1344     /*   Abort a command (using the new error code stuff)                       */
1345     /*                                                                          */
1346     /****************************************************************************/
1347     int
1348     ips_eh_abort(Scsi_Cmnd *SC) {
1349        ips_ha_t         *ha;
1350        ips_copp_wait_item_t *item;
1351     
1352        METHOD_TRACE("ips_eh_abort", 1);
1353     
1354        if (!SC)
1355           return (FAILED);
1356     
1357        ha = (ips_ha_t *) SC->host->hostdata;
1358     
1359        if (!ha)
1360           return (FAILED);
1361     
1362        if (!ha->active)
1363           return (FAILED);
1364     
1365        if (SC->serial_number != SC->serial_number_at_timeout) {
1366           /* HMM, looks like a bogus command */
1367           DEBUG(1, "Abort called with bogus scsi command");
1368     
1369           return (FAILED);
1370        }
1371     
1372        if (test_and_set_bit(IPS_IN_ABORT, &ha->flags))
1373           return (FAILED);
1374     
1375        /* See if the command is on the copp queue */
1376        IPS_QUEUE_LOCK(&ha->copp_waitlist);
1377        item = ha->copp_waitlist.head;
1378        while ((item) && (item->scsi_cmd != SC))
1379           item = item->next;
1380        IPS_QUEUE_UNLOCK(&ha->copp_waitlist);
1381     
1382        if (item) {
1383           /* Found it */
1384           ips_removeq_copp(&ha->copp_waitlist, item);
1385           clear_bit(IPS_IN_ABORT, &ha->flags);
1386     
1387           return (SUCCESS);
1388        }
1389     
1390        /* See if the command is on the wait queue */
1391        if (ips_removeq_wait(&ha->scb_waitlist, SC)) {
1392           /* command not sent yet */
1393           clear_bit(IPS_IN_ABORT, &ha->flags);
1394     
1395           return (SUCCESS);
1396        } else {
1397           /* command must have already been sent */
1398           clear_bit(IPS_IN_ABORT, &ha->flags);
1399     
1400           return (FAILED);
1401        }
1402     }
1403     
1404     /****************************************************************************/
1405     /*                                                                          */
1406     /* Routine Name: ips_eh_reset                                               */
1407     /*                                                                          */
1408     /* Routine Description:                                                     */
1409     /*                                                                          */
1410     /*   Reset the controller (with new eh error code)                          */
1411     /*                                                                          */
1412     /* NOTE: this routine is called under the io_request_lock spinlock          */
1413     /*                                                                          */
1414     /****************************************************************************/
1415     int
1416     ips_eh_reset(Scsi_Cmnd *SC) {
1417        int                   ret;
1418        int                   i;
1419        unsigned long         cpu_flags;
1420        ips_ha_t             *ha;
1421        ips_scb_t            *scb;
1422        ips_copp_wait_item_t *item;
1423     
1424        METHOD_TRACE("ips_eh_reset", 1);
1425     
1426     #ifdef NO_IPS_RESET
1427        return (FAILED);
1428     #else
1429     
1430        if (!SC) {
1431           DEBUG(1, "Reset called with NULL scsi command");
1432     
1433           return (FAILED);
1434        }
1435     
1436        ha = (ips_ha_t *) SC->host->hostdata;
1437     
1438        if (!ha) {
1439           DEBUG(1, "Reset called with NULL ha struct");
1440     
1441           return (FAILED);
1442        }
1443     
1444        if (!ha->active)
1445           return (FAILED);
1446     
1447        if (test_and_set_bit(IPS_IN_RESET, &ha->flags))
1448           return (FAILED);
1449     
1450        /* See if the command is on the copp queue */
1451        IPS_QUEUE_LOCK(&ha->copp_waitlist);
1452        item = ha->copp_waitlist.head;
1453        while ((item) && (item->scsi_cmd != SC))
1454           item = item->next;
1455        IPS_QUEUE_UNLOCK(&ha->copp_waitlist);
1456     
1457        if (item) {
1458           /* Found it */
1459           ips_removeq_copp(&ha->copp_waitlist, item);
1460           clear_bit(IPS_IN_RESET, &ha->flags);
1461     
1462           return (SUCCESS);
1463        }
1464     
1465        /* See if the command is on the wait queue */
1466        if (ips_removeq_wait(&ha->scb_waitlist, SC)) {
1467           /* command not sent yet */
1468           clear_bit(IPS_IN_RESET, &ha->flags);
1469     
1470           return (SUCCESS);
1471        }
1472     
1473        /*
1474         * command must have already been sent
1475         * reset the controller
1476         */
1477        printk(KERN_NOTICE "(%s%d) Resetting controller.\n",
1478               ips_name, ha->host_num);
1479        ret = (*ha->func.reset)(ha);
1480     
1481        if (!ret) {
1482           Scsi_Cmnd *scsi_cmd;
1483     
1484           printk(KERN_NOTICE
1485                  "(%s%d) Controller reset failed - controller now offline.\n",
1486                  ips_name, ha->host_num);
1487     
1488           /* Now fail all of the active commands */
1489           DEBUG_VAR(1, "(%s%d) Failing active commands",
1490                     ips_name, ha->host_num);
1491     
1492           while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) {
1493              scb->scsi_cmd->result = DID_ERROR << 16;
1494              scb->scsi_cmd->scsi_done(scb->scsi_cmd);
1495              ips_freescb(ha, scb);
1496           }
1497     
1498           /* Now fail all of the pending commands */
1499           DEBUG_VAR(1, "(%s%d) Failing pending commands",
1500                     ips_name, ha->host_num);
1501     
1502           while ((scsi_cmd = ips_removeq_wait_head(&ha->scb_waitlist))) {
1503              scsi_cmd->result = DID_ERROR;
1504              scsi_cmd->scsi_done(scsi_cmd);
1505           }
1506     
1507           ha->active = FALSE;
1508           clear_bit(IPS_IN_RESET, &ha->flags);
1509     
1510           return (FAILED);
1511        }
1512     
1513        if (!ips_clear_adapter(ha, IPS_INTR_IORL)) {
1514           Scsi_Cmnd *scsi_cmd;
1515     
1516           printk(KERN_NOTICE
1517                  "(%s%d) Controller reset failed - controller now offline.\n",
1518                  ips_name, ha->host_num);
1519     
1520           /* Now fail all of the active commands */
1521           DEBUG_VAR(1, "(%s%d) Failing active commands",
1522                     ips_name, ha->host_num);
1523     
1524           while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) {
1525              scb->scsi_cmd->result = DID_ERROR << 16;
1526              scb->scsi_cmd->scsi_done(scb->scsi_cmd);
1527              ips_freescb(ha, scb);
1528           }
1529     
1530           /* Now fail all of the pending commands */
1531           DEBUG_VAR(1, "(%s%d) Failing pending commands",
1532                     ips_name, ha->host_num);
1533     
1534           while ((scsi_cmd = ips_removeq_wait_head(&ha->scb_waitlist))) {
1535              scsi_cmd->result = DID_ERROR << 16;
1536              scsi_cmd->scsi_done(scsi_cmd);
1537           }
1538     
1539           ha->active = FALSE;
1540           clear_bit(IPS_IN_RESET, &ha->flags);
1541     
1542           return (FAILED);
1543        }
1544     
1545        /* FFDC */
1546        if (ha->subsys->param[3] & 0x300000) {
1547           struct timeval tv;
1548     
1549           do_gettimeofday(&tv);
1550           IPS_HA_LOCK(cpu_flags);
1551           ha->last_ffdc = tv.tv_sec;
1552           ha->reset_count++;
1553           IPS_HA_UNLOCK(cpu_flags);
1554           ips_ffdc_reset(ha, IPS_INTR_IORL);
1555        }
1556     
1557        /* Now fail all of the active commands */
1558        DEBUG_VAR(1, "(%s%d) Failing active commands",
1559                  ips_name, ha->host_num);
1560     
1561        while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) {
1562           scb->scsi_cmd->result = (DID_RESET << 16) | (SUGGEST_RETRY << 24);
1563           scb->scsi_cmd->scsi_done(scb->scsi_cmd);
1564           ips_freescb(ha, scb);
1565        }
1566     
1567        /* Reset DCDB active command bits */
1568        for (i = 1; i < ha->nbus; i++)
1569           ha->dcdb_active[i-1] = 0;
1570     
1571        /* Reset the number of active IOCTLs */
1572        IPS_HA_LOCK(cpu_flags);
1573        ha->num_ioctl = 0;
1574        IPS_HA_UNLOCK(cpu_flags);
1575     
1576        clear_bit(IPS_IN_RESET, &ha->flags);
1577     
1578        if (!test_bit(IPS_IN_INTR, &ha->flags)) {
1579           /*
1580            * Only execute the next command when
1581            * we are not being called from the
1582            * interrupt handler.  The interrupt
1583            * handler wants to do this and since
1584            * interrupts are turned off here....
1585            */
1586           ips_next(ha, IPS_INTR_IORL);
1587        }
1588     
1589        return (SUCCESS);
1590     
1591     #endif /* NO_IPS_RESET */
1592     
1593     }
1594     
1595     /****************************************************************************/
1596     /*                                                                          */
1597     /* Routine Name: ips_queue                                                  */
1598     /*                                                                          */
1599     /* Routine Description:                                                     */
1600     /*                                                                          */
1601     /*   Send a command to the controller                                       */
1602     /*                                                                          */
1603     /* NOTE:                                                                    */
1604     /*    Linux obtains io_request_lock before calling this function            */
1605     /*                                                                          */
1606     /****************************************************************************/
1607     int
1608     ips_queue(Scsi_Cmnd *SC, void (*done) (Scsi_Cmnd *)) {
1609        ips_ha_t         *ha;
1610        unsigned long     cpu_flags;
1611        DECLARE_MUTEX_LOCKED(sem);
1612     
1613        METHOD_TRACE("ips_queue", 1);
1614     
1615        ha = (ips_ha_t *) SC->host->hostdata;
1616     
1617        if (!ha)
1618           return (1);
1619     
1620        if (!ha->active)
1621           return (DID_ERROR);
1622     
1623     #ifndef NO_IPS_CMDLINE
1624        if (ips_is_passthru(SC)) {
1625           IPS_QUEUE_LOCK(&ha->copp_waitlist);
1626           if (ha->copp_waitlist.count == IPS_MAX_IOCTL_QUEUE) {
1627              IPS_QUEUE_UNLOCK(&ha->copp_waitlist);
1628              SC->result = DID_BUS_BUSY << 16;
1629              done(SC);
1630     
1631              return (0);
1632           } else {
1633              IPS_QUEUE_UNLOCK(&ha->copp_waitlist);
1634           }
1635        } else {
1636     #endif
1637           IPS_QUEUE_LOCK(&ha->scb_waitlist);
1638           if (ha->scb_waitlist.count == IPS_MAX_QUEUE) {
1639              IPS_QUEUE_UNLOCK(&ha->scb_waitlist);
1640              SC->result = DID_BUS_BUSY << 16;
1641              done(SC);
1642     
1643              return (0);
1644           } else {
1645              IPS_QUEUE_UNLOCK(&ha->scb_waitlist);
1646           }
1647     
1648     #ifndef NO_IPS_CMDLINE
1649        }
1650     #endif
1651     
1652        SC->scsi_done = done;
1653     
1654        DEBUG_VAR(2, "(%s%d): ips_queue: cmd 0x%X (%d %d %d)",
1655                  ips_name,
1656                  ha->host_num,
1657                  SC->cmnd[0],
1658                  SC->channel,
1659                  SC->target,
1660                  SC->lun);
1661     
1662        /* Check for command to initiator IDs */
1663        if ((SC->channel > 0) && (SC->target == ha->ha_id[SC->channel])) {
1664           SC->result = DID_NO_CONNECT << 16;
1665           done(SC);
1666     
1667           return (0);
1668        }
1669     
1670     #ifndef NO_IPS_CMDLINE
1671        if (ips_is_passthru(SC)) {
1672           ips_copp_wait_item_t *scratch;
1673     
1674           /* allocate space for the scribble */
1675           scratch = kmalloc(sizeof(ips_copp_wait_item_t), GFP_ATOMIC);
1676     
1677           if (!scratch) {
1678              SC->result = DID_ERROR << 16;
1679              done(SC);
1680     
1681              return (0);
1682           }
1683     
1684           scratch->scsi_cmd = SC;
1685           scratch->sem = &sem;
1686           scratch->next = NULL;
1687     
1688           ips_putq_copp_tail(&ha->copp_waitlist, scratch);
1689        }
1690        else
1691     #endif
1692           ips_putq_wait_tail(&ha->scb_waitlist, SC);
1693     
1694        IPS_HA_LOCK(cpu_flags);
1695        if ((!test_bit(IPS_IN_INTR, &ha->flags)) &&
1696            (!test_bit(IPS_IN_ABORT, &ha->flags)) &&
1697            (!test_bit(IPS_IN_RESET, &ha->flags))) {
1698           IPS_HA_UNLOCK(cpu_flags);
1699           ips_next(ha, IPS_INTR_IORL);
1700        } else {
1701           IPS_HA_UNLOCK(cpu_flags);
1702        }
1703     
1704        /*
1705         * If this request was a new style IOCTL wait
1706         * for it to finish.
1707         *
1708         * NOTE: we relinquished the lock above so this should
1709         * not cause contention problems
1710         */
1711        if (ips_is_passthru(SC) && SC->cmnd[0] == IPS_IOCTL_NEW_COMMAND) {
1712           char *user_area;
1713           char *kern_area;
1714           u32   datasize;
1715     
1716           /* free io_request_lock */
1717           spin_unlock_irq(&io_request_lock);
1718     
1719           /* wait for the command to finish */
1720           down(&sem);
1721     
1722           /* reobtain the lock */
1723           spin_lock_irq(&io_request_lock);
1724     
1725           /* command finished -- copy back */
1726           user_area = *((char **) &SC->cmnd[4]);
1727           kern_area = ha->ioctl_data;
1728           datasize = *((u32 *) &SC->cmnd[8]);
1729     
1730           if (datasize) {
1731              if (copy_to_user(user_area, kern_area, datasize) > 0) {
1732                 DEBUG_VAR(1, "(%s%d) passthru failed - unable to copy out user data",
1733                           ips_name, ha->host_num);
1734     
1735                 SC->result = DID_ERROR << 16;
1736                 SC->scsi_done(SC);
1737              } else {
1738                 SC->scsi_done(SC);
1739              }
1740           } else {
1741              SC->scsi_done(SC);
1742           }
1743        }
1744     
1745        /* If We were using the CD Boot Flash Buffer, Restore the Old Values */
1746        if ( ips_FlashData == ha->ioctl_data ) {                               
1747           ha->ioctl_data = ha->save_ioctl_data;                           
1748           ha->ioctl_order = ha->save_ioctl_order;                          
1749           ha->ioctl_datasize = ha->save_ioctl_datasize;                       
1750           ips_FlashDataInUse = 0;                                             
1751        }
1752     
1753        return (0);
1754     }
1755     
1756     /****************************************************************************/
1757     /*                                                                          */
1758     /* Routine Name: ips_biosparam                                              */
1759     /*                                                                          */
1760     /* Routine Description:                                                     */
1761     /*                                                                          */
1762     /*   Set bios geometry for the controller                                   */
1763     /*                                                                          */
1764     /****************************************************************************/
1765     int
1766     ips_biosparam(Disk *disk, kdev_t dev, int geom[]) {
1767        ips_ha_t         *ha;
1768        int               heads;
1769        int               sectors;
1770        int               cylinders;
1771     
1772        METHOD_TRACE("ips_biosparam", 1);
1773     
1774        ha = (ips_ha_t *) disk->device->host->hostdata;
1775     
1776        if (!ha)
1777           /* ?!?! host adater info invalid */
1778           return (0);
1779     
1780        if (!ha->active)
1781           return (0);
1782     
1783        if (!ips_read_adapter_status(ha, IPS_INTR_ON))
1784           /* ?!?! Enquiry command failed */
1785           return (0);
1786     
1787        if ((disk->capacity > 0x400000) &&
1788            ((ha->enq->ucMiscFlag & 0x8) == 0)) {
1789           heads = IPS_NORM_HEADS;
1790           sectors = IPS_NORM_SECTORS;
1791        } else {
1792           heads = IPS_COMP_HEADS;
1793           sectors = IPS_COMP_SECTORS;
1794        }
1795     
1796        cylinders = disk->capacity / (heads * sectors);
1797     
1798        DEBUG_VAR(2, "Geometry: heads: %d, sectors: %d, cylinders: %d",
1799                  heads, sectors, cylinders);
1800     
1801        geom[0] = heads;
1802        geom[1] = sectors;
1803        geom[2] = cylinders;
1804     
1805        return (0);
1806     }
1807     
1808     /****************************************************************************/
1809     /*                                                                          */
1810     /* Routine Name: ips_select_queue_depth                                     */
1811     /*                                                                          */
1812     /* Routine Description:                                                     */
1813     /*                                                                          */
1814     /*   Select queue depths for the devices on the contoller                   */
1815     /*                                                                          */
1816     /****************************************************************************/
1817     static void
1818     ips_select_queue_depth(struct Scsi_Host *host, Scsi_Device *scsi_devs) {
1819        Scsi_Device *device;
1820        ips_ha_t    *ha;
1821        int          count = 0;
1822     
1823        ha = IPS_HA(host);
1824     
1825        for (device = scsi_devs; device; device = device->next) {
1826          if (device->host == host) {
1827             if ((device->channel == 0) && (device->type == 0))
1828                count++;
1829          }
1830        }
1831     
1832        for (device = scsi_devs; device; device = device->next) {
1833           if (device->host == host) {
1834              if ((device->channel == 0) && (device->type == 0))
1835                 device->queue_depth = ha->max_cmds / count - 1;
1836              else
1837                 device->queue_depth = 2;
1838     
1839              if (device->queue_depth < 2)
1840                 device->queue_depth = 2;
1841           }
1842        }
1843     }
1844     
1845     /****************************************************************************/
1846     /*                                                                          */
1847     /* Routine Name: do_ipsintr                                                 */
1848     /*                                                                          */
1849     /* Routine Description:                                                     */
1850     /*                                                                          */
1851     /*   Wrapper for the interrupt handler                                      */
1852     /*                                                                          */
1853     /****************************************************************************/
1854     void
1855     do_ipsintr(int irq, void *dev_id, struct pt_regs *regs) {
1856        ips_ha_t         *ha;
1857        unsigned long     cpu_flags;
1858     
1859        METHOD_TRACE("do_ipsintr", 2);
1860     
1861        ha = (ips_ha_t *) dev_id;
1862     
1863        spin_lock_irqsave(&io_request_lock, cpu_flags);
1864     
1865        if (test_and_set_bit(IPS_IN_INTR, &ha->flags)) {
1866           spin_unlock_irqrestore(&io_request_lock, cpu_flags);
1867     
1868           return ;
1869        }
1870     
1871        if (!ha) {
1872           clear_bit(IPS_IN_INTR, &ha->flags);
1873           spin_unlock_irqrestore(&io_request_lock, cpu_flags);
1874     
1875           return;
1876        }
1877     
1878        if (!ha->active) {
1879           clear_bit(IPS_IN_INTR, &ha->flags);
1880           spin_unlock_irqrestore(&io_request_lock, cpu_flags);
1881     
1882           return;
1883        }
1884     
1885        (*ha->func.intr)(ha);
1886     
1887        clear_bit(IPS_IN_INTR, &ha->flags);
1888     
1889        spin_unlock_irqrestore(&io_request_lock, cpu_flags);
1890     
1891        /* start the next command */
1892        ips_next(ha, IPS_INTR_ON);
1893     }
1894     
1895     /****************************************************************************/
1896     /*                                                                          */
1897     /* Routine Name: ips_intr_copperhead                                        */
1898     /*                                                                          */
1899     /* Routine Description:                                                     */
1900     /*                                                                          */
1901     /*   Polling interrupt handler                                              */
1902     /*                                                                          */
1903     /*   ASSUMES interrupts are disabled                                        */
1904     /*                                                                          */
1905     /****************************************************************************/
1906     void
1907     ips_intr_copperhead(ips_ha_t *ha) {
1908        ips_stat_t       *sp;
1909        ips_scb_t        *scb;
1910        IPS_STATUS        cstatus;
1911        int               intrstatus;
1912        unsigned long     cpu_flags;
1913     
1914        METHOD_TRACE("ips_intr", 2);
1915     
1916        if (!ha)
1917           return;
1918     
1919        if (!ha->active)
1920           return;
1921     
1922        IPS_HA_LOCK(cpu_flags);
1923     
1924        intrstatus = (*ha->func.isintr)(ha);
1925     
1926        if (!intrstatus) {
1927           /*
1928            * Unexpected/Shared interrupt
1929            */
1930           IPS_HA_UNLOCK(cpu_flags);
1931     
1932           return;
1933        }
1934     
1935        while (TRUE) {
1936           sp = &ha->sp;
1937     
1938           intrstatus = (*ha->func.isintr)(ha);
1939     
1940           if (!intrstatus)
1941              break;
1942           else
1943              cstatus.value = (*ha->func.statupd)(ha);
1944     
1945           if (cstatus.fields.command_id > (IPS_MAX_CMDS - 1)) {
1946              printk(KERN_WARNING "(%s%d) Spurious interrupt; no ccb.\n",
1947                     ips_name, ha->host_num);
1948     
1949              continue;
1950           }
1951     
1952           ips_chkstatus(ha, &cstatus);
1953           scb = (ips_scb_t *) sp->scb_addr;
1954     
1955           /*
1956            * use the callback function to finish things up
1957            * NOTE: interrupts are OFF for this
1958            */
1959           IPS_HA_UNLOCK(cpu_flags);
1960           (*scb->callback) (ha, scb);
1961           IPS_HA_LOCK(cpu_flags);
1962        } /* end while */
1963     
1964        IPS_HA_UNLOCK(cpu_flags);
1965     }
1966     
1967     /****************************************************************************/
1968     /*                                                                          */
1969     /* Routine Name: ips_intr_morpheus                                          */
1970     /*                                                                          */
1971     /* Routine Description:                                                     */
1972     /*                                                                          */
1973     /*   Polling interrupt handler                                              */
1974     /*                                                                          */
1975     /*   ASSUMES interrupts are disabled                                        */
1976     /*                                                                          */
1977     /****************************************************************************/
1978     void
1979     ips_intr_morpheus(ips_ha_t *ha) {
1980        ips_stat_t       *sp;
1981        ips_scb_t        *scb;
1982        IPS_STATUS        cstatus;
1983        int               intrstatus;
1984        unsigned long     cpu_flags;
1985     
1986        METHOD_TRACE("ips_intr_morpheus", 2);
1987     
1988        if (!ha)
1989           return;
1990     
1991        if (!ha->active)
1992           return;
1993     
1994        IPS_HA_LOCK(cpu_flags);
1995     
1996        intrstatus = (*ha->func.isintr)(ha);
1997     
1998        if (!intrstatus) {
1999           /*
2000            * Unexpected/Shared interrupt
2001            */
2002           IPS_HA_UNLOCK(cpu_flags);
2003     
2004           return;
2005        }
2006     
2007        while (TRUE) {
2008           sp = &ha->sp;
2009     
2010           intrstatus = (*ha->func.isintr)(ha);
2011     
2012           if (!intrstatus)
2013              break;
2014           else
2015              cstatus.value = (*ha->func.statupd)(ha);
2016     
2017           if (cstatus.value == 0xffffffff)
2018              /* No more to process */
2019              break;
2020     
2021           if (cstatus.fields.command_id > (IPS_MAX_CMDS - 1)) {
2022              printk(KERN_WARNING "(%s%d) Spurious interrupt; no ccb.\n",
2023                     ips_name, ha->host_num);
2024     
2025              continue;
2026           }
2027     
2028           ips_chkstatus(ha, &cstatus);
2029           scb = (ips_scb_t *) sp->scb_addr;
2030     
2031           /*
2032            * use the callback function to finish things up
2033            * NOTE: interrupts are OFF for this
2034            */
2035           IPS_HA_UNLOCK(cpu_flags);
2036           (*scb->callback) (ha, scb);
2037           IPS_HA_LOCK(cpu_flags);
2038        } /* end while */
2039     
2040        IPS_HA_UNLOCK(cpu_flags);
2041     }
2042     
2043     /****************************************************************************/
2044     /*                                                                          */
2045     /* Routine Name: ips_info                                                   */
2046     /*                                                                          */
2047     /* Routine Description:                                                     */
2048     /*                                                                          */
2049     /*   Return info about the driver                                           */
2050     /*                                                                          */
2051     /****************************************************************************/
2052     const char *
2053     ips_info(struct Scsi_Host *SH) {
2054        static char  buffer[256];
2055        char        *bp;
2056        ips_ha_t    *ha;
2057     
2058        METHOD_TRACE("ips_info", 1);
2059     
2060        ha = IPS_HA(SH);
2061     
2062        if (!ha)
2063           return (NULL);
2064     
2065        bp = &buffer[0];
2066        memset(bp, 0, sizeof(buffer));
2067     
2068        strcpy(bp, "IBM PCI ServeRAID ");
2069        strcat(bp, IPS_VERSION_HIGH);
2070        strcat(bp, IPS_VERSION_LOW);
2071     
2072        if (ha->ad_type > 0 &&
2073            ha->ad_type <= MAX_ADAPTER_NAME) {
2074           strcat(bp, " <");
2075           strcat(bp, ips_adapter_name[ha->ad_type-1]);
2076           strcat(bp, ">");
2077        }
2078     
2079        return (bp);
2080     }
2081     
2082     /****************************************************************************/
2083     /*                                                                          */
2084     /* Routine Name: ips_proc_info                                              */
2085     /*                                                                          */
2086     /* Routine Description:                                                     */
2087     /*                                                                          */
2088     /*   The passthru interface for the driver                                  */
2089     /*                                                                          */
2090     /****************************************************************************/
2091     int
2092     ips_proc_info(char *buffer, char **start, off_t offset,
2093                   int length, int hostno, int func) {
2094        int           i;
2095        int           ret;
2096        ips_ha_t     *ha = NULL;
2097     
2098        METHOD_TRACE("ips_proc_info", 1);
2099     
2100        /* Find our host structure */
2101        for (i = 0; i < ips_next_controller; i++) {
2102           if (ips_sh[i]) {
2103              if (ips_sh[i]->host_no == hostno) {
2104                 ha = (ips_ha_t *) ips_sh[i]->hostdata;
2105                 break;
2106              }
2107           }
2108        }
2109     
2110        if (!ha)
2111           return (-EINVAL);
2112     
2113        if (func) {
2114           /* write */
2115           return (0);
2116        } else {
2117           /* read */
2118           if (start)
2119              *start = buffer;
2120     
2121           ret = ips_host_info(ha, buffer, offset, length);
2122     
2123           return (ret);
2124        }
2125     }
2126     
2127     /*--------------------------------------------------------------------------*/
2128     /* Helper Functions                                                         */
2129     /*--------------------------------------------------------------------------*/
2130     
2131     #ifndef NO_IPS_CMDLINE
2132     
2133     /****************************************************************************/
2134     /*                                                                          */
2135     /* Routine Name: ips_is_passthru                                            */
2136     /*                                                                          */
2137     /* Routine Description:                                                     */
2138     /*                                                                          */
2139     /*   Determine if the specified SCSI command is really a passthru command   */
2140     /*                                                                          */
2141     /****************************************************************************/
2142     static int
2143     ips_is_passthru(Scsi_Cmnd *SC) {
2144        METHOD_TRACE("ips_is_passthru", 1);
2145     
2146        if (!SC)
2147           return (0);
2148     
2149        if (((SC->cmnd[0] == IPS_IOCTL_COMMAND) || (SC->cmnd[0] == IPS_IOCTL_NEW_COMMAND)) &&
2150            (SC->channel == 0) &&
2151            (SC->target == IPS_ADAPTER_ID) &&
2152            (SC->lun == 0) &&
2153            (SC->request_bufflen) &&
2154            (!SC->use_sg) &&
2155            (((char *) SC->request_buffer)[0] == 'C') &&
2156            (((char *) SC->request_buffer)[1] == 'O') &&
2157            (((char *) SC->request_buffer)[2] == 'P') &&
2158            (((char *) SC->request_buffer)[3] == 'P')) {
2159           return (1);
2160        } else {
2161           return (0);
2162        }
2163     }
2164     
2165     /****************************************************************************/
2166     /*                                                                          */
2167     /* Routine Name: ips_make_passthru                                          */
2168     /*                                                                          */
2169     /* Routine Description:                                                     */
2170     /*                                                                          */
2171     /*   Make a passthru command out of the info in the Scsi block              */
2172     /*                                                                          */
2173     /****************************************************************************/
2174     static int
2175     ips_make_passthru(ips_ha_t *ha, Scsi_Cmnd *SC, ips_scb_t *scb, int intr) {
2176        IPS_NVRAM_P5    nvram;
2177        ips_passthru_t *pt;
2178     
2179        METHOD_TRACE("ips_make_passthru", 1);
2180     
2181        if (!SC->request_bufflen || !SC->request_buffer) {
2182           /* no data */
2183           DEBUG_VAR(1, "(%s%d) No passthru structure",
2184                     ips_name, ha->host_num);
2185     
2186           return (IPS_FAILURE);
2187        }
2188     
2189        if (SC->request_bufflen < sizeof(ips_passthru_t)) {
2190           /* wrong size */
2191           DEBUG_VAR(1, "(%s%d) Passthru structure wrong size",
2192                  ips_name, ha->host_num);
2193     
2194           return (IPS_FAILURE);
2195        }
2196     
2197        if ((((char *) SC->request_buffer)[0] != 'C') ||
2198            (((char *) SC->request_buffer)[1] != 'O') ||
2199            (((char *) SC->request_buffer)[2] != 'P') ||
2200            (((char *) SC->request_buffer)[3] != 'P')) {
2201           /* signature doesn't match */
2202           DEBUG_VAR(1, "(%s%d) Wrong signature on passthru structure.",
2203                     ips_name, ha->host_num);
2204     
2205           return (IPS_FAILURE);
2206        }
2207     
2208        pt = (ips_passthru_t *) SC->request_buffer;
2209     
2210        /*
2211         * Some notes about the passthru interface used
2212         *
2213         * IF the scsi op_code == 0x0d then we assume
2214         * that the data came along with/goes with the
2215         * packet we received from the sg driver. In this
2216         * case the CmdBSize field of the pt structure is
2217         * used for the size of the buffer.
2218         *
2219         * IF the scsi op_code == 0x81 then we assume that
2220         * we will need our own buffer and we will copy the
2221         * data to/from the user buffer passed in the scsi
2222         * command.  The data address resides at offset 4
2223         * in the scsi command.  The length of the data resides
2224         * at offset 8 in the scsi command.
2225         */
2226     
2227        switch (pt->CoppCmd) {
2228        case IPS_NUMCTRLS:
2229           memcpy(SC->request_buffer + sizeof(ips_passthru_t),
2230                  &ips_num_controllers, sizeof(int));
2231           SC->result = DID_OK << 16;
2232     
2233           return (IPS_SUCCESS_IMM);
2234     
2235        case IPS_CTRLINFO:
2236           memcpy(SC->request_buffer + sizeof(ips_passthru_t),
2237                  ha, sizeof(ips_ha_t));
2238           SC->result = DID_OK << 16;
2239     
2240           return (IPS_SUCCESS_IMM);
2241     
2242        case IPS_COPPUSRCMD:
2243        case IPS_COPPIOCCMD:
2244           if (SC->cmnd[0] == IPS_IOCTL_COMMAND) {
2245              if (SC->request_bufflen < (sizeof(ips_passthru_t) + pt->CmdBSize)) {
2246                 /* wrong size */
2247                 DEBUG_VAR(1, "(%s%d) Passthru structure wrong size",
2248                           ips_name, ha->host_num);
2249     
2250                 return (IPS_FAILURE);
2251              }
2252     
2253              if ((pt->CoppCP.cmd.nvram.op_code == IPS_CMD_RW_NVRAM_PAGE) &&
2254                  (pt->CoppCP.cmd.nvram.page == 5) &&
2255                  (pt->CoppCP.cmd.nvram.write == 0)) {
2256     
2257                 if (pt->CmdBSize < sizeof(IPS_NVRAM_P5)) {
2258                    SC->result = DID_ERROR << 16;
2259     
2260                    return (IPS_FAILURE);
2261                 }
2262     
2263                 ips_get_bios_version(ha, IPS_INTR_IORL);
2264                 ips_create_nvrampage5(ha, &nvram);
2265     
2266                 /* Copy the result back */
2267                 memcpy(SC->request_buffer + sizeof(ips_passthru_t), &nvram, sizeof(IPS_NVRAM_P5));
2268     
2269                 SC->result = DID_OK << 16;
2270                 pt->BasicStatus = 0x00;
2271                 pt->ExtendedStatus = 0x00;
2272     
2273                 return (IPS_SUCCESS_IMM);
2274              }
2275     
2276              if (ips_usrcmd(ha, pt, scb))
2277                 return (IPS_SUCCESS);
2278              else
2279                 return (IPS_FAILURE);
2280           } else if (SC->cmnd[0] == IPS_IOCTL_NEW_COMMAND) {
2281              char           *user_area;
2282              char           *kern_area;
2283              u32             datasize;
2284     
2285              if (SC->request_bufflen < (sizeof(ips_passthru_t))) {
2286                 /* wrong size */
2287                 DEBUG_VAR(1, "(%s%d) Passthru structure wrong size",
2288                           ips_name, ha->host_num);
2289     
2290                 SC->result = DID_ERROR << 16;
2291     
2292                 return (IPS_FAILURE);
2293              }
2294     
2295     
2296              /* IF it's OK to Use the "CD BOOT" Flash Buffer, then you can     */
2297              /* avoid allocating a huge buffer per adapter ( which can fail ). */
2298              if ( (ips_FlashData) &&                                            
2299                   (pt->CmdBSize == IPS_IMAGE_SIZE) &&                                   
2300                   (ips_FlashDataInUse == 0) ) {                                 
2301                 ips_FlashDataInUse = 1;                                         
2302                 ha->save_ioctl_data  = ha->ioctl_data;                          
2303                 ha->save_ioctl_order = ha->ioctl_order;                         
2304                 ha->save_ioctl_datasize = ha->ioctl_datasize;                   
2305                 ha->ioctl_data  = ips_FlashData;                                
2306                 ha->ioctl_order = 7;                                            
2307                 ha->ioctl_datasize = IPS_IMAGE_SIZE;                                    
2308              }                                                                  
2309     
2310              if ((pt->CoppCP.cmd.nvram.op_code == IPS_CMD_RW_NVRAM_PAGE) &&
2311                  (pt->CoppCP.cmd.nvram.page == 5) &&
2312                  (pt->CoppCP.cmd.nvram.write == 0)) {
2313     
2314                 datasize = *((u32 *) &scb->scsi_cmd->cmnd[8]);
2315     
2316                 if (datasize < sizeof(IPS_NVRAM_P5)) {
2317                    pt->BasicStatus = 0x0B;
2318                    pt->ExtendedStatus = 0x00;
2319                    SC->result = DID_ERROR << 16;
2320     
2321                    return (IPS_FAILURE);
2322                 }
2323     
2324                 ips_get_bios_version(ha, IPS_INTR_IORL);
2325                 ips_create_nvrampage5(ha, &nvram);
2326     
2327                 user_area = *((char **) &scb->scsi_cmd->cmnd[4]);
2328                 kern_area = (char *) &nvram;
2329                 datasize = *((u32 *) &scb->scsi_cmd->cmnd[8]);
2330     
2331                 if (datasize > sizeof(IPS_NVRAM_P5))
2332                    datasize = sizeof(IPS_NVRAM_P5);
2333     
2334                 /* Copy out the buffer */
2335                 if (copy_to_user((void *) user_area, (void *) kern_area, datasize) > 0) {
2336                    pt->BasicStatus = 0x0B;
2337                    pt->ExtendedStatus = 0x00;
2338                    SC->result = DID_ERROR << 16;
2339     
2340                    return (IPS_FAILURE);
2341                 }
2342     
2343                 pt->BasicStatus = 0x00;
2344                 pt->ExtendedStatus = 0x00;
2345                 SC->result = DID_OK << 16;
2346     
2347                 return (IPS_SUCCESS_IMM);
2348              }
2349     
2350              /*
2351               * IPSSEND flashing BIOS
2352               */
2353              if ((pt->CoppCP.cmd.flashfw.op_code == IPS_CMD_RW_BIOSFW) &&
2354                  (pt->CoppCP.cmd.flashfw.type == 1) &&
2355                  (pt->CoppCP.cmd.flashfw.direction == 2) &&
2356                  (ha->device_id == IPS_DEVICEID_COPPERHEAD)) {
2357                 struct tq_struct  task;
2358                 IPS_FLASH_DATA    flash_data;
2359                 DECLARE_MUTEX_LOCKED(sem);
2360     
2361                 /* We only support one packet */
2362                 if (pt->CoppCP.cmd.flashfw.total_packets != 1) {
2363                    pt->BasicStatus = 0x0B;
2364                    pt->ExtendedStatus = 0x00;
2365                    SC->result = DID_ERROR << 16;
2366     
2367                    return (IPS_FAILURE);
2368                 }
2369     
2370                 /* copy in the size/buffer ptr from the scsi command */
2371                 memcpy(&pt->CmdBuffer, &SC->cmnd[4], 4);
2372                 memcpy(&pt->CmdBSize, &SC->cmnd[8], 4);
2373     
2374                 if (pt->CmdBSize > pt->CoppCP.cmd.flashfw.count) {
2375                    pt->CmdBSize = pt->CoppCP.cmd.flashfw.count;
2376                 } else {
2377                    /* ERROR: Command/Buffer mismatch */
2378                    pt->BasicStatus = 0x0B;
2379                    pt->ExtendedStatus = 0x00;
2380                    SC->result = DID_ERROR << 16;
2381     
2382                    return (IPS_FAILURE);
2383                 }
2384     
2385                 if ((!ha->func.programbios) ||
2386                     (!ha->func.erasebios) ||
2387                     (!ha->func.verifybios)) {
2388                    pt->BasicStatus = 0x0B;
2389                    pt->ExtendedStatus = 0x00;
2390                    SC->result = DID_ERROR << 16;
2391     
2392                    return (IPS_FAILURE);
2393                 }
2394     
2395                 /* must have a buffer */
2396                 if ((!pt->CmdBSize) || (!pt->CmdBuffer)) {
2397                    pt->BasicStatus = 0x0B;
2398                    pt->ExtendedStatus = 0x00;
2399                    SC->result = DID_ERROR << 16;
2400     
2401                    return (IPS_FAILURE);
2402                 }
2403     
2404                 /* make sure buffer is big enough */
2405                 if (pt->CmdBSize > ha->ioctl_datasize) {
2406                    void *bigger_struct;
2407                    u32   count;
2408                    u32   order;
2409     
2410                    /* try to allocate a bigger struct */
2411                    for (count = PAGE_SIZE, order = 0;
2412                         count < pt->CmdBSize;
2413                         order++, count <<= 1);
2414     
2415                    bigger_struct = (void *) __get_free_pages(GFP_ATOMIC, order);
2416                    if (bigger_struct) {
2417                       /* free the old memory */
2418                       free_pages((unsigned long) ha->ioctl_data, ha->ioctl_order);
2419     
2420                       /* use the new memory */
2421                       ha->ioctl_data = (char *) bigger_struct;
2422                       ha->ioctl_order = order;
2423                       ha->ioctl_datasize = count;
2424                    } else {
2425                       pt->BasicStatus = 0x0B;
2426                       pt->ExtendedStatus = 0x00;
2427                       SC->result = DID_ERROR << 16;
2428     
2429                       spin_unlock(&ha->ips_lock);
2430     
2431                       return (IPS_FAILURE);
2432                    }
2433                 }
2434     
2435                 /* copy in the buffer */
2436                 if (copy_from_user(ha->ioctl_data, pt->CmdBuffer, pt->CmdBSize) > 0) {
2437                    DEBUG_VAR(1, "(%s%d) flash bios failed - unable to copy user buffer",
2438                              ips_name, ha->host_num);
2439                    pt->BasicStatus = 0x0B;
2440                    pt->ExtendedStatus = 0x00;
2441                    SC->result = DID_ERROR << 16;
2442     
2443                    return (IPS_FAILURE);
2444                 }
2445     
2446                 flash_data.userbuffer = pt->CmdBuffer;
2447                 flash_data.usersize = pt->CmdBSize;
2448                 flash_data.kernbuffer = ha->ioctl_data;
2449                 flash_data.kernsize = ha->ioctl_datasize;
2450                 flash_data.offset = 0;
2451                 flash_data.SC = (void *) SC;
2452                 flash_data.pt = (void *) pt;
2453                 flash_data.ha = (void *) ha;
2454                 flash_data.sem = &sem;
2455     
2456                 task.sync = 0;
2457                 task.routine = ips_scheduled_flash_bios;
2458                 task.data = (void *) &flash_data;
2459     
2460                 /* Unlock the master lock */
2461                 spin_unlock_irq(&io_request_lock);
2462     
2463                 queue_task(&task, &tq_immediate);
2464                 mark_bh(IMMEDIATE_BH);
2465     
2466                 /* Wait for the flash to complete */
2467                 down(&sem);
2468     
2469                 /* Obtain the master lock */
2470                 spin_lock_irq(&io_request_lock);
2471     
2472                 return (flash_data.retcode);
2473              }
2474     
2475              /*
2476               * IPSSEND flashing BIOS in sectioned mode
2477               */
2478              if ((pt->CoppCP.cmd.flashbios.op_code == IPS_CMD_RW_BIOSFW) &&
2479                  (pt->CoppCP.cmd.flashbios.type == 1) &&
2480                  (pt->CoppCP.cmd.flashbios.direction == 4) &&
2481                  (ha->device_id == IPS_DEVICEID_COPPERHEAD)) {
2482                 struct tq_struct  task;
2483                 IPS_FLASH_DATA    flash_data;
2484                 DECLARE_MUTEX_LOCKED(sem);
2485     
2486                 /* copy in the size/buffer ptr from the scsi command */
2487                 memcpy(&pt->CmdBuffer, &SC->cmnd[4], 4);
2488                 memcpy(&pt->CmdBSize, &SC->cmnd[8], 4);
2489     
2490                 if (pt->CmdBSize > pt->CoppCP.cmd.flashbios.count) {
2491                    pt->CmdBSize = pt->CoppCP.cmd.flashbios.count;
2492                 } else {
2493                    /* ERROR: Command/Buffer mismatch */
2494                    pt->BasicStatus = 0x0B;
2495                    pt->ExtendedStatus = 0x00;
2496                    SC->result = DID_ERROR << 16;
2497     
2498                    return (IPS_FAILURE);
2499                 }
2500     
2501                 /* Update the Card BIOS */
2502                 if ((!ha->func.programbios) ||
2503                     (!ha->func.erasebios) ||
2504                     (!ha->func.verifybios)) {
2505                    pt->BasicStatus = 0x0B;
2506                    pt->ExtendedStatus = 0x00;
2507                    SC->result = DID_ERROR << 16;
2508     
2509                    return (IPS_FAILURE);
2510                 }
2511     
2512                 /* must have a buffer */
2513                 if ((!pt->CmdBSize) || (!pt->CmdBuffer)) {
2514                    pt->BasicStatus = 0x0B;
2515                    pt->ExtendedStatus = 0x00;
2516                    SC->result = DID_ERROR << 16;
2517     
2518                    return (IPS_FAILURE);
2519                 }
2520     
2521                 /* make sure buffer is big enough */
2522                 if (pt->CmdBSize > ha->ioctl_datasize) {
2523                    void *bigger_struct;
2524                    u32   count;
2525                    u32   order;
2526     
2527                    /* try to allocate a bigger struct */
2528                    for (count = PAGE_SIZE, order = 0;
2529                         count < pt->CmdBSize;
2530                         order++, count <<= 1);
2531     
2532                    bigger_struct = (void *) __get_free_pages(GFP_ATOMIC, order);
2533                    if (bigger_struct) {
2534                       /* free the old memory */
2535                       free_pages((unsigned long) ha->ioctl_data, ha->ioctl_order);
2536     
2537                       /* use the new memory */
2538                       ha->ioctl_data = (char *) bigger_struct;
2539                       ha->ioctl_order = order;
2540                       ha->ioctl_datasize = count;
2541                    } else {
2542                       pt->BasicStatus = 0x0B;
2543                       pt->ExtendedStatus = 0x00;
2544                       SC->result = DID_ERROR << 16;
2545     
2546                       spin_unlock(&ha->ips_lock);
2547     
2548                       return (IPS_FAILURE);
2549                    }
2550                 }
2551     
2552                 /* copy in the buffer */
2553                 if (copy_from_user(ha->ioctl_data, pt->CmdBuffer, pt->CmdBSize) > 0) {
2554                    DEBUG_VAR(1, "(%s%d) flash bios failed - unable to copy user buffer",
2555                              ips_name, ha->host_num);
2556                    pt->BasicStatus = 0x0B;
2557                    pt->ExtendedStatus = 0x00;
2558                    SC->result = DID_ERROR << 16;
2559     
2560                    return (IPS_FAILURE);
2561                 }
2562     
2563                 flash_data.userbuffer = pt->CmdBuffer;
2564                 flash_data.usersize = pt->CmdBSize;
2565                 flash_data.kernbuffer = ha->ioctl_data;
2566                 flash_data.kernsize = ha->ioctl_datasize;
2567                 flash_data.offset = pt->CoppCP.cmd.flashbios.offset;
2568                 flash_data.SC = (void *) SC;
2569                 flash_data.pt = (void *) pt;
2570                 flash_data.ha = (void *) ha;
2571                 flash_data.sem = &sem;
2572     
2573                 task.sync = 0;
2574                 task.routine = ips_flash_bios_section;
2575                 task.data = (void *) &flash_data;
2576     
2577                 /* Unlock the master lock */
2578                 spin_unlock_irq(&io_request_lock);
2579     
2580                 queue_task(&task, &tq_immediate);
2581                 mark_bh(IMMEDIATE_BH);
2582                
2583                 /* Wait for the flash to complete */
2584                 down(&sem);
2585     
2586                 /* Obtain the master lock */
2587                 spin_lock_irq(&io_request_lock);
2588     
2589                 return (flash_data.retcode);
2590              }
2591     
2592              if ((pt->CoppCP.cmd.flashfw.op_code == IPS_CMD_RW_BIOSFW) &&
2593                  (pt->CoppCP.cmd.flashfw.type == 1) &&
2594                  (pt->CoppCP.cmd.flashfw.direction == 3) &&
2595                  (ha->device_id == IPS_DEVICEID_COPPERHEAD)) {
2596                 /* Erase the Card BIOS */
2597                 if (!ha->func.erasebios) {
2598                    pt->BasicStatus = 0x0B;
2599                    pt->ExtendedStatus = 0x00;
2600                    SC->result = DID_ERROR << 16;
2601     
2602                    return (IPS_FAILURE);
2603                 }
2604     
2605                 if ((*ha->func.erasebios)(ha)) {
2606                    DEBUG_VAR(1, "(%s%d) flash bios failed - unable to erase flash",
2607                              ips_name, ha->host_num);
2608                    pt->BasicStatus = 0x0B;
2609                    pt->ExtendedStatus = 0x00;
2610                    SC->result = DID_ERROR << 16;
2611     
2612                    return (IPS_FAILURE);
2613                 }
2614     
2615                 SC->result = DID_OK << 16;
2616                 pt->BasicStatus = 0x00;
2617                 pt->ExtendedStatus = 0x00;
2618     
2619                 return (IPS_SUCCESS_IMM);
2620              }
2621     
2622              if (ips_newusrcmd(ha, pt, scb))
2623                 return (IPS_SUCCESS);
2624              else
2625                 return (IPS_FAILURE);
2626           }
2627     
2628           break;
2629     
2630        } /* end switch */
2631     
2632        return (IPS_FAILURE);
2633     }
2634     
2635     /****************************************************************************/
2636     /*                                                                          */
2637     /* Routine Name: ips_scheduled_flash_bios                                   */
2638     /*                                                                          */
2639     /* Routine Description:                                                     */
2640     /*                                                                          */
2641     /*   Flash the BIOS on a Copperhead style controller                        */
2642     /*   To be called from a task queue                                         */
2643     /*                                                                          */
2644     /****************************************************************************/
2645     static void
2646     ips_scheduled_flash_bios(void *data) {
2647        ips_ha_t       *ha;
2648        Scsi_Cmnd      *SC;
2649        ips_passthru_t *pt;
2650        IPS_FLASH_DATA *fd;
2651     
2652        fd = (IPS_FLASH_DATA *) data;
2653        ha = (ips_ha_t *) fd->ha;
2654        pt = (ips_passthru_t *) fd->pt;
2655        SC = (Scsi_Cmnd *) fd->SC;
2656     
2657        /*
2658         * Set initial return codes
2659         */
2660        SC->result = DID_OK << 16;
2661        pt->BasicStatus = 0x00;
2662        pt->ExtendedStatus = 0x00;
2663        fd->retcode = IPS_SUCCESS_IMM;
2664     
2665        /*
2666         * Fix the size/ptr to account for the
2667         * flash header
2668         */
2669        fd->kernbuffer += 0xC0;
2670        fd->kernsize -= 0xC0;
2671        fd->userbuffer += 0xC0;
2672        fd->usersize -= 0xC0;
2673     
2674        if ((*ha->func.erasebios)(ha)) {
2675           DEBUG_VAR(1, "(%s%d) flash bios failed - unable to erase flash",
2676                     ips_name, ha->host_num);
2677           pt->BasicStatus = 0x0B;
2678           pt->ExtendedStatus = 0x00;
2679           SC->result = DID_ERROR << 16;
2680           fd->retcode = IPS_FAILURE;
2681           up(fd->sem);
2682     
2683           return ;
2684        }
2685     
2686        ips_flash_bios_segment(data);
2687     
2688        if (fd->retcode == IPS_FAILURE)
2689           return ;
2690     
2691        if ((*ha->func.verifybios)(ha, fd->kernbuffer, fd->usersize, fd->offset)) {
2692           DEBUG_VAR(1, "(%s%d) flash bios failed - unable to verify flash",
2693                     ips_name, ha->host_num);
2694           pt->BasicStatus = 0x0B;
2695           pt->ExtendedStatus = 0x00;
2696           SC->result = DID_ERROR << 16;
2697           fd->retcode = IPS_FAILURE;
2698           up(fd->sem);
2699     
2700           return ;
2701        }
2702     
2703        /* Tell them we are done */
2704        if (fd->retcode != IPS_FAILURE)
2705           up(fd->sem);
2706     }
2707     
2708     /****************************************************************************/
2709     /*                                                                          */
2710     /* Routine Name: ips_flash_bios_section                                     */
2711     /*                                                                          */
2712     /* Routine Description:                                                     */
2713     /*                                                                          */
2714     /*   wrapper for ips_flash_bios_segment that raises the semaphore           */
2715     /*                                                                          */
2716     /****************************************************************************/
2717     static void
2718     ips_flash_bios_section(void *data) {
2719        ips_ha_t       *ha;
2720        Scsi_Cmnd      *SC;
2721        ips_passthru_t *pt;
2722        IPS_FLASH_DATA *fd;
2723     
2724        fd = (IPS_FLASH_DATA *) data;
2725        ha = (ips_ha_t *) fd->ha;
2726        pt = (ips_passthru_t *) fd->pt;
2727        SC = (Scsi_Cmnd *) fd->SC;
2728     
2729        /*
2730         * Set initial return codes
2731         */
2732        SC->result = DID_OK << 16;
2733        pt->BasicStatus = 0x00;
2734        pt->ExtendedStatus = 0x00;
2735        fd->retcode = IPS_SUCCESS_IMM;
2736     
2737        ips_flash_bios_segment(data);
2738     
2739        if (fd->retcode != IPS_FAILURE)
2740           up(fd->sem);
2741     }
2742     
2743     /****************************************************************************/
2744     /*                                                                          */
2745     /* Routine Name: ips_flash_bios_segment                                     */
2746     /*                                                                          */
2747     /* Routine Description:                                                     */
2748     /*                                                                          */
2749     /*   Flash a portion of the BIOS on a Copperhead style controller           */
2750     /*   To be called from a task queue                                         */
2751     /*                                                                          */
2752     /****************************************************************************/
2753     static void
2754     ips_flash_bios_segment(void *data) {
2755        ips_ha_t       *ha;
2756        Scsi_Cmnd      *SC;
2757        ips_passthru_t *pt;
2758        IPS_FLASH_DATA *fd;
2759     
2760        fd = (IPS_FLASH_DATA *) data;
2761        ha = (ips_ha_t *) fd->ha;
2762        pt = (ips_passthru_t *) fd->pt;
2763        SC = (Scsi_Cmnd *) fd->SC;
2764     
2765        if ((*ha->func.programbios)(ha, fd->kernbuffer, fd->usersize, fd->offset)) {
2766           DEBUG_VAR(1, "(%s%d) flash bios failed - unable to program flash",
2767                     ips_name, ha->host_num);
2768           pt->BasicStatus = 0x0B;
2769           pt->ExtendedStatus = 0x00;
2770           SC->result = DID_ERROR << 16;
2771           fd->retcode = IPS_FAILURE;
2772           up(fd->sem);
2773     
2774           return ;
2775        }
2776     }
2777     
2778     /****************************************************************************/
2779     /*                                                                          */
2780     /* Routine Name: ips_usrcmd                                                 */
2781     /*                                                                          */
2782     /* Routine Description:                                                     */
2783     /*                                                                          */
2784     /*   Process a user command and make it ready to send                       */
2785     /*                                                                          */
2786     /****************************************************************************/
2787     static int
2788     ips_usrcmd(ips_ha_t *ha, ips_passthru_t *pt, ips_scb_t *scb) {
2789        IPS_SG_LIST *sg_list;
2790     
2791        METHOD_TRACE("ips_usrcmd", 1);
2792     
2793        if ((!scb) || (!pt) || (!ha))
2794           return (0);
2795     
2796        /* Save the S/G list pointer so it doesn't get clobbered */
2797        sg_list = scb->sg_list;
2798     
2799        /* copy in the CP */
2800        memcpy(&scb->cmd, &pt->CoppCP.cmd, sizeof(IPS_IOCTL_CMD));
2801        memcpy(&scb->dcdb, &pt->CoppCP.dcdb, sizeof(IPS_DCDB_TABLE));
2802     
2803        /* FIX stuff that might be wrong */
2804        scb->sg_list = sg_list;
2805        scb->scb_busaddr = VIRT_TO_BUS(scb);
2806        scb->bus = scb->scsi_cmd->channel;
2807        scb->target_id = scb->scsi_cmd->target;
2808        scb->lun = scb->scsi_cmd->lun;
2809        scb->sg_len = 0;
2810        scb->data_len = 0;
2811        scb->flags = 0;
2812        scb->op_code = 0;
2813        scb->callback = ipsintr_done;
2814        scb->timeout = ips_cmd_timeout;
2815        scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
2816     
2817        /* we don't support DCDB/READ/WRITE Scatter Gather */
2818        if ((scb->cmd.basic_io.op_code == IPS_CMD_READ_SG) ||
2819            (scb->cmd.basic_io.op_code == IPS_CMD_WRITE_SG) ||
2820            (scb->cmd.basic_io.op_code == IPS_CMD_DCDB_SG))
2821           return (0);
2822     
2823        if (pt->CmdBSize) {
2824           scb->data_busaddr = VIRT_TO_BUS(scb->scsi_cmd->request_buffer + sizeof(ips_passthru_t));
2825        } else {
2826           scb->data_busaddr = 0L;
2827        }
2828     
2829        if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)
2830           scb->cmd.dcdb.dcdb_address = VIRT_TO_BUS(&scb->dcdb);
2831     
2832        if (pt->CmdBSize) {
2833           if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)
2834              scb->dcdb.buffer_pointer = scb->data_busaddr;
2835           else
2836              scb->cmd.basic_io.sg_addr = scb->data_busaddr;
2837        }
2838     
2839        /* set timeouts */
2840        if (pt->TimeOut) {
2841           scb->timeout = pt->TimeOut;
2842     
2843           if (pt->TimeOut <= 10)
2844              scb->dcdb.cmd_attribute |= IPS_TIMEOUT10;
2845           else if (pt->TimeOut <= 60)
2846              scb->dcdb.cmd_attribute |= IPS_TIMEOUT60;
2847           else
2848              scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M;
2849        }
2850     
2851        /* assume success */
2852        scb->scsi_cmd->result = DID_OK << 16;
2853     
2854        /* success */
2855        return (1);
2856     }
2857     
2858     /****************************************************************************/
2859     /*                                                                          */
2860     /* Routine Name: ips_newusrcmd                                              */
2861     /*                                                                          */
2862     /* Routine Description:                                                     */
2863     /*                                                                          */
2864     /*   Process a user command and make it ready to send                       */
2865     /*                                                                          */
2866     /****************************************************************************/
2867     static int
2868     ips_newusrcmd(ips_ha_t *ha, ips_passthru_t *pt, ips_scb_t *scb) {
2869        IPS_SG_LIST    *sg_list;
2870        char           *user_area;
2871        char           *kern_area;
2872        u32             datasize;
2873     
2874        METHOD_TRACE("ips_usrcmd", 1);
2875     
2876        if ((!scb) || (!pt) || (!ha))
2877           return (0);
2878     
2879        /* Save the S/G list pointer so it doesn't get clobbered */
2880        sg_list = scb->sg_list;
2881     
2882        /* copy in the CP */
2883        memcpy(&scb->cmd, &pt->CoppCP.cmd, sizeof(IPS_IOCTL_CMD));
2884        memcpy(&scb->dcdb, &pt->CoppCP.dcdb, sizeof(IPS_DCDB_TABLE));
2885     
2886        /* FIX stuff that might be wrong */
2887        scb->sg_list = sg_list;
2888        scb->scb_busaddr = VIRT_TO_BUS(scb);
2889        scb->bus = scb->scsi_cmd->channel;
2890        scb->target_id = scb->scsi_cmd->target;
2891        scb->lun = scb->scsi_cmd->lun;
2892        scb->sg_len = 0;
2893        scb->data_len = 0;
2894        scb->flags = 0;
2895        scb->op_code = 0;
2896        scb->callback = ipsintr_done;
2897        scb->timeout = ips_cmd_timeout;
2898        scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
2899     
2900        /* we don't support DCDB/READ/WRITE Scatter Gather */
2901        if ((scb->cmd.basic_io.op_code == IPS_CMD_READ_SG) ||
2902            (scb->cmd.basic_io.op_code == IPS_CMD_WRITE_SG) ||
2903            (scb->cmd.basic_io.op_code == IPS_CMD_DCDB_SG))
2904           return (0);
2905     
2906        if (pt->CmdBSize) {
2907           if (pt->CmdBSize > ha->ioctl_datasize) {
2908              void *bigger_struct;
2909              u32   count;
2910              u32   order;
2911     
2912              /* try to allocate a bigger struct */
2913              for (count = PAGE_SIZE, order = 0;
2914                   count < pt->CmdBSize;
2915                   order++, count <<= 1);
2916     
2917              bigger_struct = (void *) __get_free_pages(GFP_ATOMIC, order);
2918              if (bigger_struct) {
2919                 /* free the old memory */
2920                 free_pages((unsigned long) ha->ioctl_data, ha->ioctl_order);
2921     
2922                 /* use the new memory */
2923                 ha->ioctl_data = (char *) bigger_struct;
2924                 ha->ioctl_order = order;
2925                 ha->ioctl_datasize = count;
2926              } else
2927                 return (0);
2928     
2929           }
2930     
2931           scb->data_busaddr = VIRT_TO_BUS(ha->ioctl_data);
2932     
2933           /* Attempt to copy in the data */
2934           user_area = *((char **) &scb->scsi_cmd->cmnd[4]);
2935           kern_area = ha->ioctl_data;
2936           datasize = *((u32 *) &scb->scsi_cmd->cmnd[8]);
2937     
2938           if (copy_from_user(kern_area, user_area, datasize) > 0) {
2939              DEBUG_VAR(1, "(%s%d) passthru failed - unable to copy in user data",
2940                        ips_name, ha->host_num);
2941     
2942              return (0);
2943           }
2944     
2945        } else {
2946           scb->data_busaddr = 0L;
2947        }
2948     
2949        if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)
2950           scb->cmd.dcdb.dcdb_address = VIRT_TO_BUS(&scb->dcdb);
2951     
2952        if (pt->CmdBSize) {
2953           if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)
2954              scb->dcdb.buffer_pointer = scb->data_busaddr;
2955           else
2956              scb->cmd.basic_io.sg_addr = scb->data_busaddr;
2957        }
2958     
2959        /* set timeouts */
2960        if (pt->TimeOut) {
2961           scb->timeout = pt->TimeOut;
2962     
2963           if (pt->TimeOut <= 10)
2964              scb->dcdb.cmd_attribute |= IPS_TIMEOUT10;
2965           else if (pt->TimeOut <= 60)
2966              scb->dcdb.cmd_attribute |= IPS_TIMEOUT60;
2967           else
2968              scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M;
2969        }
2970     
2971        /* assume success */
2972        scb->scsi_cmd->result = DID_OK << 16;
2973     
2974        /* success */
2975        return (1);
2976     }
2977     
2978     /****************************************************************************/
2979     /*                                                                          */
2980     /* Routine Name: ips_cleanup_passthru                                       */
2981     /*                                                                          */
2982     /* Routine Description:                                                     */
2983     /*                                                                          */
2984     /*   Cleanup after a passthru command                                       */
2985     /*                                                                          */
2986     /****************************************************************************/
2987     static void
2988     ips_cleanup_passthru(ips_ha_t *ha, ips_scb_t *scb) {
2989        ips_passthru_t *pt;
2990     
2991        METHOD_TRACE("ips_cleanup_passthru", 1);
2992     
2993        if ((!scb) || (!scb->scsi_cmd) || (!scb->scsi_cmd->request_buffer)) {
2994           DEBUG_VAR(1, "(%s%d) couldn't cleanup after passthru",
2995                     ips_name, ha->host_num);
2996     
2997           return ;
2998        }
2999     
3000        pt = (ips_passthru_t *) scb->scsi_cmd->request_buffer;
3001     
3002        /* Copy data back to the user */
3003        if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB) {       /* Copy DCDB Back to Caller's Area */
3004           memcpy(&pt->CoppCP.dcdb, &scb->dcdb, sizeof(IPS_DCDB_TABLE));
3005        }
3006     
3007        if (scb->scsi_cmd->cmnd[0] == IPS_IOCTL_COMMAND) {
3008           /* Copy data back to the user */
3009           pt->BasicStatus = scb->basic_status;
3010           pt->ExtendedStatus = scb->extended_status;
3011        } else {
3012           pt->BasicStatus = scb->basic_status;
3013           pt->ExtendedStatus = scb->extended_status;
3014           up(scb->sem);
3015        }
3016     }
3017     
3018     #endif
3019     
3020     /****************************************************************************/
3021     /*                                                                          */
3022     /* Routine Name: ips_host_info                                              */
3023     /*                                                                          */
3024     /* Routine Description:                                                     */
3025     /*                                                                          */
3026     /*   The passthru interface for the driver                                  */
3027     /*                                                                          */
3028     /****************************************************************************/
3029     static int
3030     ips_host_info(ips_ha_t *ha, char *ptr, off_t offset, int len) {
3031        IPS_INFOSTR info;
3032     
3033        METHOD_TRACE("ips_host_info", 1);
3034     
3035        info.buffer = ptr;
3036        info.length = len;
3037        info.offset = offset;
3038        info.pos = 0;
3039        info.localpos = 0;
3040     
3041        copy_info(&info, "\nIBM ServeRAID General Information:\n\n");
3042     
3043        if ((ha->nvram->signature == IPS_NVRAM_P5_SIG) &&
3044            (ha->nvram->adapter_type != 0))
3045           copy_info(&info, "\tController Type                   : %s\n", ips_adapter_name[ha->ad_type-1]);
3046        else
3047           copy_info(&info, "\tController Type                   : Unknown\n");
3048     
3049        if (ha->io_addr)
3050           copy_info(&info, "\tIO region                         : 0x%lx (%d bytes)\n",
3051                     ha->io_addr, ha->io_len);
3052     
3053        if (ha->mem_addr) {
3054           copy_info(&info, "\tMemory region                     : 0x%lx (%d bytes)\n",
3055                     ha->mem_addr, ha->mem_len);
3056           copy_info(&info, "\tShared memory address             : 0x%lx\n", ha->mem_ptr);
3057        }
3058     
3059        copy_info(&info, "\tIRQ number                        : %d\n", ha->irq);
3060     
3061        if (ha->nvram->signature == IPS_NVRAM_P5_SIG)
3062           copy_info(&info, "\tBIOS Version                      : %c%c%c%c%c%c%c%c\n",
3063                     ha->nvram->bios_high[0], ha->nvram->bios_high[1],
3064                     ha->nvram->bios_high[2], ha->nvram->bios_high[3],
3065                     ha->nvram->bios_low[0], ha->nvram->bios_low[1],
3066                     ha->nvram->bios_low[2], ha->nvram->bios_low[3]);
3067     
3068        copy_info(&info, "\tFirmware Version                  : %c%c%c%c%c%c%c%c\n",
3069                  ha->enq->CodeBlkVersion[0], ha->enq->CodeBlkVersion[1],
3070                  ha->enq->CodeBlkVersion[2], ha->enq->CodeBlkVersion[3],
3071                  ha->enq->CodeBlkVersion[4], ha->enq->CodeBlkVersion[5],
3072                  ha->enq->CodeBlkVersion[6], ha->enq->CodeBlkVersion[7]);
3073     
3074        copy_info(&info, "\tBoot Block Version                : %c%c%c%c%c%c%c%c\n",
3075                  ha->enq->BootBlkVersion[0], ha->enq->BootBlkVersion[1],
3076                  ha->enq->BootBlkVersion[2], ha->enq->BootBlkVersion[3],
3077                  ha->enq->BootBlkVersion[4], ha->enq->BootBlkVersion[5],
3078                  ha->enq->BootBlkVersion[6], ha->enq->BootBlkVersion[7]);
3079     
3080        copy_info(&info, "\tDriver Version                    : %s%s\n",
3081                  IPS_VERSION_HIGH, IPS_VERSION_LOW);
3082     
3083        copy_info(&info, "\tMax Physical Devices              : %d\n",
3084                  ha->enq->ucMaxPhysicalDevices);
3085        copy_info(&info, "\tMax Active Commands               : %d\n",
3086                  ha->max_cmds);
3087        copy_info(&info, "\tCurrent Queued Commands           : %d\n",
3088                  ha->scb_waitlist.count);
3089        copy_info(&info, "\tCurrent Active Commands           : %d\n",
3090                  ha->scb_activelist.count - ha->num_ioctl);
3091        copy_info(&info, "\tCurrent Queued PT Commands        : %d\n",
3092                  ha->copp_waitlist.count);
3093        copy_info(&info, "\tCurrent Active PT Commands        : %d\n",
3094                  ha->num_ioctl);
3095     
3096        copy_info(&info, "\n");
3097     
3098        return (info.localpos);
3099     }
3100     
3101     /****************************************************************************/
3102     /*                                                                          */
3103     /* Routine Name: copy_mem_info                                              */
3104     /*                                                                          */
3105     /* Routine Description:                                                     */
3106     /*                                                                          */
3107     /*   Copy data into an IPS_INFOSTR structure                                */
3108     /*                                                                          */
3109     /****************************************************************************/
3110     static void
3111     copy_mem_info(IPS_INFOSTR *info, char *data, int len) {
3112        METHOD_TRACE("copy_mem_info", 1);
3113     
3114        if (info->pos + len < info->offset) {
3115           info->pos += len;
3116           return;
3117        }
3118     
3119        if (info->pos < info->offset) {
3120           data += (info->offset - info->pos);
3121           len -= (info->offset - info->pos);
3122           info->pos += (info->offset - info->pos);
3123        }
3124     
3125        if (info->localpos + len > info->length)
3126           len = info->length - info->localpos;
3127     
3128        if (len > 0) {
3129           memcpy(info->buffer + info->localpos, data, len);
3130           info->pos += len;
3131           info->localpos += len;
3132        }
3133     }
3134     
3135     /****************************************************************************/
3136     /*                                                                          */
3137     /* Routine Name: copy_info                                                  */
3138     /*                                                                          */
3139     /* Routine Description:                                                     */
3140     /*                                                                          */
3141     /*   printf style wrapper for an info structure                             */
3142     /*                                                                          */
3143     /****************************************************************************/
3144     static int
3145     copy_info(IPS_INFOSTR *info, char *fmt, ...) {
3146        va_list args;
3147        char buf[128];
3148        int len;
3149     
3150        METHOD_TRACE("copy_info", 1);
3151     
3152        va_start(args, fmt);
3153        len = vsprintf(buf, fmt, args);
3154        va_end(args);
3155     
3156        copy_mem_info(info, buf, len);
3157     
3158        return (len);
3159     }
3160     
3161     /****************************************************************************/
3162     /*                                                                          */
3163     /* Routine Name: ips_identify_controller                                    */
3164     /*                                                                          */
3165     /* Routine Description:                                                     */
3166     /*                                                                          */
3167     /*   Identify this controller                                               */
3168     /*                                                                          */
3169     /****************************************************************************/
3170     static void
3171     ips_identify_controller(ips_ha_t *ha) {
3172        METHOD_TRACE("ips_identify_controller", 1);
3173     
3174        switch (ha->device_id) {
3175        case IPS_DEVICEID_COPPERHEAD:
3176           if (ha->revision_id <= IPS_REVID_SERVERAID) {
3177              ha->ad_type = IPS_ADTYPE_SERVERAID;
3178           } else if (ha->revision_id == IPS_REVID_SERVERAID2) {
3179              ha->ad_type = IPS_ADTYPE_SERVERAID2;
3180           } else if (ha->revision_id == IPS_REVID_NAVAJO) {
3181              ha->ad_type = IPS_ADTYPE_NAVAJO;
3182           } else if ((ha->revision_id == IPS_REVID_SERVERAID2) && (ha->slot_num == 0)) {
3183              ha->ad_type = IPS_ADTYPE_KIOWA;
3184           } else if ((ha->revision_id >= IPS_REVID_CLARINETP1) &&
3185                      (ha->revision_id <= IPS_REVID_CLARINETP3)) {
3186              if (ha->enq->ucMaxPhysicalDevices == 15)
3187                 ha->ad_type = IPS_ADTYPE_SERVERAID3L;
3188              else
3189                 ha->ad_type = IPS_ADTYPE_SERVERAID3;
3190           } else if ((ha->revision_id >= IPS_REVID_TROMBONE32) &&
3191                      (ha->revision_id <= IPS_REVID_TROMBONE64)) {
3192              ha->ad_type = IPS_ADTYPE_SERVERAID4H;
3193           }
3194           break;
3195     
3196        case IPS_DEVICEID_MORPHEUS:
3197           switch (ha->subdevice_id) {
3198           case IPS_SUBDEVICEID_4L:
3199              ha->ad_type = IPS_ADTYPE_SERVERAID4L;
3200              break;
3201     
3202           case IPS_SUBDEVICEID_4M:
3203              ha->ad_type = IPS_ADTYPE_SERVERAID4M;
3204              break;
3205     
3206           case IPS_SUBDEVICEID_4MX:
3207              ha->ad_type = IPS_ADTYPE_SERVERAID4MX;
3208              break;
3209     
3210           case IPS_SUBDEVICEID_4LX:
3211              ha->ad_type = IPS_ADTYPE_SERVERAID4LX;
3212              break;
3213           }
3214     
3215           break;
3216        }
3217     }
3218     
3219     /****************************************************************************/
3220     /*                                                                          */
3221     /* Routine Name: ips_create_nvrampage5                                      */
3222     /*                                                                          */
3223     /* Routine Description:                                                     */
3224     /*                                                                          */
3225     /*   Create a pseudo nvram page 5                                           */
3226     /*                                                                          */
3227     /****************************************************************************/
3228     static void
3229     ips_create_nvrampage5(ips_ha_t *ha, IPS_NVRAM_P5 *nvram) {
3230        METHOD_TRACE("ips_create_nvrampage5", 1);
3231     
3232        memset(nvram, 0, sizeof(IPS_NVRAM_P5));
3233     
3234        nvram->signature = IPS_NVRAM_P5_SIG;
3235        nvram->adapter_slot = ha->slot_num;
3236        nvram->adapter_type = ha->ad_type;
3237        nvram->operating_system = IPS_OS_LINUX;
3238        strncpy((char *) nvram->driver_high, IPS_VERSION_HIGH, 4);
3239        strncpy((char *) nvram->driver_low, IPS_VERSION_LOW, 4);
3240        strncpy((char *) nvram->bios_high, ha->bios_version, 4);
3241        strncpy((char *) nvram->bios_low, ha->bios_version + 4, 4);
3242     }
3243     
3244     /****************************************************************************/
3245     /*                                                                          */
3246     /* Routine Name: ips_get_bios_version                                       */
3247     /*                                                                          */
3248     /* Routine Description:                                                     */
3249     /*                                                                          */
3250     /*   Get the BIOS revision number                                           */
3251     /*                                                                          */
3252     /****************************************************************************/
3253     static void
3254     ips_get_bios_version(ips_ha_t *ha, int intr) {
3255        ips_scb_t *scb;
3256        int        ret;
3257        u8         major;
3258        u8         minor;
3259        u8         subminor; 
3260        u8        *buffer;
3261        char       hexDigits[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
3262     
3263        METHOD_TRACE("ips_get_bios_version", 1);
3264     
3265        major = 0;
3266        minor = 0;
3267     
3268        strncpy(ha->bios_version, "       ?", 8);
3269     
3270        if (ha->device_id == IPS_DEVICEID_COPPERHEAD) {
3271           if (IPS_USE_MEMIO(ha)) {
3272              /* Memory Mapped I/O */
3273     
3274              /* test 1st byte */
3275              writel(0, ha->mem_ptr + IPS_REG_FLAP);
3276              if (ha->revision_id == IPS_REVID_TROMBONE64)
3277                 udelay(5); /* 5 us */
3278     
3279              if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0x55)
3280                 return;
3281     
3282              writel(1, ha->mem_ptr + IPS_REG_FLAP);
3283              if (ha->revision_id == IPS_REVID_TROMBONE64)
3284                 udelay(5); /* 5 us */
3285     
3286              if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0xAA)
3287                 return;
3288     
3289              /* Get Major version */
3290              writel(0x1FF, ha->mem_ptr + IPS_REG_FLAP);
3291              if (ha->revision_id == IPS_REVID_TROMBONE64)
3292                 udelay(5); /* 5 us */
3293     
3294              major = readb(ha->mem_ptr + IPS_REG_FLDP);
3295     
3296              /* Get Minor version */
3297              writel(0x1FE, ha->mem_ptr + IPS_REG_FLAP);
3298              if (ha->revision_id == IPS_REVID_TROMBONE64)
3299                 udelay(5); /* 5 us */
3300     
3301              minor = readb(ha->mem_ptr + IPS_REG_FLDP);
3302     
3303              /* Get Sub Minor version */
3304              writel(0x1FD, ha->mem_ptr + IPS_REG_FLAP);
3305              if (ha->revision_id == IPS_REVID_TROMBONE64)
3306                 udelay(5);/* 5 us */
3307     
3308              subminor = readb(ha->mem_ptr + IPS_REG_FLDP);
3309     
3310     
3311           } else {
3312              /* Programmed I/O */
3313     
3314              /* test 1st byte */
3315              outl(0, ha->io_addr + IPS_REG_FLAP);
3316              if (ha->revision_id == IPS_REVID_TROMBONE64)
3317                 udelay(5); /* 5 us */
3318     
3319              if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55)
3320                 return ;
3321     
3322              outl(1, ha->io_addr + IPS_REG_FLAP);
3323              if (ha->revision_id == IPS_REVID_TROMBONE64)
3324                 udelay(5); /* 5 us */
3325     
3326              if (inb(ha->io_addr + IPS_REG_FLDP) != 0xAA)
3327                 return ;
3328     
3329              /* Get Major version */
3330              outl(0x1FF, ha->io_addr + IPS_REG_FLAP);
3331              if (ha->revision_id == IPS_REVID_TROMBONE64)
3332                 udelay(5); /* 5 us */
3333     
3334              major = inb(ha->io_addr + IPS_REG_FLDP);
3335     
3336              /* Get Minor version */
3337              outl(0x1FE, ha->io_addr + IPS_REG_FLAP);
3338              if (ha->revision_id == IPS_REVID_TROMBONE64)
3339                 udelay(5); /* 5 us */
3340     
3341              minor = inb(ha->io_addr + IPS_REG_FLDP);
3342              
3343              /* Get SubMinor version */
3344              outl(0x1FD, ha->io_addr + IPS_REG_FLAP);
3345              if (ha->revision_id == IPS_REVID_TROMBONE64)
3346                 udelay(5); /* 5 us */
3347     
3348              subminor = inb(ha->io_addr + IPS_REG_FLDP);
3349     
3350           }
3351        } else {
3352           /* Morpheus Family - Send Command to the card */
3353     
3354           buffer = kmalloc(0x1000, GFP_ATOMIC);
3355           if (!buffer)
3356              return;
3357     
3358           memset(buffer, 0, 0x1000);
3359     
3360           scb = &ha->scbs[ha->max_cmds-1];
3361     
3362           ips_init_scb(ha, scb);
3363     
3364           scb->timeout = ips_cmd_timeout;
3365           scb->cdb[0] = IPS_CMD_RW_BIOSFW;
3366     
3367           scb->cmd.flashfw.op_code = IPS_CMD_RW_BIOSFW;
3368           scb->cmd.flashfw.command_id = IPS_COMMAND_ID(ha, scb);
3369           scb->cmd.flashfw.type = 1;
3370           scb->cmd.flashfw.direction = 0;
3371           scb->cmd.flashfw.count = 0x800;
3372           scb->cmd.flashfw.buffer_addr = VIRT_TO_BUS(buffer);
3373           scb->cmd.flashfw.total_packets = 1;
3374           scb->cmd.flashfw.packet_num = 0;
3375     
3376           /* issue the command */
3377           if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) ||
3378               (ret == IPS_SUCCESS_IMM) ||
3379               ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) {
3380              /* Error occurred */
3381              kfree(buffer);
3382     
3383              return;
3384           }
3385     
3386           if ((buffer[0xC0] == 0x55) && (buffer[0xC1] == 0xAA)) {
3387              major = buffer[0x1ff + 0xC0]; /* Offset 0x1ff after the header (0xc0) */
3388              minor = buffer[0x1fe + 0xC0]; /* Offset 0x1fe after the header (0xc0) */
3389              subminor = buffer[0x1fd + 0xC0]; /* Offset 0x1fe after the header (0xc0) */
3390     
3391           } else {
3392              return;
3393           }
3394     
3395           kfree(buffer);
3396        }
3397     
3398        ha->bios_version[0] = hexDigits[(major & 0xF0) >> 4];
3399        ha->bios_version[1] = '.';
3400        ha->bios_version[2] = hexDigits[major & 0x0F];
3401        ha->bios_version[3] = hexDigits[subminor];
3402        ha->bios_version[4] = '.';
3403        ha->bios_version[5] = hexDigits[(minor & 0xF0) >> 4];
3404        ha->bios_version[6] = hexDigits[minor & 0x0F];
3405        ha->bios_version[7] = 0;
3406     }
3407     
3408     /****************************************************************************/
3409     /*                                                                          */
3410     /* Routine Name: ips_hainit                                                 */
3411     /*                                                                          */
3412     /* Routine Description:                                                     */
3413     /*                                                                          */
3414     /*   Initialize the controller                                              */
3415     /*                                                                          */
3416     /* NOTE: Assumes to be called from with a lock                              */
3417     /*                                                                          */
3418     /****************************************************************************/
3419     static int
3420     ips_hainit(ips_ha_t *ha) {
3421        int            i;
3422        struct timeval tv;
3423     
3424        METHOD_TRACE("ips_hainit", 1);
3425     
3426        if (!ha)
3427           return (0);
3428     
3429        if (ha->func.statinit)
3430           (*ha->func.statinit)(ha);
3431     
3432        if (ha->func.enableint)
3433           (*ha->func.enableint)(ha);
3434     
3435        /* Send FFDC */
3436        ha->reset_count = 1;
3437        do_gettimeofday(&tv);
3438        ha->last_ffdc = tv.tv_sec;
3439        ips_ffdc_reset(ha, IPS_INTR_IORL);
3440     
3441        if (!ips_read_config(ha, IPS_INTR_IORL)) {
3442           printk(KERN_WARNING "(%s%d) unable to read config from controller.\n",
3443                  ips_name, ha->host_num);
3444     
3445           return (0);
3446        } /* end if */
3447     
3448        if (!ips_read_adapter_status(ha, IPS_INTR_IORL)) {
3449           printk(KERN_WARNING "(%s%d) unable to read controller status.\n",
3450                  ips_name, ha->host_num);
3451     
3452           return (0);
3453        }
3454     
3455        /* Identify this controller */
3456        ips_identify_controller(ha);
3457     
3458        if (!ips_read_subsystem_parameters(ha, IPS_INTR_IORL)) {
3459           printk(KERN_WARNING "(%s%d) unable to read subsystem parameters.\n",
3460                  ips_name, ha->host_num);
3461     
3462           return (0);
3463        }
3464     
3465        /* write nvram user page 5 */
3466        if (!ips_write_driver_status(ha, IPS_INTR_IORL)) {
3467           printk(KERN_WARNING "(%s%d) unable to write driver info to controller.\n",
3468                  ips_name, ha->host_num);
3469     
3470           return (0);
3471        }
3472     
3473        /* set limits on SID, LUN, BUS */
3474        ha->ntargets = IPS_MAX_TARGETS + 1;
3475        ha->nlun = 1;
3476        ha->nbus = (ha->enq->ucMaxPhysicalDevices / IPS_MAX_TARGETS) + 1;
3477     
3478        switch (ha->conf->logical_drive[0].ucStripeSize) {
3479        case 4:
3480           ha->max_xfer = 0x10000;
3481           break;
3482     
3483        case 5:
3484           ha->max_xfer = 0x20000;
3485           break;
3486     
3487        case 6:
3488           ha->max_xfer = 0x40000;
3489           break;
3490     
3491        case 7:
3492        default:
3493           ha->max_xfer = 0x80000;
3494           break;
3495        }
3496     
3497        /* setup max concurrent commands */
3498        if (ha->subsys->param[4] & 0x1) {
3499           /* Use the new method */
3500           ha->max_cmds = ha->enq->ucConcurrentCmdCount;
3501        } else {
3502           /* use the old method */
3503           switch (ha->conf->logical_drive[0].ucStripeSize) {
3504           case 4:
3505              ha->max_cmds = 32;
3506              break;
3507     
3508           case 5:
3509              ha->max_cmds = 16;
3510              break;
3511     
3512           case 6:
3513              ha->max_cmds = 8;
3514              break;
3515     
3516           case 7:
3517           default:
3518              ha->max_cmds = 4;
3519              break;
3520           }
3521        }
3522     
3523        /* set controller IDs */
3524        ha->ha_id[0] = IPS_ADAPTER_ID;
3525        for (i = 1; i < ha->nbus; i++) {
3526           ha->ha_id[i] = ha->conf->init_id[i-1] & 0x1f;
3527           ha->dcdb_active[i-1] = 0;
3528        }
3529     
3530        return (1);
3531     }
3532     
3533     /****************************************************************************/
3534     /*                                                                          */
3535     /* Routine Name: ips_next                                                   */
3536     /*                                                                          */
3537     /* Routine Description:                                                     */
3538     /*                                                                          */
3539     /*   Take the next command off the queue and send it to the controller      */
3540     /*                                                                          */
3541     /****************************************************************************/
3542     static void
3543     ips_next(ips_ha_t *ha, int intr) {
3544        ips_scb_t            *scb;
3545        Scsi_Cmnd            *SC;
3546        Scsi_Cmnd            *p;
3547        Scsi_Cmnd            *q;
3548        ips_copp_wait_item_t *item;
3549        int                   ret;
3550        int                   intr_status;
3551        unsigned long         cpu_flags;
3552        unsigned long         cpu_flags2;
3553     
3554        METHOD_TRACE("ips_next", 1);
3555     
3556        if (!ha)
3557           return ;
3558     
3559        /*
3560         * Block access to the queue function so
3561         * this command won't time out
3562         */
3563        if (intr == IPS_INTR_ON) {
3564            spin_lock_irqsave(&io_request_lock, cpu_flags2);
3565            intr_status = IPS_INTR_IORL;
3566        } else {
3567            intr_status = intr;
3568     
3569            /* Quiet the compiler */
3570            cpu_flags2 = 0;
3571        }
3572     
3573        if (ha->subsys->param[3] & 0x300000) {
3574           struct timeval tv;
3575     
3576           do_gettimeofday(&tv);
3577     
3578           IPS_HA_LOCK(cpu_flags);
3579           if (tv.tv_sec - ha->last_ffdc > IPS_SECS_8HOURS) {
3580              ha->last_ffdc = tv.tv_sec;
3581              IPS_HA_UNLOCK(cpu_flags);
3582              ips_ffdc_time(ha, intr_status);
3583           } else {
3584              IPS_HA_UNLOCK(cpu_flags);
3585           }
3586        }
3587     
3588        if (intr == IPS_INTR_ON)
3589            spin_unlock_irqrestore(&io_request_lock, cpu_flags2);
3590     
3591     #ifndef NO_IPS_CMDLINE
3592        /*
3593         * Send passthru commands
3594         * These have priority over normal I/O
3595         * but shouldn't affect performance too much
3596         * since we limit the number that can be active
3597         * on the card at any one time
3598         */
3599        IPS_HA_LOCK(cpu_flags);
3600        IPS_QUEUE_LOCK(&ha->copp_waitlist);
3601        while ((ha->num_ioctl < IPS_MAX_IOCTL) &&
3602               (ha->copp_waitlist.head) &&
3603               (scb = ips_getscb(ha))) {
3604     
3605           IPS_QUEUE_UNLOCK(&ha->copp_waitlist);
3606           item = ips_removeq_copp_head(&ha->copp_waitlist);
3607           IPS_HA_UNLOCK(cpu_flags);
3608           scb->scsi_cmd = item->scsi_cmd;
3609           scb->sem = item->sem;
3610           kfree(item);
3611     
3612           ret = ips_make_passthru(ha, scb->scsi_cmd, scb, intr);
3613     
3614           switch (ret) {
3615           case IPS_FAILURE:
3616              if (scb->scsi_cmd) {
3617                 scb->scsi_cmd->result = DID_ERROR << 16;
3618     
3619                 /* raise the semaphore */
3620                 if (scb->scsi_cmd->cmnd[0] == IPS_IOCTL_NEW_COMMAND) {
3621                    u32 datasize;
3622     
3623                    datasize = 0;
3624                    memcpy(&scb->scsi_cmd->cmnd[8], &datasize, 4);
3625                    up(scb->sem);
3626                 } else {
3627                    scb->scsi_cmd->scsi_done(scb->scsi_cmd);
3628                 }
3629              }
3630     
3631              ips_freescb(ha, scb);
3632              break;
3633           case IPS_SUCCESS_IMM:
3634              if (scb->scsi_cmd) {
3635                 scb->scsi_cmd->result = DID_OK << 16;
3636     
3637                 /* raise the semaphore */
3638                 if (scb->scsi_cmd->cmnd[0] == IPS_IOCTL_NEW_COMMAND) {
3639                    u32 datasize;
3640     
3641                    datasize = 0;
3642                    memcpy(&scb->scsi_cmd->cmnd[8], &datasize, 4);
3643                    up(scb->sem);
3644                 } else {
3645                    scb->scsi_cmd->scsi_done(scb->scsi_cmd);
3646                 }
3647              }
3648     
3649              ips_freescb(ha, scb);
3650              break;
3651           default:
3652              break;
3653           } /* end case */
3654     
3655           if (ret != IPS_SUCCESS) {
3656              IPS_HA_LOCK(cpu_flags);
3657              IPS_QUEUE_LOCK(&ha->copp_waitlist);
3658              continue;
3659           }
3660     
3661           ret = ips_send_cmd(ha, scb);
3662     
3663           if (ret == IPS_SUCCESS) {
3664              ips_putq_scb_head(&ha->scb_activelist, scb);
3665              ha->num_ioctl++;
3666           }
3667     
3668           switch(ret) {
3669           case IPS_FAILURE:
3670              if (scb->scsi_cmd) {
3671                 /* raise the semaphore */
3672                 if (scb->scsi_cmd->cmnd[0] == IPS_IOCTL_NEW_COMMAND)
3673                    up(scb->sem);
3674     
3675                 scb->scsi_cmd->result = DID_ERROR << 16;
3676              }
3677     
3678              ips_freescb(ha, scb);
3679              break;
3680           case IPS_SUCCESS_IMM:
3681              if (scb->scsi_cmd) {
3682                 /* raise the semaphore */
3683                 if (scb->scsi_cmd->cmnd[0] == IPS_IOCTL_NEW_COMMAND)
3684                    up(scb->sem);
3685              }
3686     
3687              ips_freescb(ha, scb);
3688              break;
3689           default:
3690              break;
3691           } /* end case */
3692     
3693           IPS_HA_LOCK(cpu_flags);
3694           IPS_QUEUE_LOCK(&ha->copp_waitlist);
3695        }
3696     
3697        IPS_QUEUE_UNLOCK(&ha->copp_waitlist);
3698        IPS_HA_UNLOCK(cpu_flags);
3699     #endif
3700     
3701        /*
3702         * Send "Normal" I/O commands
3703         */
3704        IPS_HA_LOCK(cpu_flags);
3705        IPS_QUEUE_LOCK(&ha->scb_waitlist);
3706        p = ha->scb_waitlist.head;
3707        IPS_QUEUE_UNLOCK(&ha->scb_waitlist);
3708        while ((p) && (scb = ips_getscb(ha))) {
3709           if ((p->channel > 0) && (ha->dcdb_active[p->channel-1] & (1 << p->target))) {
3710              ips_freescb(ha, scb);
3711              p = (Scsi_Cmnd *) p->host_scribble;
3712              continue;
3713           }
3714     
3715           q = p;
3716           SC = ips_removeq_wait(&ha->scb_waitlist, q);
3717           if (SC == NULL)                    /* Should never happen, but good to check anyway */
3718              continue;
3719           
3720           IPS_HA_UNLOCK(cpu_flags);          /* Unlock HA after command is taken off queue */
3721     
3722           SC->result = DID_OK;
3723           SC->host_scribble = NULL;
3724     
3725           memset(SC->sense_buffer, 0, sizeof(SC->sense_buffer));
3726     
3727           scb->target_id = SC->target;
3728           scb->lun = SC->lun;
3729           scb->bus = SC->channel;
3730           scb->scsi_cmd = SC;
3731           scb->breakup = 0;
3732           scb->data_len = 0;
3733           scb->callback = ipsintr_done;
3734           scb->timeout = ips_cmd_timeout;
3735           memset(&scb->cmd, 0, 16);
3736     
3737           /* copy in the CDB */
3738           memcpy(scb->cdb, SC->cmnd, SC->cmd_len);
3739     
3740           /* Now handle the data buffer */
3741           if (SC->use_sg) {
3742              struct scatterlist *sg;
3743              int                 i;
3744     
3745              sg = SC->request_buffer;
3746     
3747              if (SC->use_sg == 1) {
3748                 if (sg[0].length > ha->max_xfer) {
3749                    scb->breakup = 1;
3750                    scb->data_len = ha->max_xfer;
3751                 } else
3752                    scb->data_len = sg[0].length;
3753     
3754                 scb->dcdb.transfer_length = scb->data_len;
3755                 scb->data_busaddr = VIRT_TO_BUS(sg[0].address);
3756                 scb->sg_len = 0;
3757              } else {
3758                 /* Check for the first Element being bigger than MAX_XFER */
3759                 if (sg[0].length > ha->max_xfer) {
3760                    scb->sg_list[0].address = VIRT_TO_BUS(sg[0].address);
3761                    scb->sg_list[0].length = ha->max_xfer;
3762                    scb->data_len = ha->max_xfer;
3763                    scb->breakup = 0; 
3764     	            scb->sg_break=1;  
3765                    scb->sg_len = 1;
3766     	         }
3767                 else {
3768                    for (i = 0; i < SC->use_sg; i++) {
3769                       scb->sg_list[i].address = VIRT_TO_BUS(sg[i].address);
3770                       scb->sg_list[i].length = sg[i].length;
3771                 
3772                       if (scb->data_len + sg[i].length > ha->max_xfer) {
3773                          /*
3774                           * Data Breakup required
3775                           */
3776                          scb->breakup = i;
3777                          break;
3778                       }
3779     
3780                       scb->data_len += sg[i].length;
3781                    }
3782     
3783                    if (!scb->breakup)
3784                       scb->sg_len = SC->use_sg;
3785                    else
3786                       scb->sg_len = scb->breakup;
3787                 }
3788     
3789                 scb->dcdb.transfer_length = scb->data_len;
3790                 scb->data_busaddr = VIRT_TO_BUS(scb->sg_list);
3791              }
3792           } else {
3793              if (SC->request_bufflen) {
3794                 if (SC->request_bufflen > ha->max_xfer) {
3795                    /*
3796                     * Data breakup required
3797                     */
3798                    scb->breakup = 1;
3799                    scb->data_len = ha->max_xfer;
3800                 } else {
3801                    scb->data_len = SC->request_bufflen;
3802                 }
3803     
3804                 scb->dcdb.transfer_length = scb->data_len;
3805                 scb->data_busaddr = VIRT_TO_BUS(SC->request_buffer);
3806                 scb->sg_len = 0;
3807              } else {
3808                 scb->data_busaddr = 0L;
3809                 scb->sg_len = 0;
3810                 scb->data_len = 0;
3811                 scb->dcdb.transfer_length = 0;
3812              }
3813     
3814           }
3815     
3816           scb->dcdb.cmd_attribute |=
3817              ips_command_direction[scb->scsi_cmd->cmnd[0]];
3818     
3819           if (!scb->dcdb.cmd_attribute & 0x3)
3820              scb->dcdb.transfer_length = 0;
3821     
3822           if (scb->data_len >= IPS_MAX_XFER) {
3823              scb->dcdb.cmd_attribute |= IPS_TRANSFER64K;
3824              scb->dcdb.transfer_length = 0;
3825           }
3826     
3827           ret = ips_send_cmd(ha, scb);
3828     
3829           if (ret == IPS_SUCCESS)
3830              ips_putq_scb_head(&ha->scb_activelist, scb);
3831     
3832           switch(ret) {
3833           case IPS_FAILURE:
3834              if (scb->scsi_cmd) {
3835                 scb->scsi_cmd->result = DID_ERROR << 16;
3836                 scb->scsi_cmd->scsi_done(scb->scsi_cmd);
3837              }
3838     
3839              if (scb->bus)
3840                 ha->dcdb_active[scb->bus-1] &= ~(1 << scb->target_id);
3841     
3842              ips_freescb(ha, scb);
3843              break;
3844           case IPS_SUCCESS_IMM:
3845              if (scb->scsi_cmd)
3846                 scb->scsi_cmd->scsi_done(scb->scsi_cmd);
3847     
3848              if (scb->bus)
3849                 ha->dcdb_active[scb->bus-1] &= ~(1 << scb->target_id);
3850     
3851              ips_freescb(ha, scb);
3852              break;
3853           default:
3854              break;
3855           } /* end case */
3856     
3857           p = (Scsi_Cmnd *) p->host_scribble;
3858     
3859           IPS_HA_LOCK(cpu_flags);
3860        } /* end while */
3861     
3862        IPS_HA_UNLOCK(cpu_flags);
3863     }
3864     
3865     /****************************************************************************/
3866     /*                                                                          */
3867     /* Routine Name: ips_putq_scb_head                                          */
3868     /*                                                                          */
3869     /* Routine Description:                                                     */
3870     /*                                                                          */
3871     /*   Add an item to the head of the queue                                   */
3872     /*                                                                          */
3873     /* ASSUMED to be called from within a lock                                  */
3874     /*                                                                          */
3875     /****************************************************************************/
3876     static inline void
3877     ips_putq_scb_head(ips_scb_queue_t *queue, ips_scb_t *item) {
3878        METHOD_TRACE("ips_putq_scb_head", 1);
3879     
3880        if (!item)
3881           return ;
3882     
3883        IPS_QUEUE_LOCK(queue);
3884     
3885        item->q_next = queue->head;
3886        queue->head = item;
3887     
3888        if (!queue->tail)
3889           queue->tail = item;
3890     
3891        queue->count++;
3892     
3893        IPS_QUEUE_UNLOCK(queue);
3894     }
3895     
3896     /****************************************************************************/
3897     /*                                                                          */
3898     /* Routine Name: ips_putq_scb_tail                                          */
3899     /*                                                                          */
3900     /* Routine Description:                                                     */
3901     /*                                                                          */
3902     /*   Add an item to the tail of the queue                                   */
3903     /*                                                                          */
3904     /* ASSUMED to be called from within a lock                                  */
3905     /*                                                                          */
3906     /****************************************************************************/
3907     static inline void
3908     ips_putq_scb_tail(ips_scb_queue_t *queue, ips_scb_t *item) {
3909        METHOD_TRACE("ips_putq_scb_tail", 1);
3910     
3911        if (!item)
3912           return ;
3913     
3914        IPS_QUEUE_LOCK(queue);
3915     
3916        item->q_next = NULL;
3917     
3918        if (queue->tail)
3919           queue->tail->q_next = item;
3920     
3921        queue->tail = item;
3922     
3923        if (!queue->head)
3924           queue->head = item;
3925     
3926        queue->count++;
3927     
3928        IPS_QUEUE_UNLOCK(queue);
3929     }
3930     
3931     /****************************************************************************/
3932     /*                                                                          */
3933     /* Routine Name: ips_removeq_scb_head                                       */
3934     /*                                                                          */
3935     /* Routine Description:                                                     */
3936     /*                                                                          */
3937     /*   Remove the head of the queue                                           */
3938     /*                                                                          */
3939     /* ASSUMED to be called from within a lock                                  */
3940     /*                                                                          */
3941     /****************************************************************************/
3942     static inline ips_scb_t *
3943     ips_removeq_scb_head(ips_scb_queue_t *queue) {
3944        ips_scb_t  *item;
3945     
3946        METHOD_TRACE("ips_removeq_scb_head", 1);
3947     
3948        IPS_QUEUE_LOCK(queue);
3949     
3950        item = queue->head;
3951     
3952        if (!item) {
3953           IPS_QUEUE_UNLOCK(queue);
3954     
3955           return (NULL);
3956        }
3957     
3958        queue->head = item->q_next;
3959        item->q_next = NULL;
3960     
3961        if (queue->tail == item)
3962           queue->tail = NULL;
3963     
3964        queue->count--;
3965     
3966        IPS_QUEUE_UNLOCK(queue);
3967     
3968        return (item);
3969     }
3970     
3971     /****************************************************************************/
3972     /*                                                                          */
3973     /* Routine Name: ips_removeq_scb                                            */
3974     /*                                                                          */
3975     /* Routine Description:                                                     */
3976     /*                                                                          */
3977     /*   Remove an item from a queue                                            */
3978     /*                                                                          */
3979     /* ASSUMED to be called from within a lock                                  */
3980     /*                                                                          */
3981     /****************************************************************************/
3982     static inline ips_scb_t *
3983     ips_removeq_scb(ips_scb_queue_t *queue, ips_scb_t *item) {
3984        ips_scb_t  *p;
3985     
3986        METHOD_TRACE("ips_removeq_scb", 1);
3987     
3988        if (!item)
3989           return (NULL);
3990     
3991        IPS_QUEUE_LOCK(queue);
3992     
3993        if (item == queue->head) {
3994           IPS_QUEUE_UNLOCK(queue);
3995     
3996           return (ips_removeq_scb_head(queue));
3997        }
3998     
3999        p = queue->head;
4000     
4001        while ((p) && (item != p->q_next))
4002           p = p->q_next;
4003     
4004        if (p) {
4005           /* found a match */
4006           p->q_next = item->q_next;
4007     
4008           if (!item->q_next)
4009              queue->tail = p;
4010     
4011           item->q_next = NULL;
4012           queue->count--;
4013     
4014           IPS_QUEUE_UNLOCK(queue);
4015     
4016           return (item);
4017        }
4018     
4019        IPS_QUEUE_UNLOCK(queue);
4020     
4021        return (NULL);
4022     }
4023     
4024     /****************************************************************************/
4025     /*                                                                          */
4026     /* Routine Name: ips_putq_wait_head                                         */
4027     /*                                                                          */
4028     /* Routine Description:                                                     */
4029     /*                                                                          */
4030     /*   Add an item to the head of the queue                                   */
4031     /*                                                                          */
4032     /* ASSUMED to be called from within a lock                                  */
4033     /*                                                                          */
4034     /****************************************************************************/
4035     static inline void
4036     ips_putq_wait_head(ips_wait_queue_t *queue, Scsi_Cmnd *item) {
4037        METHOD_TRACE("ips_putq_wait_head", 1);
4038     
4039        if (!item)
4040           return ;
4041     
4042        IPS_QUEUE_LOCK(queue);
4043     
4044        item->host_scribble = (char *) queue->head;
4045        queue->head = item;
4046     
4047        if (!queue->tail)
4048           queue->tail = item;
4049     
4050        queue->count++;
4051     
4052        IPS_QUEUE_UNLOCK(queue);
4053     }
4054     
4055     /****************************************************************************/
4056     /*                                                                          */
4057     /* Routine Name: ips_putq_wait_tail                                         */
4058     /*                                                                          */
4059     /* Routine Description:                                                     */
4060     /*                                                                          */
4061     /*   Add an item to the tail of the queue                                   */
4062     /*                                                                          */
4063     /* ASSUMED to be called from within a lock                                  */
4064     /*                                                                          */
4065     /****************************************************************************/
4066     static inline void
4067     ips_putq_wait_tail(ips_wait_queue_t *queue, Scsi_Cmnd *item) {
4068        METHOD_TRACE("ips_putq_wait_tail", 1);
4069     
4070        if (!item)
4071           return ;
4072     
4073        IPS_QUEUE_LOCK(queue);
4074     
4075        item->host_scribble = NULL;
4076     
4077        if (queue->tail)
4078           queue->tail->host_scribble = (char *)item;
4079     
4080        queue->tail = item;
4081     
4082        if (!queue->head)
4083           queue->head = item;
4084     
4085        queue->count++;
4086     
4087        IPS_QUEUE_UNLOCK(queue);
4088     }
4089     
4090     /****************************************************************************/
4091     /*                                                                          */
4092     /* Routine Name: ips_removeq_wait_head                                      */
4093     /*                                                                          */
4094     /* Routine Description:                                                     */
4095     /*                                                                          */
4096     /*   Remove the head of the queue                                           */
4097     /*                                                                          */
4098     /* ASSUMED to be called from within a lock                                  */
4099     /*                                                                          */
4100     /****************************************************************************/
4101     static inline Scsi_Cmnd *
4102     ips_removeq_wait_head(ips_wait_queue_t *queue) {
4103        Scsi_Cmnd  *item;
4104     
4105        METHOD_TRACE("ips_removeq_wait_head", 1);
4106     
4107        IPS_QUEUE_LOCK(queue);
4108     
4109        item = queue->head;
4110     
4111        if (!item) {
4112           IPS_QUEUE_UNLOCK(queue);
4113     
4114           return (NULL);
4115        }
4116     
4117        queue->head = (Scsi_Cmnd *) item->host_scribble;
4118        item->host_scribble = NULL;
4119     
4120        if (queue->tail == item)
4121           queue->tail = NULL;
4122     
4123        queue->count--;
4124     
4125        IPS_QUEUE_UNLOCK(queue);
4126     
4127        return (item);
4128     }
4129     
4130     /****************************************************************************/
4131     /*                                                                          */
4132     /* Routine Name: ips_removeq_wait                                           */
4133     /*                                                                          */
4134     /* Routine Description:                                                     */
4135     /*                                                                          */
4136     /*   Remove an item from a queue                                            */
4137     /*                                                                          */
4138     /* ASSUMED to be called from within a lock                                  */
4139     /*                                                                          */
4140     /****************************************************************************/
4141     static inline Scsi_Cmnd *
4142     ips_removeq_wait(ips_wait_queue_t *queue, Scsi_Cmnd *item) {
4143        Scsi_Cmnd  *p;
4144     
4145        METHOD_TRACE("ips_removeq_wait", 1);
4146     
4147        if (!item)
4148           return (NULL);
4149     
4150        IPS_QUEUE_LOCK(queue);
4151     
4152        if (item == queue->head) {
4153           IPS_QUEUE_UNLOCK(queue);
4154     
4155           return (ips_removeq_wait_head(queue));
4156        }
4157     
4158        p = queue->head;
4159     
4160        while ((p) && (item != (Scsi_Cmnd *) p->host_scribble))
4161           p = (Scsi_Cmnd *) p->host_scribble;
4162     
4163        if (p) {
4164           /* found a match */
4165           p->host_scribble = item->host_scribble;
4166     
4167           if (!item->host_scribble)
4168              queue->tail = p;
4169     
4170           item->host_scribble = NULL;
4171           queue->count--;
4172     
4173           IPS_QUEUE_UNLOCK(queue);
4174     
4175           return (item);
4176        }
4177     
4178        IPS_QUEUE_UNLOCK(queue);
4179     
4180        return (NULL);
4181     }
4182     
4183     /****************************************************************************/
4184     /*                                                                          */
4185     /* Routine Name: ips_putq_copp_head                                         */
4186     /*                                                                          */
4187     /* Routine Description:                                                     */
4188     /*                                                                          */
4189     /*   Add an item to the head of the queue                                   */
4190     /*                                                                          */
4191     /* ASSUMED to be called from within a lock                                  */
4192     /*                                                                          */
4193     /****************************************************************************/
4194     static inline void
4195     ips_putq_copp_head(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) {
4196        METHOD_TRACE("ips_putq_copp_head", 1);
4197     
4198        if (!item)
4199           return ;
4200     
4201        IPS_QUEUE_LOCK(queue);
4202     
4203        item->next = queue->head;
4204        queue->head = item;
4205     
4206        if (!queue->tail)
4207           queue->tail = item;
4208     
4209        queue->count++;
4210     
4211        IPS_QUEUE_UNLOCK(queue);
4212     }
4213     
4214     /****************************************************************************/
4215     /*                                                                          */
4216     /* Routine Name: ips_putq_copp_tail                                         */
4217     /*                                                                          */
4218     /* Routine Description:                                                     */
4219     /*                                                                          */
4220     /*   Add an item to the tail of the queue                                   */
4221     /*                                                                          */
4222     /* ASSUMED to be called from within a lock                                  */
4223     /*                                                                          */
4224     /****************************************************************************/
4225     static inline void
4226     ips_putq_copp_tail(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) {
4227        METHOD_TRACE("ips_putq_copp_tail", 1);
4228     
4229        if (!item)
4230           return ;
4231     
4232        IPS_QUEUE_LOCK(queue);
4233     
4234        item->next = NULL;
4235     
4236        if (queue->tail)
4237           queue->tail->next = item;
4238     
4239        queue->tail = item;
4240     
4241        if (!queue->head)
4242           queue->head = item;
4243     
4244        queue->count++;
4245     
4246        IPS_QUEUE_UNLOCK(queue);
4247     }
4248     
4249     /****************************************************************************/
4250     /*                                                                          */
4251     /* Routine Name: ips_removeq_copp_head                                      */
4252     /*                                                                          */
4253     /* Routine Description:                                                     */
4254     /*                                                                          */
4255     /*   Remove the head of the queue                                           */
4256     /*                                                                          */
4257     /* ASSUMED to be called from within a lock                                  */
4258     /*                                                                          */
4259     /****************************************************************************/
4260     static inline ips_copp_wait_item_t *
4261     ips_removeq_copp_head(ips_copp_queue_t *queue) {
4262        ips_copp_wait_item_t *item;
4263     
4264        METHOD_TRACE("ips_removeq_copp_head", 1);
4265     
4266        IPS_QUEUE_LOCK(queue);
4267     
4268        item = queue->head;
4269     
4270        if (!item) {
4271           IPS_QUEUE_UNLOCK(queue);
4272     
4273           return (NULL);
4274        }
4275     
4276        queue->head = item->next;
4277        item->next = NULL;
4278     
4279        if (queue->tail == item)
4280           queue->tail = NULL;
4281     
4282        queue->count--;
4283     
4284        IPS_QUEUE_UNLOCK(queue);
4285     
4286        return (item);
4287     }
4288     
4289     /****************************************************************************/
4290     /*                                                                          */
4291     /* Routine Name: ips_removeq_copp                                           */
4292     /*                                                                          */
4293     /* Routine Description:                                                     */
4294     /*                                                                          */
4295     /*   Remove an item from a queue                                            */
4296     /*                                                                          */
4297     /* ASSUMED to be called from within a lock                                  */
4298     /*                                                                          */
4299     /****************************************************************************/
4300     static inline ips_copp_wait_item_t *
4301     ips_removeq_copp(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) {
4302        ips_copp_wait_item_t *p;
4303     
4304        METHOD_TRACE("ips_removeq_copp", 1);
4305     
4306        if (!item)
4307           return (NULL);
4308     
4309        IPS_QUEUE_LOCK(queue);
4310     
4311        if (item == queue->head) {
4312           IPS_QUEUE_UNLOCK(queue);
4313     
4314           return (ips_removeq_copp_head(queue));
4315        }
4316     
4317        p = queue->head;
4318     
4319        while ((p) && (item != p->next))
4320           p = p->next;
4321     
4322        if (p) {
4323           /* found a match */
4324           p->next = item->next;
4325     
4326           if (!item->next)
4327              queue->tail = p;
4328     
4329           item->next = NULL;
4330           queue->count--;
4331     
4332           IPS_QUEUE_UNLOCK(queue);
4333     
4334           return (item);
4335        }
4336     
4337        IPS_QUEUE_UNLOCK(queue);
4338     
4339        return (NULL);
4340     }
4341     
4342     /****************************************************************************/
4343     /*                                                                          */
4344     /* Routine Name: ipsintr_blocking                                           */
4345     /*                                                                          */
4346     /* Routine Description:                                                     */
4347     /*                                                                          */
4348     /*   Finalize an interrupt for internal commands                            */
4349     /*                                                                          */
4350     /****************************************************************************/
4351     static void
4352     ipsintr_blocking(ips_ha_t *ha, ips_scb_t *scb) {
4353        METHOD_TRACE("ipsintr_blocking", 2);
4354     
4355        if ((ha->waitflag == TRUE) &&
4356            (ha->cmd_in_progress == scb->cdb[0])) {
4357           ha->waitflag = FALSE;
4358     
4359           return ;
4360        }
4361     }
4362     
4363     /****************************************************************************/
4364     /*                                                                          */
4365     /* Routine Name: ipsintr_done                                               */
4366     /*                                                                          */
4367     /* Routine Description:                                                     */
4368     /*                                                                          */
4369     /*   Finalize an interrupt for non-internal commands                        */
4370     /*                                                                          */
4371     /****************************************************************************/
4372     static void
4373     ipsintr_done(ips_ha_t *ha, ips_scb_t *scb) {
4374        METHOD_TRACE("ipsintr_done", 2);
4375     
4376        if (!scb) {
4377           printk(KERN_WARNING "(%s%d) Spurious interrupt; scb NULL.\n",
4378                  ips_name, ha->host_num);
4379     
4380           return ;
4381        }
4382     
4383        if (scb->scsi_cmd == NULL) {
4384           /* unexpected interrupt */
4385           printk(KERN_WARNING "(%s%d) Spurious interrupt; scsi_cmd not set.\n",
4386                  ips_name, ha->host_num);
4387     
4388           return;
4389        }
4390     
4391        ips_done(ha, scb);
4392     }
4393     
4394     /****************************************************************************/
4395     /*                                                                          */
4396     /* Routine Name: ips_done                                                   */
4397     /*                                                                          */
4398     /* Routine Description:                                                     */
4399     /*                                                                          */
4400     /*   Do housekeeping on completed commands                                  */
4401     /*                                                                          */
4402     /****************************************************************************/
4403     static void
4404     ips_done(ips_ha_t *ha, ips_scb_t *scb) {
4405        int ret;
4406        unsigned long cpu_flags;
4407     
4408        METHOD_TRACE("ips_done", 1);
4409     
4410        if (!scb)
4411           return ;
4412     
4413     #ifndef NO_IPS_CMDLINE
4414        if ((scb->scsi_cmd) && (ips_is_passthru(scb->scsi_cmd))) {
4415           ips_cleanup_passthru(ha, scb);
4416           IPS_HA_LOCK(cpu_flags);
4417           ha->num_ioctl--;
4418           IPS_HA_UNLOCK(cpu_flags);
4419        } else {
4420     #endif
4421           /*
4422            * Check to see if this command had too much
4423            * data and had to be broke up.  If so, queue
4424            * the rest of the data and continue.
4425            */
4426           if (scb->breakup || scb->sg_break) { 
4427              /* We had a data breakup */
4428              u8 bk_save;
4429     
4430              bk_save = scb->breakup;
4431              scb->breakup = 0;
4432     
4433              if (scb->scsi_cmd->use_sg) {
4434                 /* S/G request */
4435                 struct scatterlist *sg;
4436                 int                 i;
4437     
4438                 sg = scb->scsi_cmd->request_buffer;
4439     
4440                 if (scb->scsi_cmd->use_sg == 1) {
4441                    if (sg[0].length - (bk_save * ha->max_xfer)) {
4442                       /* Further breakup required */
4443                       scb->data_len = ha->max_xfer;
4444                       scb->data_busaddr = VIRT_TO_BUS(sg[0].address + (bk_save * ha->max_xfer));
4445                       scb->breakup = bk_save + 1;
4446                    } else {
4447                       scb->data_len = sg[0].length - (bk_save * ha->max_xfer);
4448                       scb->data_busaddr = VIRT_TO_BUS(sg[0].address + (bk_save * ha->max_xfer));
4449                    }
4450     
4451                    scb->dcdb.transfer_length = scb->data_len;
4452                    scb->sg_len = 0;
4453                 } else {
4454                    /* We're here because there was MORE than one s/g unit. */
4455     	            /* bk_save points to which sg unit to look at           */
4456     	            /* sg_break points to how far through this unit we are  */
4457     	            /* NOTE: We will not move from one sg to another here,  */
4458                    /*    just finish the one we are in.  Not the most      */
4459                    /*    efficient, but it keeps it from getting too hacky */
4460     
4461     		         /* IF sg_break is non-zero, then just work on this current sg piece, */
4462                    /* pointed to by bk_save                                             */
4463                    if (scb->sg_break) {
4464                       scb->sg_len = 1;
4465             			   scb->sg_list[0].address = VIRT_TO_BUS(sg[bk_save].address+ha->max_xfer*scb->sg_break);
4466                       if (ha->max_xfer > sg[bk_save].length-ha->max_xfer * scb->sg_break) 
4467                          scb->sg_list[0].length = sg[bk_save].length-ha->max_xfer * scb->sg_break;
4468                       else 
4469                          scb->sg_list[0].length = ha->max_xfer;
4470                       scb->sg_break++;              /* MUST GO HERE for math below to work */
4471     			         scb->data_len = scb->sg_list[0].length;;
4472     
4473     		            if (sg[bk_save].length <= ha->max_xfer * scb->sg_break ) {
4474                          scb->sg_break = 0;         /* No more work in this unit */
4475                          if (( bk_save + 1 ) >= scb->scsi_cmd->use_sg) 
4476                             scb->breakup = 0;
4477                          else 
4478                             scb->breakup = bk_save + 1;
4479                       }
4480                    } else {
4481     			         /* ( sg_break == 0 ), so this is our first look at a new sg piece */
4482                       if (sg[bk_save].length > ha->max_xfer) {
4483     			            scb->sg_list[0].address = VIRT_TO_BUS(sg[bk_save].address);
4484     				         scb->sg_list[0].length = ha->max_xfer;
4485     				         scb->breakup = bk_save;
4486     				         scb->sg_break = 1;
4487     				         scb->data_len = ha->max_xfer;
4488     				         scb->sg_len = 1;
4489      	        		   } else {
4490     				         /* OK, the next sg is a short one, so loop until full */
4491     			            scb->data_len = 0;
4492     		     	         scb->sg_len = 0;
4493           			      scb->sg_break = 0;
4494                          /*   We're only doing full units here */
4495     				         for (i = bk_save; i < scb->scsi_cmd->use_sg; i++) {
4496     					         scb->sg_list[i - bk_save].address = VIRT_TO_BUS(sg[i].address);
4497     				            scb->sg_list[i - bk_save].length = sg[i].length;
4498                             if (scb->data_len + sg[i].length > ha->max_xfer) {
4499     					            scb->breakup = i;  /* sneaky, if not more work, than breakup is 0 */
4500     					            break;
4501     					         }
4502     					         scb->data_len += sg[i].length;
4503     					         scb->sg_len++;           /* only if we didn't get too big */
4504     		  		         }
4505     			         }
4506     		         }
4507     
4508                    /* Also, we need to be sure we don't queue work ( breakup != 0 )
4509                       if no more sg units for next time */
4510                    scb->dcdb.transfer_length = scb->data_len;
4511                    scb->data_busaddr = VIRT_TO_BUS(scb->sg_list);
4512                 }
4513              } else {
4514                 /* Non S/G Request */
4515                 if ((scb->scsi_cmd->request_bufflen - (bk_save * ha->max_xfer)) > ha->max_xfer) {
4516                    /* Further breakup required */
4517                    scb->data_len = ha->max_xfer;
4518                    scb->data_busaddr = VIRT_TO_BUS(scb->scsi_cmd->request_buffer + (bk_save * ha->max_xfer));
4519                    scb->breakup = bk_save + 1;
4520                 } else {
4521                    scb->data_len = scb->scsi_cmd->request_bufflen - (bk_save * ha->max_xfer);
4522                    scb->data_busaddr = VIRT_TO_BUS(scb->scsi_cmd->request_buffer + (bk_save * ha->max_xfer));
4523                 }
4524     
4525                 scb->dcdb.transfer_length = scb->data_len;
4526                 scb->sg_len = 0;
4527              }
4528     
4529              scb->dcdb.cmd_attribute |=
4530                 ips_command_direction[scb->scsi_cmd->cmnd[0]];
4531     
4532              if (!scb->dcdb.cmd_attribute & 0x3)
4533                 scb->dcdb.transfer_length = 0;
4534     
4535              if (scb->data_len >= IPS_MAX_XFER) {
4536                 scb->dcdb.cmd_attribute |= IPS_TRANSFER64K;
4537                 scb->dcdb.transfer_length = 0;
4538              }
4539     
4540              ret = ips_send_cmd(ha, scb);
4541     
4542              switch(ret) {
4543              case IPS_FAILURE:
4544                 if (scb->scsi_cmd) {
4545                    scb->scsi_cmd->result = DID_ERROR << 16;
4546                    scb->scsi_cmd->scsi_done(scb->scsi_cmd);
4547                 }
4548     
4549                 ips_freescb(ha, scb);
4550                 break;
4551              case IPS_SUCCESS_IMM:
4552                 if (scb->scsi_cmd) {
4553                    scb->scsi_cmd->result = DID_ERROR << 16;
4554                    scb->scsi_cmd->scsi_done(scb->scsi_cmd);
4555                 }
4556     
4557                 ips_freescb(ha, scb);
4558                 break;
4559              default:
4560                 break;
4561              } /* end case */
4562     
4563              return ;
4564           }
4565     #ifndef NO_IPS_CMDLINE
4566        } /* end if passthru */
4567     #endif
4568     
4569        if (scb->bus) {
4570           IPS_HA_LOCK(cpu_flags);
4571           ha->dcdb_active[scb->bus-1] &= ~(1 << scb->target_id);
4572           IPS_HA_UNLOCK(cpu_flags);
4573        }
4574     
4575        /* call back to SCSI layer */
4576        if (scb->scsi_cmd && scb->scsi_cmd->cmnd[0] != IPS_IOCTL_NEW_COMMAND)
4577           scb->scsi_cmd->scsi_done(scb->scsi_cmd);
4578     
4579        ips_freescb(ha, scb);
4580     }
4581     
4582     /****************************************************************************/
4583     /*                                                                          */
4584     /* Routine Name: ips_map_status                                             */
4585     /*                                                                          */
4586     /* Routine Description:                                                     */
4587     /*                                                                          */
4588     /*   Map ServeRAID error codes to Linux Error Codes                         */
4589     /*                                                                          */
4590     /****************************************************************************/
4591     static int
4592     ips_map_status(ips_ha_t *ha, ips_scb_t *scb, ips_stat_t *sp) {
4593        int       errcode;
4594        int       device_error;
4595     
4596        METHOD_TRACE("ips_map_status", 1);
4597     
4598        if (scb->bus) {
4599           DEBUG_VAR(2, "(%s%d) Physical device error (%d %d %d): %x %x, Sense Key: %x, ASC: %x, ASCQ: %x",
4600                     ips_name,
4601                     ha->host_num,
4602                     scb->scsi_cmd->channel,
4603                     scb->scsi_cmd->target,
4604                     scb->scsi_cmd->lun,
4605                     scb->basic_status,
4606                     scb->extended_status,
4607                     scb->extended_status == IPS_ERR_CKCOND ? scb->dcdb.sense_info[2] & 0xf : 0,
4608                     scb->extended_status == IPS_ERR_CKCOND ? scb->dcdb.sense_info[12] : 0,
4609                     scb->extended_status == IPS_ERR_CKCOND ? scb->dcdb.sense_info[13] : 0);
4610        }
4611     
4612        /* default driver error */
4613        errcode = DID_ERROR;
4614        device_error = 0;
4615     
4616        switch (scb->basic_status & IPS_GSC_STATUS_MASK) {
4617        case IPS_CMD_TIMEOUT:
4618           errcode = DID_TIME_OUT;
4619           break;
4620     
4621        case IPS_INVAL_OPCO:
4622        case IPS_INVAL_CMD_BLK:
4623        case IPS_INVAL_PARM_BLK:
4624        case IPS_LD_ERROR:
4625        case IPS_CMD_CMPLT_WERROR:
4626           break;
4627     
4628        case IPS_PHYS_DRV_ERROR:
4629           switch (scb->extended_status) {
4630           case IPS_ERR_SEL_TO:
4631              if (scb->bus)
4632                 errcode = DID_NO_CONNECT;
4633     
4634              break;
4635     
4636           case IPS_ERR_OU_RUN:
4637              if ((scb->bus) && (scb->dcdb.transfer_length < scb->data_len)) {
4638                 /* Underrun - set default to no error */
4639                 errcode = DID_OK;
4640     
4641                 /* Restrict access to physical DASD */
4642                 if ((scb->scsi_cmd->cmnd[0] == INQUIRY) &&
4643                     ((((char *) scb->scsi_cmd->buffer)[0] & 0x1f) == TYPE_DISK)) {
4644                    /* underflow -- no error               */
4645                    /* restrict access to physical DASD    */
4646                    errcode = DID_TIME_OUT;
4647                    break;
4648                 }
4649              } else
4650                 errcode = DID_ERROR;
4651     
4652              break;
4653     
4654           case IPS_ERR_RECOVERY:
4655              /* don't fail recovered errors */
4656              if (scb->bus)
4657                 errcode = DID_OK;
4658     
4659              break;
4660     
4661           case IPS_ERR_HOST_RESET:
4662           case IPS_ERR_DEV_RESET:
4663              errcode = DID_RESET;
4664              break;
4665     
4666           case IPS_ERR_CKCOND:
4667              if (scb->bus) {
4668                 memcpy(scb->scsi_cmd->sense_buffer, scb->dcdb.sense_info,
4669                        sizeof(scb->scsi_cmd->sense_buffer));
4670     
4671                 device_error = 2; /* check condition */
4672              }
4673     
4674              errcode = DID_OK;
4675     
4676              break;
4677     
4678           default:
4679              errcode = DID_ERROR;
4680              break;
4681     
4682           } /* end switch */
4683        } /* end switch */
4684     
4685        scb->scsi_cmd->result = device_error | (errcode << 16);
4686     
4687        return (1);
4688     }
4689     
4690     /****************************************************************************/
4691     /*                                                                          */
4692     /* Routine Name: ips_send                                                   */
4693     /*                                                                          */
4694     /* Routine Description:                                                     */
4695     /*                                                                          */
4696     /*   Wrapper for ips_send_cmd                                               */
4697     /*                                                                          */
4698     /****************************************************************************/
4699     static int
4700     ips_send(ips_ha_t *ha, ips_scb_t *scb, ips_scb_callback callback) {
4701        int ret;
4702     
4703        METHOD_TRACE("ips_send", 1);
4704     
4705        scb->callback = callback;
4706     
4707        ret = ips_send_cmd(ha, scb);
4708     
4709        return (ret);
4710     }
4711     
4712     /****************************************************************************/
4713     /*                                                                          */
4714     /* Routine Name: ips_send_wait                                              */
4715     /*                                                                          */
4716     /* Routine Description:                                                     */
4717     /*                                                                          */
4718     /*   Send a command to the controller and wait for it to return             */
4719     /*                                                                          */
4720     /****************************************************************************/
4721     static int
4722     ips_send_wait(ips_ha_t *ha, ips_scb_t *scb, int timeout, int intr) {
4723        int       ret;
4724     
4725        METHOD_TRACE("ips_send_wait", 1);
4726     
4727        ha->waitflag = TRUE;
4728        ha->cmd_in_progress = scb->cdb[0];
4729     
4730        ret = ips_send(ha, scb, ipsintr_blocking);
4731     
4732        if ((ret == IPS_FAILURE) || (ret == IPS_SUCCESS_IMM))
4733           return (ret);
4734     
4735        ret = ips_wait(ha, timeout, intr);
4736     
4737        return (ret);
4738     }
4739     
4740     /****************************************************************************/
4741     /*                                                                          */
4742     /* Routine Name: ips_send_cmd                                               */
4743     /*                                                                          */
4744     /* Routine Description:                                                     */
4745     /*                                                                          */
4746     /*   Map SCSI commands to ServeRAID commands for logical drives             */
4747     /*                                                                          */
4748     /****************************************************************************/
4749     static int
4750     ips_send_cmd(ips_ha_t *ha, ips_scb_t *scb) {
4751        int       ret;
4752        char     *sp;
4753        int       device_error;
4754       
4755        METHOD_TRACE("ips_send_cmd", 1);
4756     
4757        ret = IPS_SUCCESS;
4758     
4759        if (!scb->scsi_cmd) {
4760           /* internal command */
4761     
4762           if (scb->bus > 0) {
4763              /* ServeRAID commands can't be issued */
4764              /* to real devices -- fail them       */
4765              if ((ha->waitflag == TRUE) &&
4766                  (ha->cmd_in_progress == scb->cdb[0])) {
4767                 ha->waitflag = FALSE;
4768              }
4769     
4770              return (1);
4771           }
4772     #ifndef NO_IPS_CMDLINE
4773        } else if ((scb->bus == 0) && (!ips_is_passthru(scb->scsi_cmd))) {
4774     #else
4775        } else if (scb->bus == 0) {
4776     #endif
4777           /* command to logical bus -- interpret */
4778           ret = IPS_SUCCESS_IMM;
4779     
4780           switch (scb->scsi_cmd->cmnd[0]) {
4781           case ALLOW_MEDIUM_REMOVAL:
4782           case REZERO_UNIT:
4783           case ERASE:
4784           case WRITE_FILEMARKS:
4785           case SPACE:
4786              scb->scsi_cmd->result = DID_ERROR << 16;
4787              break;
4788     
4789           case START_STOP:
4790              scb->scsi_cmd->result = DID_OK << 16;
4791     
4792           case TEST_UNIT_READY:
4793           case INQUIRY:
4794              if (scb->target_id == IPS_ADAPTER_ID) {
4795                 /*
4796                  * Either we have a TUR
4797                  * or we have a SCSI inquiry
4798                  */
4799                 if (scb->scsi_cmd->cmnd[0] == TEST_UNIT_READY)
4800                    scb->scsi_cmd->result = DID_OK << 16;
4801     
4802                 if (scb->scsi_cmd->cmnd[0] == INQUIRY) {
4803                    IPS_INQ_DATA inq;
4804     
4805                    memset(&inq, 0, sizeof(IPS_INQ_DATA));
4806     
4807                    inq.DeviceType = TYPE_PROCESSOR;
4808                    inq.DeviceTypeQualifier = 0;
4809                    inq.RemoveableMedia = 0;
4810                    inq.Versions = 0x1;  /* SCSI I */
4811                    inq.AdditionalLength = 31;
4812                    strncpy(inq.VendorId, "IBM     ", 8);
4813                    strncpy(inq.ProductId, "SERVERAID       ", 16);
4814                    strncpy(inq.ProductRevisionLevel, "1.00", 4);
4815     
4816                    memcpy(scb->scsi_cmd->request_buffer, &inq, scb->scsi_cmd->request_bufflen);
4817     
4818                    scb->scsi_cmd->result = DID_OK << 16;
4819                 }
4820              } else {
4821                 scb->cmd.logical_info.op_code = IPS_CMD_GET_LD_INFO;
4822                 scb->cmd.logical_info.command_id = IPS_COMMAND_ID(ha, scb);
4823                 scb->cmd.logical_info.buffer_addr = VIRT_TO_BUS(&ha->adapt->logical_drive_info);
4824                 scb->cmd.logical_info.reserved = 0;
4825                 scb->cmd.logical_info.reserved2 = 0;
4826                 ret = IPS_SUCCESS;
4827              }
4828     
4829              break;
4830     
4831           case REQUEST_SENSE:
4832              ips_reqsen(ha, scb);
4833              scb->scsi_cmd->result = DID_OK << 16;
4834              break;
4835     
4836           case READ_6:
4837           case WRITE_6:
4838              if (!scb->sg_len) {
4839                 scb->cmd.basic_io.op_code =
4840                 (scb->scsi_cmd->cmnd[0] == READ_6) ? IPS_CMD_READ : IPS_CMD_WRITE;
4841              } else {
4842                 scb->cmd.basic_io.op_code =
4843                 (scb->scsi_cmd->cmnd[0] == READ_6) ? IPS_CMD_READ_SG : IPS_CMD_WRITE_SG;
4844              }
4845     
4846              scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
4847              scb->cmd.basic_io.log_drv = scb->target_id;
4848              scb->cmd.basic_io.sg_count = scb->sg_len;
4849              scb->cmd.basic_io.sg_addr = scb->data_busaddr;
4850     
4851              if (scb->cmd.basic_io.lba)
4852                 scb->cmd.basic_io.lba += scb->cmd.basic_io.sector_count;
4853              else
4854                 scb->cmd.basic_io.lba = (((scb->scsi_cmd->cmnd[1] & 0x1f) << 16) |
4855                                          (scb->scsi_cmd->cmnd[2] << 8) |
4856                                          (scb->scsi_cmd->cmnd[3]));
4857     
4858              scb->cmd.basic_io.sector_count = scb->data_len / IPS_BLKSIZE;
4859     
4860              if (scb->cmd.basic_io.sector_count == 0)
4861                 scb->cmd.basic_io.sector_count = 256;
4862     
4863              scb->cmd.basic_io.reserved = 0;
4864              ret = IPS_SUCCESS;
4865              break;
4866     
4867           case READ_10:
4868           case WRITE_10:
4869              if (!scb->sg_len) {
4870                 scb->cmd.basic_io.op_code =
4871                 (scb->scsi_cmd->cmnd[0] == READ_10) ? IPS_CMD_READ : IPS_CMD_WRITE;
4872              } else {
4873                 scb->cmd.basic_io.op_code =
4874                 (scb->scsi_cmd->cmnd[0] == READ_10) ? IPS_CMD_READ_SG : IPS_CMD_WRITE_SG;
4875              }
4876     
4877              scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
4878              scb->cmd.basic_io.log_drv = scb->target_id;
4879              scb->cmd.basic_io.sg_count = scb->sg_len;
4880              scb->cmd.basic_io.sg_addr = scb->data_busaddr;
4881     
4882              if (scb->cmd.basic_io.lba)
4883                 scb->cmd.basic_io.lba += scb->cmd.basic_io.sector_count;
4884              else
4885                 scb->cmd.basic_io.lba = ((scb->scsi_cmd->cmnd[2] << 24) |
4886                                          (scb->scsi_cmd->cmnd[3] << 16) |
4887                                          (scb->scsi_cmd->cmnd[4] << 8) |
4888                                          scb->scsi_cmd->cmnd[5]);
4889     
4890              scb->cmd.basic_io.sector_count = scb->data_len / IPS_BLKSIZE;
4891     
4892              scb->cmd.basic_io.reserved = 0;
4893     
4894              if (scb->cmd.basic_io.sector_count == 0) {
4895                 /*
4896                  * This is a null condition
4897                  * we don't have to do anything
4898                  * so just return
4899                  */
4900                 scb->scsi_cmd->result = DID_OK << 16;
4901              } else
4902                 ret = IPS_SUCCESS;
4903     
4904              break;
4905     
4906           case RESERVE:
4907           case RELEASE:
4908              scb->scsi_cmd->result = DID_OK << 16;
4909              break;
4910     
4911           case MODE_SENSE:
4912              scb->cmd.basic_io.op_code = IPS_CMD_ENQUIRY;
4913              scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
4914              scb->cmd.basic_io.sg_addr = VIRT_TO_BUS(ha->enq);
4915              ret = IPS_SUCCESS;
4916              break;
4917     
4918           case READ_CAPACITY:
4919              scb->cmd.logical_info.op_code = IPS_CMD_GET_LD_INFO;
4920              scb->cmd.logical_info.command_id = IPS_COMMAND_ID(ha, scb);
4921              scb->cmd.logical_info.buffer_addr = VIRT_TO_BUS(&ha->adapt->logical_drive_info);
4922              scb->cmd.logical_info.reserved = 0;
4923              scb->cmd.logical_info.reserved2 = 0;
4924              scb->cmd.logical_info.reserved3 = 0;
4925              ret = IPS_SUCCESS;
4926              break;
4927     
4928           case SEND_DIAGNOSTIC:
4929           case REASSIGN_BLOCKS:
4930           case FORMAT_UNIT:
4931           case SEEK_10:
4932           case VERIFY:
4933           case READ_DEFECT_DATA:
4934           case READ_BUFFER:
4935           case WRITE_BUFFER:
4936              scb->scsi_cmd->result = DID_OK << 16;
4937              break;
4938     
4939           default:
4940              /* Set the Return Info to appear like the Command was */
4941              /* attempted, a Check Condition occurred, and Sense   */
4942              /* Data indicating an Invalid CDB OpCode is returned. */
4943              sp = (char *) scb->scsi_cmd->sense_buffer;
4944              memset(sp, 0, sizeof(scb->scsi_cmd->sense_buffer));
4945       
4946              sp[0] = 0x70;             /* Error Code               */ 
4947              sp[2] = ILLEGAL_REQUEST;  /* Sense Key 5 Illegal Req. */
4948              sp[7] = 0x0A;             /* Additional Sense Length  */
4949              sp[12] = 0x20;            /* ASC = Invalid OpCode     */
4950              sp[13] = 0x00;            /* ASCQ                     */
4951        
4952              device_error = 2;         /* Indicate Check Condition */
4953              scb->scsi_cmd->result = device_error | (DID_OK << 16);
4954              break;
4955           } /* end switch */
4956        } /* end if */
4957     
4958        if (ret == IPS_SUCCESS_IMM)
4959           return (ret);
4960     
4961        /* setup DCDB */
4962        if (scb->bus > 0) {
4963           if (!scb->sg_len)
4964              scb->cmd.dcdb.op_code = IPS_CMD_DCDB;
4965           else
4966              scb->cmd.dcdb.op_code = IPS_CMD_DCDB_SG;
4967     
4968           /* If we already know the Device is Not there, no need to attempt a Command   */
4969           /* This also protects an NT FailOver Controller from getting CDB's sent to it */
4970           if ( ha->conf->dev[scb->bus-1][scb->target_id].ucState == 0 ) {
4971              scb->scsi_cmd->result = DID_NO_CONNECT << 16;
4972              return (IPS_SUCCESS_IMM); 
4973           }
4974     
4975           ha->dcdb_active[scb->bus-1] |= (1 << scb->target_id);
4976           scb->cmd.dcdb.command_id = IPS_COMMAND_ID(ha, scb);
4977           scb->cmd.dcdb.dcdb_address = VIRT_TO_BUS(&scb->dcdb);
4978           scb->cmd.dcdb.reserved = 0;
4979           scb->cmd.dcdb.reserved2 = 0;
4980           scb->cmd.dcdb.reserved3 = 0;
4981     
4982           scb->dcdb.device_address = ((scb->bus - 1) << 4) | scb->target_id;
4983           scb->dcdb.cmd_attribute |= IPS_DISCONNECT_ALLOWED;
4984     
4985           if (scb->timeout) {
4986              if (scb->timeout <= 10)
4987                 scb->dcdb.cmd_attribute |= IPS_TIMEOUT10;
4988              else if (scb->timeout <= 60)
4989                 scb->dcdb.cmd_attribute |= IPS_TIMEOUT60;
4990              else
4991                 scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M;
4992           }
4993     
4994           if (!(scb->dcdb.cmd_attribute & IPS_TIMEOUT20M))
4995              scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M;
4996     
4997           scb->dcdb.sense_length = sizeof(scb->scsi_cmd->sense_buffer);
4998           scb->dcdb.buffer_pointer = scb->data_busaddr;
4999           scb->dcdb.sg_count = scb->sg_len;
5000           scb->dcdb.cdb_length = scb->scsi_cmd->cmd_len;
5001           memcpy(scb->dcdb.scsi_cdb, scb->scsi_cmd->cmnd, scb->scsi_cmd->cmd_len);
5002        }
5003     
5004        return ((*ha->func.issue)(ha, scb));
5005     }
5006     
5007     /****************************************************************************/
5008     /*                                                                          */
5009     /* Routine Name: ips_chk_status                                             */
5010     /*                                                                          */
5011     /* Routine Description:                                                     */
5012     /*                                                                          */
5013     /*   Check the status of commands to logical drives                         */
5014     /*                                                                          */
5015     /****************************************************************************/
5016     static void
5017     ips_chkstatus(ips_ha_t *ha, IPS_STATUS *pstatus) {
5018        ips_scb_t  *scb;
5019        ips_stat_t *sp;
5020        u8          basic_status;
5021        u8          ext_status;
5022        int         errcode;
5023     
5024        METHOD_TRACE("ips_chkstatus", 1);
5025     
5026        scb = &ha->scbs[pstatus->fields.command_id];
5027        scb->basic_status = basic_status = pstatus->fields.basic_status & IPS_BASIC_STATUS_MASK;
5028        scb->extended_status = ext_status = pstatus->fields.extended_status;
5029     
5030        sp = &ha->sp;
5031        sp->residue_len = 0;
5032        sp->scb_addr = (u32) scb;
5033     
5034        /* Remove the item from the active queue */
5035        ips_removeq_scb(&ha->scb_activelist, scb);
5036     
5037        if (!scb->scsi_cmd)
5038           /* internal commands are handled in do_ipsintr */
5039           return ;
5040     
5041        DEBUG_VAR(2, "(%s%d) ips_chkstatus: cmd 0x%X id %d (%d %d %d)",
5042                  ips_name,
5043                  ha->host_num,
5044                  scb->cdb[0],
5045                  scb->cmd.basic_io.command_id,
5046                  scb->bus,
5047                  scb->target_id,
5048                  scb->lun);
5049     
5050     #ifndef NO_IPS_CMDLINE
5051        if ((scb->scsi_cmd) && (ips_is_passthru(scb->scsi_cmd)))
5052           /* passthru - just returns the raw result */
5053           return ;
5054     #endif
5055     
5056        errcode = DID_OK;
5057     
5058        if (((basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_SUCCESS) ||
5059            ((basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_RECOVERED_ERROR)) {
5060     
5061           if (scb->bus == 0) {
5062              if ((basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_RECOVERED_ERROR) {
5063                 DEBUG_VAR(1, "(%s%d) Recovered Logical Drive Error OpCode: %x, BSB: %x, ESB: %x",
5064                           ips_name, ha->host_num,
5065                           scb->cmd.basic_io.op_code, basic_status, ext_status);
5066              }
5067     
5068              switch (scb->scsi_cmd->cmnd[0]) {
5069              case ALLOW_MEDIUM_REMOVAL:
5070              case REZERO_UNIT:
5071              case ERASE:
5072              case WRITE_FILEMARKS:
5073              case SPACE:
5074                 errcode = DID_ERROR;
5075                 break;
5076     
5077              case START_STOP:
5078                 break;
5079     
5080              case TEST_UNIT_READY:
5081                 if (!ips_online(ha, scb)) {
5082                    errcode = DID_TIME_OUT;
5083                 }
5084                 break;
5085     
5086              case INQUIRY:
5087                 if (ips_online(ha, scb)) {
5088                    ips_inquiry(ha, scb);
5089                 } else {
5090                    errcode = DID_TIME_OUT;
5091                 }
5092                 break;
5093     
5094              case REQUEST_SENSE:
5095                 ips_reqsen(ha, scb);
5096                 break;
5097     
5098              case READ_6:
5099              case WRITE_6:
5100              case READ_10:
5101              case WRITE_10:
5102              case RESERVE:
5103              case RELEASE:
5104                 break;
5105     
5106              case MODE_SENSE:
5107                 if (!ips_online(ha, scb) || !ips_msense(ha, scb)) {
5108                    errcode = DID_ERROR;
5109                 }
5110                 break;
5111     
5112              case READ_CAPACITY:
5113                 if (ips_online(ha, scb))
5114                    ips_rdcap(ha, scb);
5115                 else {
5116                    errcode = DID_TIME_OUT;
5117                 }
5118                 break;
5119     
5120              case SEND_DIAGNOSTIC:
5121              case REASSIGN_BLOCKS:
5122                 break;
5123     
5124              case FORMAT_UNIT:
5125                 errcode = DID_ERROR;
5126                 break;
5127     
5128              case SEEK_10:
5129              case VERIFY:
5130              case READ_DEFECT_DATA:
5131              case READ_BUFFER:
5132              case WRITE_BUFFER:
5133                 break;
5134     
5135              default:
5136                 errcode = DID_ERROR;
5137              } /* end switch */
5138     
5139              scb->scsi_cmd->result = errcode << 16;
5140           } else { /* bus == 0 */
5141              /* restrict access to physical drives */
5142              if ((scb->scsi_cmd->cmnd[0] == INQUIRY) &&
5143                  ((((char *) scb->scsi_cmd->buffer)[0] & 0x1f) == TYPE_DISK)) {
5144     
5145                 scb->scsi_cmd->result = DID_TIME_OUT << 16;
5146              }
5147           } /* else */
5148        } else { /* recovered error / success */
5149           if (scb->bus == 0) {
5150              DEBUG_VAR(1, "(%s%d) Unrecovered Logical Drive Error OpCode: %x, BSB: %x, ESB: %x",
5151                        ips_name, ha->host_num,
5152                        scb->cmd.basic_io.op_code, basic_status, ext_status);
5153           }
5154     
5155           ips_map_status(ha, scb, sp);
5156        } /* else */
5157     }
5158     
5159     /****************************************************************************/
5160     /*                                                                          */
5161     /* Routine Name: ips_online                                                 */
5162     /*                                                                          */
5163     /* Routine Description:                                                     */
5164     /*                                                                          */
5165     /*   Determine if a logical drive is online                                 */
5166     /*                                                                          */
5167     /****************************************************************************/
5168     static int
5169     ips_online(ips_ha_t *ha, ips_scb_t *scb) {
5170        METHOD_TRACE("ips_online", 1);
5171     
5172        if (scb->target_id >= IPS_MAX_LD)
5173           return (0);
5174     
5175        if ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1) {
5176           memset(&ha->adapt->logical_drive_info, 0, sizeof(ha->adapt->logical_drive_info));
5177     
5178           return (0);
5179        }
5180     
5181        if (ha->adapt->logical_drive_info.drive_info[scb->target_id].state != IPS_LD_OFFLINE &&
5182            ha->adapt->logical_drive_info.drive_info[scb->target_id].state != IPS_LD_FREE &&
5183            ha->adapt->logical_drive_info.drive_info[scb->target_id].state != IPS_LD_CRS &&
5184            ha->adapt->logical_drive_info.drive_info[scb->target_id].state != IPS_LD_SYS)
5185           return (1);
5186        else
5187           return (0);
5188     }
5189     
5190     /****************************************************************************/
5191     /*                                                                          */
5192     /* Routine Name: ips_inquiry                                                */
5193     /*                                                                          */
5194     /* Routine Description:                                                     */
5195     /*                                                                          */
5196     /*   Simulate an inquiry command to a logical drive                         */
5197     /*                                                                          */
5198     /****************************************************************************/
5199     static int
5200     ips_inquiry(ips_ha_t *ha, ips_scb_t *scb) {
5201        IPS_INQ_DATA inq;
5202     
5203        METHOD_TRACE("ips_inquiry", 1);
5204     
5205        memset(&inq, 0, sizeof(IPS_INQ_DATA));
5206     
5207        inq.DeviceType = TYPE_DISK;
5208        inq.DeviceTypeQualifier = 0;
5209        inq.RemoveableMedia = 0;
5210        inq.Versions = 0x1;  /* SCSI I */
5211        inq.AdditionalLength = 31;
5212        strncpy(inq.VendorId, "IBM     ", 8);
5213        strncpy(inq.ProductId, "SERVERAID       ", 16);
5214        strncpy(inq.ProductRevisionLevel, "1.00", 4);
5215     
5216        memcpy(scb->scsi_cmd->request_buffer, &inq, scb->scsi_cmd->request_bufflen);
5217     
5218        return (1);
5219     }
5220     
5221     /****************************************************************************/
5222     /*                                                                          */
5223     /* Routine Name: ips_rdcap                                                  */
5224     /*                                                                          */
5225     /* Routine Description:                                                     */
5226     /*                                                                          */
5227     /*   Simulate a read capacity command to a logical drive                    */
5228     /*                                                                          */
5229     /****************************************************************************/
5230     static int
5231     ips_rdcap(ips_ha_t *ha, ips_scb_t *scb) {
5232        IPS_CAPACITY *cap;
5233     
5234        METHOD_TRACE("ips_rdcap", 1);
5235     
5236        if (scb->scsi_cmd->bufflen < 8)
5237           return (0);
5238     
5239        cap = (IPS_CAPACITY *) scb->scsi_cmd->request_buffer;
5240     
5241        cap->lba = htonl(ha->adapt->logical_drive_info.drive_info[scb->target_id].sector_count - 1);
5242        cap->len = htonl((u32) IPS_BLKSIZE);
5243     
5244        return (1);
5245     }
5246     
5247     /****************************************************************************/
5248     /*                                                                          */
5249     /* Routine Name: ips_msense                                                 */
5250     /*                                                                          */
5251     /* Routine Description:                                                     */
5252     /*                                                                          */
5253     /*   Simulate a mode sense command to a logical drive                       */
5254     /*                                                                          */
5255     /****************************************************************************/
5256     static int
5257     ips_msense(ips_ha_t *ha, ips_scb_t *scb) {
5258        u16          heads;
5259        u16          sectors;
5260        u32          cylinders;
5261        ips_mdata_t  mdata;
5262     
5263        METHOD_TRACE("ips_msense", 1);
5264     
5265        if (ha->enq->ulDriveSize[scb->target_id] > 0x400000 &&
5266            (ha->enq->ucMiscFlag & 0x8) == 0) {
5267           heads = IPS_NORM_HEADS;
5268           sectors = IPS_NORM_SECTORS;
5269        } else {
5270           heads = IPS_COMP_HEADS;
5271           sectors = IPS_COMP_SECTORS;
5272        }
5273     
5274        cylinders = ha->enq->ulDriveSize[scb->target_id] / (heads * sectors);
5275     
5276        mdata.plh.plh_type = 0;
5277        mdata.plh.plh_wp = 0;
5278        mdata.plh.plh_bdl = 8;
5279     
5280        switch (scb->scsi_cmd->cmnd[2] & 0x3f) {
5281        case 0x03: /* page 3 */
5282           mdata.pdata.pg3.pg_pc = 0x3;
5283           mdata.pdata.pg3.pg_res1 = 0;
5284           mdata.pdata.pg3.pg_len = sizeof(IPS_DADF);
5285           mdata.plh.plh_len = 3 + mdata.plh.plh_bdl + mdata.pdata.pg3.pg_len;
5286           mdata.pdata.pg3.pg_trk_z = 0;
5287           mdata.pdata.pg3.pg_asec_z = 0;
5288           mdata.pdata.pg3.pg_atrk_z = 0;
5289           mdata.pdata.pg3.pg_atrk_v = 0;
5290           mdata.pdata.pg3.pg_sec_t = htons(sectors);
5291           mdata.pdata.pg3.pg_bytes_s = htons(IPS_BLKSIZE);
5292           mdata.pdata.pg3.pg_intl = htons(1);
5293           mdata.pdata.pg3.pg_trkskew = 0;
5294           mdata.pdata.pg3.pg_cylskew = 0;
5295           mdata.pdata.pg3.pg_res2 = 0;
5296           mdata.pdata.pg3.pg_ins = 0;
5297           mdata.pdata.pg3.pg_surf = 0;
5298           mdata.pdata.pg3.pg_rmb = 0;
5299           mdata.pdata.pg3.pg_hsec = 0;
5300           mdata.pdata.pg3.pg_ssec = 1;
5301           break;
5302     
5303        case 0x4:
5304           mdata.pdata.pg4.pg_pc = 0x4;
5305           mdata.pdata.pg4.pg_res1 = 0;
5306           mdata.pdata.pg4.pg_len = sizeof(IPS_RDDG);
5307           mdata.plh.plh_len = 3 + mdata.plh.plh_bdl + mdata.pdata.pg4.pg_len;
5308           mdata.pdata.pg4.pg_cylu = (cylinders >> 8) & 0xffff;
5309           mdata.pdata.pg4.pg_cyll = cylinders & 0xff;
5310           mdata.pdata.pg4.pg_head = heads;
5311           mdata.pdata.pg4.pg_wrpcompu = 0;
5312           mdata.pdata.pg4.pg_wrpcompl = 0;
5313           mdata.pdata.pg4.pg_redwrcur = 0;
5314           mdata.pdata.pg4.pg_drstep = htons(1);
5315           mdata.pdata.pg4.pg_landu = 0;
5316           mdata.pdata.pg4.pg_landl = 0;
5317           mdata.pdata.pg4.pg_res2 = 0;
5318           break;
5319        default:
5320           return (0);
5321        } /* end switch */
5322     
5323        memcpy(scb->scsi_cmd->request_buffer, &mdata, scb->scsi_cmd->request_bufflen);
5324     
5325        return (1);
5326     }
5327     
5328     /****************************************************************************/
5329     /*                                                                          */
5330     /* Routine Name: ips_reqsen                                                 */
5331     /*                                                                          */
5332     /* Routine Description:                                                     */
5333     /*                                                                          */
5334     /*   Simulate a request sense command to a logical drive                    */
5335     /*                                                                          */
5336     /****************************************************************************/
5337     static int
5338     ips_reqsen(ips_ha_t *ha, ips_scb_t *scb) {
5339        char *sp;
5340     
5341        METHOD_TRACE("ips_reqsen", 1);
5342     
5343        sp = (char *) scb->scsi_cmd->sense_buffer;
5344        memset(sp, 0, sizeof(scb->scsi_cmd->sense_buffer));
5345     
5346        sp[0] = 0x70;
5347        sp[3] = NO_SENSE;
5348        sp[7] = 0xe;
5349        sp[12] = NO_SENSE;
5350     
5351        return (0);
5352     }
5353     
5354     /****************************************************************************/
5355     /*                                                                          */
5356     /* Routine Name: ips_free                                                   */
5357     /*                                                                          */
5358     /* Routine Description:                                                     */
5359     /*                                                                          */
5360     /*   Free any allocated space for this controller                           */
5361     /*                                                                          */
5362     /****************************************************************************/
5363     static void
5364     ips_free(ips_ha_t *ha) {
5365        int i;
5366     
5367        METHOD_TRACE("ips_free", 1);
5368     
5369        if (ha) {
5370           if (ha->enq) {
5371              kfree(ha->enq);
5372              ha->enq = NULL;
5373           }
5374     
5375           if (ha->conf) {
5376              kfree(ha->conf);
5377              ha->conf = NULL;
5378           }
5379     
5380           if (ha->adapt) {
5381              kfree(ha->adapt);
5382              ha->adapt = NULL;
5383           }
5384     
5385           if (ha->nvram) {
5386              kfree(ha->nvram);
5387              ha->nvram = NULL;
5388           }
5389     
5390           if (ha->subsys) {
5391              kfree(ha->subsys);
5392              ha->subsys = NULL;
5393           }
5394     
5395           if (ha->dummy) {
5396              kfree(ha->dummy);
5397              ha->dummy = NULL;
5398           }
5399     
5400           if (ha->ioctl_data) {
5401              free_pages((unsigned long) ha->ioctl_data, ha->ioctl_order);
5402              ha->ioctl_data = NULL;
5403              ha->ioctl_datasize = 0;
5404              ha->ioctl_order = 0;
5405           }
5406     
5407           if (ha->scbs) {
5408              for (i = 0; i < ha->max_cmds; i++) {
5409                 if (ha->scbs[i].sg_list)
5410                    kfree(ha->scbs[i].sg_list);
5411              }
5412     
5413              kfree(ha->scbs);
5414              ha->scbs = NULL;
5415           } /* end if */
5416     
5417           /* free memory mapped (if applicable) */
5418           if (ha->mem_ptr) {
5419              iounmap(ha->ioremap_ptr);
5420              ha->ioremap_ptr = NULL;
5421              ha->mem_ptr = NULL;
5422              ha->mem_addr = 0;
5423           }
5424        }
5425     }
5426     
5427     /****************************************************************************/
5428     /*                                                                          */
5429     /* Routine Name: ips_allocatescbs                                           */
5430     /*                                                                          */
5431     /* Routine Description:                                                     */
5432     /*                                                                          */
5433     /*   Allocate the command blocks                                            */
5434     /*                                                                          */
5435     /****************************************************************************/
5436     static int
5437     ips_allocatescbs(ips_ha_t *ha) {
5438        ips_scb_t *scb_p;
5439        int        i;
5440     
5441        METHOD_TRACE("ips_allocatescbs", 1);
5442     
5443        /* Allocate memory for the CCBs */
5444        ha->scbs = (ips_scb_t *) kmalloc(ha->max_cmds * sizeof(ips_scb_t), GFP_ATOMIC);
5445        if (ha->scbs == NULL)
5446         	return 0;
5447     
5448     
5449        memset(ha->scbs, 0, ha->max_cmds * sizeof(ips_scb_t));
5450     
5451        for (i = 0; i < ha->max_cmds; i++) {
5452           scb_p = &ha->scbs[i];
5453     
5454           /* allocate S/G list */
5455           scb_p->sg_list = (IPS_SG_LIST *) kmalloc(sizeof(IPS_SG_LIST) * IPS_MAX_SG, GFP_ATOMIC);
5456     
5457           if (! scb_p->sg_list)
5458              return (0);
5459     
5460           /* add to the free list */
5461           if (i < ha->max_cmds - 1) {
5462              scb_p->q_next = ha->scb_freelist;
5463              ha->scb_freelist = scb_p;
5464           }
5465        }
5466     
5467        /* success */
5468        return (1);
5469     }
5470     
5471     /****************************************************************************/
5472     /*                                                                          */
5473     /* Routine Name: ips_init_scb                                               */
5474     /*                                                                          */
5475     /* Routine Description:                                                     */
5476     /*                                                                          */
5477     /*   Initialize a CCB to default values                                     */
5478     /*                                                                          */
5479     /****************************************************************************/
5480     static void
5481     ips_init_scb(ips_ha_t *ha, ips_scb_t *scb) {
5482        IPS_SG_LIST *sg_list;
5483     
5484        METHOD_TRACE("ips_init_scb", 1);
5485     
5486        if (scb == NULL)
5487           return ;
5488     
5489        sg_list = scb->sg_list;
5490     
5491        /* zero fill */
5492        memset(scb, 0, sizeof(ips_scb_t));
5493        memset(ha->dummy, 0, sizeof(IPS_IO_CMD));
5494     
5495        /* Initialize dummy command bucket */
5496        ha->dummy->op_code = 0xFF;
5497        ha->dummy->ccsar = VIRT_TO_BUS(ha->dummy);
5498        ha->dummy->command_id = IPS_MAX_CMDS;
5499     
5500        /* set bus address of scb */
5501        scb->scb_busaddr = VIRT_TO_BUS(scb);
5502        scb->sg_list = sg_list;
5503     
5504        /* Neptune Fix */
5505        scb->cmd.basic_io.cccr = IPS_BIT_ILE;
5506        scb->cmd.basic_io.ccsar = VIRT_TO_BUS(ha->dummy);
5507     }
5508     
5509     /****************************************************************************/
5510     /*                                                                          */
5511     /* Routine Name: ips_get_scb                                                */
5512     /*                                                                          */
5513     /* Routine Description:                                                     */
5514     /*                                                                          */
5515     /*   Initialize a CCB to default values                                     */
5516     /*                                                                          */
5517     /* ASSUMED to be callled from within a lock                                 */
5518     /*                                                                          */
5519     /****************************************************************************/
5520     static ips_scb_t *
5521     ips_getscb(ips_ha_t *ha) {
5522        ips_scb_t     *scb;
5523        unsigned long  cpu_flags;
5524     
5525        METHOD_TRACE("ips_getscb", 1);
5526     
5527        IPS_SCB_LOCK(cpu_flags);
5528        if ((scb = ha->scb_freelist) == NULL) {
5529           IPS_SCB_UNLOCK(cpu_flags);
5530     
5531           return (NULL);
5532        }
5533     
5534        ha->scb_freelist = scb->q_next;
5535        scb->q_next = NULL;
5536     
5537        IPS_SCB_UNLOCK(cpu_flags);
5538     
5539        ips_init_scb(ha, scb);
5540     
5541        return (scb);
5542     }
5543     
5544     /****************************************************************************/
5545     /*                                                                          */
5546     /* Routine Name: ips_free_scb                                               */
5547     /*                                                                          */
5548     /* Routine Description:                                                     */
5549     /*                                                                          */
5550     /*   Return an unused CCB back to the free list                             */
5551     /*                                                                          */
5552     /* ASSUMED to be called from within a lock                                  */
5553     /*                                                                          */
5554     /****************************************************************************/
5555     static void
5556     ips_freescb(ips_ha_t *ha, ips_scb_t *scb) {
5557        unsigned long cpu_flags;
5558     
5559        METHOD_TRACE("ips_freescb", 1);
5560     
5561        /* check to make sure this is not our "special" scb */
5562        if (IPS_COMMAND_ID(ha, scb) < (ha->max_cmds - 1)) {
5563           IPS_SCB_LOCK(cpu_flags);
5564           scb->q_next = ha->scb_freelist;
5565           ha->scb_freelist = scb;
5566           IPS_SCB_UNLOCK(cpu_flags);
5567        }
5568     }
5569     
5570     /****************************************************************************/
5571     /*                                                                          */
5572     /* Routine Name: ips_isinit_copperhead                                      */
5573     /*                                                                          */
5574     /* Routine Description:                                                     */
5575     /*                                                                          */
5576     /*   Reset the controller                                                   */
5577     /*                                                                          */
5578     /****************************************************************************/
5579     static int
5580     ips_isinit_copperhead(ips_ha_t *ha) {
5581        u8 scpr;
5582        u8 isr;
5583     
5584        METHOD_TRACE("ips_isinit_copperhead", 1);
5585     
5586        isr = inb(ha->io_addr + IPS_REG_HISR);
5587        scpr = inb(ha->io_addr + IPS_REG_SCPR);
5588     
5589        if (((isr & IPS_BIT_EI) == 0) && ((scpr & IPS_BIT_EBM) == 0))
5590            return (0);
5591        else
5592            return (1);
5593     }
5594     
5595     /****************************************************************************/
5596     /*                                                                          */
5597     /* Routine Name: ips_isinit_copperhead_memio                                */
5598     /*                                                                          */
5599     /* Routine Description:                                                     */
5600     /*                                                                          */
5601     /*   Reset the controller                                                   */
5602     /*                                                                          */
5603     /****************************************************************************/
5604     static int
5605     ips_isinit_copperhead_memio(ips_ha_t *ha) {
5606        u8 isr=0;
5607        u8 scpr;
5608     
5609        METHOD_TRACE("ips_is_init_copperhead_memio", 1);
5610     
5611        isr = readb(ha->mem_ptr + IPS_REG_HISR);
5612        scpr = readb(ha->mem_ptr + IPS_REG_SCPR);
5613     
5614        if (((isr & IPS_BIT_EI) == 0) && ((scpr & IPS_BIT_EBM) == 0))
5615            return (0);
5616        else
5617            return (1);
5618     }
5619     
5620     /****************************************************************************/
5621     /*                                                                          */
5622     /* Routine Name: ips_isinit_morpheus                                        */
5623     /*                                                                          */
5624     /* Routine Description:                                                     */
5625     /*                                                                          */
5626     /*   Reset the controller                                                   */
5627     /*                                                                          */
5628     /****************************************************************************/
5629     static int
5630     ips_isinit_morpheus(ips_ha_t *ha) {
5631        u32 post;
5632        u32 bits;
5633     
5634        METHOD_TRACE("ips_is_init_morpheus", 1);
5635     
5636        post = readl(ha->mem_ptr + IPS_REG_I960_MSG0);
5637        bits = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
5638     
5639        if (post == 0)
5640            return (0);
5641        else if (bits & 0x3)
5642            return (0);
5643        else
5644            return (1);
5645     }
5646     
5647     /****************************************************************************/
5648     /*                                                                          */
5649     /* Routine Name: ips_enable_int_copperhead                                  */
5650     /*                                                                          */
5651     /* Routine Description:                                                     */
5652     /*   Turn on interrupts                                                     */
5653     /*                                                                          */
5654     /****************************************************************************/
5655     static void
5656     ips_enable_int_copperhead(ips_ha_t *ha) {
5657        METHOD_TRACE("ips_enable_int_copperhead", 1);
5658     
5659        outb(ha->io_addr + IPS_REG_HISR, IPS_BIT_EI);
5660     }
5661     
5662     /****************************************************************************/
5663     /*                                                                          */
5664     /* Routine Name: ips_enable_int_copperhead_memio                            */
5665     /*                                                                          */
5666     /* Routine Description:                                                     */
5667     /*   Turn on interrupts                                                     */
5668     /*                                                                          */
5669     /****************************************************************************/
5670     static void
5671     ips_enable_int_copperhead_memio(ips_ha_t *ha) {
5672        METHOD_TRACE("ips_enable_int_copperhead_memio", 1);
5673     
5674        writeb(IPS_BIT_EI, ha->mem_ptr + IPS_REG_HISR);
5675     }
5676     
5677     /****************************************************************************/
5678     /*                                                                          */
5679     /* Routine Name: ips_enable_int_morpheus                                    */
5680     /*                                                                          */
5681     /* Routine Description:                                                     */
5682     /*   Turn on interrupts                                                     */
5683     /*                                                                          */
5684     /****************************************************************************/
5685     static void
5686     ips_enable_int_morpheus(ips_ha_t *ha) {
5687        u32              Oimr;
5688     
5689        METHOD_TRACE("ips_enable_int_morpheus", 1);
5690     
5691        Oimr = readl(ha->mem_ptr + IPS_REG_I960_OIMR);
5692        Oimr &= ~0x08;
5693        writel(Oimr, ha->mem_ptr + IPS_REG_I960_OIMR);
5694     }
5695     
5696     /****************************************************************************/
5697     /*                                                                          */
5698     /* Routine Name: ips_init_copperhead                                        */
5699     /*                                                                          */
5700     /* Routine Description:                                                     */
5701     /*                                                                          */
5702     /*   Initialize a copperhead controller                                     */
5703     /*                                                                          */
5704     /****************************************************************************/
5705     static int
5706     ips_init_copperhead(ips_ha_t *ha) {
5707        u8  Isr;
5708        u8  Cbsp;
5709        u8  PostByte[IPS_MAX_POST_BYTES];
5710        u8  ConfigByte[IPS_MAX_CONFIG_BYTES];
5711        int i, j;
5712     
5713        METHOD_TRACE("ips_init_copperhead", 1);
5714     
5715        for (i = 0; i < IPS_MAX_POST_BYTES; i++) {
5716           for (j = 0; j < 45; j++) {
5717              Isr = inb(ha->io_addr + IPS_REG_HISR);
5718              if (Isr & IPS_BIT_GHI)
5719                 break;
5720     
5721              MDELAY(IPS_ONE_SEC);
5722           }
5723     
5724           if (j >= 45)
5725              /* error occurred */
5726              return (0);
5727     
5728           PostByte[i] = inb(ha->io_addr + IPS_REG_ISPR);
5729           outb(Isr, ha->io_addr + IPS_REG_HISR);
5730        }
5731     
5732        if (PostByte[0] < IPS_GOOD_POST_STATUS) {
5733           printk(KERN_WARNING "(%s%d) reset controller fails (post status %x %x).\n",
5734                  ips_name, ha->host_num, PostByte[0], PostByte[1]);
5735     
5736           return (0);
5737        }
5738     
5739        for (i = 0; i < IPS_MAX_CONFIG_BYTES; i++) {
5740           for (j = 0; j < 240; j++) {
5741              Isr = inb(ha->io_addr + IPS_REG_HISR);
5742              if (Isr & IPS_BIT_GHI)
5743                 break;
5744     
5745              MDELAY(IPS_ONE_SEC); /* 100 msec */
5746           }
5747     
5748           if (j >= 240)
5749              /* error occurred */
5750              return (0);
5751     
5752           ConfigByte[i] = inb(ha->io_addr + IPS_REG_ISPR);
5753           outb(Isr, ha->io_addr + IPS_REG_HISR);
5754        }
5755     
5756        for (i = 0; i < 240; i++) {
5757           Cbsp = inb(ha->io_addr + IPS_REG_CBSP);
5758     
5759           if ((Cbsp & IPS_BIT_OP) == 0)
5760              break;
5761     
5762           MDELAY(IPS_ONE_SEC);
5763        }
5764     
5765        if (i >= 240)
5766           /* reset failed */
5767           return (0);
5768     
5769        /* setup CCCR */
5770        outw(0x1010, ha->io_addr + IPS_REG_CCCR);
5771     
5772        /* Enable busmastering */
5773        outb(IPS_BIT_EBM, ha->io_addr + IPS_REG_SCPR);
5774     
5775        if (ha->revision_id == IPS_REVID_TROMBONE64)
5776           /* fix for anaconda64 */
5777           outl(0, ha->io_addr + IPS_REG_NDAE);
5778     
5779        /* Enable interrupts */
5780        outb(IPS_BIT_EI, ha->io_addr + IPS_REG_HISR);
5781     
5782        return (1);
5783     }
5784     
5785     /****************************************************************************/
5786     /*                                                                          */
5787     /* Routine Name: ips_init_copperhead_memio                                  */
5788     /*                                                                          */
5789     /* Routine Description:                                                     */
5790     /*                                                                          */
5791     /*   Initialize a copperhead controller with memory mapped I/O              */
5792     /*                                                                          */
5793     /****************************************************************************/
5794     static int
5795     ips_init_copperhead_memio(ips_ha_t *ha) {
5796        u8  Isr=0;
5797        u8  Cbsp;
5798        u8  PostByte[IPS_MAX_POST_BYTES];
5799        u8  ConfigByte[IPS_MAX_CONFIG_BYTES];
5800        int i, j;
5801     
5802        METHOD_TRACE("ips_init_copperhead_memio", 1);
5803     
5804        for (i = 0; i < IPS_MAX_POST_BYTES; i++) {
5805           for (j = 0; j < 45; j++) {
5806              Isr = readb(ha->mem_ptr + IPS_REG_HISR);
5807              if (Isr & IPS_BIT_GHI)
5808                 break;
5809     
5810              MDELAY(IPS_ONE_SEC);
5811           }
5812     
5813           if (j >= 45)
5814              /* error occurred */
5815              return (0);
5816     
5817           PostByte[i] = readb(ha->mem_ptr + IPS_REG_ISPR);
5818           writeb(Isr, ha->mem_ptr + IPS_REG_HISR);
5819        }
5820     
5821        if (PostByte[0] < IPS_GOOD_POST_STATUS) {
5822           printk(KERN_WARNING "(%s%d) reset controller fails (post status %x %x).\n",
5823                  ips_name, ha->host_num, PostByte[0], PostByte[1]);
5824     
5825           return (0);
5826        }
5827     
5828        for (i = 0; i < IPS_MAX_CONFIG_BYTES; i++) {
5829           for (j = 0; j < 240; j++) {
5830              Isr = readb(ha->mem_ptr + IPS_REG_HISR);
5831              if (Isr & IPS_BIT_GHI)
5832                 break;
5833     
5834              MDELAY(IPS_ONE_SEC); /* 100 msec */
5835           }
5836     
5837           if (j >= 240)
5838              /* error occurred */
5839              return (0);
5840     
5841           ConfigByte[i] = readb(ha->mem_ptr + IPS_REG_ISPR);
5842           writeb(Isr, ha->mem_ptr + IPS_REG_HISR);
5843        }
5844     
5845        for (i = 0; i < 240; i++) {
5846           Cbsp = readb(ha->mem_ptr + IPS_REG_CBSP);
5847     
5848           if ((Cbsp & IPS_BIT_OP) == 0)
5849              break;
5850     
5851           MDELAY(IPS_ONE_SEC);
5852        }
5853     
5854        if (i >= 240)
5855           /* error occurred */
5856           return (0);
5857     
5858        /* setup CCCR */
5859        writel(0x1010, ha->mem_ptr + IPS_REG_CCCR);
5860     
5861        /* Enable busmastering */
5862        writeb(IPS_BIT_EBM, ha->mem_ptr + IPS_REG_SCPR);
5863     
5864        if (ha->revision_id == IPS_REVID_TROMBONE64)
5865           /* fix for anaconda64 */
5866           writel(0, ha->mem_ptr + IPS_REG_NDAE);
5867     
5868        /* Enable interrupts */
5869        writeb(IPS_BIT_EI, ha->mem_ptr + IPS_REG_HISR);
5870     
5871        /* if we get here then everything went OK */
5872        return (1);
5873     }
5874     
5875     /****************************************************************************/
5876     /*                                                                          */
5877     /* Routine Name: ips_init_morpheus                                          */
5878     /*                                                                          */
5879     /* Routine Description:                                                     */
5880     /*                                                                          */
5881     /*   Initialize a morpheus controller                                       */
5882     /*                                                                          */
5883     /****************************************************************************/
5884     static int
5885     ips_init_morpheus(ips_ha_t *ha) {
5886        u32 Post;
5887        u32 Config;
5888        u32 Isr;
5889        u32 Oimr;
5890        int i;
5891     
5892        METHOD_TRACE("ips_init_morpheus", 1);
5893     
5894        /* Wait up to 45 secs for Post */
5895        for (i = 0; i < 45; i++) {
5896           Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
5897     
5898           if (Isr & IPS_BIT_I960_MSG0I)
5899              break;
5900     
5901           MDELAY(IPS_ONE_SEC);
5902        }
5903     
5904        if (i >= 45) {
5905           /* error occurred */
5906           printk(KERN_WARNING "(%s%d) timeout waiting for post.\n",
5907                  ips_name, ha->host_num);
5908     
5909           return (0);
5910        }
5911     
5912        Post = readl(ha->mem_ptr + IPS_REG_I960_MSG0);
5913     
5914        /* Clear the interrupt bit */
5915        Isr = (u32) IPS_BIT_I960_MSG0I;
5916        writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR);
5917     
5918        if (Post < (IPS_GOOD_POST_STATUS << 8)) {
5919           printk(KERN_WARNING "(%s%d) reset controller fails (post status %x).\n",
5920                  ips_name, ha->host_num, Post);
5921     
5922           return (0);
5923        }
5924     
5925        /* Wait up to 240 secs for config bytes */
5926        for (i = 0; i < 240; i++) {
5927           Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
5928     
5929           if (Isr & IPS_BIT_I960_MSG1I)
5930              break;
5931     
5932           MDELAY(IPS_ONE_SEC); /* 100 msec */
5933        }
5934     
5935        if (i >= 240) {
5936           /* error occurred */
5937           printk(KERN_WARNING "(%s%d) timeout waiting for config.\n",
5938                  ips_name, ha->host_num);
5939     
5940           return (0);
5941        }
5942     
5943        Config = readl(ha->mem_ptr + IPS_REG_I960_MSG1);
5944     
5945        /* Clear interrupt bit */
5946        Isr = (u32) IPS_BIT_I960_MSG1I;
5947        writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR);
5948     
5949        /* Turn on the interrupts */
5950        Oimr = readl(ha->mem_ptr + IPS_REG_I960_OIMR);
5951        Oimr &= ~0x8;
5952        writel(Oimr, ha->mem_ptr + IPS_REG_I960_OIMR);
5953     
5954        /* if we get here then everything went OK */
5955        return (1);
5956     }
5957     
5958     /****************************************************************************/
5959     /*                                                                          */
5960     /* Routine Name: ips_reset_copperhead                                       */
5961     /*                                                                          */
5962     /* Routine Description:                                                     */
5963     /*                                                                          */
5964     /*   Reset the controller                                                   */
5965     /*                                                                          */
5966     /****************************************************************************/
5967     static int
5968     ips_reset_copperhead(ips_ha_t *ha) {
5969        int reset_counter;
5970        unsigned long cpu_flags;
5971     
5972        METHOD_TRACE("ips_reset_copperhead", 1);
5973     
5974        DEBUG_VAR(1, "(%s%d) ips_reset_copperhead: io addr: %x, irq: %d",
5975                  ips_name, ha->host_num, ha->io_addr, ha->irq);
5976     
5977        IPS_HA_LOCK(cpu_flags);
5978     
5979        reset_counter = 0;
5980     
5981        while (reset_counter < 2) {
5982           reset_counter++;
5983     
5984           outb(IPS_BIT_RST, ha->io_addr + IPS_REG_SCPR);
5985           MDELAY(IPS_ONE_SEC);
5986           outb(0, ha->io_addr + IPS_REG_SCPR);
5987           MDELAY(IPS_ONE_SEC);
5988     
5989           if ((*ha->func.init)(ha))
5990              break;
5991           else if (reset_counter >= 2) {
5992              IPS_HA_UNLOCK(cpu_flags);
5993     
5994              return (0);
5995           }
5996        }
5997     
5998        IPS_HA_UNLOCK(cpu_flags);
5999     
6000        return (1);
6001     }
6002     
6003     /****************************************************************************/
6004     /*                                                                          */
6005     /* Routine Name: ips_reset_copperhead_memio                                 */
6006     /*                                                                          */
6007     /* Routine Description:                                                     */
6008     /*                                                                          */
6009     /*   Reset the controller                                                   */
6010     /*                                                                          */
6011     /****************************************************************************/
6012     static int
6013     ips_reset_copperhead_memio(ips_ha_t *ha) {
6014        int reset_counter;
6015        unsigned long cpu_flags;
6016     
6017        METHOD_TRACE("ips_reset_copperhead_memio", 1);
6018     
6019        DEBUG_VAR(1, "(%s%d) ips_reset_copperhead_memio: mem addr: %x, irq: %d",
6020                  ips_name, ha->host_num, ha->mem_addr, ha->irq);
6021     
6022        IPS_HA_LOCK(cpu_flags);
6023     
6024        reset_counter = 0;
6025     
6026        while (reset_counter < 2) {
6027           reset_counter++;
6028     
6029           writeb(IPS_BIT_RST, ha->mem_ptr + IPS_REG_SCPR);
6030           MDELAY(IPS_ONE_SEC);
6031           writeb(0, ha->mem_ptr + IPS_REG_SCPR);
6032           MDELAY(IPS_ONE_SEC);
6033     
6034           if ((*ha->func.init)(ha))
6035              break;
6036           else if (reset_counter >= 2) {
6037              IPS_HA_UNLOCK(cpu_flags);
6038     
6039              return (0);
6040           }
6041        }
6042     
6043        IPS_HA_UNLOCK(cpu_flags);
6044     
6045        return (1);
6046     }
6047     
6048     /****************************************************************************/
6049     /*                                                                          */
6050     /* Routine Name: ips_reset_morpheus                                         */
6051     /*                                                                          */
6052     /* Routine Description:                                                     */
6053     /*                                                                          */
6054     /*   Reset the controller                                                   */
6055     /*                                                                          */
6056     /****************************************************************************/
6057     static int
6058     ips_reset_morpheus(ips_ha_t *ha) {
6059        int reset_counter;
6060        u8  junk;
6061        unsigned long cpu_flags;
6062     
6063        METHOD_TRACE("ips_reset_morpheus", 1);
6064     
6065        DEBUG_VAR(1, "(%s%d) ips_reset_morpheus: mem addr: %x, irq: %d",
6066                  ips_name, ha->host_num, ha->mem_addr, ha->irq);
6067     
6068        IPS_HA_LOCK(cpu_flags);
6069     
6070        reset_counter = 0;
6071     
6072        while (reset_counter < 2) {
6073           reset_counter++;
6074     
6075           writel(0x80000000, ha->mem_ptr + IPS_REG_I960_IDR);
6076     
6077           /* Delay for 300 msec */
6078           MDELAY(300 * IPS_ONE_MSEC);
6079     
6080           /* Do a PCI config read to wait for adapter */
6081           pci_read_config_byte(ha->pcidev, 4, &junk);
6082     
6083           if ((*ha->func.init)(ha))
6084              break;
6085           else if (reset_counter >= 2) {
6086              IPS_HA_UNLOCK(cpu_flags);
6087     
6088              return (0);
6089           }
6090        }
6091     
6092        IPS_HA_UNLOCK(cpu_flags);
6093     
6094        return (1);
6095     }
6096     
6097     /****************************************************************************/
6098     /*                                                                          */
6099     /* Routine Name: ips_statinit                                               */
6100     /*                                                                          */
6101     /* Routine Description:                                                     */
6102     /*                                                                          */
6103     /*   Initialize the status queues on the controller                         */
6104     /*                                                                          */
6105     /****************************************************************************/
6106     static void
6107     ips_statinit(ips_ha_t *ha) {
6108        u32        phys_status_start;
6109     
6110        METHOD_TRACE("ips_statinit", 1);
6111     
6112        ha->adapt->p_status_start = ha->adapt->status;
6113        ha->adapt->p_status_end = ha->adapt->status + IPS_MAX_CMDS;
6114        ha->adapt->p_status_tail = ha->adapt->status;
6115     
6116        phys_status_start = VIRT_TO_BUS(ha->adapt->status);
6117        outl(phys_status_start, ha->io_addr + IPS_REG_SQSR);
6118        outl(phys_status_start + IPS_STATUS_Q_SIZE, ha->io_addr + IPS_REG_SQER);
6119        outl(phys_status_start + IPS_STATUS_SIZE, ha->io_addr + IPS_REG_SQHR);
6120        outl(phys_status_start, ha->io_addr + IPS_REG_SQTR);
6121     
6122        ha->adapt->hw_status_start = phys_status_start;
6123        ha->adapt->hw_status_tail = phys_status_start;
6124     }
6125     
6126     /****************************************************************************/
6127     /*                                                                          */
6128     /* Routine Name: ips_statinit_memio                                         */
6129     /*                                                                          */
6130     /* Routine Description:                                                     */
6131     /*                                                                          */
6132     /*   Initialize the status queues on the controller                         */
6133     /*                                                                          */
6134     /****************************************************************************/
6135     static void
6136     ips_statinit_memio(ips_ha_t *ha) {
6137        u32        phys_status_start;
6138     
6139        METHOD_TRACE("ips_statinit_memio", 1);
6140     
6141        ha->adapt->p_status_start = ha->adapt->status;
6142        ha->adapt->p_status_end = ha->adapt->status + IPS_MAX_CMDS;
6143        ha->adapt->p_status_tail = ha->adapt->status;
6144     
6145        phys_status_start = VIRT_TO_BUS(ha->adapt->status);
6146        writel(phys_status_start, ha->mem_ptr + IPS_REG_SQSR);
6147        writel(phys_status_start + IPS_STATUS_Q_SIZE, ha->mem_ptr + IPS_REG_SQER);
6148        writel(phys_status_start + IPS_STATUS_SIZE, ha->mem_ptr + IPS_REG_SQHR);
6149        writel(phys_status_start, ha->mem_ptr + IPS_REG_SQTR);
6150     
6151        ha->adapt->hw_status_start = phys_status_start;
6152        ha->adapt->hw_status_tail = phys_status_start;
6153     }
6154     
6155     /****************************************************************************/
6156     /*                                                                          */
6157     /* Routine Name: ips_statupd_copperhead                                     */
6158     /*                                                                          */
6159     /* Routine Description:                                                     */
6160     /*                                                                          */
6161     /*   Remove an element from the status queue                                */
6162     /*                                                                          */
6163     /****************************************************************************/
6164     static u32
6165     ips_statupd_copperhead(ips_ha_t *ha) {
6166        METHOD_TRACE("ips_statupd_copperhead", 1);
6167     
6168        if (ha->adapt->p_status_tail != ha->adapt->p_status_end) {
6169           ha->adapt->p_status_tail++;
6170           ha->adapt->hw_status_tail += sizeof(IPS_STATUS);
6171        } else {
6172           ha->adapt->p_status_tail = ha->adapt->p_status_start;
6173           ha->adapt->hw_status_tail = ha->adapt->hw_status_start;
6174        }
6175     
6176        outl(ha->adapt->hw_status_tail, ha->io_addr + IPS_REG_SQTR);
6177     
6178        return (ha->adapt->p_status_tail->value);
6179     }
6180     
6181     /****************************************************************************/
6182     /*                                                                          */
6183     /* Routine Name: ips_statupd_copperhead_memio                               */
6184     /*                                                                          */
6185     /* Routine Description:                                                     */
6186     /*                                                                          */
6187     /*   Remove an element from the status queue                                */
6188     /*                                                                          */
6189     /****************************************************************************/
6190     static u32
6191     ips_statupd_copperhead_memio(ips_ha_t *ha) {
6192        METHOD_TRACE("ips_statupd_copperhead_memio", 1);
6193     
6194        if (ha->adapt->p_status_tail != ha->adapt->p_status_end) {
6195           ha->adapt->p_status_tail++;
6196           ha->adapt->hw_status_tail += sizeof(IPS_STATUS);
6197        } else {
6198           ha->adapt->p_status_tail = ha->adapt->p_status_start;
6199           ha->adapt->hw_status_tail = ha->adapt->hw_status_start;
6200        }
6201     
6202        writel(ha->adapt->hw_status_tail, ha->mem_ptr + IPS_REG_SQTR);
6203     
6204        return (ha->adapt->p_status_tail->value);
6205     }
6206     
6207     /****************************************************************************/
6208     /*                                                                          */
6209     /* Routine Name: ips_statupd_morpheus                                       */
6210     /*                                                                          */
6211     /* Routine Description:                                                     */
6212     /*                                                                          */
6213     /*   Remove an element from the status queue                                */
6214     /*                                                                          */
6215     /****************************************************************************/
6216     static u32
6217     ips_statupd_morpheus(ips_ha_t *ha) {
6218        u32       val;
6219     
6220        METHOD_TRACE("ips_statupd_morpheus", 1);
6221     
6222        val = readl(ha->mem_ptr + IPS_REG_I2O_OUTMSGQ);
6223     
6224        return (val);
6225     }
6226     
6227     /****************************************************************************/
6228     /*                                                                          */
6229     /* Routine Name: ips_issue_copperhead                                       */
6230     /*                                                                          */
6231     /* Routine Description:                                                     */
6232     /*                                                                          */
6233     /*   Send a command down to the controller                                  */
6234     /*                                                                          */
6235     /****************************************************************************/
6236     static int
6237     ips_issue_copperhead(ips_ha_t *ha, ips_scb_t *scb) {
6238        u32       TimeOut;
6239        u16       val;
6240        unsigned long       cpu_flags;
6241     
6242        METHOD_TRACE("ips_issue_copperhead", 1);
6243     
6244        if (scb->scsi_cmd) {
6245           DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)",
6246                     ips_name,
6247                     ha->host_num,
6248                     scb->cdb[0],
6249                     scb->cmd.basic_io.command_id,
6250                     scb->bus,
6251                     scb->target_id,
6252                     scb->lun);
6253        } else {
6254           DEBUG_VAR(2, KERN_NOTICE "(%s%d) ips_issue: logical cmd id %d",
6255                     ips_name,
6256                     ha->host_num,
6257                     scb->cmd.basic_io.command_id);
6258        }
6259     
6260        IPS_HA_LOCK(cpu_flags);
6261     
6262        TimeOut = 0;
6263     
6264        while ((val = inw(ha->io_addr + IPS_REG_CCCR)) & IPS_BIT_SEM) {
6265           udelay(1000);
6266     
6267           if (++TimeOut >= IPS_SEM_TIMEOUT) {
6268              if (!(val & IPS_BIT_START_STOP))
6269                 break;
6270     
6271              printk(KERN_WARNING "(%s%d) ips_issue val [0x%x].\n",
6272                     ips_name, ha->host_num, val);
6273              printk(KERN_WARNING "(%s%d) ips_issue semaphore chk timeout.\n",
6274                     ips_name, ha->host_num);
6275     
6276              IPS_HA_UNLOCK(cpu_flags);
6277     
6278              return (IPS_FAILURE);
6279           } /* end if */
6280        } /* end while */
6281     
6282        outl(scb->scb_busaddr, ha->io_addr + IPS_REG_CCSAR);
6283        outw(IPS_BIT_START_CMD, ha->io_addr + IPS_REG_CCCR);
6284     
6285        IPS_HA_UNLOCK(cpu_flags);
6286     
6287        return (IPS_SUCCESS);
6288     }
6289     
6290     /****************************************************************************/
6291     /*                                                                          */
6292     /* Routine Name: ips_issue_copperhead_memio                                 */
6293     /*                                                                          */
6294     /* Routine Description:                                                     */
6295     /*                                                                          */
6296     /*   Send a command down to the controller                                  */
6297     /*                                                                          */
6298     /****************************************************************************/
6299     static int
6300     ips_issue_copperhead_memio(ips_ha_t *ha, ips_scb_t *scb) {
6301        u32       TimeOut;
6302        u32       val;
6303        unsigned long cpu_flags;
6304     
6305        METHOD_TRACE("ips_issue_copperhead_memio", 1);
6306     
6307        if (scb->scsi_cmd) {
6308           DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)",
6309                     ips_name,
6310                     ha->host_num,
6311                     scb->cdb[0],
6312                     scb->cmd.basic_io.command_id,
6313                     scb->bus,
6314                     scb->target_id,
6315                     scb->lun);
6316        } else {
6317           DEBUG_VAR(2, "(%s%d) ips_issue: logical cmd id %d",
6318                     ips_name,
6319                     ha->host_num,
6320                     scb->cmd.basic_io.command_id);
6321        }
6322     
6323        IPS_HA_LOCK(cpu_flags);
6324     
6325        TimeOut = 0;
6326     
6327        while ((val = readl(ha->mem_ptr + IPS_REG_CCCR)) & IPS_BIT_SEM) {
6328           udelay(1000);
6329     
6330           if (++TimeOut >= IPS_SEM_TIMEOUT) {
6331              if (!(val & IPS_BIT_START_STOP))
6332                 break;
6333     
6334              printk(KERN_WARNING "(%s%d) ips_issue val [0x%x].\n",
6335                     ips_name, ha->host_num, val);
6336              printk(KERN_WARNING "(%s%d) ips_issue semaphore chk timeout.\n",
6337                     ips_name, ha->host_num);
6338     
6339              IPS_HA_UNLOCK(cpu_flags);
6340     
6341              return (IPS_FAILURE);
6342           } /* end if */
6343        } /* end while */
6344     
6345        writel(scb->scb_busaddr, ha->mem_ptr + IPS_REG_CCSAR);
6346        writel(IPS_BIT_START_CMD, ha->mem_ptr + IPS_REG_CCCR);
6347     
6348        IPS_HA_UNLOCK(cpu_flags);
6349     
6350        return (IPS_SUCCESS);
6351     }
6352     
6353     /****************************************************************************/
6354     /*                                                                          */
6355     /* Routine Name: ips_issue_i2o                                              */
6356     /*                                                                          */
6357     /* Routine Description:                                                     */
6358     /*                                                                          */
6359     /*   Send a command down to the controller                                  */
6360     /*                                                                          */
6361     /****************************************************************************/
6362     static int
6363     ips_issue_i2o(ips_ha_t *ha, ips_scb_t *scb) {
6364        unsigned long cpu_flags;
6365     
6366        METHOD_TRACE("ips_issue_i2o", 1);
6367     
6368        if (scb->scsi_cmd) {
6369           DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)",
6370                     ips_name,
6371                     ha->host_num,
6372                     scb->cdb[0],
6373                     scb->cmd.basic_io.command_id,
6374                     scb->bus,
6375                     scb->target_id,
6376                     scb->lun);
6377        } else {
6378           DEBUG_VAR(2, "(%s%d) ips_issue: logical cmd id %d",
6379                     ips_name,
6380                     ha->host_num,
6381                     scb->cmd.basic_io.command_id);
6382        }
6383     
6384        IPS_HA_LOCK(cpu_flags);
6385     
6386        outl(scb->scb_busaddr, ha->io_addr + IPS_REG_I2O_INMSGQ);
6387     
6388        IPS_HA_UNLOCK(cpu_flags);
6389     
6390        return (IPS_SUCCESS);
6391     }
6392     
6393     /****************************************************************************/
6394     /*                                                                          */
6395     /* Routine Name: ips_issue_i2o_memio                                        */
6396     /*                                                                          */
6397     /* Routine Description:                                                     */
6398     /*                                                                          */
6399     /*   Send a command down to the controller                                  */
6400     /*                                                                          */
6401     /****************************************************************************/
6402     static int
6403     ips_issue_i2o_memio(ips_ha_t *ha, ips_scb_t *scb) {
6404        unsigned long cpu_flags;
6405     
6406        METHOD_TRACE("ips_issue_i2o_memio", 1);
6407     
6408        if (scb->scsi_cmd) {
6409           DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)",
6410                     ips_name,
6411                     ha->host_num,
6412                     scb->cdb[0],
6413                     scb->cmd.basic_io.command_id,
6414                     scb->bus,
6415                     scb->target_id,
6416                     scb->lun);
6417        } else {
6418           DEBUG_VAR(2, "(%s%d) ips_issue: logical cmd id %d",
6419                     ips_name,
6420                     ha->host_num,
6421                     scb->cmd.basic_io.command_id);
6422        }
6423     
6424        IPS_HA_LOCK(cpu_flags);
6425     
6426        writel(scb->scb_busaddr, ha->mem_ptr + IPS_REG_I2O_INMSGQ);
6427     
6428        IPS_HA_UNLOCK(cpu_flags);
6429     
6430        return (IPS_SUCCESS);
6431     }
6432     
6433     /****************************************************************************/
6434     /*                                                                          */
6435     /* Routine Name: ips_isintr_copperhead                                      */
6436     /*                                                                          */
6437     /* Routine Description:                                                     */
6438     /*                                                                          */
6439     /*   Test to see if an interrupt is for us                                  */
6440     /*                                                                          */
6441     /****************************************************************************/
6442     static int
6443     ips_isintr_copperhead(ips_ha_t *ha) {
6444        u8 Isr;
6445     
6446        METHOD_TRACE("ips_isintr_copperhead", 2);
6447     
6448        Isr = inb(ha->io_addr + IPS_REG_HISR);
6449     
6450        if (Isr == 0xFF)
6451           /* ?!?! Nothing really there */
6452           return (0);
6453     
6454        if (Isr & IPS_BIT_SCE)
6455           return (1);
6456        else if (Isr & (IPS_BIT_SQO | IPS_BIT_GHI)) {
6457           /* status queue overflow or GHI */
6458           /* just clear the interrupt */
6459           outb(Isr, ha->io_addr + IPS_REG_HISR);
6460        }
6461     
6462        return (0);
6463     }
6464     
6465     /****************************************************************************/
6466     /*                                                                          */
6467     /* Routine Name: ips_isintr_copperhead_memio                                */
6468     /*                                                                          */
6469     /* Routine Description:                                                     */
6470     /*                                                                          */
6471     /*   Test to see if an interrupt is for us                                  */
6472     /*                                                                          */
6473     /****************************************************************************/
6474     static int
6475     ips_isintr_copperhead_memio(ips_ha_t *ha) {
6476        u8 Isr;
6477     
6478        METHOD_TRACE("ips_isintr_memio", 2);
6479     
6480        Isr = readb(ha->mem_ptr + IPS_REG_HISR);
6481     
6482        if (Isr == 0xFF)
6483           /* ?!?! Nothing really there */
6484           return (0);
6485     
6486        if (Isr & IPS_BIT_SCE)
6487           return (1);
6488        else if (Isr & (IPS_BIT_SQO | IPS_BIT_GHI)) {
6489           /* status queue overflow or GHI */
6490           /* just clear the interrupt */
6491           writeb(Isr, ha->mem_ptr + IPS_REG_HISR);
6492        }
6493     
6494        return (0);
6495     }
6496     
6497     /****************************************************************************/
6498     /*                                                                          */
6499     /* Routine Name: ips_isintr_morpheus                                        */
6500     /*                                                                          */
6501     /* Routine Description:                                                     */
6502     /*                                                                          */
6503     /*   Test to see if an interrupt is for us                                  */
6504     /*                                                                          */
6505     /****************************************************************************/
6506     static int
6507     ips_isintr_morpheus(ips_ha_t *ha) {
6508        u32 Isr;
6509     
6510        METHOD_TRACE("ips_isintr_morpheus", 2);
6511     
6512        Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
6513     
6514        if (Isr & IPS_BIT_I2O_OPQI)
6515           return (1);
6516        else
6517           return (0);
6518     }
6519     
6520     /****************************************************************************/
6521     /*                                                                          */
6522     /* Routine Name: ips_wait                                                   */
6523     /*                                                                          */
6524     /* Routine Description:                                                     */
6525     /*                                                                          */
6526     /*   Wait for a command to complete                                         */
6527     /*                                                                          */
6528     /****************************************************************************/
6529     static int
6530     ips_wait(ips_ha_t *ha, int time, int intr) {
6531        int        ret;
6532        u8         done;
6533     
6534        METHOD_TRACE("ips_wait", 1);
6535     
6536        ret = IPS_FAILURE;
6537        done = FALSE;
6538     
6539        time *= IPS_ONE_SEC; /* convert seconds to milliseconds */
6540     
6541        while ((time > 0) && (!done)) {
6542           if (intr == IPS_INTR_ON) {
6543              if (ha->waitflag == FALSE) {
6544                 ret = IPS_SUCCESS;
6545                 done = TRUE;
6546                 break;
6547              }
6548           } else if (intr == IPS_INTR_IORL) {
6549              if (ha->waitflag == FALSE) {
6550                 /*
6551                  * controller generated an interrupt to
6552                  * acknowledge completion of the command
6553                  * and ips_intr() has serviced the interrupt.
6554                  */
6555                 ret = IPS_SUCCESS;
6556                 done = TRUE;
6557                 break;
6558              }
6559     
6560              /*
6561               * NOTE: we already have the io_request_lock so
6562               * even if we get an interrupt it won't get serviced
6563               * until after we finish.
6564               */
6565     
6566              while (test_and_set_bit(IPS_IN_INTR, &ha->flags))
6567                 udelay(1000);
6568     
6569              (*ha->func.intr)(ha);
6570     
6571              clear_bit(IPS_IN_INTR, &ha->flags);
6572           } else if (intr == IPS_INTR_HAL) {
6573              if (ha->waitflag == FALSE) {
6574                 /*
6575                  * controller generated an interrupt to
6576                  * acknowledge completion of the command
6577                  * and ips_intr() has serviced the interrupt.
6578                  */
6579                 ret = IPS_SUCCESS;
6580                 done = TRUE;
6581                 break;
6582              }
6583     
6584              /*
6585               * NOTE: since we were not called with the iorequest lock
6586               * we must obtain it before we can call the interrupt handler.
6587               * We were called under the HA lock so we can assume that interrupts
6588               * are masked.
6589               */
6590              spin_lock(&io_request_lock);
6591     
6592              while (test_and_set_bit(IPS_IN_INTR, &ha->flags))
6593                 udelay(1000);
6594     
6595              (*ha->func.intr)(ha);
6596     
6597              clear_bit(IPS_IN_INTR, &ha->flags);
6598     
6599              spin_unlock(&io_request_lock);
6600           }
6601     
6602           udelay(1000); /* 1 milisecond */
6603           time--;
6604        }
6605     
6606        return (ret);
6607     }
6608     
6609     /****************************************************************************/
6610     /*                                                                          */
6611     /* Routine Name: ips_write_driver_status                                    */
6612     /*                                                                          */
6613     /* Routine Description:                                                     */
6614     /*                                                                          */
6615     /*   Write OS/Driver version to Page 5 of the nvram on the controller       */
6616     /*                                                                          */
6617     /****************************************************************************/
6618     static int
6619     ips_write_driver_status(ips_ha_t *ha, int intr) {
6620        METHOD_TRACE("ips_write_driver_status", 1);
6621     
6622        if (!ips_readwrite_page5(ha, FALSE, intr)) {
6623           printk(KERN_WARNING "(%s%d) unable to read NVRAM page 5.\n",
6624                  ips_name, ha->host_num);
6625     
6626           return (0);
6627        }
6628     
6629        /* check to make sure the page has a valid */
6630        /* signature */
6631        if (ha->nvram->signature != IPS_NVRAM_P5_SIG) {
6632           DEBUG_VAR(1, "(%s%d) NVRAM page 5 has an invalid signature: %X.",
6633                     ips_name, ha->host_num, ha->nvram->signature);
6634     
6635           return (1);
6636        }
6637     
6638        DEBUG_VAR(2, "(%s%d) Ad Type: %d, Ad Slot: %d, BIOS: %c%c%c%c %c%c%c%c.",
6639                  ips_name, ha->host_num, ha->nvram->adapter_type, ha->nvram->adapter_slot,
6640                  ha->nvram->bios_high[0], ha->nvram->bios_high[1],
6641                  ha->nvram->bios_high[2], ha->nvram->bios_high[3],
6642                  ha->nvram->bios_low[0], ha->nvram->bios_low[1],
6643                  ha->nvram->bios_low[2], ha->nvram->bios_low[3]);
6644     
6645        /* change values (as needed) */
6646        ha->nvram->operating_system = IPS_OS_LINUX;
6647        strncpy((char *) ha->nvram->driver_high, IPS_VERSION_HIGH, 4);
6648        strncpy((char *) ha->nvram->driver_low, IPS_VERSION_LOW, 4);
6649     
6650        /* now update the page */
6651        if (!ips_readwrite_page5(ha, TRUE, intr)) {
6652           printk(KERN_WARNING "(%s%d) unable to write NVRAM page 5.\n",
6653                  ips_name, ha->host_num);
6654     
6655           return (0);
6656        }
6657     
6658        /* IF NVRAM Page 5 is OK, Use it for Slot Number Info Because Linux Doesn't Do Slots */
6659        ha->slot_num = ha->nvram->adapter_slot;
6660     
6661        return (1);
6662     }
6663     
6664     /****************************************************************************/
6665     /*                                                                          */
6666     /* Routine Name: ips_read_adapter_status                                    */
6667     /*                                                                          */
6668     /* Routine Description:                                                     */
6669     /*                                                                          */
6670     /*   Do an Inquiry command to the adapter                                   */
6671     /*                                                                          */
6672     /****************************************************************************/
6673     static int
6674     ips_read_adapter_status(ips_ha_t *ha, int intr) {
6675        ips_scb_t *scb;
6676        int        ret;
6677     
6678        METHOD_TRACE("ips_read_adapter_status", 1);
6679     
6680        scb = &ha->scbs[ha->max_cmds-1];
6681     
6682        ips_init_scb(ha, scb);
6683     
6684        scb->timeout = ips_cmd_timeout;
6685        scb->cdb[0] = IPS_CMD_ENQUIRY;
6686     
6687        scb->cmd.basic_io.op_code = IPS_CMD_ENQUIRY;
6688        scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
6689        scb->cmd.basic_io.sg_count = 0;
6690        scb->cmd.basic_io.sg_addr = VIRT_TO_BUS(ha->enq);
6691        scb->cmd.basic_io.lba = 0;
6692        scb->cmd.basic_io.sector_count = 0;
6693        scb->cmd.basic_io.log_drv = 0;
6694        scb->cmd.basic_io.reserved = 0;
6695     
6696        /* send command */
6697        if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) ||
6698            (ret == IPS_SUCCESS_IMM) ||
6699            ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1))
6700           return (0);
6701     
6702        return (1);
6703     }
6704     
6705     /****************************************************************************/
6706     /*                                                                          */
6707     /* Routine Name: ips_read_subsystem_parameters                              */
6708     /*                                                                          */
6709     /* Routine Description:                                                     */
6710     /*                                                                          */
6711     /*   Read subsystem parameters from the adapter                             */
6712     /*                                                                          */
6713     /****************************************************************************/
6714     static int
6715     ips_read_subsystem_parameters(ips_ha_t *ha, int intr) {
6716        ips_scb_t *scb;
6717        int        ret;
6718     
6719        METHOD_TRACE("ips_read_subsystem_parameters", 1);
6720     
6721        scb = &ha->scbs[ha->max_cmds-1];
6722     
6723        ips_init_scb(ha, scb);
6724     
6725        scb->timeout = ips_cmd_timeout;
6726        scb->cdb[0] = IPS_CMD_GET_SUBSYS;
6727     
6728        scb->cmd.basic_io.op_code = IPS_CMD_GET_SUBSYS;
6729        scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
6730        scb->cmd.basic_io.sg_count = 0;
6731        scb->cmd.basic_io.sg_addr = VIRT_TO_BUS(ha->subsys);
6732        scb->cmd.basic_io.lba = 0;
6733        scb->cmd.basic_io.sector_count = 0;
6734        scb->cmd.basic_io.log_drv = 0;
6735        scb->cmd.basic_io.reserved = 0;
6736     
6737        /* send command */
6738        if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) ||
6739            (ret == IPS_SUCCESS_IMM) ||
6740            ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1))
6741           return (0);
6742     
6743        return (1);
6744     }
6745     
6746     /****************************************************************************/
6747     /*                                                                          */
6748     /* Routine Name: ips_read_config                                            */
6749     /*                                                                          */
6750     /* Routine Description:                                                     */
6751     /*                                                                          */
6752     /*   Read the configuration on the adapter                                  */
6753     /*                                                                          */
6754     /****************************************************************************/
6755     static int
6756     ips_read_config(ips_ha_t *ha, int intr) {
6757        ips_scb_t *scb;
6758        int        i;
6759        int        ret;
6760     
6761        METHOD_TRACE("ips_read_config", 1);
6762     
6763        /* set defaults for initiator IDs */
6764        ha->conf->init_id[0] = IPS_ADAPTER_ID;
6765        for (i = 1; i < 4; i++)
6766           ha->conf->init_id[i] = 7;
6767     
6768        scb = &ha->scbs[ha->max_cmds-1];
6769     
6770        ips_init_scb(ha, scb);
6771     
6772        scb->timeout = ips_cmd_timeout;
6773        scb->cdb[0] = IPS_CMD_READ_CONF;
6774     
6775        scb->cmd.basic_io.op_code = IPS_CMD_READ_CONF;
6776        scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
6777        scb->cmd.basic_io.sg_addr = VIRT_TO_BUS(ha->conf);
6778     
6779        /* send command */
6780        if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) ||
6781            (ret == IPS_SUCCESS_IMM) ||
6782            ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) {
6783     
6784           memset(ha->conf, 0, sizeof(IPS_CONF));
6785     
6786           /* reset initiator IDs */
6787           ha->conf->init_id[0] = IPS_ADAPTER_ID;
6788           for (i = 1; i < 4; i++)
6789              ha->conf->init_id[i] = 7;
6790     
6791           return (0);
6792        }
6793     
6794        return (1);
6795     }
6796     
6797     /****************************************************************************/
6798     /*                                                                          */
6799     /* Routine Name: ips_readwrite_page5                                        */
6800     /*                                                                          */
6801     /* Routine Description:                                                     */
6802     /*                                                                          */
6803     /*   Read nvram page 5 from the adapter                                     */
6804     /*                                                                          */
6805     /****************************************************************************/
6806     static int
6807     ips_readwrite_page5(ips_ha_t *ha, int write, int intr) {
6808        ips_scb_t *scb;
6809        int        ret;
6810     
6811        METHOD_TRACE("ips_readwrite_page5", 1);
6812     
6813        scb = &ha->scbs[ha->max_cmds-1];
6814     
6815        ips_init_scb(ha, scb);
6816     
6817        scb->timeout = ips_cmd_timeout;
6818        scb->cdb[0] = IPS_CMD_RW_NVRAM_PAGE;
6819     
6820        scb->cmd.nvram.op_code = IPS_CMD_RW_NVRAM_PAGE;
6821        scb->cmd.nvram.command_id = IPS_COMMAND_ID(ha, scb);
6822        scb->cmd.nvram.page = 5;
6823        scb->cmd.nvram.write = write;
6824        scb->cmd.nvram.buffer_addr = VIRT_TO_BUS(ha->nvram);
6825        scb->cmd.nvram.reserved = 0;
6826        scb->cmd.nvram.reserved2 = 0;
6827     
6828        /* issue the command */
6829        if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) ||
6830            (ret == IPS_SUCCESS_IMM) ||
6831            ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) {
6832     
6833           memset(ha->nvram, 0, sizeof(IPS_NVRAM_P5));
6834     
6835           return (0);
6836        }
6837     
6838        return (1);
6839     }
6840     
6841     /****************************************************************************/
6842     /*                                                                          */
6843     /* Routine Name: ips_clear_adapter                                          */
6844     /*                                                                          */
6845     /* Routine Description:                                                     */
6846     /*                                                                          */
6847     /*   Clear the stripe lock tables                                           */
6848     /*                                                                          */
6849     /****************************************************************************/
6850     static int
6851     ips_clear_adapter(ips_ha_t *ha, int intr) {
6852        ips_scb_t *scb;
6853        int        ret;
6854     
6855        METHOD_TRACE("ips_clear_adapter", 1);
6856     
6857        scb = &ha->scbs[ha->max_cmds-1];
6858     
6859        ips_init_scb(ha, scb);
6860     
6861        scb->timeout = ips_reset_timeout;
6862        scb->cdb[0] = IPS_CMD_CONFIG_SYNC;
6863     
6864        scb->cmd.config_sync.op_code = IPS_CMD_CONFIG_SYNC;
6865        scb->cmd.config_sync.command_id = IPS_COMMAND_ID(ha, scb);
6866        scb->cmd.config_sync.channel = 0;
6867        scb->cmd.config_sync.source_target = IPS_POCL;
6868        scb->cmd.config_sync.reserved = 0;
6869        scb->cmd.config_sync.reserved2 = 0;
6870        scb->cmd.config_sync.reserved3 = 0;
6871     
6872        /* issue command */
6873        if (((ret = ips_send_wait(ha, scb, ips_reset_timeout, intr)) == IPS_FAILURE) ||
6874            (ret == IPS_SUCCESS_IMM) ||
6875            ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1))
6876           return (0);
6877     
6878        /* send unlock stripe command */
6879        ips_init_scb(ha, scb);
6880     
6881        scb->cdb[0] = IPS_CMD_ERROR_TABLE;
6882        scb->timeout = ips_reset_timeout;
6883     
6884        scb->cmd.unlock_stripe.op_code = IPS_CMD_ERROR_TABLE;
6885        scb->cmd.unlock_stripe.command_id = IPS_COMMAND_ID(ha, scb);
6886        scb->cmd.unlock_stripe.log_drv = 0;
6887        scb->cmd.unlock_stripe.control = IPS_CSL;
6888        scb->cmd.unlock_stripe.reserved = 0;
6889        scb->cmd.unlock_stripe.reserved2 = 0;
6890        scb->cmd.unlock_stripe.reserved3 = 0;
6891     
6892        /* issue command */
6893        if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) ||
6894            (ret == IPS_SUCCESS_IMM) ||
6895            ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1))
6896           return (0);
6897     
6898        return (1);
6899     }
6900     
6901     /****************************************************************************/
6902     /*                                                                          */
6903     /* Routine Name: ips_ffdc_reset                                             */
6904     /*                                                                          */
6905     /* Routine Description:                                                     */
6906     /*                                                                          */
6907     /*   FFDC: write reset info                                                 */
6908     /*                                                                          */
6909     /****************************************************************************/
6910     static void
6911     ips_ffdc_reset(ips_ha_t *ha, int intr) {
6912        ips_scb_t *scb;
6913     
6914        METHOD_TRACE("ips_ffdc_reset", 1);
6915     
6916        scb = &ha->scbs[ha->max_cmds-1];
6917     
6918        ips_init_scb(ha, scb);
6919     
6920        scb->timeout = ips_cmd_timeout;
6921        scb->cdb[0] = IPS_CMD_FFDC;
6922        scb->cmd.ffdc.op_code = IPS_CMD_FFDC;
6923        scb->cmd.ffdc.command_id = IPS_COMMAND_ID(ha, scb);
6924        scb->cmd.ffdc.reset_count = ha->reset_count;
6925        scb->cmd.ffdc.reset_type = 0x80;
6926     
6927        /* convert time to what the card wants */
6928        ips_fix_ffdc_time(ha, scb, ha->last_ffdc);
6929     
6930        /* issue command */
6931        ips_send_wait(ha, scb, ips_cmd_timeout, intr);
6932     }
6933     
6934     /****************************************************************************/
6935     /*                                                                          */
6936     /* Routine Name: ips_ffdc_time                                              */
6937     /*                                                                          */
6938     /* Routine Description:                                                     */
6939     /*                                                                          */
6940     /*   FFDC: write time info                                                  */
6941     /*                                                                          */
6942     /****************************************************************************/
6943     static void
6944     ips_ffdc_time(ips_ha_t *ha, int intr) {
6945        ips_scb_t *scb;
6946     
6947        METHOD_TRACE("ips_ffdc_time", 1);
6948     
6949        DEBUG_VAR(1, "(%s%d) Sending time update.",
6950                  ips_name, ha->host_num);
6951     
6952        scb = &ha->scbs[ha->max_cmds-1];
6953     
6954        ips_init_scb(ha, scb);
6955     
6956        scb->timeout = ips_cmd_timeout;
6957        scb->cdb[0] = IPS_CMD_FFDC;
6958        scb->cmd.ffdc.op_code = IPS_CMD_FFDC;
6959        scb->cmd.ffdc.command_id = IPS_COMMAND_ID(ha, scb);
6960        scb->cmd.ffdc.reset_count = 0;
6961        scb->cmd.ffdc.reset_type = 0x80;
6962     
6963        /* convert time to what the card wants */
6964        ips_fix_ffdc_time(ha, scb, ha->last_ffdc);
6965     
6966        /* issue command */
6967        ips_send_wait(ha, scb, ips_cmd_timeout, intr);
6968     }
6969     
6970     /****************************************************************************/
6971     /*                                                                          */
6972     /* Routine Name: ips_fix_ffdc_time                                          */
6973     /*                                                                          */
6974     /* Routine Description:                                                     */
6975     /*   Adjust time_t to what the card wants                                   */
6976     /*                                                                          */
6977     /****************************************************************************/
6978     static void
6979     ips_fix_ffdc_time(ips_ha_t *ha, ips_scb_t *scb, time_t current_time) {
6980        long days;
6981        long rem;
6982        int  i;
6983        int  year;
6984        int  yleap;
6985        int  year_lengths[2] = { IPS_DAYS_NORMAL_YEAR, IPS_DAYS_LEAP_YEAR };
6986        int  month_lengths[12][2] = { {31, 31},
6987                                      {28, 29},
6988                                      {31, 31},
6989                                      {30, 30},
6990                                      {31, 31},
6991                                      {30, 30},
6992                                      {31, 31},
6993                                      {31, 31},
6994                                      {30, 30},
6995                                      {31, 31},
6996                                      {30, 30},
6997                                      {31, 31} };
6998     
6999        METHOD_TRACE("ips_fix_ffdc_time", 1);
7000     
7001        days = current_time / IPS_SECS_DAY;
7002        rem = current_time % IPS_SECS_DAY;
7003     
7004        scb->cmd.ffdc.hour = (rem / IPS_SECS_HOUR);
7005        rem = rem % IPS_SECS_HOUR;
7006        scb->cmd.ffdc.minute = (rem / IPS_SECS_MIN);
7007        scb->cmd.ffdc.second = (rem % IPS_SECS_MIN);
7008     
7009        year = IPS_EPOCH_YEAR;
7010        while (days < 0 || days >= year_lengths[yleap = IPS_IS_LEAP_YEAR(year)]) {
7011           int newy;
7012     
7013           newy = year + (days / IPS_DAYS_NORMAL_YEAR);
7014           if (days < 0)
7015              --newy;
7016           days -= (newy - year) * IPS_DAYS_NORMAL_YEAR +
7017              IPS_NUM_LEAP_YEARS_THROUGH(newy - 1) -
7018              IPS_NUM_LEAP_YEARS_THROUGH(year - 1);
7019           year = newy;
7020        }
7021     
7022        scb->cmd.ffdc.yearH = year / 100;
7023        scb->cmd.ffdc.yearL = year % 100;
7024     
7025        for (i = 0; days >= month_lengths[i][yleap]; ++i)
7026           days -= month_lengths[i][yleap];
7027     
7028        scb->cmd.ffdc.month = i + 1;
7029        scb->cmd.ffdc.day = days + 1;
7030     }
7031     
7032     /****************************************************************************
7033      * BIOS Flash Routines                                                      *
7034      ****************************************************************************/
7035     
7036     /****************************************************************************/
7037     /*                                                                          */
7038     /* Routine Name: ips_erase_bios                                             */
7039     /*                                                                          */
7040     /* Routine Description:                                                     */
7041     /*   Erase the BIOS on the adapter                                          */
7042     /*                                                                          */
7043     /****************************************************************************/
7044     static int
7045     ips_erase_bios(ips_ha_t *ha) {
7046        int   timeout;
7047        u8    status=0;
7048     
7049        METHOD_TRACE("ips_erase_bios", 1);
7050     
7051        /* Clear the status register */
7052        outl(0, ha->io_addr + IPS_REG_FLAP);
7053        if (ha->revision_id == IPS_REVID_TROMBONE64)
7054           udelay(5); /* 5 us */
7055     
7056        outb(0x50, ha->io_addr + IPS_REG_FLDP);
7057        if (ha->revision_id == IPS_REVID_TROMBONE64)
7058           udelay(5); /* 5 us */
7059     
7060        /* Erase Setup */
7061        outb(0x20, ha->io_addr + IPS_REG_FLDP);
7062        if (ha->revision_id == IPS_REVID_TROMBONE64)
7063           udelay(5); /* 5 us */
7064     
7065        /* Erase Confirm */
7066        outb(0xD0, ha->io_addr + IPS_REG_FLDP);
7067        if (ha->revision_id == IPS_REVID_TROMBONE64)
7068           udelay(5); /* 5 us */
7069     
7070        /* Erase Status */
7071        outb(0x70, ha->io_addr + IPS_REG_FLDP);
7072        if (ha->revision_id == IPS_REVID_TROMBONE64)
7073           udelay(5); /* 5 us */
7074     
7075        timeout = 80000; /* 80 seconds */
7076     
7077        while (timeout > 0) {
7078           if (ha->revision_id == IPS_REVID_TROMBONE64) {
7079              outl(0, ha->io_addr + IPS_REG_FLAP);
7080              udelay(5); /* 5 us */
7081           }
7082     
7083           status = inb(ha->io_addr + IPS_REG_FLDP);
7084     
7085           if (status & 0x80)
7086              break;
7087     
7088           MDELAY(1);
7089           timeout--;
7090        }
7091     
7092        /* check for timeout */
7093        if (timeout <= 0) {
7094           /* timeout */
7095     
7096           /* try to suspend the erase */
7097           outb(0xB0, ha->io_addr + IPS_REG_FLDP);
7098           if (ha->revision_id == IPS_REVID_TROMBONE64)
7099              udelay(5); /* 5 us */
7100     
7101           /* wait for 10 seconds */
7102           timeout = 10000;
7103           while (timeout > 0) {
7104              if (ha->revision_id == IPS_REVID_TROMBONE64) {
7105                 outl(0, ha->io_addr + IPS_REG_FLAP);
7106                 udelay(5); /* 5 us */
7107              }
7108     
7109              status = inb(ha->io_addr + IPS_REG_FLDP);
7110     
7111              if (status & 0xC0)
7112                 break;
7113     
7114              MDELAY(1);
7115              timeout--;
7116           }
7117     
7118           return (1);
7119        }
7120     
7121        /* check for valid VPP */
7122        if (status & 0x08)
7123           /* VPP failure */
7124           return (1);
7125     
7126        /* check for succesful flash */
7127        if (status & 0x30)
7128           /* sequence error */
7129           return (1);
7130     
7131        /* Otherwise, we were successful */
7132        /* clear status */
7133        outb(0x50, ha->io_addr + IPS_REG_FLDP);
7134        if (ha->revision_id == IPS_REVID_TROMBONE64)
7135           udelay(5); /* 5 us */
7136     
7137        /* enable reads */
7138        outb(0xFF, ha->io_addr + IPS_REG_FLDP);
7139        if (ha->revision_id == IPS_REVID_TROMBONE64)
7140           udelay(5); /* 5 us */
7141     
7142        return (0);
7143     }
7144     
7145     /****************************************************************************/
7146     /*                                                                          */
7147     /* Routine Name: ips_erase_bios_memio                                       */
7148     /*                                                                          */
7149     /* Routine Description:                                                     */
7150     /*   Erase the BIOS on the adapter                                          */
7151     /*                                                                          */
7152     /****************************************************************************/
7153     static int
7154     ips_erase_bios_memio(ips_ha_t *ha) {
7155        int   timeout;
7156        u8    status;
7157     
7158        METHOD_TRACE("ips_erase_bios_memio", 1);
7159     
7160        /* Clear the status register */
7161        writel(0, ha->mem_ptr + IPS_REG_FLAP);
7162        if (ha->revision_id == IPS_REVID_TROMBONE64)
7163           udelay(5); /* 5 us */
7164     
7165        writeb(0x50, ha->mem_ptr + IPS_REG_FLDP);
7166        if (ha->revision_id == IPS_REVID_TROMBONE64)
7167           udelay(5); /* 5 us */
7168     
7169        /* Erase Setup */
7170        writeb(0x20, ha->mem_ptr + IPS_REG_FLDP);
7171        if (ha->revision_id == IPS_REVID_TROMBONE64)
7172           udelay(5); /* 5 us */
7173     
7174        /* Erase Confirm */
7175        writeb(0xD0, ha->mem_ptr + IPS_REG_FLDP);
7176        if (ha->revision_id == IPS_REVID_TROMBONE64)
7177           udelay(5); /* 5 us */
7178     
7179        /* Erase Status */
7180        writeb(0x70, ha->mem_ptr + IPS_REG_FLDP);
7181        if (ha->revision_id == IPS_REVID_TROMBONE64)
7182           udelay(5); /* 5 us */
7183     
7184        timeout = 80000; /* 80 seconds */
7185     
7186        while (timeout > 0) {
7187           if (ha->revision_id == IPS_REVID_TROMBONE64) {
7188              writel(0, ha->mem_ptr + IPS_REG_FLAP);
7189              udelay(5); /* 5 us */
7190           }
7191     
7192           status = readb(ha->mem_ptr + IPS_REG_FLDP);
7193     
7194           if (status & 0x80)
7195              break;
7196     
7197           MDELAY(1);
7198           timeout--;
7199        }
7200     
7201        /* check for timeout */
7202        if (timeout <= 0) {
7203           /* timeout */
7204     
7205           /* try to suspend the erase */
7206           writeb(0xB0, ha->mem_ptr + IPS_REG_FLDP);
7207           if (ha->revision_id == IPS_REVID_TROMBONE64)
7208              udelay(5); /* 5 us */
7209     
7210           /* wait for 10 seconds */
7211           timeout = 10000;
7212           while (timeout > 0) {
7213              if (ha->revision_id == IPS_REVID_TROMBONE64) {
7214                 writel(0, ha->mem_ptr + IPS_REG_FLAP);
7215                 udelay(5); /* 5 us */
7216              }
7217     
7218              status = readb(ha->mem_ptr + IPS_REG_FLDP);
7219     
7220              if (status & 0xC0)
7221                 break;
7222     
7223              MDELAY(1);
7224              timeout--;
7225           }
7226     
7227           return (1);
7228        }
7229     
7230        /* check for valid VPP */
7231        if (status & 0x08)
7232           /* VPP failure */
7233           return (1);
7234     
7235        /* check for succesful flash */
7236        if (status & 0x30)
7237           /* sequence error */
7238           return (1);
7239     
7240        /* Otherwise, we were successful */
7241        /* clear status */
7242        writeb(0x50, ha->mem_ptr + IPS_REG_FLDP);
7243        if (ha->revision_id == IPS_REVID_TROMBONE64)
7244           udelay(5); /* 5 us */
7245     
7246        /* enable reads */
7247        writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP);
7248        if (ha->revision_id == IPS_REVID_TROMBONE64)
7249           udelay(5); /* 5 us */
7250     
7251        return (0);
7252     }
7253     
7254     /****************************************************************************/
7255     /*                                                                          */
7256     /* Routine Name: ips_program_bios                                           */
7257     /*                                                                          */
7258     /* Routine Description:                                                     */
7259     /*   Program the BIOS on the adapter                                        */
7260     /*                                                                          */
7261     /****************************************************************************/
7262     static int
7263     ips_program_bios(ips_ha_t *ha, char *buffer, u32 buffersize, u32 offset) {
7264        int   i;
7265        int   timeout;
7266        u8    status=0;
7267     
7268        METHOD_TRACE("ips_program_bios", 1);
7269     
7270        for (i = 0; i < buffersize; i++) {
7271           /* write a byte */
7272           outl(i + offset, ha->io_addr + IPS_REG_FLAP);
7273           if (ha->revision_id == IPS_REVID_TROMBONE64)
7274              udelay(5); /* 5 us */
7275     
7276           outb(0x40, ha->io_addr + IPS_REG_FLDP);
7277           if (ha->revision_id == IPS_REVID_TROMBONE64)
7278              udelay(5); /* 5 us */
7279     
7280           outb(buffer[i], ha->io_addr + IPS_REG_FLDP);
7281           if (ha->revision_id == IPS_REVID_TROMBONE64)
7282              udelay(5); /* 5 us */
7283     
7284           /* wait up to one second */
7285           timeout = 1000;
7286           while (timeout > 0) {
7287              if (ha->revision_id == IPS_REVID_TROMBONE64) {
7288                 outl(0, ha->io_addr + IPS_REG_FLAP);
7289                 udelay(5); /* 5 us */
7290              }
7291     
7292              status = inb(ha->io_addr + IPS_REG_FLDP);
7293     
7294              if (status & 0x80)
7295                 break;
7296     
7297              MDELAY(1);
7298              timeout--;
7299           }
7300     
7301           if (timeout == 0) {
7302              /* timeout error */
7303              outl(0, ha->io_addr + IPS_REG_FLAP);
7304              if (ha->revision_id == IPS_REVID_TROMBONE64)
7305                 udelay(5); /* 5 us */
7306     
7307              outb(0xFF, ha->io_addr + IPS_REG_FLDP);
7308              if (ha->revision_id == IPS_REVID_TROMBONE64)
7309                 udelay(5); /* 5 us */
7310     
7311              return (1);
7312           }
7313     
7314           /* check the status */
7315           if (status & 0x18) {
7316              /* programming error */
7317              outl(0, ha->io_addr + IPS_REG_FLAP);
7318              if (ha->revision_id == IPS_REVID_TROMBONE64)
7319                 udelay(5); /* 5 us */
7320     
7321              outb(0xFF, ha->io_addr + IPS_REG_FLDP);
7322              if (ha->revision_id == IPS_REVID_TROMBONE64)
7323                 udelay(5); /* 5 us */
7324     
7325              return (1);
7326           }
7327        } /* end for */
7328     
7329        /* Enable reading */
7330        outl(0, ha->io_addr + IPS_REG_FLAP);
7331        if (ha->revision_id == IPS_REVID_TROMBONE64)
7332           udelay(5); /* 5 us */
7333     
7334        outb(0xFF, ha->io_addr + IPS_REG_FLDP);
7335        if (ha->revision_id == IPS_REVID_TROMBONE64)
7336           udelay(5); /* 5 us */
7337     
7338        return (0);
7339     }
7340     
7341     /****************************************************************************/
7342     /*                                                                          */
7343     /* Routine Name: ips_program_bios_memio                                     */
7344     /*                                                                          */
7345     /* Routine Description:                                                     */
7346     /*   Program the BIOS on the adapter                                        */
7347     /*                                                                          */
7348     /****************************************************************************/
7349     static int
7350     ips_program_bios_memio(ips_ha_t *ha, char *buffer, u32 buffersize, u32 offset) {
7351        int   i;
7352        int   timeout;
7353        u8    status=0;
7354     
7355        METHOD_TRACE("ips_program_bios_memio", 1);
7356     
7357        for (i = 0; i < buffersize; i++) {
7358           /* write a byte */
7359           writel(i + offset, ha->mem_ptr + IPS_REG_FLAP);
7360           if (ha->revision_id == IPS_REVID_TROMBONE64)
7361              udelay(5); /* 5 us */
7362     
7363           writeb(0x40, ha->mem_ptr + IPS_REG_FLDP);
7364           if (ha->revision_id == IPS_REVID_TROMBONE64)
7365              udelay(5); /* 5 us */
7366     
7367           writeb(buffer[i], ha->mem_ptr + IPS_REG_FLDP);
7368           if (ha->revision_id == IPS_REVID_TROMBONE64)
7369              udelay(5); /* 5 us */
7370     
7371           /* wait up to one second */
7372           timeout = 1000;
7373           while (timeout > 0) {
7374              if (ha->revision_id == IPS_REVID_TROMBONE64) {
7375                 writel(0, ha->mem_ptr + IPS_REG_FLAP);
7376                 udelay(5); /* 5 us */
7377              }
7378     
7379              status = readb(ha->mem_ptr + IPS_REG_FLDP);
7380     
7381              if (status & 0x80)
7382                 break;
7383     
7384              MDELAY(1);
7385              timeout--;
7386           }
7387     
7388           if (timeout == 0) {
7389              /* timeout error */
7390              writel(0, ha->mem_ptr + IPS_REG_FLAP);
7391              if (ha->revision_id == IPS_REVID_TROMBONE64)
7392                 udelay(5); /* 5 us */
7393     
7394              writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP);
7395              if (ha->revision_id == IPS_REVID_TROMBONE64)
7396                 udelay(5); /* 5 us */
7397     
7398              return (1);
7399           }
7400     
7401           /* check the status */
7402           if (status & 0x18) {
7403              /* programming error */
7404              writel(0, ha->mem_ptr + IPS_REG_FLAP);
7405              if (ha->revision_id == IPS_REVID_TROMBONE64)
7406                 udelay(5); /* 5 us */
7407     
7408              writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP);
7409              if (ha->revision_id == IPS_REVID_TROMBONE64)
7410                 udelay(5); /* 5 us */
7411     
7412              return (1);
7413           }
7414        } /* end for */
7415     
7416        /* Enable reading */
7417        writel(0, ha->mem_ptr + IPS_REG_FLAP);
7418        if (ha->revision_id == IPS_REVID_TROMBONE64)
7419           udelay(5); /* 5 us */
7420     
7421        writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP);
7422        if (ha->revision_id == IPS_REVID_TROMBONE64)
7423           udelay(5); /* 5 us */
7424     
7425        return (0);
7426     }
7427     
7428     /****************************************************************************/
7429     /*                                                                          */
7430     /* Routine Name: ips_verify_bios                                            */
7431     /*                                                                          */
7432     /* Routine Description:                                                     */
7433     /*   Verify the BIOS on the adapter                                         */
7434     /*                                                                          */
7435     /****************************************************************************/
7436     static int
7437     ips_verify_bios(ips_ha_t *ha, char *buffer, u32 buffersize, u32 offset) {
7438        u8    checksum;
7439        int   i;
7440     
7441        METHOD_TRACE("ips_verify_bios", 1);
7442     
7443        /* test 1st byte */
7444        outl(0, ha->io_addr + IPS_REG_FLAP);
7445        if (ha->revision_id == IPS_REVID_TROMBONE64)
7446           udelay(5); /* 5 us */
7447     
7448        if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55)
7449           return (1);
7450     
7451        outl(1, ha->io_addr + IPS_REG_FLAP);
7452        if (ha->revision_id == IPS_REVID_TROMBONE64)
7453           udelay(5); /* 5 us */
7454        if (inb(ha->io_addr + IPS_REG_FLDP) != 0xAA)
7455           return (1);
7456     
7457        checksum = 0xff;
7458        for (i = 2; i < buffersize; i++) {
7459     
7460           outl(i + offset, ha->io_addr + IPS_REG_FLAP);
7461           if (ha->revision_id == IPS_REVID_TROMBONE64)
7462              udelay(5); /* 5 us */
7463     
7464           checksum = (u8) checksum + inb(ha->io_addr + IPS_REG_FLDP);
7465        }
7466     
7467        if (checksum != 0)
7468           /* failure */
7469           return (1);
7470        else
7471           /* success */
7472           return (0);
7473     }
7474     
7475     /****************************************************************************/
7476     /*                                                                          */
7477     /* Routine Name: ips_verify_bios_memio                                      */
7478     /*                                                                          */
7479     /* Routine Description:                                                     */
7480     /*   Verify the BIOS on the adapter                                         */
7481     /*                                                                          */
7482     /****************************************************************************/
7483     static int
7484     ips_verify_bios_memio(ips_ha_t *ha, char *buffer, u32 buffersize, u32 offset) {
7485        u8    checksum;
7486        int   i;
7487     
7488        METHOD_TRACE("ips_verify_bios_memio", 1);
7489     
7490        /* test 1st byte */
7491        writel(0, ha->mem_ptr + IPS_REG_FLAP);
7492        if (ha->revision_id == IPS_REVID_TROMBONE64)
7493           udelay(5); /* 5 us */
7494     
7495        if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0x55)
7496           return (1);
7497     
7498        writel(1, ha->mem_ptr + IPS_REG_FLAP);
7499        if (ha->revision_id == IPS_REVID_TROMBONE64)
7500           udelay(5); /* 5 us */
7501        if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0xAA)
7502           return (1);
7503     
7504        checksum = 0xff;
7505        for (i = 2; i < buffersize; i++) {
7506     
7507           writel(i + offset, ha->mem_ptr + IPS_REG_FLAP);
7508           if (ha->revision_id == IPS_REVID_TROMBONE64)
7509              udelay(5); /* 5 us */
7510     
7511           checksum = (u8) checksum + readb(ha->mem_ptr + IPS_REG_FLDP);
7512        }
7513     
7514        if (checksum != 0)
7515           /* failure */
7516           return (1);
7517        else
7518           /* success */
7519           return (0);
7520     }
7521     
7522     static Scsi_Host_Template driver_template = IPS;
7523     #include "scsi_module.c"
7524     
7525     
7526     /*
7527      * Overrides for Emacs so that we almost follow Linus's tabbing style.
7528      * Emacs will notice this stuff at the end of the file and automatically
7529      * adjust the settings for this buffer only.  This must remain at the end
7530      * of the file.
7531      * ---------------------------------------------------------------------------
7532      * Local variables:
7533      * c-indent-level: 2
7534      * c-brace-imaginary-offset: 0
7535      * c-brace-offset: -2
7536      * c-argdecl-indent: 2
7537      * c-label-offset: -2
7538      * c-continued-statement-offset: 2
7539      * c-continued-brace-offset: 0
7540      * indent-tabs-mode: nil
7541      * tab-width: 8
7542      * End:
7543      */
7544