1 /*****************************************************************************/
2 /* ips.c -- driver for the IBM ServeRAID controller */
4 /* Written By: Keith Mitchell, IBM Corporation */
6 /* Copyright (C) 1999 IBM Corporation */
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. */
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. */
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. */
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 */
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 */
42 /* Bugs/Comments/Suggestions should be mailed to: */
43 /* ipslinux@us.ibm.com */
45 /*****************************************************************************/
47 /*****************************************************************************/
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 */
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 */
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 */
90 /*****************************************************************************/
93 * Conditional Compilation directives for this driver:
95 * IPS_DEBUG - Turn on debugging info
100 * debug:<number> - Set debug level to <number>
101 * NOTE: only works when IPS_DEBUG compile directive
104 * 1 - Normal debug messages
105 * 2 - Verbose debug messages
106 * 11 - Method trace (non interrupt)
107 * 12 - Method trace (includes interrupt)
109 * noreset - Don't reset the controller
110 * nocmdline - Turn off passthru support
111 * noi2o - Don't use I2O Queues (ServeRAID 4 only)
112 * nommap - Don't use memory mapped I/O
116 #include <linux/module.h>
119 #include <asm/byteorder.h>
120 #include <linux/stddef.h>
121 #include <linux/version.h>
122 #include <linux/string.h>
123 #include <linux/errno.h>
124 #include <linux/kernel.h>
125 #include <linux/ioport.h>
126 #include <linux/malloc.h>
127 #include <linux/vmalloc.h>
128 #include <linux/delay.h>
129 #include <linux/sched.h>
130 #include <linux/pci.h>
131 #include <linux/proc_fs.h>
132 #include <linux/reboot.h>
134 #include <linux/blk.h>
135 #include <linux/types.h>
137 #ifndef NO_IPS_CMDLINE
146 #include <linux/stat.h>
147 #include <linux/config.h>
149 #if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,18)
150 #include <linux/spinlock.h>
152 #include <asm/spinlock.h>
155 #if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,13)
156 #include <linux/init.h>
159 #include <linux/smp.h>
162 static char *ips
= NULL
;
163 MODULE_PARM(ips
, "s");
169 #define IPS_VERSION_HIGH "4.20"
170 #define IPS_VERSION_LOW ".20 "
172 #if LINUX_VERSION_CODE < LinuxVersionCode(2,3,27)
173 struct proc_dir_entry proc_scsi_ips
= {
176 S_IFDIR
| S_IRUGO
| S_IXUGO
, 2
180 #if !defined(__i386__)
181 #error "This driver has only been tested on the x86 platform"
184 #if LINUX_VERSION_CODE < LinuxVersionCode(2,2,0)
185 #error "This driver only works with kernel 2.2.0 and later"
188 #if !defined(NO_IPS_CMDLINE) && ((SG_BIG_BUFF < 8192) || !defined(SG_BIG_BUFF))
189 #error "To use the command-line interface you need to define SG_BIG_BUFF"
193 #define METHOD_TRACE(s, i) if (ips_debug >= (i+10)) printk(KERN_NOTICE s "\n");
194 #define DEBUG(i, s) if (ips_debug >= i) printk(KERN_NOTICE s "\n");
195 #define DEBUG_VAR(i, s, v...) if (ips_debug >= i) printk(KERN_NOTICE s "\n", v);
197 #define METHOD_TRACE(s, i)
199 #define DEBUG_VAR(i, s, v...)
205 static const char * ips_name
= "ips";
206 static struct Scsi_Host
* ips_sh
[IPS_MAX_ADAPTERS
]; /* Array of host controller structures */
207 static ips_ha_t
* ips_ha
[IPS_MAX_ADAPTERS
]; /* Array of HA structures */
208 static unsigned int ips_next_controller
= 0;
209 static unsigned int ips_num_controllers
= 0;
210 static unsigned int ips_released_controllers
= 0;
211 static int ips_cmd_timeout
= 60;
212 static int ips_reset_timeout
= 60 * 5;
213 static int ips_force_memio
= 1; /* Always use Memory Mapped I/O */
214 static int ips_force_i2o
= 1; /* Always use I2O command delivery */
215 static int ips_resetcontroller
= 1; /* Reset the controller */
216 static int ips_cmdline
= 1; /* Support for passthru */
219 static int ips_debug
= 0; /* Debug mode */
223 * Necessary forward function protoypes
225 static int ips_halt(struct notifier_block
*nb
, ulong event
, void *buf
);
227 #define MAX_ADAPTER_NAME 9
229 static char ips_adapter_name
[][30] = {
232 "ServeRAID on motherboard",
233 "ServeRAID on motherboard",
241 static struct notifier_block ips_notifier
= {
248 static char ips_command_direction
[] = {
249 IPS_DATA_NONE
, IPS_DATA_NONE
, IPS_DATA_IN
, IPS_DATA_IN
, IPS_DATA_OUT
,
250 IPS_DATA_IN
, IPS_DATA_IN
, IPS_DATA_OUT
, IPS_DATA_IN
, IPS_DATA_UNK
,
251 IPS_DATA_OUT
, IPS_DATA_OUT
, IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
,
252 IPS_DATA_IN
, IPS_DATA_NONE
, IPS_DATA_IN
, IPS_DATA_IN
, IPS_DATA_OUT
,
253 IPS_DATA_IN
, IPS_DATA_OUT
, IPS_DATA_NONE
, IPS_DATA_NONE
, IPS_DATA_OUT
,
254 IPS_DATA_NONE
, IPS_DATA_IN
, IPS_DATA_NONE
, IPS_DATA_IN
, IPS_DATA_OUT
,
255 IPS_DATA_NONE
, IPS_DATA_UNK
, IPS_DATA_IN
, IPS_DATA_UNK
, IPS_DATA_IN
,
256 IPS_DATA_UNK
, IPS_DATA_OUT
, IPS_DATA_IN
, IPS_DATA_UNK
, IPS_DATA_UNK
,
257 IPS_DATA_IN
, IPS_DATA_IN
, IPS_DATA_OUT
, IPS_DATA_NONE
, IPS_DATA_UNK
,
258 IPS_DATA_IN
, IPS_DATA_OUT
, IPS_DATA_OUT
, IPS_DATA_OUT
, IPS_DATA_OUT
,
259 IPS_DATA_OUT
, IPS_DATA_NONE
, IPS_DATA_IN
, IPS_DATA_NONE
, IPS_DATA_NONE
,
260 IPS_DATA_IN
, IPS_DATA_OUT
, IPS_DATA_OUT
, IPS_DATA_OUT
, IPS_DATA_OUT
,
261 IPS_DATA_IN
, IPS_DATA_OUT
, IPS_DATA_IN
, IPS_DATA_OUT
, IPS_DATA_OUT
,
262 IPS_DATA_OUT
, IPS_DATA_IN
, IPS_DATA_IN
, IPS_DATA_IN
, IPS_DATA_NONE
,
263 IPS_DATA_UNK
, IPS_DATA_NONE
, IPS_DATA_NONE
, IPS_DATA_NONE
, IPS_DATA_UNK
,
264 IPS_DATA_NONE
, IPS_DATA_OUT
, IPS_DATA_IN
, IPS_DATA_UNK
, IPS_DATA_UNK
,
265 IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
,
266 IPS_DATA_OUT
, IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
,
267 IPS_DATA_IN
, IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
,
268 IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
,
269 IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
,
270 IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
,
271 IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
,
272 IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
,
273 IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
,
274 IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
,
275 IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
,
276 IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
,
277 IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
,
278 IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
,
279 IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
,
280 IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
,
281 IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
,
282 IPS_DATA_NONE
, IPS_DATA_NONE
, IPS_DATA_UNK
, IPS_DATA_IN
, IPS_DATA_NONE
,
283 IPS_DATA_OUT
, IPS_DATA_UNK
, IPS_DATA_NONE
, IPS_DATA_UNK
, IPS_DATA_OUT
,
284 IPS_DATA_OUT
, IPS_DATA_OUT
, IPS_DATA_OUT
, IPS_DATA_OUT
, IPS_DATA_NONE
,
285 IPS_DATA_UNK
, IPS_DATA_IN
, IPS_DATA_OUT
, IPS_DATA_IN
, IPS_DATA_IN
,
286 IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
,
287 IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
, 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_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
, IPS_DATA_UNK
,
290 IPS_DATA_UNK
, 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_OUT
,
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
303 * Function prototypes
305 int ips_detect(Scsi_Host_Template
*);
306 int ips_release(struct Scsi_Host
*);
307 int ips_eh_abort(Scsi_Cmnd
*);
308 int ips_eh_reset(Scsi_Cmnd
*);
309 int ips_queue(Scsi_Cmnd
*, void (*) (Scsi_Cmnd
*));
310 int ips_biosparam(Disk
*, kdev_t
, int *);
311 const char * ips_info(struct Scsi_Host
*);
312 void do_ipsintr(int, void *, struct pt_regs
*);
313 static int ips_hainit(ips_ha_t
*);
314 static int ips_map_status(ips_ha_t
*, ips_scb_t
*, ips_stat_t
*);
315 static int ips_send(ips_ha_t
*, ips_scb_t
*, ips_scb_callback
);
316 static int ips_send_wait(ips_ha_t
*, ips_scb_t
*, int, int);
317 static int ips_send_cmd(ips_ha_t
*, ips_scb_t
*);
318 static int ips_online(ips_ha_t
*, ips_scb_t
*);
319 static int ips_inquiry(ips_ha_t
*, ips_scb_t
*);
320 static int ips_rdcap(ips_ha_t
*, ips_scb_t
*);
321 static int ips_msense(ips_ha_t
*, ips_scb_t
*);
322 static int ips_reqsen(ips_ha_t
*, ips_scb_t
*);
323 static int ips_allocatescbs(ips_ha_t
*);
324 static int ips_reset_copperhead(ips_ha_t
*);
325 static int ips_reset_copperhead_memio(ips_ha_t
*);
326 static int ips_reset_morpheus(ips_ha_t
*);
327 static int ips_issue_copperhead(ips_ha_t
*, ips_scb_t
*);
328 static int ips_issue_copperhead_memio(ips_ha_t
*, ips_scb_t
*);
329 static int ips_issue_i2o(ips_ha_t
*, ips_scb_t
*);
330 static int ips_issue_i2o_memio(ips_ha_t
*, ips_scb_t
*);
331 static int ips_isintr_copperhead(ips_ha_t
*);
332 static int ips_isintr_copperhead_memio(ips_ha_t
*);
333 static int ips_isintr_morpheus(ips_ha_t
*);
334 static int ips_wait(ips_ha_t
*, int, int);
335 static int ips_write_driver_status(ips_ha_t
*, int);
336 static int ips_read_adapter_status(ips_ha_t
*, int);
337 static int ips_read_subsystem_parameters(ips_ha_t
*, int);
338 static int ips_read_config(ips_ha_t
*, int);
339 static int ips_clear_adapter(ips_ha_t
*, int);
340 static int ips_readwrite_page5(ips_ha_t
*, int, int);
341 static int ips_init_copperhead(ips_ha_t
*);
342 static int ips_init_copperhead_memio(ips_ha_t
*);
343 static int ips_init_morpheus(ips_ha_t
*);
344 static int ips_isinit_copperhead(ips_ha_t
*);
345 static int ips_isinit_copperhead_memio(ips_ha_t
*);
346 static int ips_isinit_morpheus(ips_ha_t
*);
347 static u32
ips_statupd_copperhead(ips_ha_t
*);
348 static u32
ips_statupd_copperhead_memio(ips_ha_t
*);
349 static u32
ips_statupd_morpheus(ips_ha_t
*);
350 static void ips_select_queue_depth(struct Scsi_Host
*, Scsi_Device
*);
351 static void ips_chkstatus(ips_ha_t
*, IPS_STATUS
*);
352 static void ips_enable_int_copperhead(ips_ha_t
*);
353 static void ips_enable_int_copperhead_memio(ips_ha_t
*);
354 static void ips_enable_int_morpheus(ips_ha_t
*);
355 static void ips_intr_copperhead(ips_ha_t
*);
356 static void ips_intr_morpheus(ips_ha_t
*);
357 static void ips_next(ips_ha_t
*, int);
358 static void ipsintr_blocking(ips_ha_t
*, struct ips_scb
*);
359 static void ipsintr_done(ips_ha_t
*, struct ips_scb
*);
360 static void ips_done(ips_ha_t
*, ips_scb_t
*);
361 static void ips_free(ips_ha_t
*);
362 static void ips_init_scb(ips_ha_t
*, ips_scb_t
*);
363 static void ips_freescb(ips_ha_t
*, ips_scb_t
*);
364 static void ips_statinit(ips_ha_t
*);
365 static void ips_statinit_memio(ips_ha_t
*);
366 static void ips_fix_ffdc_time(ips_ha_t
*, ips_scb_t
*, time_t);
367 static void ips_ffdc_reset(ips_ha_t
*, int);
368 static void ips_ffdc_time(ips_ha_t
*, int);
369 static ips_scb_t
* ips_getscb(ips_ha_t
*);
370 static inline void ips_putq_scb_head(ips_scb_queue_t
*, ips_scb_t
*);
371 static inline void ips_putq_scb_tail(ips_scb_queue_t
*, ips_scb_t
*);
372 static inline ips_scb_t
* ips_removeq_scb_head(ips_scb_queue_t
*);
373 static inline ips_scb_t
* ips_removeq_scb(ips_scb_queue_t
*, ips_scb_t
*);
374 static inline void ips_putq_wait_head(ips_wait_queue_t
*, Scsi_Cmnd
*);
375 static inline void ips_putq_wait_tail(ips_wait_queue_t
*, Scsi_Cmnd
*);
376 static inline Scsi_Cmnd
* ips_removeq_wait_head(ips_wait_queue_t
*);
377 static inline Scsi_Cmnd
* ips_removeq_wait(ips_wait_queue_t
*, Scsi_Cmnd
*);
378 static inline void ips_putq_copp_head(ips_copp_queue_t
*, ips_copp_wait_item_t
*);
379 static inline void ips_putq_copp_tail(ips_copp_queue_t
*, ips_copp_wait_item_t
*);
380 static inline ips_copp_wait_item_t
* ips_removeq_copp(ips_copp_queue_t
*, ips_copp_wait_item_t
*);
381 static inline ips_copp_wait_item_t
* ips_removeq_copp_head(ips_copp_queue_t
*);
382 static int ips_erase_bios(ips_ha_t
*);
383 static int ips_program_bios(ips_ha_t
*, char *, int);
384 static int ips_verify_bios(ips_ha_t
*, char *, int);
385 static int ips_erase_bios_memio(ips_ha_t
*);
386 static int ips_program_bios_memio(ips_ha_t
*, char *, int);
387 static int ips_verify_bios_memio(ips_ha_t
*, char *, int);
389 #ifndef NO_IPS_CMDLINE
390 static int ips_is_passthru(Scsi_Cmnd
*);
391 static int ips_make_passthru(ips_ha_t
*, Scsi_Cmnd
*, ips_scb_t
*);
392 static int ips_usrcmd(ips_ha_t
*, ips_passthru_t
*, ips_scb_t
*);
393 static int ips_newusrcmd(ips_ha_t
*, ips_passthru_t
*, ips_scb_t
*);
394 static void ips_cleanup_passthru(ips_ha_t
*, ips_scb_t
*);
397 int ips_proc_info(char *, char **, off_t
, int, int, int);
398 static int ips_host_info(ips_ha_t
*, char *, off_t
, int);
399 static void copy_mem_info(IPS_INFOSTR
*, char *, int);
400 static int copy_info(IPS_INFOSTR
*, char *, ...);
402 /*--------------------------------------------------------------------------*/
403 /* Exported Functions */
404 /*--------------------------------------------------------------------------*/
406 /****************************************************************************/
408 /* Routine Name: ips_setup */
410 /* Routine Description: */
412 /* setup parameters to the driver */
414 /****************************************************************************/
415 #if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,13)
417 ips_setup(char *ips_str
) {
420 ips_setup(char *ips_str
, int *dummy
) {
426 char tokens
[3] = {',', '.', 0};
427 IPS_OPTION options
[] = {
428 {"noreset", &ips_resetcontroller
, 0},
430 {"debug", &ips_debug
, 1},
432 {"noi2o", &ips_force_i2o
, 0},
433 {"nommap", &ips_force_memio
, 0},
434 {"nocmdline", &ips_cmdline
, 0},
437 METHOD_TRACE("ips_setup", 1);
439 for (key
= strtok(ips_str
, tokens
); key
; key
= strtok(NULL
, tokens
)) {
442 /* Search for value */
443 while ((p
) && (*p
!= ':'))
453 * We now have key/value pairs.
454 * Update the variables
456 for (i
= 0; i
< (sizeof(options
) / sizeof(options
[0])); i
++) {
457 if (strnicmp(key
, options
[i
].option_name
, strlen(ips_str
)) == 0) {
459 *options
[i
].option_flag
= simple_strtoul(value
, NULL
, 0);
461 *options
[i
].option_flag
= options
[i
].option_value
;
467 #if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,13)
472 #if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,13)
473 __setup("ips=", ips_setup
);
476 /****************************************************************************/
478 /* Routine Name: ips_detect */
480 /* Routine Description: */
482 /* Detect and initialize the driver */
484 /* NOTE: this routine is called under the io_request_lock spinlock */
486 /****************************************************************************/
488 ips_detect(Scsi_Host_Template
*SHT
) {
489 struct Scsi_Host
*sh
;
505 struct pci_dev
*dev
[2];
506 struct pci_dev
*morpheus
= NULL
;
507 struct pci_dev
*trombone
= NULL
;
508 #if LINUX_VERSION_CODE < LinuxVersionCode(2,3,14)
514 METHOD_TRACE("ips_detect", 1);
518 #if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,13)
521 ips_setup(ips
, NULL
);
525 SHT
->proc_info
= ips_proc_info
;
526 #if LINUX_VERSION_CODE < LinuxVersionCode(2,3,27)
527 SHT
->proc_dir
= &proc_scsi_ips
;
529 SHT
->proc_name
= "ips";
532 #if defined(CONFIG_PCI)
534 /* initalize number of controllers */
535 ips_num_controllers
= 0;
536 ips_next_controller
= 0;
537 ips_released_controllers
= 0;
542 morpheus
= pci_find_device(IPS_VENDORID
, IPS_MORPHEUS_DEVICEID
, morpheus
);
543 trombone
= pci_find_device(IPS_VENDORID
, IPS_COPPERHEAD_DEVICEID
, trombone
);
545 /* determine which controller to probe first */
547 /* we only have trombone */
550 deviceID
[0] = IPS_COPPERHEAD_DEVICEID
;
551 } else if (!trombone
) {
552 /* we only have morpheus */
555 deviceID
[0] = IPS_MORPHEUS_DEVICEID
;
557 /* we have both in the system */
558 if (trombone
->bus
< morpheus
->bus
) {
561 deviceID
[0] = IPS_COPPERHEAD_DEVICEID
;
562 deviceID
[1] = IPS_MORPHEUS_DEVICEID
;
563 } else if (trombone
->bus
> morpheus
->bus
) {
566 deviceID
[0] = IPS_MORPHEUS_DEVICEID
;
567 deviceID
[1] = IPS_COPPERHEAD_DEVICEID
;
569 /* further detection required */
570 if (trombone
->devfn
< morpheus
->devfn
) {
573 deviceID
[0] = IPS_COPPERHEAD_DEVICEID
;
574 deviceID
[1] = IPS_MORPHEUS_DEVICEID
;
578 deviceID
[0] = IPS_MORPHEUS_DEVICEID
;
579 deviceID
[1] = IPS_COPPERHEAD_DEVICEID
;
584 /* Now scan the controllers */
585 for (i
= 0; i
< 2; i
++) {
590 if (ips_next_controller
>= IPS_MAX_ADAPTERS
)
593 #if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
594 if (pci_enable_device(dev
[i
]))
598 /* stuff that we get in dev */
600 bus
= dev
[i
]->bus
->number
;
601 func
= dev
[i
]->devfn
;
603 /* Init MEM/IO addresses to 0 */
609 for (j
= 0; j
< 2; j
++) {
610 #if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
611 if (!pci_resource_start(dev
[i
], j
))
614 if (pci_resource_flags(dev
[i
], j
) & IORESOURCE_IO
) {
615 io_addr
= pci_resource_start(dev
[i
], j
);
616 io_len
= pci_resource_len(dev
[i
], j
);
618 mem_addr
= pci_resource_start(dev
[i
], j
);
619 mem_len
= pci_resource_len(dev
[i
], j
);
621 #elif LINUX_VERSION_CODE >= LinuxVersionCode(2,3,14)
622 if (!dev
[i
]->resource
[j
].start
)
625 if ((dev
[i
]->resource
[j
].start
& PCI_BASE_ADDRESS_SPACE
) == PCI_BASE_ADDRESS_SPACE_IO
) {
626 io_addr
= dev
[i
]->resource
[j
].start
;
627 io_len
= dev
[i
]->resource
[j
].end
- dev
[i
]->resource
[j
].start
+ 1;
629 mem_addr
= dev
[i
]->resource
[j
].start
;
630 mem_len
= dev
[i
]->resource
[j
].end
- dev
[i
]->resource
[j
].start
+ 1;
633 if (!dev
[i
]->base_address
[j
])
636 if ((dev
[i
]->base_address
[j
] & PCI_BASE_ADDRESS_SPACE
) == PCI_BASE_ADDRESS_SPACE_IO
) {
637 barnum
= PCI_BASE_ADDRESS_0
+ (j
* 4);
638 io_addr
= dev
[i
]->base_address
[j
] & PCI_BASE_ADDRESS_IO_MASK
;
641 pci_read_config_dword(dev
[i
], barnum
, &currbar
);
642 pci_write_config_dword(dev
[i
], barnum
, ~0);
643 pci_read_config_dword(dev
[i
], barnum
, &maskbar
);
644 pci_write_config_dword(dev
[i
], barnum
, currbar
);
646 io_len
= ~(maskbar
& PCI_BASE_ADDRESS_IO_MASK
) + 1;
648 barnum
= PCI_BASE_ADDRESS_0
+ (j
* 4);
649 mem_addr
= dev
[i
]->base_address
[j
] & PCI_BASE_ADDRESS_MEM_MASK
;
652 pci_read_config_dword(dev
[i
], barnum
, &currbar
);
653 pci_write_config_dword(dev
[i
], barnum
, ~0);
654 pci_read_config_dword(dev
[i
], barnum
, &maskbar
);
655 pci_write_config_dword(dev
[i
], barnum
, currbar
);
657 mem_len
= ~(maskbar
& PCI_BASE_ADDRESS_MEM_MASK
) + 1;
662 /* setup memory mapped area (if applicable) */
667 DEBUG_VAR(1, "(%s%d) detect, Memory region %x, size: %d",
668 ips_name
, ips_next_controller
, mem_addr
, mem_len
);
670 #if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,17)
671 if (check_mem_region(mem_addr
, mem_len
)) {
672 /* Couldn't allocate io space */
673 printk(KERN_WARNING
"(%s%d) couldn't allocate IO space %x len %d.\n",
674 ips_name
, ips_next_controller
, io_addr
, io_len
);
676 ips_next_controller
++;
681 request_mem_region(mem_addr
, mem_len
, "ips");
684 base
= mem_addr
& PAGE_MASK
;
685 offs
= mem_addr
- base
;
687 ioremap_ptr
= ioremap(base
, PAGE_SIZE
);
688 mem_ptr
= ioremap_ptr
+ offs
;
694 /* setup I/O mapped area (if applicable) */
696 DEBUG_VAR(1, "(%s%d) detect, IO region %x, size: %d",
697 ips_name
, ips_next_controller
, io_addr
, io_len
);
699 if (check_region(io_addr
, io_len
)) {
700 /* Couldn't allocate io space */
701 printk(KERN_WARNING
"(%s%d) couldn't allocate IO space %x len %d.\n",
702 ips_name
, ips_next_controller
, io_addr
, io_len
);
704 ips_next_controller
++;
709 request_region(io_addr
, io_len
, "ips");
712 /* get planer status */
713 if (pci_read_config_word(dev
[i
], 0x04, &planer
)) {
714 printk(KERN_WARNING
"(%s%d) can't get planer status.\n",
715 ips_name
, ips_next_controller
);
717 ips_next_controller
++;
722 /* check to see if an onboard planer controller is disabled */
723 if (!(planer
& 0x000C)) {
725 DEBUG_VAR(1, "(%s%d) detect, Onboard ServeRAID disabled by BIOS",
726 ips_name
, ips_next_controller
);
728 ips_next_controller
++;
733 DEBUG_VAR(1, "(%s%d) detect bus %d, func %x, irq %d, io %x, mem: %x, ptr: %x",
734 ips_name
, ips_next_controller
, bus
, func
, irq
, io_addr
, mem_addr
, (u32
) mem_ptr
);
736 /* get the revision ID */
737 if (pci_read_config_byte(dev
[i
], 0x08, &revision_id
)) {
738 printk(KERN_WARNING
"(%s%d) can't get revision id.\n",
739 ips_name
, ips_next_controller
);
741 ips_next_controller
++;
746 /* found a controller */
747 sh
= scsi_register(SHT
, sizeof(ips_ha_t
));
750 printk(KERN_WARNING
"(%s%d) Unable to register controller with SCSI subsystem - skipping controller\n",
751 ips_name
, ips_next_controller
);
753 ips_next_controller
++;
759 memset(ha
, 0, sizeof(ips_ha_t
));
761 /* Initialize spin lock */
762 spin_lock_init(&ha
->scb_lock
);
763 spin_lock_init(&ha
->copp_lock
);
764 spin_lock_init(&ha
->ips_lock
);
765 spin_lock_init(&ha
->copp_waitlist
.lock
);
766 spin_lock_init(&ha
->scb_waitlist
.lock
);
767 spin_lock_init(&ha
->scb_activelist
.lock
);
769 ips_sh
[ips_next_controller
] = sh
;
770 ips_ha
[ips_next_controller
] = ha
;
771 ips_num_controllers
++;
774 ha
->enq
= kmalloc(sizeof(IPS_ENQ
), GFP_ATOMIC
|GFP_DMA
);
777 printk(KERN_WARNING
"(%s%d) Unable to allocate host inquiry structure - skipping contoller\n",
778 ips_name
, ips_next_controller
);
782 ips_next_controller
++;
783 ips_num_controllers
--;
788 ha
->adapt
= kmalloc(sizeof(IPS_ADAPTER
), GFP_ATOMIC
|GFP_DMA
);
791 printk(KERN_WARNING
"(%s%d) Unable to allocate host adapt structure - skipping controller\n",
792 ips_name
, ips_next_controller
);
795 ips_next_controller
++;
796 ips_num_controllers
--;
801 ha
->conf
= kmalloc(sizeof(IPS_CONF
), GFP_ATOMIC
|GFP_DMA
);
804 printk(KERN_WARNING
"(%s%d) Unable to allocate host conf structure - skipping controller\n",
805 ips_name
, ips_next_controller
);
809 ips_next_controller
++;
810 ips_num_controllers
--;
815 ha
->nvram
= kmalloc(sizeof(IPS_NVRAM_P5
), GFP_ATOMIC
|GFP_DMA
);
818 printk(KERN_WARNING
"(%s%d) Unable to allocate host nvram structure - skipping controller\n",
819 ips_name
, ips_next_controller
);
823 ips_next_controller
++;
824 ips_num_controllers
--;
829 ha
->subsys
= kmalloc(sizeof(IPS_SUBSYS
), GFP_ATOMIC
|GFP_DMA
);
832 printk(KERN_WARNING
"(%s%d) Unable to allocate host subsystem structure - skipping controller\n",
833 ips_name
, ips_next_controller
);
837 ips_next_controller
++;
838 ips_num_controllers
--;
843 ha
->dummy
= kmalloc(sizeof(IPS_IO_CMD
), GFP_ATOMIC
|GFP_DMA
);
846 printk(KERN_WARNING
"(%s%d) Unable to allocate host dummy structure - skipping controller\n",
847 ips_name
, ips_next_controller
);
851 ips_next_controller
++;
852 ips_num_controllers
--;
857 ha
->ioctl_data
= kmalloc(IPS_IOCTL_SIZE
, GFP_ATOMIC
|GFP_DMA
);
858 ha
->ioctl_datasize
= IPS_IOCTL_SIZE
;
859 if (!ha
->ioctl_data
) {
860 printk(KERN_WARNING
"(%s%d) Unable to allocate ioctl data - skipping controller\n",
861 ips_name
, ips_next_controller
);
865 ips_next_controller
++;
866 ips_num_controllers
--;
871 /* Store away needed values for later use */
872 sh
->io_port
= io_addr
;
873 sh
->n_io_port
= io_addr
? 255 : 0;
874 sh
->unique_id
= (io_addr
) ? io_addr
: mem_addr
;
876 sh
->select_queue_depths
= ips_select_queue_depth
;
877 sh
->sg_tablesize
= sh
->hostt
->sg_tablesize
;
878 sh
->can_queue
= sh
->hostt
->can_queue
;
879 sh
->cmd_per_lun
= sh
->hostt
->cmd_per_lun
;
880 sh
->unchecked_isa_dma
= sh
->hostt
->unchecked_isa_dma
;
881 sh
->use_clustering
= sh
->hostt
->use_clustering
;
883 #if LINUX_VERSION_CODE < LinuxVersionCode(2,3,32)
884 sh
->wish_block
= FALSE
;
887 /* Store info in HA structure */
889 ha
->io_addr
= io_addr
;
891 ha
->mem_addr
= mem_addr
;
892 ha
->mem_len
= mem_len
;
893 ha
->mem_ptr
= mem_ptr
;
894 ha
->ioremap_ptr
= ioremap_ptr
;
895 ha
->host_num
= ips_next_controller
;
896 ha
->revision_id
= revision_id
;
897 ha
->device_id
= deviceID
[i
];
903 if (IPS_IS_MORPHEUS(ha
)) {
905 ha
->func
.isintr
= ips_isintr_morpheus
;
906 ha
->func
.isinit
= ips_isinit_morpheus
;
907 ha
->func
.issue
= ips_issue_i2o_memio
;
908 ha
->func
.init
= ips_init_morpheus
;
909 ha
->func
.statupd
= ips_statupd_morpheus
;
910 ha
->func
.reset
= ips_reset_morpheus
;
911 ha
->func
.intr
= ips_intr_morpheus
;
912 ha
->func
.enableint
= ips_enable_int_morpheus
;
913 } else if (IPS_USE_MEMIO(ha
)) {
914 /* copperhead w/MEMIO */
915 ha
->func
.isintr
= ips_isintr_copperhead_memio
;
916 ha
->func
.isinit
= ips_isinit_copperhead_memio
;
917 ha
->func
.init
= ips_init_copperhead_memio
;
918 ha
->func
.statupd
= ips_statupd_copperhead_memio
;
919 ha
->func
.statinit
= ips_statinit_memio
;
920 ha
->func
.reset
= ips_reset_copperhead_memio
;
921 ha
->func
.intr
= ips_intr_copperhead
;
922 ha
->func
.erasebios
= ips_erase_bios_memio
;
923 ha
->func
.programbios
= ips_program_bios_memio
;
924 ha
->func
.verifybios
= ips_verify_bios_memio
;
925 ha
->func
.enableint
= ips_enable_int_copperhead_memio
;
927 if (IPS_USE_I2O_DELIVER(ha
))
928 ha
->func
.issue
= ips_issue_i2o_memio
;
930 ha
->func
.issue
= ips_issue_copperhead_memio
;
933 ha
->func
.isintr
= ips_isintr_copperhead
;
934 ha
->func
.isinit
= ips_isinit_copperhead
;
935 ha
->func
.init
= ips_init_copperhead
;
936 ha
->func
.statupd
= ips_statupd_copperhead
;
937 ha
->func
.statinit
= ips_statinit
;
938 ha
->func
.reset
= ips_reset_copperhead
;
939 ha
->func
.intr
= ips_intr_copperhead
;
940 ha
->func
.erasebios
= ips_erase_bios
;
941 ha
->func
.programbios
= ips_program_bios
;
942 ha
->func
.verifybios
= ips_verify_bios
;
943 ha
->func
.enableint
= ips_enable_int_copperhead
;
945 if (IPS_USE_I2O_DELIVER(ha
))
946 ha
->func
.issue
= ips_issue_i2o
;
948 ha
->func
.issue
= ips_issue_copperhead
;
952 * Initialize the card if it isn't already
954 if (!(*ha
->func
.isinit
)(ha
)) {
955 if (!(*ha
->func
.init
)(ha
)) {
957 * Initialization failed
959 printk(KERN_WARNING
"(%s%d) unable to initialize controller - skipping controller\n",
960 ips_name
, ips_next_controller
);
964 ips_next_controller
++;
965 ips_num_controllers
--;
971 /* install the interrupt handler */
972 if (request_irq(irq
, do_ipsintr
, SA_SHIRQ
, ips_name
, ha
)) {
973 printk(KERN_WARNING
"(%s%d) unable to install interrupt handler - skipping controller\n",
974 ips_name
, ips_next_controller
);
978 ips_next_controller
++;
979 ips_num_controllers
--;
985 * Allocate a temporary SCB for initialization
987 ha
->scbs
= (ips_scb_t
*) kmalloc(sizeof(ips_scb_t
), GFP_ATOMIC
|GFP_DMA
);
989 /* couldn't allocate a temp SCB */
990 printk(KERN_WARNING
"(%s%d) unable to allocate CCBs - skipping contoller\n",
991 ips_name
, ips_next_controller
);
995 free_irq(ha
->irq
, ha
);
996 ips_next_controller
++;
997 ips_num_controllers
--;
1002 memset(ha
->scbs
, 0, sizeof(ips_scb_t
));
1003 ha
->scbs
->sg_list
= (IPS_SG_LIST
*) kmalloc(sizeof(IPS_SG_LIST
) * IPS_MAX_SG
, GFP_ATOMIC
|GFP_DMA
);
1004 if (!ha
->scbs
->sg_list
) {
1005 /* couldn't allocate a temp SCB S/G list */
1006 printk(KERN_WARNING
"(%s%d) unable to allocate CCBs - skipping contoller\n",
1007 ips_name
, ips_next_controller
);
1011 free_irq(ha
->irq
, ha
);
1012 ips_next_controller
++;
1013 ips_num_controllers
--;
1020 ips_next_controller
++;
1021 } while ((dev
[i
] = pci_find_device(IPS_VENDORID
, deviceID
[i
], dev
[i
])));
1025 * Do Phase 2 Initialization
1028 for (i
= 0; i
< ips_next_controller
; i
++) {
1033 scsi_unregister(sh
);
1040 if (!ips_hainit(ha
)) {
1041 printk(KERN_WARNING
"(%s%d) unable to initialize controller - skipping\n",
1046 free_irq(ha
->irq
, ha
);
1047 scsi_unregister(sh
);
1050 ips_num_controllers
--;
1056 * Free the temporary SCB
1058 kfree(ha
->scbs
->sg_list
);
1063 if (!ips_allocatescbs(ha
)) {
1064 printk(KERN_WARNING
"(%s%d) unable to allocate CCBs - skipping contoller\n",
1069 free_irq(ha
->irq
, ha
);
1070 scsi_unregister(sh
);
1073 ips_num_controllers
--;
1078 /* finish setting values */
1079 sh
->max_id
= ha
->ntargets
;
1080 sh
->max_lun
= ha
->nlun
;
1081 sh
->max_channel
= ha
->nbus
- 1;
1082 sh
->can_queue
= ha
->max_cmds
-1;
1085 if (ips_num_controllers
> 0)
1086 register_reboot_notifier(&ips_notifier
);
1088 return (ips_num_controllers
);
1092 /* No PCI -- No ServeRAID */
1094 #endif /* CONFIG_PCI */
1097 /****************************************************************************/
1099 /* Routine Name: ips_release */
1101 /* Routine Description: */
1103 /* Remove a driver */
1105 /****************************************************************************/
1107 ips_release(struct Scsi_Host
*sh
) {
1112 METHOD_TRACE("ips_release", 1);
1114 for (i
= 0; i
< IPS_MAX_ADAPTERS
&& ips_sh
[i
] != sh
; i
++);
1116 if (i
== IPS_MAX_ADAPTERS
)
1117 panic("(%s) release, invalid Scsi_Host pointer.\n",
1125 /* flush the cache on the controller */
1126 scb
= &ha
->scbs
[ha
->max_cmds
-1];
1128 ips_init_scb(ha
, scb
);
1130 scb
->timeout
= ips_cmd_timeout
;
1131 scb
->cdb
[0] = IPS_CMD_FLUSH
;
1133 scb
->cmd
.flush_cache
.op_code
= IPS_CMD_FLUSH
;
1134 scb
->cmd
.flush_cache
.command_id
= IPS_COMMAND_ID(ha
, scb
);
1135 scb
->cmd
.flush_cache
.state
= IPS_NORM_STATE
;
1136 scb
->cmd
.flush_cache
.reserved
= 0;
1137 scb
->cmd
.flush_cache
.reserved2
= 0;
1138 scb
->cmd
.flush_cache
.reserved3
= 0;
1139 scb
->cmd
.flush_cache
.reserved4
= 0;
1141 printk("(%s%d) Flushing Cache.\n", ips_name
, ha
->host_num
);
1144 if (ips_send_wait(ha
, scb
, ips_cmd_timeout
, IPS_INTR_ON
) == IPS_FAILURE
)
1145 printk("(%s%d) Incomplete Flush.\n", ips_name
, ha
->host_num
);
1147 printk("(%s%d) Flushing Complete.\n", ips_name
, ha
->host_num
);
1152 /* free extra memory */
1155 /* Free I/O Region */
1157 release_region(ha
->io_addr
, ha
->io_len
);
1159 #if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,17)
1161 release_mem_region(ha
->mem_addr
, ha
->mem_len
);
1165 free_irq(ha
->irq
, ha
);
1167 ips_released_controllers
++;
1169 if (ips_num_controllers
== ips_released_controllers
)
1170 unregister_reboot_notifier(&ips_notifier
);
1175 /****************************************************************************/
1177 /* Routine Name: ips_halt */
1179 /* Routine Description: */
1181 /* Perform cleanup when the system reboots */
1183 /****************************************************************************/
1185 ips_halt(struct notifier_block
*nb
, ulong event
, void *buf
) {
1190 if ((event
!= SYS_RESTART
) && (event
!= SYS_HALT
) &&
1191 (event
!= SYS_POWER_OFF
))
1192 return (NOTIFY_DONE
);
1194 for (i
= 0; i
< ips_next_controller
; i
++) {
1195 ha
= (ips_ha_t
*) ips_ha
[i
];
1203 /* flush the cache on the controller */
1204 scb
= &ha
->scbs
[ha
->max_cmds
-1];
1206 ips_init_scb(ha
, scb
);
1208 scb
->timeout
= ips_cmd_timeout
;
1209 scb
->cdb
[0] = IPS_CMD_FLUSH
;
1211 scb
->cmd
.flush_cache
.op_code
= IPS_CMD_FLUSH
;
1212 scb
->cmd
.flush_cache
.command_id
= IPS_COMMAND_ID(ha
, scb
);
1213 scb
->cmd
.flush_cache
.state
= IPS_NORM_STATE
;
1214 scb
->cmd
.flush_cache
.reserved
= 0;
1215 scb
->cmd
.flush_cache
.reserved2
= 0;
1216 scb
->cmd
.flush_cache
.reserved3
= 0;
1217 scb
->cmd
.flush_cache
.reserved4
= 0;
1219 printk("(%s%d) Flushing Cache.\n", ips_name
, ha
->host_num
);
1222 if (ips_send_wait(ha
, scb
, ips_cmd_timeout
, IPS_INTR_ON
) == IPS_FAILURE
)
1223 printk("(%s%d) Incomplete Flush.\n", ips_name
, ha
->host_num
);
1225 printk("(%s%d) Flushing Complete.\n", ips_name
, ha
->host_num
);
1228 unregister_reboot_notifier(&ips_notifier
);
1232 /****************************************************************************/
1234 /* Routine Name: ips_eh_abort */
1236 /* Routine Description: */
1238 /* Abort a command (using the new error code stuff) */
1240 /****************************************************************************/
1242 ips_eh_abort(Scsi_Cmnd
*SC
) {
1244 ips_copp_wait_item_t
*item
;
1246 METHOD_TRACE("ips_eh_abort", 1);
1251 ha
= (ips_ha_t
*) SC
->host
->hostdata
;
1259 if (SC
->serial_number
!= SC
->serial_number_at_timeout
) {
1260 /* HMM, looks like a bogus command */
1261 DEBUG(1, "Abort called with bogus scsi command");
1266 if (test_and_set_bit(IPS_IN_ABORT
, &ha
->flags
))
1269 /* See if the command is on the copp queue */
1270 IPS_QUEUE_LOCK(&ha
->copp_waitlist
);
1271 item
= ha
->copp_waitlist
.head
;
1272 while ((item
) && (item
->scsi_cmd
!= SC
))
1274 IPS_QUEUE_UNLOCK(&ha
->copp_waitlist
);
1278 ips_removeq_copp(&ha
->copp_waitlist
, item
);
1279 clear_bit(IPS_IN_ABORT
, &ha
->flags
);
1284 /* See if the command is on the wait queue */
1285 if (ips_removeq_wait(&ha
->scb_waitlist
, SC
)) {
1286 /* command not sent yet */
1287 clear_bit(IPS_IN_ABORT
, &ha
->flags
);
1291 /* command must have already been sent */
1292 clear_bit(IPS_IN_ABORT
, &ha
->flags
);
1298 /****************************************************************************/
1300 /* Routine Name: ips_eh_reset */
1302 /* Routine Description: */
1304 /* Reset the controller (with new eh error code) */
1306 /* NOTE: this routine is called under the io_request_lock spinlock */
1308 /****************************************************************************/
1310 ips_eh_reset(Scsi_Cmnd
*SC
) {
1316 ips_copp_wait_item_t
*item
;
1318 METHOD_TRACE("ips_eh_reset", 1);
1325 DEBUG(1, "Reset called with NULL scsi command");
1330 ha
= (ips_ha_t
*) SC
->host
->hostdata
;
1333 DEBUG(1, "Reset called with NULL ha struct");
1341 if (test_and_set_bit(IPS_IN_RESET
, &ha
->flags
))
1344 /* See if the command is on the copp queue */
1345 IPS_QUEUE_LOCK(&ha
->copp_waitlist
);
1346 item
= ha
->copp_waitlist
.head
;
1347 while ((item
) && (item
->scsi_cmd
!= SC
))
1349 IPS_QUEUE_UNLOCK(&ha
->copp_waitlist
);
1353 ips_removeq_copp(&ha
->copp_waitlist
, item
);
1354 clear_bit(IPS_IN_RESET
, &ha
->flags
);
1359 /* See if the command is on the wait queue */
1360 if (ips_removeq_wait(&ha
->scb_waitlist
, SC
)) {
1361 /* command not sent yet */
1362 clear_bit(IPS_IN_RESET
, &ha
->flags
);
1368 * command must have already been sent
1369 * reset the controller
1371 printk(KERN_NOTICE
"(%s%d) Resetting controller.\n",
1372 ips_name
, ha
->host_num
);
1373 ret
= (*ha
->func
.reset
)(ha
);
1376 Scsi_Cmnd
*scsi_cmd
;
1379 "(%s%d) Controller reset failed - controller now offline.\n",
1380 ips_name
, ha
->host_num
);
1382 /* Now fail all of the active commands */
1383 DEBUG_VAR(1, "(%s%d) Failing active commands",
1384 ips_name
, ha
->host_num
);
1386 while ((scb
= ips_removeq_scb_head(&ha
->scb_activelist
))) {
1387 scb
->scsi_cmd
->result
= DID_ERROR
<< 16;
1388 scb
->scsi_cmd
->scsi_done(scb
->scsi_cmd
);
1389 ips_freescb(ha
, scb
);
1392 /* Now fail all of the pending commands */
1393 DEBUG_VAR(1, "(%s%d) Failing pending commands",
1394 ips_name
, ha
->host_num
);
1396 while ((scsi_cmd
= ips_removeq_wait_head(&ha
->scb_waitlist
))) {
1397 scsi_cmd
->result
= DID_ERROR
;
1398 scsi_cmd
->scsi_done(scsi_cmd
);
1402 clear_bit(IPS_IN_RESET
, &ha
->flags
);
1407 if (!ips_clear_adapter(ha
, IPS_INTR_IORL
)) {
1408 Scsi_Cmnd
*scsi_cmd
;
1411 "(%s%d) Controller reset failed - controller now offline.\n",
1412 ips_name
, ha
->host_num
);
1414 /* Now fail all of the active commands */
1415 DEBUG_VAR(1, "(%s%d) Failing active commands",
1416 ips_name
, ha
->host_num
);
1418 while ((scb
= ips_removeq_scb_head(&ha
->scb_activelist
))) {
1419 scb
->scsi_cmd
->result
= DID_ERROR
<< 16;
1420 scb
->scsi_cmd
->scsi_done(scb
->scsi_cmd
);
1421 ips_freescb(ha
, scb
);
1424 /* Now fail all of the pending commands */
1425 DEBUG_VAR(1, "(%s%d) Failing pending commands",
1426 ips_name
, ha
->host_num
);
1428 while ((scsi_cmd
= ips_removeq_wait_head(&ha
->scb_waitlist
))) {
1429 scsi_cmd
->result
= DID_ERROR
<< 16;
1430 scsi_cmd
->scsi_done(scsi_cmd
);
1434 clear_bit(IPS_IN_RESET
, &ha
->flags
);
1440 if (ha
->subsys
->param
[3] & 0x300000) {
1443 do_gettimeofday(&tv
);
1444 IPS_HA_LOCK(cpu_flags
);
1445 ha
->last_ffdc
= tv
.tv_sec
;
1447 IPS_HA_UNLOCK(cpu_flags
);
1448 ips_ffdc_reset(ha
, IPS_INTR_IORL
);
1451 /* Now fail all of the active commands */
1452 DEBUG_VAR(1, "(%s%d) Failing active commands",
1453 ips_name
, ha
->host_num
);
1455 while ((scb
= ips_removeq_scb_head(&ha
->scb_activelist
))) {
1456 scb
->scsi_cmd
->result
= (DID_RESET
<< 16) | (SUGGEST_RETRY
<< 24);
1457 scb
->scsi_cmd
->scsi_done(scb
->scsi_cmd
);
1458 ips_freescb(ha
, scb
);
1461 /* Reset DCDB active command bits */
1462 for (i
= 1; i
< ha
->nbus
; i
++)
1463 ha
->dcdb_active
[i
-1] = 0;
1465 /* Reset the number of active IOCTLs */
1466 IPS_HA_LOCK(cpu_flags
);
1468 IPS_HA_UNLOCK(cpu_flags
);
1470 clear_bit(IPS_IN_RESET
, &ha
->flags
);
1472 if (!test_bit(IPS_IN_INTR
, &ha
->flags
)) {
1474 * Only execute the next command when
1475 * we are not being called from the
1476 * interrupt handler. The interrupt
1477 * handler wants to do this and since
1478 * interrupts are turned off here....
1480 ips_next(ha
, IPS_INTR_IORL
);
1485 #endif /* NO_IPS_RESET */
1489 /****************************************************************************/
1491 /* Routine Name: ips_queue */
1493 /* Routine Description: */
1495 /* Send a command to the controller */
1498 /* Linux obtains io_request_lock before calling this function */
1500 /****************************************************************************/
1502 ips_queue(Scsi_Cmnd
*SC
, void (*done
) (Scsi_Cmnd
*)) {
1505 DECLARE_MUTEX_LOCKED(sem
);
1507 METHOD_TRACE("ips_queue", 1);
1509 ha
= (ips_ha_t
*) SC
->host
->hostdata
;
1517 #ifndef NO_IPS_CMDLINE
1518 if (ips_is_passthru(SC
)) {
1519 IPS_QUEUE_LOCK(&ha
->copp_waitlist
);
1520 if (ha
->copp_waitlist
.count
== IPS_MAX_IOCTL_QUEUE
) {
1521 IPS_QUEUE_UNLOCK(&ha
->copp_waitlist
);
1522 SC
->result
= DID_BUS_BUSY
<< 16;
1527 IPS_QUEUE_UNLOCK(&ha
->copp_waitlist
);
1531 IPS_QUEUE_LOCK(&ha
->scb_waitlist
);
1532 if (ha
->scb_waitlist
.count
== IPS_MAX_QUEUE
) {
1533 IPS_QUEUE_UNLOCK(&ha
->scb_waitlist
);
1534 SC
->result
= DID_BUS_BUSY
<< 16;
1539 IPS_QUEUE_UNLOCK(&ha
->scb_waitlist
);
1542 #ifndef NO_IPS_CMDLINE
1546 SC
->scsi_done
= done
;
1548 DEBUG_VAR(2, "(%s%d): ips_queue: cmd 0x%X (%d %d %d)",
1556 /* Check for command to initiator IDs */
1557 if ((SC
->channel
> 0) && (SC
->target
== ha
->ha_id
[SC
->channel
])) {
1558 SC
->result
= DID_NO_CONNECT
<< 16;
1564 #ifndef NO_IPS_CMDLINE
1565 if (ips_is_passthru(SC
)) {
1566 ips_copp_wait_item_t
*scratch
;
1568 /* allocate space for the scribble */
1569 scratch
= kmalloc(sizeof(ips_copp_wait_item_t
), GFP_ATOMIC
);
1572 SC
->result
= DID_ERROR
<< 16;
1578 scratch
->scsi_cmd
= SC
;
1579 scratch
->sem
= &sem
;
1580 scratch
->next
= NULL
;
1582 ips_putq_copp_tail(&ha
->copp_waitlist
, scratch
);
1586 ips_putq_wait_tail(&ha
->scb_waitlist
, SC
);
1588 IPS_HA_LOCK(cpu_flags
);
1589 if ((!test_bit(IPS_IN_INTR
, &ha
->flags
)) &&
1590 (!test_bit(IPS_IN_ABORT
, &ha
->flags
)) &&
1591 (!test_bit(IPS_IN_RESET
, &ha
->flags
))) {
1592 IPS_HA_UNLOCK(cpu_flags
);
1593 ips_next(ha
, IPS_INTR_IORL
);
1595 IPS_HA_UNLOCK(cpu_flags
);
1599 * If this request was a new style IOCTL wait
1602 * NOTE: we relinquished the lock above so this should
1603 * not cause contention problems
1605 if (ips_is_passthru(SC
) && SC
->cmnd
[0] == IPS_IOCTL_NEW_COMMAND
) {
1610 /* free io_request_lock */
1611 spin_unlock_irq(&io_request_lock
);
1613 /* wait for the command to finish */
1616 /* reobtain the lock */
1617 spin_lock_irq(&io_request_lock
);
1619 /* command finished -- copy back */
1620 user_area
= *((char **) &SC
->cmnd
[4]);
1621 kern_area
= ha
->ioctl_data
;
1622 datasize
= *((u32
*) &SC
->cmnd
[8]);
1624 if (copy_to_user(user_area
, kern_area
, datasize
) > 0) {
1625 DEBUG_VAR(1, "(%s%d) passthru failed - unable to copy out user data",
1626 ips_name
, ha
->host_num
);
1628 SC
->result
= DID_ERROR
<< 16;
1638 /****************************************************************************/
1640 /* Routine Name: ips_biosparam */
1642 /* Routine Description: */
1644 /* Set bios geometry for the controller */
1646 /****************************************************************************/
1648 ips_biosparam(Disk
*disk
, kdev_t dev
, int geom
[]) {
1654 METHOD_TRACE("ips_biosparam", 1);
1656 ha
= (ips_ha_t
*) disk
->device
->host
->hostdata
;
1659 /* ?!?! host adater info invalid */
1665 if (!ips_read_adapter_status(ha
, IPS_INTR_ON
))
1666 /* ?!?! Enquiry command failed */
1669 if ((disk
->capacity
> 0x400000) &&
1670 ((ha
->enq
->ucMiscFlag
& 0x8) == 0)) {
1671 heads
= IPS_NORM_HEADS
;
1672 sectors
= IPS_NORM_SECTORS
;
1674 heads
= IPS_COMP_HEADS
;
1675 sectors
= IPS_COMP_SECTORS
;
1678 cylinders
= disk
->capacity
/ (heads
* sectors
);
1680 DEBUG_VAR(2, "Geometry: heads: %d, sectors: %d, cylinders: %d",
1681 heads
, sectors
, cylinders
);
1685 geom
[2] = cylinders
;
1690 /****************************************************************************/
1692 /* Routine Name: ips_select_queue_depth */
1694 /* Routine Description: */
1696 /* Select queue depths for the devices on the contoller */
1698 /****************************************************************************/
1700 ips_select_queue_depth(struct Scsi_Host
*host
, Scsi_Device
*scsi_devs
) {
1701 Scsi_Device
*device
;
1707 for (device
= scsi_devs
; device
; device
= device
->next
) {
1708 if (device
->host
== host
) {
1709 if ((device
->channel
== 0) && (device
->type
== 0))
1714 for (device
= scsi_devs
; device
; device
= device
->next
) {
1715 if (device
->host
== host
) {
1716 if ((device
->channel
== 0) && (device
->type
== 0))
1717 device
->queue_depth
= ha
->max_cmds
/ count
- 1;
1719 device
->queue_depth
= 2;
1724 /****************************************************************************/
1726 /* Routine Name: do_ipsintr */
1728 /* Routine Description: */
1730 /* Wrapper for the interrupt handler */
1732 /****************************************************************************/
1734 do_ipsintr(int irq
, void *dev_id
, struct pt_regs
*regs
) {
1738 METHOD_TRACE("do_ipsintr", 2);
1740 ha
= (ips_ha_t
*) dev_id
;
1742 spin_lock_irqsave(&io_request_lock
, cpu_flags
);
1744 if (test_and_set_bit(IPS_IN_INTR
, &ha
->flags
)) {
1745 spin_unlock_irqrestore(&io_request_lock
, cpu_flags
);
1751 clear_bit(IPS_IN_INTR
, &ha
->flags
);
1752 spin_unlock_irqrestore(&io_request_lock
, cpu_flags
);
1758 clear_bit(IPS_IN_INTR
, &ha
->flags
);
1759 spin_unlock_irqrestore(&io_request_lock
, cpu_flags
);
1764 (*ha
->func
.intr
)(ha
);
1766 clear_bit(IPS_IN_INTR
, &ha
->flags
);
1768 spin_unlock_irqrestore(&io_request_lock
, cpu_flags
);
1770 /* start the next command */
1771 ips_next(ha
, IPS_INTR_ON
);
1774 /****************************************************************************/
1776 /* Routine Name: ips_intr_copperhead */
1778 /* Routine Description: */
1780 /* Polling interrupt handler */
1782 /* ASSUMES interrupts are disabled */
1784 /****************************************************************************/
1786 ips_intr_copperhead(ips_ha_t
*ha
) {
1793 METHOD_TRACE("ips_intr", 2);
1801 IPS_HA_LOCK(cpu_flags
);
1803 intrstatus
= (*ha
->func
.isintr
)(ha
);
1807 * Unexpected/Shared interrupt
1809 IPS_HA_UNLOCK(cpu_flags
);
1817 intrstatus
= (*ha
->func
.isintr
)(ha
);
1822 cstatus
.value
= (*ha
->func
.statupd
)(ha
);
1824 if (cstatus
.fields
.command_id
> (IPS_MAX_CMDS
- 1)) {
1825 printk(KERN_WARNING
"(%s%d) Spurious interrupt; no ccb.\n",
1826 ips_name
, ha
->host_num
);
1831 ips_chkstatus(ha
, &cstatus
);
1832 scb
= (ips_scb_t
*) sp
->scb_addr
;
1835 * use the callback function to finish things up
1836 * NOTE: interrupts are OFF for this
1838 IPS_HA_UNLOCK(cpu_flags
);
1839 (*scb
->callback
) (ha
, scb
);
1840 IPS_HA_LOCK(cpu_flags
);
1843 IPS_HA_UNLOCK(cpu_flags
);
1846 /****************************************************************************/
1848 /* Routine Name: ips_intr_morpheus */
1850 /* Routine Description: */
1852 /* Polling interrupt handler */
1854 /* ASSUMES interrupts are disabled */
1856 /****************************************************************************/
1858 ips_intr_morpheus(ips_ha_t
*ha
) {
1865 METHOD_TRACE("ips_intr_morpheus", 2);
1873 IPS_HA_LOCK(cpu_flags
);
1875 intrstatus
= (*ha
->func
.isintr
)(ha
);
1879 * Unexpected/Shared interrupt
1881 IPS_HA_UNLOCK(cpu_flags
);
1889 intrstatus
= (*ha
->func
.isintr
)(ha
);
1894 cstatus
.value
= (*ha
->func
.statupd
)(ha
);
1896 if (cstatus
.value
== 0xffffffff)
1897 /* No more to process */
1900 if (cstatus
.fields
.command_id
> (IPS_MAX_CMDS
- 1)) {
1901 printk(KERN_WARNING
"(%s%d) Spurious interrupt; no ccb.\n",
1902 ips_name
, ha
->host_num
);
1907 ips_chkstatus(ha
, &cstatus
);
1908 scb
= (ips_scb_t
*) sp
->scb_addr
;
1911 * use the callback function to finish things up
1912 * NOTE: interrupts are OFF for this
1914 IPS_HA_UNLOCK(cpu_flags
);
1915 (*scb
->callback
) (ha
, scb
);
1916 IPS_HA_LOCK(cpu_flags
);
1919 IPS_HA_UNLOCK(cpu_flags
);
1922 /****************************************************************************/
1924 /* Routine Name: ips_info */
1926 /* Routine Description: */
1928 /* Return info about the driver */
1930 /****************************************************************************/
1932 ips_info(struct Scsi_Host
*SH
) {
1933 static char buffer
[256];
1937 METHOD_TRACE("ips_info", 1);
1945 memset(bp
, 0, sizeof(buffer
));
1947 strcpy(bp
, "IBM PCI ServeRAID ");
1948 strcat(bp
, IPS_VERSION_HIGH
);
1949 strcat(bp
, IPS_VERSION_LOW
);
1951 if (ha
->ad_type
> 0 &&
1952 ha
->ad_type
<= MAX_ADAPTER_NAME
) {
1954 strcat(bp
, ips_adapter_name
[ha
->ad_type
-1]);
1961 /****************************************************************************/
1963 /* Routine Name: ips_proc_info */
1965 /* Routine Description: */
1967 /* The passthru interface for the driver */
1969 /****************************************************************************/
1971 ips_proc_info(char *buffer
, char **start
, off_t offset
,
1972 int length
, int hostno
, int func
) {
1975 ips_ha_t
*ha
= NULL
;
1977 METHOD_TRACE("ips_proc_info", 1);
1979 /* Find our host structure */
1980 for (i
= 0; i
< ips_next_controller
; i
++) {
1981 if (ips_sh
[i
] && ips_sh
[i
]->host_no
== hostno
) {
1982 ha
= (ips_ha_t
*) ips_sh
[i
]->hostdata
;
1999 ret
= ips_host_info(ha
, buffer
, offset
, length
);
2005 /*--------------------------------------------------------------------------*/
2006 /* Helper Functions */
2007 /*--------------------------------------------------------------------------*/
2009 #ifndef NO_IPS_CMDLINE
2011 /****************************************************************************/
2013 /* Routine Name: ips_is_passthru */
2015 /* Routine Description: */
2017 /* Determine if the specified SCSI command is really a passthru command */
2019 /****************************************************************************/
2021 ips_is_passthru(Scsi_Cmnd
*SC
) {
2022 METHOD_TRACE("ips_is_passthru", 1);
2027 if (((SC
->cmnd
[0] == IPS_IOCTL_COMMAND
) || (SC
->cmnd
[0] == IPS_IOCTL_NEW_COMMAND
)) &&
2028 (SC
->channel
== 0) &&
2029 (SC
->target
== IPS_ADAPTER_ID
) &&
2031 (SC
->request_bufflen
) &&
2033 (((char *) SC
->request_buffer
)[0] == 'C') &&
2034 (((char *) SC
->request_buffer
)[1] == 'O') &&
2035 (((char *) SC
->request_buffer
)[2] == 'P') &&
2036 (((char *) SC
->request_buffer
)[3] == 'P')) {
2043 /****************************************************************************/
2045 /* Routine Name: ips_make_passthru */
2047 /* Routine Description: */
2049 /* Make a passthru command out of the info in the Scsi block */
2051 /****************************************************************************/
2053 ips_make_passthru(ips_ha_t
*ha
, Scsi_Cmnd
*SC
, ips_scb_t
*scb
) {
2056 METHOD_TRACE("ips_make_passthru", 1);
2058 if (!SC
->request_bufflen
|| !SC
->request_buffer
) {
2060 DEBUG_VAR(1, "(%s%d) No passthru structure",
2061 ips_name
, ha
->host_num
);
2063 return (IPS_FAILURE
);
2066 if (SC
->request_bufflen
< sizeof(ips_passthru_t
)) {
2068 DEBUG_VAR(1, "(%s%d) Passthru structure wrong size",
2069 ips_name
, ha
->host_num
);
2071 return (IPS_FAILURE
);
2074 if ((((char *) SC
->request_buffer
)[0] != 'C') ||
2075 (((char *) SC
->request_buffer
)[1] != 'O') ||
2076 (((char *) SC
->request_buffer
)[2] != 'P') ||
2077 (((char *) SC
->request_buffer
)[3] != 'P')) {
2078 /* signature doesn't match */
2079 DEBUG_VAR(1, "(%s%d) Wrong signature on passthru structure.",
2080 ips_name
, ha
->host_num
);
2082 return (IPS_FAILURE
);
2085 pt
= (ips_passthru_t
*) SC
->request_buffer
;
2088 * Some notes about the passthru interface used
2090 * IF the scsi op_code == 0x0d then we assume
2091 * that the data came along with/goes with the
2092 * packet we received from the sg driver. In this
2093 * case the CmdBSize field of the pt structure is
2094 * used for the size of the buffer.
2096 * IF the scsi op_code == 0x81 then we assume that
2097 * we will need our own buffer and we will copy the
2098 * data to/from the user buffer passed in the scsi
2099 * command. The data address resides at offset 4
2100 * in the scsi command. The length of the data resides
2101 * at offset 8 in the scsi command.
2104 switch (pt
->CoppCmd
) {
2106 memcpy(SC
->request_buffer
+ sizeof(ips_passthru_t
),
2107 &ips_num_controllers
, sizeof(int));
2108 SC
->result
= DID_OK
<< 16;
2110 return (IPS_SUCCESS_IMM
);
2113 memcpy(SC
->request_buffer
+ sizeof(ips_passthru_t
),
2114 ha
, sizeof(ips_ha_t
));
2115 SC
->result
= DID_OK
<< 16;
2117 return (IPS_SUCCESS_IMM
);
2119 case IPS_COPPUSRCMD
:
2120 case IPS_COPPIOCCMD
:
2121 if (SC
->cmnd
[0] == IPS_IOCTL_COMMAND
) {
2122 if (SC
->request_bufflen
< (sizeof(ips_passthru_t
) + pt
->CmdBSize
)) {
2124 DEBUG_VAR(1, "(%s%d) Passthru structure wrong size",
2125 ips_name
, ha
->host_num
);
2127 return (IPS_FAILURE
);
2130 if (ips_usrcmd(ha
, pt
, scb
))
2131 return (IPS_SUCCESS
);
2133 return (IPS_FAILURE
);
2134 } else if (SC
->cmnd
[0] == IPS_IOCTL_NEW_COMMAND
) {
2135 if (SC
->request_bufflen
< (sizeof(ips_passthru_t
))) {
2137 DEBUG_VAR(1, "(%s%d) Passthru structure wrong size",
2138 ips_name
, ha
->host_num
);
2140 return (IPS_FAILURE
);
2143 if (ips_newusrcmd(ha
, pt
, scb
))
2144 return (IPS_SUCCESS
);
2146 return (IPS_FAILURE
);
2152 /* we must use the new interface */
2153 if (SC
->cmnd
[0] != IPS_IOCTL_NEW_COMMAND
)
2154 return (IPS_FAILURE
);
2156 /* don't flash the BIOS on future cards */
2157 if ((ha
->device_id
!= IPS_COPPERHEAD_DEVICEID
) ||
2158 (ha
->revision_id
> IPS_REVID_TROMBONE64
)) {
2159 DEBUG_VAR(1, "(%s%d) flash bios failed - unsupported controller",
2160 ips_name
, ha
->host_num
);
2162 return (IPS_FAILURE
);
2166 * Check to make sure we have functions
2167 * to handle the request
2169 if ((!ha
->func
.programbios
) ||
2170 (!ha
->func
.erasebios
) ||
2171 (!ha
->func
.verifybios
))
2172 return (IPS_FAILURE
);
2174 /* copy in the size/buffer ptr from the scsi command */
2175 memcpy(&pt
->CmdBuffer
, &SC
->cmnd
[4], 4);
2176 memcpy(&pt
->CmdBSize
, &SC
->cmnd
[8], 4);
2178 /* must have a buffer */
2179 if ((!pt
->CmdBSize
) || (!pt
->CmdBuffer
))
2180 return (IPS_FAILURE
);
2182 /* make sure buffer is big enough */
2183 if (pt
->CmdBSize
> ha
->ioctl_datasize
) {
2184 void *bigger_struct
;
2186 /* try to allocate a bigger struct */
2187 bigger_struct
= kmalloc(pt
->CmdBSize
, GFP_ATOMIC
|GFP_DMA
);
2188 if (bigger_struct
) {
2189 /* free the old memory */
2190 kfree(ha
->ioctl_data
);
2192 /* use the new memory */
2193 ha
->ioctl_data
= bigger_struct
;
2194 ha
->ioctl_datasize
= pt
->CmdBSize
;
2196 return (IPS_FAILURE
);
2199 /* copy in the buffer */
2200 if (copy_from_user(ha
->ioctl_data
, pt
->CmdBuffer
, pt
->CmdBSize
) > 0) {
2201 DEBUG_VAR(1, "(%s%d) flash bios failed - unable to copy user buffer",
2202 ips_name
, ha
->host_num
);
2204 return (IPS_FAILURE
);
2207 if ((*ha
->func
.erasebios
)(ha
)) {
2208 DEBUG_VAR(1, "(%s%d) flash bios failed - unable to erase flash",
2209 ips_name
, ha
->host_num
);
2211 return (IPS_FAILURE
);
2214 if ((*ha
->func
.programbios
)(ha
, ha
->ioctl_data
, pt
->CmdBSize
)) {
2215 DEBUG_VAR(1, "(%s%d) flash bios failed - unable to program flash",
2216 ips_name
, ha
->host_num
);
2218 return (IPS_FAILURE
);
2221 if ((*ha
->func
.verifybios
)(ha
, ha
->ioctl_data
, pt
->CmdBSize
)) {
2222 DEBUG_VAR(1, "(%s%d) flash bios failed - unable to verify flash",
2223 ips_name
, ha
->host_num
);
2225 return (IPS_FAILURE
);
2228 return (IPS_SUCCESS_IMM
);
2231 return (IPS_FAILURE
);
2234 /****************************************************************************/
2236 /* Routine Name: ips_usrcmd */
2238 /* Routine Description: */
2240 /* Process a user command and make it ready to send */
2242 /****************************************************************************/
2244 ips_usrcmd(ips_ha_t
*ha
, ips_passthru_t
*pt
, ips_scb_t
*scb
) {
2245 IPS_SG_LIST
*sg_list
;
2247 METHOD_TRACE("ips_usrcmd", 1);
2249 if ((!scb
) || (!pt
) || (!ha
))
2252 /* Save the S/G list pointer so it doesn't get clobbered */
2253 sg_list
= scb
->sg_list
;
2255 /* copy in the CP */
2256 memcpy(&scb
->cmd
, &pt
->CoppCP
.cmd
, sizeof(IPS_IOCTL_CMD
));
2257 memcpy(&scb
->dcdb
, &pt
->CoppCP
.dcdb
, sizeof(IPS_DCDB_TABLE
));
2259 /* FIX stuff that might be wrong */
2260 scb
->sg_list
= sg_list
;
2261 scb
->scb_busaddr
= VIRT_TO_BUS(scb
);
2262 scb
->bus
= scb
->scsi_cmd
->channel
;
2263 scb
->target_id
= scb
->scsi_cmd
->target
;
2264 scb
->lun
= scb
->scsi_cmd
->lun
;
2269 scb
->callback
= ipsintr_done
;
2270 scb
->timeout
= ips_cmd_timeout
;
2271 scb
->cmd
.basic_io
.command_id
= IPS_COMMAND_ID(ha
, scb
);
2273 /* we don't support DCDB/READ/WRITE Scatter Gather */
2274 if ((scb
->cmd
.basic_io
.op_code
== IPS_CMD_READ_SG
) ||
2275 (scb
->cmd
.basic_io
.op_code
== IPS_CMD_WRITE_SG
) ||
2276 (scb
->cmd
.basic_io
.op_code
== IPS_CMD_DCDB_SG
))
2280 scb
->data_busaddr
= VIRT_TO_BUS(scb
->scsi_cmd
->request_buffer
+ sizeof(ips_passthru_t
));
2282 scb
->data_busaddr
= 0L;
2285 if (scb
->cmd
.dcdb
.op_code
== IPS_CMD_DCDB
)
2286 scb
->cmd
.dcdb
.dcdb_address
= VIRT_TO_BUS(&scb
->dcdb
);
2289 if (scb
->cmd
.dcdb
.op_code
== IPS_CMD_DCDB
)
2290 scb
->dcdb
.buffer_pointer
= scb
->data_busaddr
;
2292 scb
->cmd
.basic_io
.sg_addr
= scb
->data_busaddr
;
2297 scb
->timeout
= pt
->TimeOut
;
2299 if (pt
->TimeOut
<= 10)
2300 scb
->dcdb
.cmd_attribute
|= IPS_TIMEOUT10
;
2301 else if (pt
->TimeOut
<= 60)
2302 scb
->dcdb
.cmd_attribute
|= IPS_TIMEOUT60
;
2304 scb
->dcdb
.cmd_attribute
|= IPS_TIMEOUT20M
;
2307 /* assume success */
2308 scb
->scsi_cmd
->result
= DID_OK
<< 16;
2314 /****************************************************************************/
2316 /* Routine Name: ips_newusrcmd */
2318 /* Routine Description: */
2320 /* Process a user command and make it ready to send */
2322 /****************************************************************************/
2324 ips_newusrcmd(ips_ha_t
*ha
, ips_passthru_t
*pt
, ips_scb_t
*scb
) {
2325 IPS_SG_LIST
*sg_list
;
2330 METHOD_TRACE("ips_usrcmd", 1);
2332 if ((!scb
) || (!pt
) || (!ha
))
2335 /* Save the S/G list pointer so it doesn't get clobbered */
2336 sg_list
= scb
->sg_list
;
2338 /* copy in the CP */
2339 memcpy(&scb
->cmd
, &pt
->CoppCP
.cmd
, sizeof(IPS_IOCTL_CMD
));
2340 memcpy(&scb
->dcdb
, &pt
->CoppCP
.dcdb
, sizeof(IPS_DCDB_TABLE
));
2342 /* FIX stuff that might be wrong */
2343 scb
->sg_list
= sg_list
;
2344 scb
->scb_busaddr
= VIRT_TO_BUS(scb
);
2345 scb
->bus
= scb
->scsi_cmd
->channel
;
2346 scb
->target_id
= scb
->scsi_cmd
->target
;
2347 scb
->lun
= scb
->scsi_cmd
->lun
;
2352 scb
->callback
= ipsintr_done
;
2353 scb
->timeout
= ips_cmd_timeout
;
2354 scb
->cmd
.basic_io
.command_id
= IPS_COMMAND_ID(ha
, scb
);
2356 /* we don't support DCDB/READ/WRITE Scatter Gather */
2357 if ((scb
->cmd
.basic_io
.op_code
== IPS_CMD_READ_SG
) ||
2358 (scb
->cmd
.basic_io
.op_code
== IPS_CMD_WRITE_SG
) ||
2359 (scb
->cmd
.basic_io
.op_code
== IPS_CMD_DCDB_SG
))
2363 if (pt
->CmdBSize
> ha
->ioctl_datasize
) {
2364 void *bigger_struct
;
2366 /* try to allocate a bigger struct */
2367 bigger_struct
= kmalloc(pt
->CmdBSize
, GFP_ATOMIC
|GFP_DMA
);
2368 if (bigger_struct
) {
2369 /* free the old memory */
2370 kfree(ha
->ioctl_data
);
2372 /* use the new memory */
2373 ha
->ioctl_data
= bigger_struct
;
2374 ha
->ioctl_datasize
= pt
->CmdBSize
;
2380 scb
->data_busaddr
= VIRT_TO_BUS(ha
->ioctl_data
);
2382 /* Attempt to copy in the data */
2383 user_area
= *((char **) &scb
->scsi_cmd
->cmnd
[4]);
2384 kern_area
= ha
->ioctl_data
;
2385 datasize
= *((u32
*) &scb
->scsi_cmd
->cmnd
[8]);
2387 if (copy_from_user(kern_area
, user_area
, datasize
) > 0) {
2388 DEBUG_VAR(1, "(%s%d) passthru failed - unable to copy in user data",
2389 ips_name
, ha
->host_num
);
2395 scb
->data_busaddr
= 0L;
2398 if (scb
->cmd
.dcdb
.op_code
== IPS_CMD_DCDB
)
2399 scb
->cmd
.dcdb
.dcdb_address
= VIRT_TO_BUS(&scb
->dcdb
);
2402 if (scb
->cmd
.dcdb
.op_code
== IPS_CMD_DCDB
)
2403 scb
->dcdb
.buffer_pointer
= scb
->data_busaddr
;
2405 scb
->cmd
.basic_io
.sg_addr
= scb
->data_busaddr
;
2410 scb
->timeout
= pt
->TimeOut
;
2412 if (pt
->TimeOut
<= 10)
2413 scb
->dcdb
.cmd_attribute
|= IPS_TIMEOUT10
;
2414 else if (pt
->TimeOut
<= 60)
2415 scb
->dcdb
.cmd_attribute
|= IPS_TIMEOUT60
;
2417 scb
->dcdb
.cmd_attribute
|= IPS_TIMEOUT20M
;
2420 /* assume success */
2421 scb
->scsi_cmd
->result
= DID_OK
<< 16;
2427 /****************************************************************************/
2429 /* Routine Name: ips_cleanup_passthru */
2431 /* Routine Description: */
2433 /* Cleanup after a passthru command */
2435 /****************************************************************************/
2437 ips_cleanup_passthru(ips_ha_t
*ha
, ips_scb_t
*scb
) {
2440 METHOD_TRACE("ips_cleanup_passthru", 1);
2442 if ((!scb
) || (!scb
->scsi_cmd
) || (!scb
->scsi_cmd
->request_buffer
)) {
2443 DEBUG_VAR(1, "(%s%d) couldn't cleanup after passthru",
2444 ips_name
, ha
->host_num
);
2449 pt
= (ips_passthru_t
*) scb
->scsi_cmd
->request_buffer
;
2451 /* Copy data back to the user */
2452 if (scb
->scsi_cmd
->cmnd
[0] == IPS_IOCTL_COMMAND
) {
2453 /* Copy data back to the user */
2454 pt
->BasicStatus
= scb
->basic_status
;
2455 pt
->ExtendedStatus
= scb
->extended_status
;
2457 pt
->BasicStatus
= scb
->basic_status
;
2458 pt
->ExtendedStatus
= scb
->extended_status
;
2465 /****************************************************************************/
2467 /* Routine Name: ips_host_info */
2469 /* Routine Description: */
2471 /* The passthru interface for the driver */
2473 /****************************************************************************/
2475 ips_host_info(ips_ha_t
*ha
, char *ptr
, off_t offset
, int len
) {
2478 METHOD_TRACE("ips_host_info", 1);
2482 info
.offset
= offset
;
2486 copy_info(&info
, "\nIBM ServeRAID General Information:\n\n");
2488 if ((ha
->nvram
->signature
== IPS_NVRAM_P5_SIG
) &&
2489 (ha
->nvram
->adapter_type
!= 0))
2490 copy_info(&info
, "\tController Type : %s\n", ips_adapter_name
[ha
->ad_type
-1]);
2492 copy_info(&info
, "\tController Type : Unknown\n");
2495 copy_info(&info
, "\tIO region : 0x%lx (%d bytes)\n",
2496 ha
->io_addr
, ha
->io_len
);
2499 copy_info(&info
, "\tMemory region : 0x%lx (%d bytes)\n",
2500 ha
->mem_addr
, ha
->mem_len
);
2501 copy_info(&info
, "\tShared memory address : 0x%lx\n", ha
->mem_ptr
);
2504 copy_info(&info
, "\tIRQ number : %d\n", ha
->irq
);
2506 if (ha
->nvram
->signature
== IPS_NVRAM_P5_SIG
)
2507 copy_info(&info
, "\tBIOS Version : %c%c%c%c%c%c%c%c\n",
2508 ha
->nvram
->bios_high
[0], ha
->nvram
->bios_high
[1],
2509 ha
->nvram
->bios_high
[2], ha
->nvram
->bios_high
[3],
2510 ha
->nvram
->bios_low
[0], ha
->nvram
->bios_low
[1],
2511 ha
->nvram
->bios_low
[2], ha
->nvram
->bios_low
[3]);
2513 copy_info(&info
, "\tFirmware Version : %c%c%c%c%c%c%c%c\n",
2514 ha
->enq
->CodeBlkVersion
[0], ha
->enq
->CodeBlkVersion
[1],
2515 ha
->enq
->CodeBlkVersion
[2], ha
->enq
->CodeBlkVersion
[3],
2516 ha
->enq
->CodeBlkVersion
[4], ha
->enq
->CodeBlkVersion
[5],
2517 ha
->enq
->CodeBlkVersion
[6], ha
->enq
->CodeBlkVersion
[7]);
2519 copy_info(&info
, "\tBoot Block Version : %c%c%c%c%c%c%c%c\n",
2520 ha
->enq
->BootBlkVersion
[0], ha
->enq
->BootBlkVersion
[1],
2521 ha
->enq
->BootBlkVersion
[2], ha
->enq
->BootBlkVersion
[3],
2522 ha
->enq
->BootBlkVersion
[4], ha
->enq
->BootBlkVersion
[5],
2523 ha
->enq
->BootBlkVersion
[6], ha
->enq
->BootBlkVersion
[7]);
2525 copy_info(&info
, "\tDriver Version : %s%s\n",
2526 IPS_VERSION_HIGH
, IPS_VERSION_LOW
);
2528 copy_info(&info
, "\tMax Physical Devices : %d\n",
2529 ha
->enq
->ucMaxPhysicalDevices
);
2530 copy_info(&info
, "\tMax Active Commands : %d\n",
2532 copy_info(&info
, "\tCurrent Queued Commands : %d\n",
2533 ha
->scb_waitlist
.count
);
2534 copy_info(&info
, "\tCurrent Active Commands : %d\n",
2535 ha
->scb_activelist
.count
- ha
->num_ioctl
);
2536 copy_info(&info
, "\tCurrent Queued PT Commands : %d\n",
2537 ha
->copp_waitlist
.count
);
2538 copy_info(&info
, "\tCurrent Active PT Commands : %d\n",
2541 copy_info(&info
, "\n");
2543 return (info
.localpos
);
2546 /****************************************************************************/
2548 /* Routine Name: copy_mem_info */
2550 /* Routine Description: */
2552 /* Copy data into an IPS_INFOSTR structure */
2554 /****************************************************************************/
2556 copy_mem_info(IPS_INFOSTR
*info
, char *data
, int len
) {
2557 METHOD_TRACE("copy_mem_info", 1);
2559 if (info
->pos
+ len
< info
->offset
) {
2564 if (info
->pos
< info
->offset
) {
2565 data
+= (info
->offset
- info
->pos
);
2566 len
-= (info
->offset
- info
->pos
);
2567 info
->pos
+= (info
->offset
- info
->pos
);
2570 if (info
->localpos
+ len
> info
->length
)
2571 len
= info
->length
- info
->localpos
;
2574 memcpy(info
->buffer
+ info
->localpos
, data
, len
);
2576 info
->localpos
+= len
;
2580 /****************************************************************************/
2582 /* Routine Name: copy_info */
2584 /* Routine Description: */
2586 /* printf style wrapper for an info structure */
2588 /****************************************************************************/
2590 copy_info(IPS_INFOSTR
*info
, char *fmt
, ...) {
2595 METHOD_TRACE("copy_info", 1);
2597 va_start(args
, fmt
);
2598 len
= vsprintf(buf
, fmt
, args
);
2601 copy_mem_info(info
, buf
, len
);
2606 /****************************************************************************/
2608 /* Routine Name: ips_hainit */
2610 /* Routine Description: */
2612 /* Initialize the controller */
2614 /* NOTE: Assumes to be called from with a lock */
2616 /****************************************************************************/
2618 ips_hainit(ips_ha_t
*ha
) {
2622 METHOD_TRACE("ips_hainit", 1);
2627 if (ha
->func
.statinit
)
2628 (*ha
->func
.statinit
)(ha
);
2630 if (ha
->func
.enableint
)
2631 (*ha
->func
.enableint
)(ha
);
2634 ha
->reset_count
= 1;
2635 do_gettimeofday(&tv
);
2636 ha
->last_ffdc
= tv
.tv_sec
;
2637 ips_ffdc_reset(ha
, IPS_INTR_IORL
);
2639 if (!ips_read_config(ha
, IPS_INTR_IORL
)) {
2640 printk(KERN_WARNING
"(%s%d) unable to read config from controller.\n",
2641 ips_name
, ha
->host_num
);
2646 if (!ips_read_adapter_status(ha
, IPS_INTR_IORL
)) {
2647 printk(KERN_WARNING
"(%s%d) unable to read controller status.\n",
2648 ips_name
, ha
->host_num
);
2653 if (!ips_read_subsystem_parameters(ha
, IPS_INTR_IORL
)) {
2654 printk(KERN_WARNING
"(%s%d) unable to read subsystem parameters.\n",
2655 ips_name
, ha
->host_num
);
2660 /* write nvram user page 5 */
2661 if (!ips_write_driver_status(ha
, IPS_INTR_IORL
)) {
2662 printk(KERN_WARNING
"(%s%d) unable to write driver info to controller.\n",
2663 ips_name
, ha
->host_num
);
2668 /* set limits on SID, LUN, BUS */
2669 ha
->ntargets
= IPS_MAX_TARGETS
+ 1;
2671 ha
->nbus
= (ha
->enq
->ucMaxPhysicalDevices
/ IPS_MAX_TARGETS
) + 1;
2673 switch (ha
->conf
->logical_drive
[0].ucStripeSize
) {
2675 ha
->max_xfer
= 0x10000;
2679 ha
->max_xfer
= 0x20000;
2683 ha
->max_xfer
= 0x40000;
2688 ha
->max_xfer
= 0x80000;
2692 /* setup max concurrent commands */
2693 if (ha
->subsys
->param
[4] & 0x1) {
2694 /* Use the new method */
2695 ha
->max_cmds
= ha
->enq
->ucConcurrentCmdCount
;
2697 /* use the old method */
2698 switch (ha
->conf
->logical_drive
[0].ucStripeSize
) {
2718 /* set controller IDs */
2719 ha
->ha_id
[0] = IPS_ADAPTER_ID
;
2720 for (i
= 1; i
< ha
->nbus
; i
++) {
2721 ha
->ha_id
[i
] = ha
->conf
->init_id
[i
-1] & 0x1f;
2722 ha
->dcdb_active
[i
-1] = 0;
2728 /****************************************************************************/
2730 /* Routine Name: ips_next */
2732 /* Routine Description: */
2734 /* Take the next command off the queue and send it to the controller */
2736 /****************************************************************************/
2738 ips_next(ips_ha_t
*ha
, int intr
) {
2743 ips_copp_wait_item_t
*item
;
2749 METHOD_TRACE("ips_next", 1);
2755 * Block access to the queue function so
2756 * this command won't time out
2758 if (intr
== IPS_INTR_ON
) {
2759 spin_lock_irqsave(&io_request_lock
, cpu_flags2
);
2760 intr_status
= IPS_INTR_IORL
;
2764 /* Quiet the compiler */
2768 if (ha
->subsys
->param
[3] & 0x300000) {
2771 do_gettimeofday(&tv
);
2773 IPS_HA_LOCK(cpu_flags
);
2774 if (tv
.tv_sec
- ha
->last_ffdc
> IPS_SECS_8HOURS
) {
2775 ha
->last_ffdc
= tv
.tv_sec
;
2776 IPS_HA_UNLOCK(cpu_flags
);
2777 ips_ffdc_time(ha
, intr_status
);
2779 IPS_HA_UNLOCK(cpu_flags
);
2783 if (intr
== IPS_INTR_ON
)
2784 spin_unlock_irqrestore(&io_request_lock
, cpu_flags2
);
2786 #ifndef NO_IPS_CMDLINE
2788 * Send passthru commands
2789 * These have priority over normal I/O
2790 * but shouldn't affect performance too much
2791 * since we limit the number that can be active
2792 * on the card at any one time
2794 IPS_HA_LOCK(cpu_flags
);
2795 IPS_QUEUE_LOCK(&ha
->copp_waitlist
);
2796 while ((ha
->num_ioctl
< IPS_MAX_IOCTL
) &&
2797 (ha
->copp_waitlist
.head
) &&
2798 (scb
= ips_getscb(ha
))) {
2800 IPS_QUEUE_UNLOCK(&ha
->copp_waitlist
);
2801 IPS_HA_UNLOCK(cpu_flags
);
2802 item
= ips_removeq_copp_head(&ha
->copp_waitlist
);
2803 scb
->scsi_cmd
= item
->scsi_cmd
;
2804 scb
->sem
= item
->sem
;
2807 ret
= ips_make_passthru(ha
, scb
->scsi_cmd
, scb
);
2811 if (scb
->scsi_cmd
) {
2812 /* raise the semaphore */
2813 if (scb
->scsi_cmd
->cmnd
[0] == IPS_IOCTL_NEW_COMMAND
)
2816 scb
->scsi_cmd
->result
= DID_ERROR
<< 16;
2818 ips_freescb(ha
, scb
);
2820 case IPS_SUCCESS_IMM
:
2821 if (scb
->scsi_cmd
) {
2822 /* raise the semaphore */
2823 if (scb
->scsi_cmd
->cmnd
[0] == IPS_IOCTL_NEW_COMMAND
)
2827 ips_freescb(ha
, scb
);
2833 if (ret
!= IPS_SUCCESS
) {
2834 IPS_HA_LOCK(cpu_flags
);
2835 IPS_QUEUE_LOCK(&ha
->copp_waitlist
);
2839 ret
= ips_send_cmd(ha
, scb
);
2841 if (ret
== IPS_SUCCESS
) {
2842 ips_putq_scb_head(&ha
->scb_activelist
, scb
);
2848 if (scb
->scsi_cmd
) {
2849 /* raise the semaphore */
2850 if (scb
->scsi_cmd
->cmnd
[0] == IPS_IOCTL_NEW_COMMAND
)
2853 scb
->scsi_cmd
->result
= DID_ERROR
<< 16;
2856 ips_freescb(ha
, scb
);
2858 case IPS_SUCCESS_IMM
:
2859 if (scb
->scsi_cmd
) {
2860 /* raise the semaphore */
2861 if (scb
->scsi_cmd
->cmnd
[0] == IPS_IOCTL_NEW_COMMAND
)
2865 ips_freescb(ha
, scb
);
2871 IPS_HA_LOCK(cpu_flags
);
2872 IPS_QUEUE_LOCK(&ha
->copp_waitlist
);
2875 IPS_QUEUE_UNLOCK(&ha
->copp_waitlist
);
2876 IPS_HA_UNLOCK(cpu_flags
);
2880 * Send "Normal" I/O commands
2882 IPS_HA_LOCK(cpu_flags
);
2883 IPS_QUEUE_LOCK(&ha
->scb_waitlist
);
2884 p
= ha
->scb_waitlist
.head
;
2885 IPS_QUEUE_UNLOCK(&ha
->scb_waitlist
);
2886 while ((p
) && (scb
= ips_getscb(ha
))) {
2887 if ((p
->channel
> 0) && (ha
->dcdb_active
[p
->channel
-1] & (1 << p
->target
))) {
2888 ips_freescb(ha
, scb
);
2889 p
= (Scsi_Cmnd
*) p
->host_scribble
;
2893 IPS_HA_UNLOCK(cpu_flags
);
2896 SC
= ips_removeq_wait(&ha
->scb_waitlist
, q
);
2898 SC
->result
= DID_OK
;
2899 SC
->host_scribble
= NULL
;
2901 memset(SC
->sense_buffer
, 0, sizeof(SC
->sense_buffer
));
2903 scb
->target_id
= SC
->target
;
2905 scb
->bus
= SC
->channel
;
2909 scb
->callback
= ipsintr_done
;
2910 scb
->timeout
= ips_cmd_timeout
;
2911 memset(&scb
->cmd
, 0, 16);
2913 /* copy in the CDB */
2914 memcpy(scb
->cdb
, SC
->cmnd
, SC
->cmd_len
);
2916 /* Now handle the data buffer */
2918 struct scatterlist
*sg
;
2921 sg
= SC
->request_buffer
;
2923 if (SC
->use_sg
== 1) {
2924 if (sg
[0].length
> ha
->max_xfer
) {
2926 scb
->data_len
= ha
->max_xfer
;
2928 scb
->data_len
= sg
[0].length
;
2930 scb
->dcdb
.transfer_length
= scb
->data_len
;
2931 scb
->data_busaddr
= VIRT_TO_BUS(sg
[0].address
);
2935 for (i
= 0; i
< SC
->use_sg
; i
++) {
2936 scb
->sg_list
[i
].address
= VIRT_TO_BUS(sg
[i
].address
);
2937 scb
->sg_list
[i
].length
= sg
[i
].length
;
2939 if (scb
->data_len
+ sg
[i
].length
> ha
->max_xfer
) {
2941 * Data Breakup required
2947 scb
->data_len
+= sg
[i
].length
;
2951 scb
->sg_len
= SC
->use_sg
;
2953 scb
->sg_len
= scb
->breakup
;
2955 scb
->dcdb
.transfer_length
= scb
->data_len
;
2956 scb
->data_busaddr
= VIRT_TO_BUS(scb
->sg_list
);
2959 if (SC
->request_bufflen
) {
2960 if (SC
->request_bufflen
> ha
->max_xfer
) {
2962 * Data breakup required
2965 scb
->data_len
= ha
->max_xfer
;
2967 scb
->data_len
= SC
->request_bufflen
;
2970 scb
->dcdb
.transfer_length
= scb
->data_len
;
2971 scb
->data_busaddr
= VIRT_TO_BUS(SC
->request_buffer
);
2974 scb
->data_busaddr
= 0L;
2977 scb
->dcdb
.transfer_length
= 0;
2982 scb
->dcdb
.cmd_attribute
|=
2983 ips_command_direction
[scb
->scsi_cmd
->cmnd
[0]];
2985 if (!scb
->dcdb
.cmd_attribute
& 0x3)
2986 scb
->dcdb
.transfer_length
= 0;
2988 if (scb
->data_len
>= IPS_MAX_XFER
) {
2989 scb
->dcdb
.cmd_attribute
|= IPS_TRANSFER64K
;
2990 scb
->dcdb
.transfer_length
= 0;
2993 ret
= ips_send_cmd(ha
, scb
);
2995 if (ret
== IPS_SUCCESS
)
2996 ips_putq_scb_head(&ha
->scb_activelist
, scb
);
3000 if (scb
->scsi_cmd
) {
3001 scb
->scsi_cmd
->result
= DID_ERROR
<< 16;
3002 scb
->scsi_cmd
->scsi_done(scb
->scsi_cmd
);
3006 ha
->dcdb_active
[scb
->bus
-1] &= ~(1 << scb
->target_id
);
3008 ips_freescb(ha
, scb
);
3010 case IPS_SUCCESS_IMM
:
3012 scb
->scsi_cmd
->scsi_done(scb
->scsi_cmd
);
3015 ha
->dcdb_active
[scb
->bus
-1] &= ~(1 << scb
->target_id
);
3017 ips_freescb(ha
, scb
);
3023 p
= (Scsi_Cmnd
*) p
->host_scribble
;
3025 IPS_HA_LOCK(cpu_flags
);
3028 IPS_HA_UNLOCK(cpu_flags
);
3031 /****************************************************************************/
3033 /* Routine Name: ips_putq_scb_head */
3035 /* Routine Description: */
3037 /* Add an item to the head of the queue */
3039 /* ASSUMED to be called from within a lock */
3041 /****************************************************************************/
3043 ips_putq_scb_head(ips_scb_queue_t
*queue
, ips_scb_t
*item
) {
3044 METHOD_TRACE("ips_putq_scb_head", 1);
3049 IPS_QUEUE_LOCK(queue
);
3051 item
->q_next
= queue
->head
;
3059 IPS_QUEUE_UNLOCK(queue
);
3062 /****************************************************************************/
3064 /* Routine Name: ips_putq_scb_tail */
3066 /* Routine Description: */
3068 /* Add an item to the tail of the queue */
3070 /* ASSUMED to be called from within a lock */
3072 /****************************************************************************/
3074 ips_putq_scb_tail(ips_scb_queue_t
*queue
, ips_scb_t
*item
) {
3075 METHOD_TRACE("ips_putq_scb_tail", 1);
3080 IPS_QUEUE_LOCK(queue
);
3082 item
->q_next
= NULL
;
3085 queue
->tail
->q_next
= item
;
3094 IPS_QUEUE_UNLOCK(queue
);
3097 /****************************************************************************/
3099 /* Routine Name: ips_removeq_scb_head */
3101 /* Routine Description: */
3103 /* Remove the head of the queue */
3105 /* ASSUMED to be called from within a lock */
3107 /****************************************************************************/
3108 static inline ips_scb_t
*
3109 ips_removeq_scb_head(ips_scb_queue_t
*queue
) {
3112 METHOD_TRACE("ips_removeq_scb_head", 1);
3114 IPS_QUEUE_LOCK(queue
);
3119 IPS_QUEUE_UNLOCK(queue
);
3124 queue
->head
= item
->q_next
;
3125 item
->q_next
= NULL
;
3127 if (queue
->tail
== item
)
3132 IPS_QUEUE_UNLOCK(queue
);
3137 /****************************************************************************/
3139 /* Routine Name: ips_removeq_scb */
3141 /* Routine Description: */
3143 /* Remove an item from a queue */
3145 /* ASSUMED to be called from within a lock */
3147 /****************************************************************************/
3148 static inline ips_scb_t
*
3149 ips_removeq_scb(ips_scb_queue_t
*queue
, ips_scb_t
*item
) {
3152 METHOD_TRACE("ips_removeq_scb", 1);
3157 IPS_QUEUE_LOCK(queue
);
3159 if (item
== queue
->head
) {
3160 IPS_QUEUE_UNLOCK(queue
);
3162 return (ips_removeq_scb_head(queue
));
3167 while ((p
) && (item
!= p
->q_next
))
3172 p
->q_next
= item
->q_next
;
3177 item
->q_next
= NULL
;
3180 IPS_QUEUE_UNLOCK(queue
);
3185 IPS_QUEUE_UNLOCK(queue
);
3190 /****************************************************************************/
3192 /* Routine Name: ips_putq_wait_head */
3194 /* Routine Description: */
3196 /* Add an item to the head of the queue */
3198 /* ASSUMED to be called from within a lock */
3200 /****************************************************************************/
3202 ips_putq_wait_head(ips_wait_queue_t
*queue
, Scsi_Cmnd
*item
) {
3203 METHOD_TRACE("ips_putq_wait_head", 1);
3208 IPS_QUEUE_LOCK(queue
);
3210 item
->host_scribble
= (char *) queue
->head
;
3218 IPS_QUEUE_UNLOCK(queue
);
3221 /****************************************************************************/
3223 /* Routine Name: ips_putq_wait_tail */
3225 /* Routine Description: */
3227 /* Add an item to the tail of the queue */
3229 /* ASSUMED to be called from within a lock */
3231 /****************************************************************************/
3233 ips_putq_wait_tail(ips_wait_queue_t
*queue
, Scsi_Cmnd
*item
) {
3234 METHOD_TRACE("ips_putq_wait_tail", 1);
3239 IPS_QUEUE_LOCK(queue
);
3241 item
->host_scribble
= NULL
;
3244 queue
->tail
->host_scribble
= (char *)item
;
3253 IPS_QUEUE_UNLOCK(queue
);
3256 /****************************************************************************/
3258 /* Routine Name: ips_removeq_wait_head */
3260 /* Routine Description: */
3262 /* Remove the head of the queue */
3264 /* ASSUMED to be called from within a lock */
3266 /****************************************************************************/
3267 static inline Scsi_Cmnd
*
3268 ips_removeq_wait_head(ips_wait_queue_t
*queue
) {
3271 METHOD_TRACE("ips_removeq_wait_head", 1);
3273 IPS_QUEUE_LOCK(queue
);
3278 IPS_QUEUE_UNLOCK(queue
);
3283 queue
->head
= (Scsi_Cmnd
*) item
->host_scribble
;
3284 item
->host_scribble
= NULL
;
3286 if (queue
->tail
== item
)
3291 IPS_QUEUE_UNLOCK(queue
);
3296 /****************************************************************************/
3298 /* Routine Name: ips_removeq_wait */
3300 /* Routine Description: */
3302 /* Remove an item from a queue */
3304 /* ASSUMED to be called from within a lock */
3306 /****************************************************************************/
3307 static inline Scsi_Cmnd
*
3308 ips_removeq_wait(ips_wait_queue_t
*queue
, Scsi_Cmnd
*item
) {
3311 METHOD_TRACE("ips_removeq_wait", 1);
3316 IPS_QUEUE_LOCK(queue
);
3318 if (item
== queue
->head
) {
3319 IPS_QUEUE_UNLOCK(queue
);
3321 return (ips_removeq_wait_head(queue
));
3326 while ((p
) && (item
!= (Scsi_Cmnd
*) p
->host_scribble
))
3327 p
= (Scsi_Cmnd
*) p
->host_scribble
;
3331 p
->host_scribble
= item
->host_scribble
;
3333 if (!item
->host_scribble
)
3336 item
->host_scribble
= NULL
;
3339 IPS_QUEUE_UNLOCK(queue
);
3344 IPS_QUEUE_UNLOCK(queue
);
3349 /****************************************************************************/
3351 /* Routine Name: ips_putq_copp_head */
3353 /* Routine Description: */
3355 /* Add an item to the head of the queue */
3357 /* ASSUMED to be called from within a lock */
3359 /****************************************************************************/
3361 ips_putq_copp_head(ips_copp_queue_t
*queue
, ips_copp_wait_item_t
*item
) {
3362 METHOD_TRACE("ips_putq_copp_head", 1);
3367 IPS_QUEUE_LOCK(queue
);
3369 item
->next
= queue
->head
;
3377 IPS_QUEUE_UNLOCK(queue
);
3380 /****************************************************************************/
3382 /* Routine Name: ips_putq_copp_tail */
3384 /* Routine Description: */
3386 /* Add an item to the tail of the queue */
3388 /* ASSUMED to be called from within a lock */
3390 /****************************************************************************/
3392 ips_putq_copp_tail(ips_copp_queue_t
*queue
, ips_copp_wait_item_t
*item
) {
3393 METHOD_TRACE("ips_putq_copp_tail", 1);
3398 IPS_QUEUE_LOCK(queue
);
3403 queue
->tail
->next
= item
;
3412 IPS_QUEUE_UNLOCK(queue
);
3415 /****************************************************************************/
3417 /* Routine Name: ips_removeq_copp_head */
3419 /* Routine Description: */
3421 /* Remove the head of the queue */
3423 /* ASSUMED to be called from within a lock */
3425 /****************************************************************************/
3426 static inline ips_copp_wait_item_t
*
3427 ips_removeq_copp_head(ips_copp_queue_t
*queue
) {
3428 ips_copp_wait_item_t
*item
;
3430 METHOD_TRACE("ips_removeq_copp_head", 1);
3432 IPS_QUEUE_LOCK(queue
);
3437 IPS_QUEUE_UNLOCK(queue
);
3442 queue
->head
= item
->next
;
3445 if (queue
->tail
== item
)
3450 IPS_QUEUE_UNLOCK(queue
);
3455 /****************************************************************************/
3457 /* Routine Name: ips_removeq_copp */
3459 /* Routine Description: */
3461 /* Remove an item from a queue */
3463 /* ASSUMED to be called from within a lock */
3465 /****************************************************************************/
3466 static inline ips_copp_wait_item_t
*
3467 ips_removeq_copp(ips_copp_queue_t
*queue
, ips_copp_wait_item_t
*item
) {
3468 ips_copp_wait_item_t
*p
;
3470 METHOD_TRACE("ips_removeq_copp", 1);
3475 IPS_QUEUE_LOCK(queue
);
3477 if (item
== queue
->head
) {
3478 IPS_QUEUE_UNLOCK(queue
);
3480 return (ips_removeq_copp_head(queue
));
3485 while ((p
) && (item
!= p
->next
))
3490 p
->next
= item
->next
;
3498 IPS_QUEUE_UNLOCK(queue
);
3503 IPS_QUEUE_UNLOCK(queue
);
3508 /****************************************************************************/
3510 /* Routine Name: ipsintr_blocking */
3512 /* Routine Description: */
3514 /* Finalize an interrupt for internal commands */
3516 /****************************************************************************/
3518 ipsintr_blocking(ips_ha_t
*ha
, ips_scb_t
*scb
) {
3519 METHOD_TRACE("ipsintr_blocking", 2);
3521 if ((ha
->waitflag
== TRUE
) &&
3522 (ha
->cmd_in_progress
== scb
->cdb
[0])) {
3523 ha
->waitflag
= FALSE
;
3529 /****************************************************************************/
3531 /* Routine Name: ipsintr_done */
3533 /* Routine Description: */
3535 /* Finalize an interrupt for non-internal commands */
3537 /****************************************************************************/
3539 ipsintr_done(ips_ha_t
*ha
, ips_scb_t
*scb
) {
3540 METHOD_TRACE("ipsintr_done", 2);
3543 printk(KERN_WARNING
"(%s%d) Spurious interrupt; scb NULL.\n",
3544 ips_name
, ha
->host_num
);
3549 if (scb
->scsi_cmd
== NULL
) {
3550 /* unexpected interrupt */
3551 printk(KERN_WARNING
"(%s%d) Spurious interrupt; scsi_cmd not set.\n",
3552 ips_name
, ha
->host_num
);
3560 /****************************************************************************/
3562 /* Routine Name: ips_done */
3564 /* Routine Description: */
3566 /* Do housekeeping on completed commands */
3568 /****************************************************************************/
3570 ips_done(ips_ha_t
*ha
, ips_scb_t
*scb
) {
3574 METHOD_TRACE("ips_done", 1);
3579 #ifndef NO_IPS_CMDLINE
3580 if ((scb
->scsi_cmd
) && (ips_is_passthru(scb
->scsi_cmd
))) {
3581 ips_cleanup_passthru(ha
, scb
);
3582 IPS_HA_LOCK(cpu_flags
);
3584 IPS_HA_UNLOCK(cpu_flags
);
3588 * Check to see if this command had too much
3589 * data and had to be broke up. If so, queue
3590 * the rest of the data and continue.
3593 /* we had a data breakup */
3596 bk_save
= scb
->breakup
;
3599 if (scb
->scsi_cmd
->use_sg
) {
3601 struct scatterlist
*sg
;
3604 sg
= scb
->scsi_cmd
->request_buffer
;
3606 if (scb
->scsi_cmd
->use_sg
== 1) {
3607 if (sg
[0].length
- (bk_save
* ha
->max_xfer
)) {
3608 /* Further breakup required */
3609 scb
->data_len
= ha
->max_xfer
;
3610 scb
->data_busaddr
= VIRT_TO_BUS(sg
[0].address
+ (bk_save
* ha
->max_xfer
));
3611 scb
->breakup
= bk_save
+ 1;
3613 scb
->data_len
= sg
[0].length
- (bk_save
* ha
->max_xfer
);
3614 scb
->data_busaddr
= VIRT_TO_BUS(sg
[0].address
+ (bk_save
* ha
->max_xfer
));
3617 scb
->dcdb
.transfer_length
= scb
->data_len
;
3622 for (i
= bk_save
; i
< scb
->scsi_cmd
->use_sg
; i
++) {
3623 scb
->sg_list
[i
- bk_save
].address
= VIRT_TO_BUS(sg
[i
].address
);
3624 scb
->sg_list
[i
- bk_save
].length
= sg
[i
].length
;
3626 if (scb
->data_len
+ sg
[i
].length
> ha
->max_xfer
) {
3628 * Data Breakup required
3634 scb
->data_len
+= sg
[i
].length
;
3638 scb
->sg_len
= scb
->scsi_cmd
->use_sg
- bk_save
;
3640 scb
->sg_len
= scb
->breakup
- bk_save
;
3642 scb
->dcdb
.transfer_length
= scb
->data_len
;
3643 scb
->data_busaddr
= VIRT_TO_BUS(scb
->sg_list
);
3646 /* Non S/G Request */
3647 if (scb
->scsi_cmd
->request_bufflen
- (bk_save
* ha
->max_xfer
)) {
3648 /* Further breakup required */
3649 scb
->data_len
= ha
->max_xfer
;
3650 scb
->data_busaddr
= VIRT_TO_BUS(scb
->scsi_cmd
->request_buffer
+ (bk_save
* ha
->max_xfer
));
3651 scb
->breakup
= bk_save
+ 1;
3653 scb
->data_len
= scb
->scsi_cmd
->request_bufflen
- (bk_save
* ha
->max_xfer
);
3654 scb
->data_busaddr
= VIRT_TO_BUS(scb
->scsi_cmd
->request_buffer
+ (bk_save
* ha
->max_xfer
));
3657 scb
->dcdb
.transfer_length
= scb
->data_len
;
3661 scb
->dcdb
.cmd_attribute
|=
3662 ips_command_direction
[scb
->scsi_cmd
->cmnd
[0]];
3664 if (!scb
->dcdb
.cmd_attribute
& 0x3)
3665 scb
->dcdb
.transfer_length
= 0;
3667 if (scb
->data_len
>= IPS_MAX_XFER
) {
3668 scb
->dcdb
.cmd_attribute
|= IPS_TRANSFER64K
;
3669 scb
->dcdb
.transfer_length
= 0;
3672 ret
= ips_send_cmd(ha
, scb
);
3676 if (scb
->scsi_cmd
) {
3677 scb
->scsi_cmd
->result
= DID_ERROR
<< 16;
3678 scb
->scsi_cmd
->scsi_done(scb
->scsi_cmd
);
3681 ips_freescb(ha
, scb
);
3683 case IPS_SUCCESS_IMM
:
3684 if (scb
->scsi_cmd
) {
3685 scb
->scsi_cmd
->result
= DID_ERROR
<< 16;
3686 scb
->scsi_cmd
->scsi_done(scb
->scsi_cmd
);
3689 ips_freescb(ha
, scb
);
3697 #ifndef NO_IPS_CMDLINE
3698 } /* end if passthru */
3702 IPS_HA_LOCK(cpu_flags
);
3703 ha
->dcdb_active
[scb
->bus
-1] &= ~(1 << scb
->target_id
);
3704 IPS_HA_UNLOCK(cpu_flags
);
3707 /* call back to SCSI layer */
3708 if (scb
->scsi_cmd
&& scb
->scsi_cmd
->cmnd
[0] != IPS_IOCTL_NEW_COMMAND
)
3709 scb
->scsi_cmd
->scsi_done(scb
->scsi_cmd
);
3711 ips_freescb(ha
, scb
);
3714 /****************************************************************************/
3716 /* Routine Name: ips_map_status */
3718 /* Routine Description: */
3720 /* Map ServeRAID error codes to Linux Error Codes */
3722 /****************************************************************************/
3724 ips_map_status(ips_ha_t
*ha
, ips_scb_t
*scb
, ips_stat_t
*sp
) {
3728 METHOD_TRACE("ips_map_status", 1);
3731 DEBUG_VAR(2, "(%s%d) Physical device error (%d %d %d): %x %x, Sense Key: %x, ASC: %x, ASCQ: %x",
3734 scb
->scsi_cmd
->channel
,
3735 scb
->scsi_cmd
->target
,
3738 scb
->extended_status
,
3739 scb
->extended_status
== IPS_ERR_CKCOND
? scb
->dcdb
.sense_info
[2] & 0xf : 0,
3740 scb
->extended_status
== IPS_ERR_CKCOND
? scb
->dcdb
.sense_info
[12] : 0,
3741 scb
->extended_status
== IPS_ERR_CKCOND
? scb
->dcdb
.sense_info
[13] : 0);
3744 /* default driver error */
3745 errcode
= DID_ERROR
;
3748 switch (scb
->basic_status
& IPS_GSC_STATUS_MASK
) {
3749 case IPS_CMD_TIMEOUT
:
3750 errcode
= DID_TIME_OUT
;
3753 case IPS_INVAL_OPCO
:
3754 case IPS_INVAL_CMD_BLK
:
3755 case IPS_INVAL_PARM_BLK
:
3757 case IPS_CMD_CMPLT_WERROR
:
3760 case IPS_PHYS_DRV_ERROR
:
3761 switch (scb
->extended_status
) {
3762 case IPS_ERR_SEL_TO
:
3764 errcode
= DID_NO_CONNECT
;
3768 case IPS_ERR_OU_RUN
:
3769 if ((scb
->bus
) && (scb
->dcdb
.transfer_length
< scb
->data_len
)) {
3770 /* Underrun - set default to no error */
3773 /* Restrict access to physical DASD */
3774 if ((scb
->scsi_cmd
->cmnd
[0] == INQUIRY
) &&
3775 ((((char *) scb
->scsi_cmd
->buffer
)[0] & 0x1f) == TYPE_DISK
)) {
3776 /* underflow -- no error */
3777 /* restrict access to physical DASD */
3778 errcode
= DID_TIME_OUT
;
3782 errcode
= DID_ERROR
;
3786 case IPS_ERR_RECOVERY
:
3787 /* don't fail recovered errors */
3793 case IPS_ERR_HOST_RESET
:
3794 case IPS_ERR_DEV_RESET
:
3795 errcode
= DID_RESET
;
3798 case IPS_ERR_CKCOND
:
3800 memcpy(scb
->scsi_cmd
->sense_buffer
, scb
->dcdb
.sense_info
,
3801 sizeof(scb
->scsi_cmd
->sense_buffer
));
3803 device_error
= 2; /* check condition */
3811 errcode
= DID_ERROR
;
3817 scb
->scsi_cmd
->result
= device_error
| (errcode
<< 16);
3822 /****************************************************************************/
3824 /* Routine Name: ips_send */
3826 /* Routine Description: */
3828 /* Wrapper for ips_send_cmd */
3830 /****************************************************************************/
3832 ips_send(ips_ha_t
*ha
, ips_scb_t
*scb
, ips_scb_callback callback
) {
3835 METHOD_TRACE("ips_send", 1);
3837 scb
->callback
= callback
;
3839 ret
= ips_send_cmd(ha
, scb
);
3844 /****************************************************************************/
3846 /* Routine Name: ips_send_wait */
3848 /* Routine Description: */
3850 /* Send a command to the controller and wait for it to return */
3852 /****************************************************************************/
3854 ips_send_wait(ips_ha_t
*ha
, ips_scb_t
*scb
, int timeout
, int intr
) {
3857 METHOD_TRACE("ips_send_wait", 1);
3859 ha
->waitflag
= TRUE
;
3860 ha
->cmd_in_progress
= scb
->cdb
[0];
3862 ret
= ips_send(ha
, scb
, ipsintr_blocking
);
3864 if ((ret
== IPS_FAILURE
) || (ret
== IPS_SUCCESS_IMM
))
3867 ret
= ips_wait(ha
, timeout
, intr
);
3872 /****************************************************************************/
3874 /* Routine Name: ips_send_cmd */
3876 /* Routine Description: */
3878 /* Map SCSI commands to ServeRAID commands for logical drives */
3880 /****************************************************************************/
3882 ips_send_cmd(ips_ha_t
*ha
, ips_scb_t
*scb
) {
3885 METHOD_TRACE("ips_send_cmd", 1);
3889 if (!scb
->scsi_cmd
) {
3890 /* internal command */
3893 /* ServeRAID commands can't be issued */
3894 /* to real devices -- fail them */
3895 if ((ha
->waitflag
== TRUE
) &&
3896 (ha
->cmd_in_progress
== scb
->cdb
[0])) {
3897 ha
->waitflag
= FALSE
;
3902 #ifndef NO_IPS_CMDLINE
3903 } else if ((scb
->bus
== 0) && (!ips_is_passthru(scb
->scsi_cmd
))) {
3905 } else if (scb
->bus
== 0) {
3907 /* command to logical bus -- interpret */
3908 ret
= IPS_SUCCESS_IMM
;
3910 switch (scb
->scsi_cmd
->cmnd
[0]) {
3911 case ALLOW_MEDIUM_REMOVAL
:
3914 case WRITE_FILEMARKS
:
3916 scb
->scsi_cmd
->result
= DID_ERROR
<< 16;
3920 scb
->scsi_cmd
->result
= DID_OK
<< 16;
3922 case TEST_UNIT_READY
:
3924 if (scb
->target_id
== IPS_ADAPTER_ID
) {
3926 * Either we have a TUR
3927 * or we have a SCSI inquiry
3929 if (scb
->scsi_cmd
->cmnd
[0] == TEST_UNIT_READY
)
3930 scb
->scsi_cmd
->result
= DID_OK
<< 16;
3932 if (scb
->scsi_cmd
->cmnd
[0] == INQUIRY
) {
3935 memset(&inq
, 0, sizeof(IPS_INQ_DATA
));
3937 inq
.DeviceType
= TYPE_PROCESSOR
;
3938 inq
.DeviceTypeQualifier
= 0;
3939 inq
.RemoveableMedia
= 0;
3940 inq
.Versions
= 0x1; /* SCSI I */
3941 inq
.AdditionalLength
= 31;
3942 strncpy(inq
.VendorId
, "IBM ", 8);
3943 strncpy(inq
.ProductId
, "SERVERAID ", 16);
3944 strncpy(inq
.ProductRevisionLevel
, "1.00", 4);
3946 memcpy(scb
->scsi_cmd
->request_buffer
, &inq
, scb
->scsi_cmd
->request_bufflen
);
3948 scb
->scsi_cmd
->result
= DID_OK
<< 16;
3951 scb
->cmd
.logical_info
.op_code
= IPS_CMD_GET_LD_INFO
;
3952 scb
->cmd
.logical_info
.command_id
= IPS_COMMAND_ID(ha
, scb
);
3953 scb
->cmd
.logical_info
.buffer_addr
= VIRT_TO_BUS(&ha
->adapt
->logical_drive_info
);
3954 scb
->cmd
.logical_info
.reserved
= 0;
3955 scb
->cmd
.logical_info
.reserved2
= 0;
3962 ips_reqsen(ha
, scb
);
3963 scb
->scsi_cmd
->result
= DID_OK
<< 16;
3969 scb
->cmd
.basic_io
.op_code
=
3970 (scb
->scsi_cmd
->cmnd
[0] == READ_6
) ? IPS_CMD_READ
: IPS_CMD_WRITE
;
3972 scb
->cmd
.basic_io
.op_code
=
3973 (scb
->scsi_cmd
->cmnd
[0] == READ_6
) ? IPS_CMD_READ_SG
: IPS_CMD_WRITE_SG
;
3976 scb
->cmd
.basic_io
.command_id
= IPS_COMMAND_ID(ha
, scb
);
3977 scb
->cmd
.basic_io
.log_drv
= scb
->target_id
;
3978 scb
->cmd
.basic_io
.sg_count
= scb
->sg_len
;
3979 scb
->cmd
.basic_io
.sg_addr
= scb
->data_busaddr
;
3981 if (scb
->cmd
.basic_io
.lba
)
3982 scb
->cmd
.basic_io
.lba
+= scb
->cmd
.basic_io
.sector_count
;
3984 scb
->cmd
.basic_io
.lba
= (((scb
->scsi_cmd
->cmnd
[1] & 0x1f) << 16) |
3985 (scb
->scsi_cmd
->cmnd
[2] << 8) |
3986 (scb
->scsi_cmd
->cmnd
[3]));
3988 scb
->cmd
.basic_io
.sector_count
= scb
->data_len
/ IPS_BLKSIZE
;
3990 if (scb
->cmd
.basic_io
.sector_count
== 0)
3991 scb
->cmd
.basic_io
.sector_count
= 256;
3993 scb
->cmd
.basic_io
.reserved
= 0;
4000 scb
->cmd
.basic_io
.op_code
=
4001 (scb
->scsi_cmd
->cmnd
[0] == READ_10
) ? IPS_CMD_READ
: IPS_CMD_WRITE
;
4003 scb
->cmd
.basic_io
.op_code
=
4004 (scb
->scsi_cmd
->cmnd
[0] == READ_10
) ? IPS_CMD_READ_SG
: IPS_CMD_WRITE_SG
;
4007 scb
->cmd
.basic_io
.command_id
= IPS_COMMAND_ID(ha
, scb
);
4008 scb
->cmd
.basic_io
.log_drv
= scb
->target_id
;
4009 scb
->cmd
.basic_io
.sg_count
= scb
->sg_len
;
4010 scb
->cmd
.basic_io
.sg_addr
= scb
->data_busaddr
;
4012 if (scb
->cmd
.basic_io
.lba
)
4013 scb
->cmd
.basic_io
.lba
+= scb
->cmd
.basic_io
.sector_count
;
4015 scb
->cmd
.basic_io
.lba
= ((scb
->scsi_cmd
->cmnd
[2] << 24) |
4016 (scb
->scsi_cmd
->cmnd
[3] << 16) |
4017 (scb
->scsi_cmd
->cmnd
[4] << 8) |
4018 scb
->scsi_cmd
->cmnd
[5]);
4020 scb
->cmd
.basic_io
.sector_count
= scb
->data_len
/ IPS_BLKSIZE
;
4022 scb
->cmd
.basic_io
.reserved
= 0;
4024 if (scb
->cmd
.basic_io
.sector_count
== 0) {
4026 * This is a null condition
4027 * we don't have to do anything
4030 scb
->scsi_cmd
->result
= DID_OK
<< 16;
4038 scb
->scsi_cmd
->result
= DID_OK
<< 16;
4042 scb
->cmd
.basic_io
.op_code
= IPS_CMD_ENQUIRY
;
4043 scb
->cmd
.basic_io
.command_id
= IPS_COMMAND_ID(ha
, scb
);
4044 scb
->cmd
.basic_io
.sg_addr
= VIRT_TO_BUS(ha
->enq
);
4049 scb
->cmd
.logical_info
.op_code
= IPS_CMD_GET_LD_INFO
;
4050 scb
->cmd
.logical_info
.command_id
= IPS_COMMAND_ID(ha
, scb
);
4051 scb
->cmd
.logical_info
.buffer_addr
= VIRT_TO_BUS(&ha
->adapt
->logical_drive_info
);
4052 scb
->cmd
.logical_info
.reserved
= 0;
4053 scb
->cmd
.logical_info
.reserved2
= 0;
4054 scb
->cmd
.logical_info
.reserved3
= 0;
4058 case SEND_DIAGNOSTIC
:
4059 case REASSIGN_BLOCKS
:
4063 case READ_DEFECT_DATA
:
4066 scb
->scsi_cmd
->result
= DID_OK
<< 16;
4070 scb
->scsi_cmd
->result
= DID_ERROR
<< 16;
4075 if (ret
== IPS_SUCCESS_IMM
)
4081 scb
->cmd
.dcdb
.op_code
= IPS_CMD_DCDB
;
4083 scb
->cmd
.dcdb
.op_code
= IPS_CMD_DCDB_SG
;
4085 ha
->dcdb_active
[scb
->bus
-1] |= (1 << scb
->target_id
);
4086 scb
->cmd
.dcdb
.command_id
= IPS_COMMAND_ID(ha
, scb
);
4087 scb
->cmd
.dcdb
.dcdb_address
= VIRT_TO_BUS(&scb
->dcdb
);
4088 scb
->cmd
.dcdb
.reserved
= 0;
4089 scb
->cmd
.dcdb
.reserved2
= 0;
4090 scb
->cmd
.dcdb
.reserved3
= 0;
4092 scb
->dcdb
.device_address
= ((scb
->bus
- 1) << 4) | scb
->target_id
;
4093 scb
->dcdb
.cmd_attribute
|= IPS_DISCONNECT_ALLOWED
;
4096 if (scb
->timeout
<= 10)
4097 scb
->dcdb
.cmd_attribute
|= IPS_TIMEOUT10
;
4098 else if (scb
->timeout
<= 60)
4099 scb
->dcdb
.cmd_attribute
|= IPS_TIMEOUT60
;
4101 scb
->dcdb
.cmd_attribute
|= IPS_TIMEOUT20M
;
4104 if (!(scb
->dcdb
.cmd_attribute
& IPS_TIMEOUT20M
))
4105 scb
->dcdb
.cmd_attribute
|= IPS_TIMEOUT20M
;
4107 scb
->dcdb
.sense_length
= sizeof(scb
->scsi_cmd
->sense_buffer
);
4108 scb
->dcdb
.buffer_pointer
= scb
->data_busaddr
;
4109 scb
->dcdb
.sg_count
= scb
->sg_len
;
4110 scb
->dcdb
.cdb_length
= scb
->scsi_cmd
->cmd_len
;
4111 memcpy(scb
->dcdb
.scsi_cdb
, scb
->scsi_cmd
->cmnd
, scb
->scsi_cmd
->cmd_len
);
4114 return ((*ha
->func
.issue
)(ha
, scb
));
4117 /****************************************************************************/
4119 /* Routine Name: ips_chk_status */
4121 /* Routine Description: */
4123 /* Check the status of commands to logical drives */
4125 /****************************************************************************/
4127 ips_chkstatus(ips_ha_t
*ha
, IPS_STATUS
*pstatus
) {
4134 METHOD_TRACE("ips_chkstatus", 1);
4136 scb
= &ha
->scbs
[pstatus
->fields
.command_id
];
4137 scb
->basic_status
= basic_status
= pstatus
->fields
.basic_status
& IPS_BASIC_STATUS_MASK
;
4138 scb
->extended_status
= ext_status
= pstatus
->fields
.extended_status
;
4141 sp
->residue_len
= 0;
4142 sp
->scb_addr
= (u32
) scb
;
4144 /* Remove the item from the active queue */
4145 ips_removeq_scb(&ha
->scb_activelist
, scb
);
4148 /* internal commands are handled in do_ipsintr */
4151 DEBUG_VAR(2, "(%s%d) ips_chkstatus: cmd 0x%X id %d (%d %d %d)",
4155 scb
->cmd
.basic_io
.command_id
,
4160 #ifndef NO_IPS_CMDLINE
4161 if ((scb
->scsi_cmd
) && (ips_is_passthru(scb
->scsi_cmd
)))
4162 /* passthru - just returns the raw result */
4168 if (((basic_status
& IPS_GSC_STATUS_MASK
) == IPS_CMD_SUCCESS
) ||
4169 ((basic_status
& IPS_GSC_STATUS_MASK
) == IPS_CMD_RECOVERED_ERROR
)) {
4171 if (scb
->bus
== 0) {
4172 if ((basic_status
& IPS_GSC_STATUS_MASK
) == IPS_CMD_RECOVERED_ERROR
) {
4173 DEBUG_VAR(1, "(%s%d) Recovered Logical Drive Error OpCode: %x, BSB: %x, ESB: %x",
4174 ips_name
, ha
->host_num
,
4175 scb
->cmd
.basic_io
.op_code
, basic_status
, ext_status
);
4178 switch (scb
->scsi_cmd
->cmnd
[0]) {
4179 case ALLOW_MEDIUM_REMOVAL
:
4182 case WRITE_FILEMARKS
:
4184 errcode
= DID_ERROR
;
4190 case TEST_UNIT_READY
:
4191 if (!ips_online(ha
, scb
)) {
4192 errcode
= DID_TIME_OUT
;
4197 if (ips_online(ha
, scb
)) {
4198 ips_inquiry(ha
, scb
);
4200 errcode
= DID_TIME_OUT
;
4205 ips_reqsen(ha
, scb
);
4217 if (!ips_online(ha
, scb
) || !ips_msense(ha
, scb
)) {
4218 errcode
= DID_ERROR
;
4223 if (ips_online(ha
, scb
))
4226 errcode
= DID_TIME_OUT
;
4230 case SEND_DIAGNOSTIC
:
4231 case REASSIGN_BLOCKS
:
4235 errcode
= DID_ERROR
;
4240 case READ_DEFECT_DATA
:
4246 errcode
= DID_ERROR
;
4249 scb
->scsi_cmd
->result
= errcode
<< 16;
4250 } else { /* bus == 0 */
4251 /* restrict access to physical drives */
4252 if ((scb
->scsi_cmd
->cmnd
[0] == INQUIRY
) &&
4253 ((((char *) scb
->scsi_cmd
->buffer
)[0] & 0x1f) == TYPE_DISK
)) {
4255 scb
->scsi_cmd
->result
= DID_TIME_OUT
<< 16;
4258 } else { /* recovered error / success */
4259 if (scb
->bus
== 0) {
4260 DEBUG_VAR(1, "(%s%d) Unrecovered Logical Drive Error OpCode: %x, BSB: %x, ESB: %x",
4261 ips_name
, ha
->host_num
,
4262 scb
->cmd
.basic_io
.op_code
, basic_status
, ext_status
);
4265 ips_map_status(ha
, scb
, sp
);
4269 /****************************************************************************/
4271 /* Routine Name: ips_online */
4273 /* Routine Description: */
4275 /* Determine if a logical drive is online */
4277 /****************************************************************************/
4279 ips_online(ips_ha_t
*ha
, ips_scb_t
*scb
) {
4280 METHOD_TRACE("ips_online", 1);
4282 if (scb
->target_id
>= IPS_MAX_LD
)
4285 if ((scb
->basic_status
& IPS_GSC_STATUS_MASK
) > 1) {
4286 memset(&ha
->adapt
->logical_drive_info
, 0, sizeof(ha
->adapt
->logical_drive_info
));
4291 if (scb
->target_id
< ha
->adapt
->logical_drive_info
.no_of_log_drive
&&
4292 ha
->adapt
->logical_drive_info
.drive_info
[scb
->target_id
].state
!= IPS_LD_OFFLINE
&&
4293 ha
->adapt
->logical_drive_info
.drive_info
[scb
->target_id
].state
!= IPS_LD_FREE
&&
4294 ha
->adapt
->logical_drive_info
.drive_info
[scb
->target_id
].state
!= IPS_LD_CRS
&&
4295 ha
->adapt
->logical_drive_info
.drive_info
[scb
->target_id
].state
!= IPS_LD_SYS
)
4301 /****************************************************************************/
4303 /* Routine Name: ips_inquiry */
4305 /* Routine Description: */
4307 /* Simulate an inquiry command to a logical drive */
4309 /****************************************************************************/
4311 ips_inquiry(ips_ha_t
*ha
, ips_scb_t
*scb
) {
4314 METHOD_TRACE("ips_inquiry", 1);
4316 memset(&inq
, 0, sizeof(IPS_INQ_DATA
));
4318 inq
.DeviceType
= TYPE_DISK
;
4319 inq
.DeviceTypeQualifier
= 0;
4320 inq
.RemoveableMedia
= 0;
4321 inq
.Versions
= 0x1; /* SCSI I */
4322 inq
.AdditionalLength
= 31;
4323 strncpy(inq
.VendorId
, "IBM ", 8);
4324 strncpy(inq
.ProductId
, "SERVERAID ", 16);
4325 strncpy(inq
.ProductRevisionLevel
, "1.00", 4);
4327 memcpy(scb
->scsi_cmd
->request_buffer
, &inq
, scb
->scsi_cmd
->request_bufflen
);
4332 /****************************************************************************/
4334 /* Routine Name: ips_rdcap */
4336 /* Routine Description: */
4338 /* Simulate a read capacity command to a logical drive */
4340 /****************************************************************************/
4342 ips_rdcap(ips_ha_t
*ha
, ips_scb_t
*scb
) {
4345 METHOD_TRACE("ips_rdcap", 1);
4347 if (scb
->scsi_cmd
->bufflen
< 8)
4350 cap
= (IPS_CAPACITY
*) scb
->scsi_cmd
->request_buffer
;
4352 cap
->lba
= htonl(ha
->adapt
->logical_drive_info
.drive_info
[scb
->target_id
].sector_count
- 1);
4353 cap
->len
= htonl((u32
) IPS_BLKSIZE
);
4358 /****************************************************************************/
4360 /* Routine Name: ips_msense */
4362 /* Routine Description: */
4364 /* Simulate a mode sense command to a logical drive */
4366 /****************************************************************************/
4368 ips_msense(ips_ha_t
*ha
, ips_scb_t
*scb
) {
4374 METHOD_TRACE("ips_msense", 1);
4376 if (ha
->enq
->ulDriveSize
[scb
->target_id
] > 0x400000 &&
4377 (ha
->enq
->ucMiscFlag
& 0x8) == 0) {
4378 heads
= IPS_NORM_HEADS
;
4379 sectors
= IPS_NORM_SECTORS
;
4381 heads
= IPS_COMP_HEADS
;
4382 sectors
= IPS_COMP_SECTORS
;
4385 cylinders
= ha
->enq
->ulDriveSize
[scb
->target_id
] / (heads
* sectors
);
4387 mdata
.plh
.plh_type
= 0;
4388 mdata
.plh
.plh_wp
= 0;
4389 mdata
.plh
.plh_bdl
= 8;
4391 switch (scb
->scsi_cmd
->cmnd
[2] & 0x3f) {
4392 case 0x03: /* page 3 */
4393 mdata
.pdata
.pg3
.pg_pc
= 0x3;
4394 mdata
.pdata
.pg3
.pg_res1
= 0;
4395 mdata
.pdata
.pg3
.pg_len
= sizeof(IPS_DADF
);
4396 mdata
.plh
.plh_len
= 3 + mdata
.plh
.plh_bdl
+ mdata
.pdata
.pg3
.pg_len
;
4397 mdata
.pdata
.pg3
.pg_trk_z
= 0;
4398 mdata
.pdata
.pg3
.pg_asec_z
= 0;
4399 mdata
.pdata
.pg3
.pg_atrk_z
= 0;
4400 mdata
.pdata
.pg3
.pg_atrk_v
= 0;
4401 mdata
.pdata
.pg3
.pg_sec_t
= htons(sectors
);
4402 mdata
.pdata
.pg3
.pg_bytes_s
= htons(IPS_BLKSIZE
);
4403 mdata
.pdata
.pg3
.pg_intl
= htons(1);
4404 mdata
.pdata
.pg3
.pg_trkskew
= 0;
4405 mdata
.pdata
.pg3
.pg_cylskew
= 0;
4406 mdata
.pdata
.pg3
.pg_res2
= 0;
4407 mdata
.pdata
.pg3
.pg_ins
= 0;
4408 mdata
.pdata
.pg3
.pg_surf
= 0;
4409 mdata
.pdata
.pg3
.pg_rmb
= 0;
4410 mdata
.pdata
.pg3
.pg_hsec
= 0;
4411 mdata
.pdata
.pg3
.pg_ssec
= 1;
4415 mdata
.pdata
.pg4
.pg_pc
= 0x4;
4416 mdata
.pdata
.pg4
.pg_res1
= 0;
4417 mdata
.pdata
.pg4
.pg_len
= sizeof(IPS_RDDG
);
4418 mdata
.plh
.plh_len
= 3 + mdata
.plh
.plh_bdl
+ mdata
.pdata
.pg4
.pg_len
;
4419 mdata
.pdata
.pg4
.pg_cylu
= (cylinders
>> 8) & 0xffff;
4420 mdata
.pdata
.pg4
.pg_cyll
= cylinders
& 0xff;
4421 mdata
.pdata
.pg4
.pg_head
= heads
;
4422 mdata
.pdata
.pg4
.pg_wrpcompu
= 0;
4423 mdata
.pdata
.pg4
.pg_wrpcompl
= 0;
4424 mdata
.pdata
.pg4
.pg_redwrcur
= 0;
4425 mdata
.pdata
.pg4
.pg_drstep
= htons(1);
4426 mdata
.pdata
.pg4
.pg_landu
= 0;
4427 mdata
.pdata
.pg4
.pg_landl
= 0;
4428 mdata
.pdata
.pg4
.pg_res2
= 0;
4434 memcpy(scb
->scsi_cmd
->request_buffer
, &mdata
, scb
->scsi_cmd
->request_bufflen
);
4439 /****************************************************************************/
4441 /* Routine Name: ips_reqsen */
4443 /* Routine Description: */
4445 /* Simulate a request sense command to a logical drive */
4447 /****************************************************************************/
4449 ips_reqsen(ips_ha_t
*ha
, ips_scb_t
*scb
) {
4452 METHOD_TRACE("ips_reqsen", 1);
4454 sp
= (char *) scb
->scsi_cmd
->sense_buffer
;
4455 memset(sp
, 0, sizeof(scb
->scsi_cmd
->sense_buffer
));
4465 /****************************************************************************/
4467 /* Routine Name: ips_free */
4469 /* Routine Description: */
4471 /* Free any allocated space for this controller */
4473 /****************************************************************************/
4475 ips_free(ips_ha_t
*ha
) {
4478 METHOD_TRACE("ips_free", 1);
4511 if (ha
->ioctl_data
) {
4512 kfree(ha
->ioctl_data
);
4513 ha
->ioctl_data
= NULL
;
4514 ha
->ioctl_datasize
= 0;
4518 for (i
= 0; i
< ha
->max_cmds
; i
++) {
4519 if (ha
->scbs
[i
].sg_list
)
4520 kfree(ha
->scbs
[i
].sg_list
);
4527 /* free memory mapped (if applicable) */
4529 iounmap(ha
->ioremap_ptr
);
4530 ha
->ioremap_ptr
= NULL
;
4537 /****************************************************************************/
4539 /* Routine Name: ips_allocatescbs */
4541 /* Routine Description: */
4543 /* Allocate the command blocks */
4545 /****************************************************************************/
4547 ips_allocatescbs(ips_ha_t
*ha
) {
4551 METHOD_TRACE("ips_allocatescbs", 1);
4553 /* Allocate memory for the CCBs */
4554 ha
->scbs
= (ips_scb_t
*) kmalloc(ha
->max_cmds
* sizeof(ips_scb_t
), GFP_ATOMIC
|GFP_DMA
);
4555 if(ha
->scbs
== NULL
)
4558 memset(ha
->scbs
, 0, ha
->max_cmds
* sizeof(ips_scb_t
));
4560 for (i
= 0; i
< ha
->max_cmds
; i
++) {
4561 scb_p
= &ha
->scbs
[i
];
4563 /* allocate S/G list */
4564 scb_p
->sg_list
= (IPS_SG_LIST
*) kmalloc(sizeof(IPS_SG_LIST
) * IPS_MAX_SG
, GFP_ATOMIC
|GFP_DMA
);
4566 if (! scb_p
->sg_list
)
4569 /* add to the free list */
4570 if (i
< ha
->max_cmds
- 1) {
4571 scb_p
->q_next
= ha
->scb_freelist
;
4572 ha
->scb_freelist
= scb_p
;
4580 /****************************************************************************/
4582 /* Routine Name: ips_init_scb */
4584 /* Routine Description: */
4586 /* Initialize a CCB to default values */
4588 /****************************************************************************/
4590 ips_init_scb(ips_ha_t
*ha
, ips_scb_t
*scb
) {
4591 IPS_SG_LIST
*sg_list
;
4593 METHOD_TRACE("ips_init_scb", 1);
4598 sg_list
= scb
->sg_list
;
4601 memset(scb
, 0, sizeof(ips_scb_t
));
4602 memset(ha
->dummy
, 0, sizeof(IPS_IO_CMD
));
4604 /* Initialize dummy command bucket */
4605 ha
->dummy
->op_code
= 0xFF;
4606 ha
->dummy
->ccsar
= VIRT_TO_BUS(ha
->dummy
);
4607 ha
->dummy
->command_id
= IPS_MAX_CMDS
;
4609 /* set bus address of scb */
4610 scb
->scb_busaddr
= VIRT_TO_BUS(scb
);
4611 scb
->sg_list
= sg_list
;
4614 scb
->cmd
.basic_io
.cccr
= IPS_BIT_ILE
;
4615 scb
->cmd
.basic_io
.ccsar
= VIRT_TO_BUS(ha
->dummy
);
4618 /****************************************************************************/
4620 /* Routine Name: ips_get_scb */
4622 /* Routine Description: */
4624 /* Initialize a CCB to default values */
4626 /* ASSUMED to be callled from within a lock */
4628 /****************************************************************************/
4630 ips_getscb(ips_ha_t
*ha
) {
4634 METHOD_TRACE("ips_getscb", 1);
4636 IPS_SCB_LOCK(cpu_flags
);
4637 if ((scb
= ha
->scb_freelist
) == NULL
) {
4638 IPS_SCB_UNLOCK(cpu_flags
);
4643 ha
->scb_freelist
= scb
->q_next
;
4646 IPS_SCB_UNLOCK(cpu_flags
);
4648 ips_init_scb(ha
, scb
);
4653 /****************************************************************************/
4655 /* Routine Name: ips_free_scb */
4657 /* Routine Description: */
4659 /* Return an unused CCB back to the free list */
4661 /* ASSUMED to be called from within a lock */
4663 /****************************************************************************/
4665 ips_freescb(ips_ha_t
*ha
, ips_scb_t
*scb
) {
4668 METHOD_TRACE("ips_freescb", 1);
4670 /* check to make sure this is not our "special" scb */
4671 if (IPS_COMMAND_ID(ha
, scb
) < (ha
->max_cmds
- 1)) {
4672 IPS_SCB_LOCK(cpu_flags
);
4673 scb
->q_next
= ha
->scb_freelist
;
4674 ha
->scb_freelist
= scb
;
4675 IPS_SCB_UNLOCK(cpu_flags
);
4679 /****************************************************************************/
4681 /* Routine Name: ips_isinit_copperhead */
4683 /* Routine Description: */
4685 /* Reset the controller */
4687 /****************************************************************************/
4689 ips_isinit_copperhead(ips_ha_t
*ha
) {
4693 METHOD_TRACE("ips_isinit_copperhead", 1);
4695 isr
= inb(ha
->io_addr
+ IPS_REG_HISR
);
4696 scpr
= inb(ha
->io_addr
+ IPS_REG_SCPR
);
4698 if (((isr
& IPS_BIT_EI
) == 0) && ((scpr
& IPS_BIT_EBM
) == 0))
4704 /****************************************************************************/
4706 /* Routine Name: ips_isinit_copperhead_memio */
4708 /* Routine Description: */
4710 /* Reset the controller */
4712 /****************************************************************************/
4714 ips_isinit_copperhead_memio(ips_ha_t
*ha
) {
4718 METHOD_TRACE("ips_is_init_copperhead_memio", 1);
4720 isr
= readb(ha
->mem_ptr
+ IPS_REG_HISR
);
4721 scpr
= readb(ha
->mem_ptr
+ IPS_REG_SCPR
);
4723 if (((isr
& IPS_BIT_EI
) == 0) && ((scpr
& IPS_BIT_EBM
) == 0))
4729 /****************************************************************************/
4731 /* Routine Name: ips_isinit_morpheus */
4733 /* Routine Description: */
4735 /* Reset the controller */
4737 /****************************************************************************/
4739 ips_isinit_morpheus(ips_ha_t
*ha
) {
4743 METHOD_TRACE("ips_is_init_morpheus", 1);
4745 post
= readl(ha
->mem_ptr
+ IPS_REG_I960_MSG0
);
4746 bits
= readl(ha
->mem_ptr
+ IPS_REG_I2O_HIR
);
4750 else if (bits
& 0x3)
4756 /****************************************************************************/
4758 /* Routine Name: ips_enable_int_copperhead */
4760 /* Routine Description: */
4761 /* Turn on interrupts */
4763 /****************************************************************************/
4765 ips_enable_int_copperhead(ips_ha_t
*ha
) {
4766 METHOD_TRACE("ips_enable_int_copperhead", 1);
4768 outb(ha
->io_addr
+ IPS_REG_HISR
, IPS_BIT_EI
);
4771 /****************************************************************************/
4773 /* Routine Name: ips_enable_int_copperhead_memio */
4775 /* Routine Description: */
4776 /* Turn on interrupts */
4778 /****************************************************************************/
4780 ips_enable_int_copperhead_memio(ips_ha_t
*ha
) {
4781 METHOD_TRACE("ips_enable_int_copperhead_memio", 1);
4783 writeb(IPS_BIT_EI
, ha
->mem_ptr
+ IPS_REG_HISR
);
4786 /****************************************************************************/
4788 /* Routine Name: ips_enable_int_morpheus */
4790 /* Routine Description: */
4791 /* Turn on interrupts */
4793 /****************************************************************************/
4795 ips_enable_int_morpheus(ips_ha_t
*ha
) {
4798 METHOD_TRACE("ips_enable_int_morpheus", 1);
4800 Oimr
= readl(ha
->mem_ptr
+ IPS_REG_I960_OIMR
);
4802 writel(Oimr
, ha
->mem_ptr
+ IPS_REG_I960_OIMR
);
4805 /****************************************************************************/
4807 /* Routine Name: ips_init_copperhead */
4809 /* Routine Description: */
4811 /* Initialize a copperhead controller */
4813 /****************************************************************************/
4815 ips_init_copperhead(ips_ha_t
*ha
) {
4818 u8 PostByte
[IPS_MAX_POST_BYTES
];
4819 u8 ConfigByte
[IPS_MAX_CONFIG_BYTES
];
4822 METHOD_TRACE("ips_init_copperhead", 1);
4824 for (i
= 0; i
< IPS_MAX_POST_BYTES
; i
++) {
4825 for (j
= 0; j
< 45; j
++) {
4826 Isr
= inb(ha
->io_addr
+ IPS_REG_HISR
);
4827 if (Isr
& IPS_BIT_GHI
)
4830 MDELAY(IPS_ONE_SEC
);
4837 PostByte
[i
] = inb(ha
->io_addr
+ IPS_REG_ISPR
);
4838 outb(Isr
, ha
->io_addr
+ IPS_REG_HISR
);
4841 if (PostByte
[0] < IPS_GOOD_POST_STATUS
) {
4842 printk(KERN_WARNING
"(%s%d) reset controller fails (post status %x %x).\n",
4843 ips_name
, ha
->host_num
, PostByte
[0], PostByte
[1]);
4848 for (i
= 0; i
< IPS_MAX_CONFIG_BYTES
; i
++) {
4849 for (j
= 0; j
< 240; j
++) {
4850 Isr
= inb(ha
->io_addr
+ IPS_REG_HISR
);
4851 if (Isr
& IPS_BIT_GHI
)
4854 MDELAY(IPS_ONE_SEC
); /* 100 msec */
4861 ConfigByte
[i
] = inb(ha
->io_addr
+ IPS_REG_ISPR
);
4862 outb(Isr
, ha
->io_addr
+ IPS_REG_HISR
);
4865 for (i
= 0; i
< 240; i
++) {
4866 Cbsp
= inb(ha
->io_addr
+ IPS_REG_CBSP
);
4868 if ((Cbsp
& IPS_BIT_OP
) == 0)
4871 MDELAY(IPS_ONE_SEC
);
4879 outw(0x1010, ha
->io_addr
+ IPS_REG_CCCR
);
4881 /* Enable busmastering */
4882 outb(IPS_BIT_EBM
, ha
->io_addr
+ IPS_REG_SCPR
);
4884 if (ha
->revision_id
== IPS_REVID_TROMBONE64
)
4885 /* fix for anaconda64 */
4886 outl(0, ha
->io_addr
+ IPS_REG_NDAE
);
4888 /* Enable interrupts */
4889 outb(IPS_BIT_EI
, ha
->io_addr
+ IPS_REG_HISR
);
4894 /****************************************************************************/
4896 /* Routine Name: ips_init_copperhead_memio */
4898 /* Routine Description: */
4900 /* Initialize a copperhead controller with memory mapped I/O */
4902 /****************************************************************************/
4904 ips_init_copperhead_memio(ips_ha_t
*ha
) {
4907 u8 PostByte
[IPS_MAX_POST_BYTES
];
4908 u8 ConfigByte
[IPS_MAX_CONFIG_BYTES
];
4911 METHOD_TRACE("ips_init_copperhead_memio", 1);
4913 for (i
= 0; i
< IPS_MAX_POST_BYTES
; i
++) {
4914 for (j
= 0; j
< 45; j
++) {
4915 Isr
= readb(ha
->mem_ptr
+ IPS_REG_HISR
);
4916 if (Isr
& IPS_BIT_GHI
)
4919 MDELAY(IPS_ONE_SEC
);
4926 PostByte
[i
] = readb(ha
->mem_ptr
+ IPS_REG_ISPR
);
4927 writeb(Isr
, ha
->mem_ptr
+ IPS_REG_HISR
);
4930 if (PostByte
[0] < IPS_GOOD_POST_STATUS
) {
4931 printk(KERN_WARNING
"(%s%d) reset controller fails (post status %x %x).\n",
4932 ips_name
, ha
->host_num
, PostByte
[0], PostByte
[1]);
4937 for (i
= 0; i
< IPS_MAX_CONFIG_BYTES
; i
++) {
4938 for (j
= 0; j
< 240; j
++) {
4939 Isr
= readb(ha
->mem_ptr
+ IPS_REG_HISR
);
4940 if (Isr
& IPS_BIT_GHI
)
4943 MDELAY(IPS_ONE_SEC
); /* 100 msec */
4950 ConfigByte
[i
] = readb(ha
->mem_ptr
+ IPS_REG_ISPR
);
4951 writeb(Isr
, ha
->mem_ptr
+ IPS_REG_HISR
);
4954 for (i
= 0; i
< 240; i
++) {
4955 Cbsp
= readb(ha
->mem_ptr
+ IPS_REG_CBSP
);
4957 if ((Cbsp
& IPS_BIT_OP
) == 0)
4960 MDELAY(IPS_ONE_SEC
);
4968 writel(0x1010, ha
->mem_ptr
+ IPS_REG_CCCR
);
4970 /* Enable busmastering */
4971 writeb(IPS_BIT_EBM
, ha
->mem_ptr
+ IPS_REG_SCPR
);
4973 if (ha
->revision_id
== IPS_REVID_TROMBONE64
)
4974 /* fix for anaconda64 */
4975 writel(0, ha
->mem_ptr
+ IPS_REG_NDAE
);
4977 /* Enable interrupts */
4978 writeb(IPS_BIT_EI
, ha
->mem_ptr
+ IPS_REG_HISR
);
4980 /* if we get here then everything went OK */
4984 /****************************************************************************/
4986 /* Routine Name: ips_init_morpheus */
4988 /* Routine Description: */
4990 /* Initialize a morpheus controller */
4992 /****************************************************************************/
4994 ips_init_morpheus(ips_ha_t
*ha
) {
5001 METHOD_TRACE("ips_init_morpheus", 1);
5003 /* Wait up to 45 secs for Post */
5004 for (i
= 0; i
< 45; i
++) {
5005 Isr
= readl(ha
->mem_ptr
+ IPS_REG_I2O_HIR
);
5007 if (Isr
& IPS_BIT_I960_MSG0I
)
5010 MDELAY(IPS_ONE_SEC
);
5015 printk(KERN_WARNING
"(%s%d) timeout waiting for post.\n",
5016 ips_name
, ha
->host_num
);
5021 Post
= readl(ha
->mem_ptr
+ IPS_REG_I960_MSG0
);
5023 /* Clear the interrupt bit */
5024 Isr
= (u32
) IPS_BIT_I960_MSG0I
;
5025 writel(Isr
, ha
->mem_ptr
+ IPS_REG_I2O_HIR
);
5027 if (Post
< (IPS_GOOD_POST_STATUS
<< 8)) {
5028 printk(KERN_WARNING
"(%s%d) reset controller fails (post status %x).\n",
5029 ips_name
, ha
->host_num
, Post
);
5034 /* Wait up to 240 secs for config bytes */
5035 for (i
= 0; i
< 240; i
++) {
5036 Isr
= readl(ha
->mem_ptr
+ IPS_REG_I2O_HIR
);
5038 if (Isr
& IPS_BIT_I960_MSG1I
)
5041 MDELAY(IPS_ONE_SEC
); /* 100 msec */
5046 printk(KERN_WARNING
"(%s%d) timeout waiting for config.\n",
5047 ips_name
, ha
->host_num
);
5052 Config
= readl(ha
->mem_ptr
+ IPS_REG_I960_MSG1
);
5054 /* Clear interrupt bit */
5055 Isr
= (u32
) IPS_BIT_I960_MSG1I
;
5056 writel(Isr
, ha
->mem_ptr
+ IPS_REG_I2O_HIR
);
5058 /* Turn on the interrupts */
5059 Oimr
= readl(ha
->mem_ptr
+ IPS_REG_I960_OIMR
);
5061 writel(Oimr
, ha
->mem_ptr
+ IPS_REG_I960_OIMR
);
5063 /* if we get here then everything went OK */
5067 /****************************************************************************/
5069 /* Routine Name: ips_reset_copperhead */
5071 /* Routine Description: */
5073 /* Reset the controller */
5075 /****************************************************************************/
5077 ips_reset_copperhead(ips_ha_t
*ha
) {
5081 METHOD_TRACE("ips_reset_copperhead", 1);
5083 DEBUG_VAR(1, "(%s%d) ips_reset_copperhead: io addr: %x, irq: %d",
5084 ips_name
, ha
->host_num
, ha
->io_addr
, ha
->irq
);
5086 IPS_HA_LOCK(cpu_flags
);
5090 while (reset_counter
< 2) {
5093 outb(IPS_BIT_RST
, ha
->io_addr
+ IPS_REG_SCPR
);
5094 MDELAY(IPS_ONE_SEC
);
5095 outb(0, ha
->io_addr
+ IPS_REG_SCPR
);
5096 MDELAY(IPS_ONE_SEC
);
5098 if ((*ha
->func
.init
)(ha
))
5100 else if (reset_counter
>= 2) {
5101 IPS_HA_UNLOCK(cpu_flags
);
5107 IPS_HA_UNLOCK(cpu_flags
);
5112 /****************************************************************************/
5114 /* Routine Name: ips_reset_copperhead_memio */
5116 /* Routine Description: */
5118 /* Reset the controller */
5120 /****************************************************************************/
5122 ips_reset_copperhead_memio(ips_ha_t
*ha
) {
5126 METHOD_TRACE("ips_reset_copperhead_memio", 1);
5128 DEBUG_VAR(1, "(%s%d) ips_reset_copperhead_memio: mem addr: %x, irq: %d",
5129 ips_name
, ha
->host_num
, ha
->mem_addr
, ha
->irq
);
5131 IPS_HA_LOCK(cpu_flags
);
5135 while (reset_counter
< 2) {
5138 writeb(IPS_BIT_RST
, ha
->mem_ptr
+ IPS_REG_SCPR
);
5139 MDELAY(IPS_ONE_SEC
);
5140 writeb(0, ha
->mem_ptr
+ IPS_REG_SCPR
);
5141 MDELAY(IPS_ONE_SEC
);
5143 if ((*ha
->func
.init
)(ha
))
5145 else if (reset_counter
>= 2) {
5146 IPS_HA_UNLOCK(cpu_flags
);
5152 IPS_HA_UNLOCK(cpu_flags
);
5157 /****************************************************************************/
5159 /* Routine Name: ips_reset_morpheus */
5161 /* Routine Description: */
5163 /* Reset the controller */
5165 /****************************************************************************/
5167 ips_reset_morpheus(ips_ha_t
*ha
) {
5172 METHOD_TRACE("ips_reset_morpheus", 1);
5174 DEBUG_VAR(1, "(%s%d) ips_reset_morpheus: mem addr: %x, irq: %d",
5175 ips_name
, ha
->host_num
, ha
->mem_addr
, ha
->irq
);
5177 IPS_HA_LOCK(cpu_flags
);
5181 while (reset_counter
< 2) {
5184 writel(0x80000000, ha
->mem_ptr
+ IPS_REG_I960_IDR
);
5186 /* Delay for 300 msec */
5187 MDELAY(300 * IPS_ONE_MSEC
);
5189 /* Do a PCI config read to wait for adapter */
5190 pci_read_config_byte(ha
->pcidev
, 4, &junk
);
5192 if ((*ha
->func
.init
)(ha
))
5194 else if (reset_counter
>= 2) {
5195 IPS_HA_UNLOCK(cpu_flags
);
5201 IPS_HA_UNLOCK(cpu_flags
);
5206 /****************************************************************************/
5208 /* Routine Name: ips_statinit */
5210 /* Routine Description: */
5212 /* Initialize the status queues on the controller */
5214 /****************************************************************************/
5216 ips_statinit(ips_ha_t
*ha
) {
5217 u32 phys_status_start
;
5219 METHOD_TRACE("ips_statinit", 1);
5221 ha
->adapt
->p_status_start
= ha
->adapt
->status
;
5222 ha
->adapt
->p_status_end
= ha
->adapt
->status
+ IPS_MAX_CMDS
;
5223 ha
->adapt
->p_status_tail
= ha
->adapt
->status
;
5225 phys_status_start
= VIRT_TO_BUS(ha
->adapt
->status
);
5226 outl(phys_status_start
, ha
->io_addr
+ IPS_REG_SQSR
);
5227 outl(phys_status_start
+ IPS_STATUS_Q_SIZE
, ha
->io_addr
+ IPS_REG_SQER
);
5228 outl(phys_status_start
+ IPS_STATUS_SIZE
, ha
->io_addr
+ IPS_REG_SQHR
);
5229 outl(phys_status_start
, ha
->io_addr
+ IPS_REG_SQTR
);
5231 ha
->adapt
->hw_status_start
= phys_status_start
;
5232 ha
->adapt
->hw_status_tail
= phys_status_start
;
5235 /****************************************************************************/
5237 /* Routine Name: ips_statinit_memio */
5239 /* Routine Description: */
5241 /* Initialize the status queues on the controller */
5243 /****************************************************************************/
5245 ips_statinit_memio(ips_ha_t
*ha
) {
5246 u32 phys_status_start
;
5248 METHOD_TRACE("ips_statinit_memio", 1);
5250 ha
->adapt
->p_status_start
= ha
->adapt
->status
;
5251 ha
->adapt
->p_status_end
= ha
->adapt
->status
+ IPS_MAX_CMDS
;
5252 ha
->adapt
->p_status_tail
= ha
->adapt
->status
;
5254 phys_status_start
= VIRT_TO_BUS(ha
->adapt
->status
);
5255 writel(phys_status_start
, ha
->mem_ptr
+ IPS_REG_SQSR
);
5256 writel(phys_status_start
+ IPS_STATUS_Q_SIZE
, ha
->mem_ptr
+ IPS_REG_SQER
);
5257 writel(phys_status_start
+ IPS_STATUS_SIZE
, ha
->mem_ptr
+ IPS_REG_SQHR
);
5258 writel(phys_status_start
, ha
->mem_ptr
+ IPS_REG_SQTR
);
5260 ha
->adapt
->hw_status_start
= phys_status_start
;
5261 ha
->adapt
->hw_status_tail
= phys_status_start
;
5264 /****************************************************************************/
5266 /* Routine Name: ips_statupd_copperhead */
5268 /* Routine Description: */
5270 /* Remove an element from the status queue */
5272 /****************************************************************************/
5274 ips_statupd_copperhead(ips_ha_t
*ha
) {
5275 METHOD_TRACE("ips_statupd_copperhead", 1);
5277 if (ha
->adapt
->p_status_tail
!= ha
->adapt
->p_status_end
) {
5278 ha
->adapt
->p_status_tail
++;
5279 ha
->adapt
->hw_status_tail
+= sizeof(IPS_STATUS
);
5281 ha
->adapt
->p_status_tail
= ha
->adapt
->p_status_start
;
5282 ha
->adapt
->hw_status_tail
= ha
->adapt
->hw_status_start
;
5285 outl(ha
->adapt
->hw_status_tail
, ha
->io_addr
+ IPS_REG_SQTR
);
5287 return (ha
->adapt
->p_status_tail
->value
);
5290 /****************************************************************************/
5292 /* Routine Name: ips_statupd_copperhead_memio */
5294 /* Routine Description: */
5296 /* Remove an element from the status queue */
5298 /****************************************************************************/
5300 ips_statupd_copperhead_memio(ips_ha_t
*ha
) {
5301 METHOD_TRACE("ips_statupd_copperhead_memio", 1);
5303 if (ha
->adapt
->p_status_tail
!= ha
->adapt
->p_status_end
) {
5304 ha
->adapt
->p_status_tail
++;
5305 ha
->adapt
->hw_status_tail
+= sizeof(IPS_STATUS
);
5307 ha
->adapt
->p_status_tail
= ha
->adapt
->p_status_start
;
5308 ha
->adapt
->hw_status_tail
= ha
->adapt
->hw_status_start
;
5311 writel(ha
->adapt
->hw_status_tail
, ha
->mem_ptr
+ IPS_REG_SQTR
);
5313 return (ha
->adapt
->p_status_tail
->value
);
5316 /****************************************************************************/
5318 /* Routine Name: ips_statupd_morpheus */
5320 /* Routine Description: */
5322 /* Remove an element from the status queue */
5324 /****************************************************************************/
5326 ips_statupd_morpheus(ips_ha_t
*ha
) {
5329 METHOD_TRACE("ips_statupd_morpheus", 1);
5331 val
= readl(ha
->mem_ptr
+ IPS_REG_I2O_OUTMSGQ
);
5336 /****************************************************************************/
5338 /* Routine Name: ips_issue_copperhead */
5340 /* Routine Description: */
5342 /* Send a command down to the controller */
5344 /****************************************************************************/
5346 ips_issue_copperhead(ips_ha_t
*ha
, ips_scb_t
*scb
) {
5351 METHOD_TRACE("ips_issue_copperhead", 1);
5353 if (scb
->scsi_cmd
) {
5354 DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)",
5358 scb
->cmd
.basic_io
.command_id
,
5363 DEBUG_VAR(2, KERN_NOTICE
"(%s%d) ips_issue: logical cmd id %d",
5366 scb
->cmd
.basic_io
.command_id
);
5369 IPS_HA_LOCK(cpu_flags
);
5373 while ((val
= inw(ha
->io_addr
+ IPS_REG_CCCR
)) & IPS_BIT_SEM
) {
5376 if (++TimeOut
>= IPS_SEM_TIMEOUT
) {
5377 if (!(val
& IPS_BIT_START_STOP
))
5380 printk(KERN_WARNING
"(%s%d) ips_issue val [0x%x].\n",
5381 ips_name
, ha
->host_num
, val
);
5382 printk(KERN_WARNING
"(%s%d) ips_issue semaphore chk timeout.\n",
5383 ips_name
, ha
->host_num
);
5385 IPS_HA_UNLOCK(cpu_flags
);
5387 return (IPS_FAILURE
);
5391 outl(scb
->scb_busaddr
, ha
->io_addr
+ IPS_REG_CCSAR
);
5392 outw(IPS_BIT_START_CMD
, ha
->io_addr
+ IPS_REG_CCCR
);
5394 IPS_HA_UNLOCK(cpu_flags
);
5396 return (IPS_SUCCESS
);
5399 /****************************************************************************/
5401 /* Routine Name: ips_issue_copperhead_memio */
5403 /* Routine Description: */
5405 /* Send a command down to the controller */
5407 /****************************************************************************/
5409 ips_issue_copperhead_memio(ips_ha_t
*ha
, ips_scb_t
*scb
) {
5414 METHOD_TRACE("ips_issue_copperhead_memio", 1);
5416 if (scb
->scsi_cmd
) {
5417 DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)",
5421 scb
->cmd
.basic_io
.command_id
,
5426 DEBUG_VAR(2, "(%s%d) ips_issue: logical cmd id %d",
5429 scb
->cmd
.basic_io
.command_id
);
5432 IPS_HA_LOCK(cpu_flags
);
5436 while ((val
= readl(ha
->mem_ptr
+ IPS_REG_CCCR
)) & IPS_BIT_SEM
) {
5439 if (++TimeOut
>= IPS_SEM_TIMEOUT
) {
5440 if (!(val
& IPS_BIT_START_STOP
))
5443 printk(KERN_WARNING
"(%s%d) ips_issue val [0x%x].\n",
5444 ips_name
, ha
->host_num
, val
);
5445 printk(KERN_WARNING
"(%s%d) ips_issue semaphore chk timeout.\n",
5446 ips_name
, ha
->host_num
);
5448 IPS_HA_UNLOCK(cpu_flags
);
5450 return (IPS_FAILURE
);
5454 writel(scb
->scb_busaddr
, ha
->mem_ptr
+ IPS_REG_CCSAR
);
5455 writel(IPS_BIT_START_CMD
, ha
->mem_ptr
+ IPS_REG_CCCR
);
5457 IPS_HA_UNLOCK(cpu_flags
);
5459 return (IPS_SUCCESS
);
5462 /****************************************************************************/
5464 /* Routine Name: ips_issue_i2o */
5466 /* Routine Description: */
5468 /* Send a command down to the controller */
5470 /****************************************************************************/
5472 ips_issue_i2o(ips_ha_t
*ha
, ips_scb_t
*scb
) {
5475 METHOD_TRACE("ips_issue_i2o", 1);
5477 if (scb
->scsi_cmd
) {
5478 DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)",
5482 scb
->cmd
.basic_io
.command_id
,
5487 DEBUG_VAR(2, "(%s%d) ips_issue: logical cmd id %d",
5490 scb
->cmd
.basic_io
.command_id
);
5493 IPS_HA_LOCK(cpu_flags
);
5495 outl(scb
->scb_busaddr
, ha
->io_addr
+ IPS_REG_I2O_INMSGQ
);
5497 IPS_HA_UNLOCK(cpu_flags
);
5499 return (IPS_SUCCESS
);
5502 /****************************************************************************/
5504 /* Routine Name: ips_issue_i2o_memio */
5506 /* Routine Description: */
5508 /* Send a command down to the controller */
5510 /****************************************************************************/
5512 ips_issue_i2o_memio(ips_ha_t
*ha
, ips_scb_t
*scb
) {
5515 METHOD_TRACE("ips_issue_i2o_memio", 1);
5517 if (scb
->scsi_cmd
) {
5518 DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)",
5522 scb
->cmd
.basic_io
.command_id
,
5527 DEBUG_VAR(2, "(%s%d) ips_issue: logical cmd id %d",
5530 scb
->cmd
.basic_io
.command_id
);
5533 IPS_HA_LOCK(cpu_flags
);
5535 writel(scb
->scb_busaddr
, ha
->mem_ptr
+ IPS_REG_I2O_INMSGQ
);
5537 IPS_HA_UNLOCK(cpu_flags
);
5539 return (IPS_SUCCESS
);
5542 /****************************************************************************/
5544 /* Routine Name: ips_isintr_copperhead */
5546 /* Routine Description: */
5548 /* Test to see if an interrupt is for us */
5550 /****************************************************************************/
5552 ips_isintr_copperhead(ips_ha_t
*ha
) {
5555 METHOD_TRACE("ips_isintr_copperhead", 2);
5557 Isr
= inb(ha
->io_addr
+ IPS_REG_HISR
);
5560 /* ?!?! Nothing really there */
5563 if (Isr
& IPS_BIT_SCE
)
5565 else if (Isr
& (IPS_BIT_SQO
| IPS_BIT_GHI
)) {
5566 /* status queue overflow or GHI */
5567 /* just clear the interrupt */
5568 outb(Isr
, ha
->io_addr
+ IPS_REG_HISR
);
5574 /****************************************************************************/
5576 /* Routine Name: ips_isintr_copperhead_memio */
5578 /* Routine Description: */
5580 /* Test to see if an interrupt is for us */
5582 /****************************************************************************/
5584 ips_isintr_copperhead_memio(ips_ha_t
*ha
) {
5587 METHOD_TRACE("ips_isintr_memio", 2);
5589 Isr
= readb(ha
->mem_ptr
+ IPS_REG_HISR
);
5592 /* ?!?! Nothing really there */
5595 if (Isr
& IPS_BIT_SCE
)
5597 else if (Isr
& (IPS_BIT_SQO
| IPS_BIT_GHI
)) {
5598 /* status queue overflow or GHI */
5599 /* just clear the interrupt */
5600 writeb(Isr
, ha
->mem_ptr
+ IPS_REG_HISR
);
5606 /****************************************************************************/
5608 /* Routine Name: ips_isintr_morpheus */
5610 /* Routine Description: */
5612 /* Test to see if an interrupt is for us */
5614 /****************************************************************************/
5616 ips_isintr_morpheus(ips_ha_t
*ha
) {
5619 METHOD_TRACE("ips_isintr_morpheus", 2);
5621 Isr
= readl(ha
->mem_ptr
+ IPS_REG_I2O_HIR
);
5623 if (Isr
& IPS_BIT_I2O_OPQI
)
5629 /****************************************************************************/
5631 /* Routine Name: ips_wait */
5633 /* Routine Description: */
5635 /* Wait for a command to complete */
5637 /****************************************************************************/
5639 ips_wait(ips_ha_t
*ha
, int time
, int intr
) {
5643 METHOD_TRACE("ips_wait", 1);
5648 time
*= IPS_ONE_SEC
; /* convert seconds to milliseconds */
5650 while ((time
> 0) && (!done
)) {
5651 if (intr
== IPS_INTR_ON
) {
5652 if (ha
->waitflag
== FALSE
) {
5657 } else if (intr
== IPS_INTR_IORL
) {
5658 if (ha
->waitflag
== FALSE
) {
5660 * controller generated an interupt to
5661 * acknowledge completion of the command
5662 * and ips_intr() has serviced the interrupt.
5670 * NOTE: we already have the io_request_lock so
5671 * even if we get an interrupt it won't get serviced
5672 * until after we finish.
5675 while (test_and_set_bit(IPS_IN_INTR
, &ha
->flags
))
5678 (*ha
->func
.intr
)(ha
);
5680 clear_bit(IPS_IN_INTR
, &ha
->flags
);
5681 } else if (intr
== IPS_INTR_HAL
) {
5682 if (ha
->waitflag
== FALSE
) {
5684 * controller generated an interupt to
5685 * acknowledge completion of the command
5686 * and ips_intr() has serviced the interrupt.
5694 * NOTE: since we were not called with the iorequest lock
5695 * we must obtain it before we can call the interrupt handler.
5696 * We were called under the HA lock so we can assume that interrupts
5699 spin_lock(&io_request_lock
);
5701 while (test_and_set_bit(IPS_IN_INTR
, &ha
->flags
))
5704 (*ha
->func
.intr
)(ha
);
5706 clear_bit(IPS_IN_INTR
, &ha
->flags
);
5708 spin_unlock(&io_request_lock
);
5711 UDELAY(1000); /* 1 milisecond */
5718 /****************************************************************************/
5720 /* Routine Name: ips_write_driver_status */
5722 /* Routine Description: */
5724 /* Write OS/Driver version to Page 5 of the nvram on the controller */
5726 /****************************************************************************/
5728 ips_write_driver_status(ips_ha_t
*ha
, int intr
) {
5729 METHOD_TRACE("ips_write_driver_status", 1);
5731 if (!ips_readwrite_page5(ha
, FALSE
, intr
)) {
5732 printk(KERN_WARNING
"(%s%d) unable to read NVRAM page 5.\n",
5733 ips_name
, ha
->host_num
);
5738 /* check to make sure the page has a valid */
5740 if (ha
->nvram
->signature
!= IPS_NVRAM_P5_SIG
) {
5741 DEBUG_VAR(1, "(%s%d) NVRAM page 5 has an invalid signature: %X.",
5742 ips_name
, ha
->host_num
, ha
->nvram
->signature
);
5747 DEBUG_VAR(2, "(%s%d) Ad Type: %d, Ad Slot: %d, BIOS: %c%c%c%c %c%c%c%c.",
5748 ips_name
, ha
->host_num
, ha
->nvram
->adapter_type
, ha
->nvram
->adapter_slot
,
5749 ha
->nvram
->bios_high
[0], ha
->nvram
->bios_high
[1],
5750 ha
->nvram
->bios_high
[2], ha
->nvram
->bios_high
[3],
5751 ha
->nvram
->bios_low
[0], ha
->nvram
->bios_low
[1],
5752 ha
->nvram
->bios_low
[2], ha
->nvram
->bios_low
[3]);
5754 /* save controller type */
5755 ha
->ad_type
= ha
->nvram
->adapter_type
;
5757 /* change values (as needed) */
5758 ha
->nvram
->operating_system
= IPS_OS_LINUX
;
5759 strncpy((char *) ha
->nvram
->driver_high
, IPS_VERSION_HIGH
, 4);
5760 strncpy((char *) ha
->nvram
->driver_low
, IPS_VERSION_LOW
, 4);
5762 /* now update the page */
5763 if (!ips_readwrite_page5(ha
, TRUE
, intr
)) {
5764 printk(KERN_WARNING
"(%s%d) unable to write NVRAM page 5.\n",
5765 ips_name
, ha
->host_num
);
5773 /****************************************************************************/
5775 /* Routine Name: ips_read_adapter_status */
5777 /* Routine Description: */
5779 /* Do an Inquiry command to the adapter */
5781 /****************************************************************************/
5783 ips_read_adapter_status(ips_ha_t
*ha
, int intr
) {
5787 METHOD_TRACE("ips_read_adapter_status", 1);
5789 scb
= &ha
->scbs
[ha
->max_cmds
-1];
5791 ips_init_scb(ha
, scb
);
5793 scb
->timeout
= ips_cmd_timeout
;
5794 scb
->cdb
[0] = IPS_CMD_ENQUIRY
;
5796 scb
->cmd
.basic_io
.op_code
= IPS_CMD_ENQUIRY
;
5797 scb
->cmd
.basic_io
.command_id
= IPS_COMMAND_ID(ha
, scb
);
5798 scb
->cmd
.basic_io
.sg_count
= 0;
5799 scb
->cmd
.basic_io
.sg_addr
= VIRT_TO_BUS(ha
->enq
);
5800 scb
->cmd
.basic_io
.lba
= 0;
5801 scb
->cmd
.basic_io
.sector_count
= 0;
5802 scb
->cmd
.basic_io
.log_drv
= 0;
5803 scb
->cmd
.basic_io
.reserved
= 0;
5806 if (((ret
= ips_send_wait(ha
, scb
, ips_cmd_timeout
, intr
)) == IPS_FAILURE
) ||
5807 (ret
== IPS_SUCCESS_IMM
) ||
5808 ((scb
->basic_status
& IPS_GSC_STATUS_MASK
) > 1))
5814 /****************************************************************************/
5816 /* Routine Name: ips_read_subsystem_parameters */
5818 /* Routine Description: */
5820 /* Read subsystem parameters from the adapter */
5822 /****************************************************************************/
5824 ips_read_subsystem_parameters(ips_ha_t
*ha
, int intr
) {
5828 METHOD_TRACE("ips_read_subsystem_parameters", 1);
5830 scb
= &ha
->scbs
[ha
->max_cmds
-1];
5832 ips_init_scb(ha
, scb
);
5834 scb
->timeout
= ips_cmd_timeout
;
5835 scb
->cdb
[0] = IPS_CMD_GET_SUBSYS
;
5837 scb
->cmd
.basic_io
.op_code
= IPS_CMD_GET_SUBSYS
;
5838 scb
->cmd
.basic_io
.command_id
= IPS_COMMAND_ID(ha
, scb
);
5839 scb
->cmd
.basic_io
.sg_count
= 0;
5840 scb
->cmd
.basic_io
.sg_addr
= VIRT_TO_BUS(ha
->subsys
);
5841 scb
->cmd
.basic_io
.lba
= 0;
5842 scb
->cmd
.basic_io
.sector_count
= 0;
5843 scb
->cmd
.basic_io
.log_drv
= 0;
5844 scb
->cmd
.basic_io
.reserved
= 0;
5847 if (((ret
= ips_send_wait(ha
, scb
, ips_cmd_timeout
, intr
)) == IPS_FAILURE
) ||
5848 (ret
== IPS_SUCCESS_IMM
) ||
5849 ((scb
->basic_status
& IPS_GSC_STATUS_MASK
) > 1))
5855 /****************************************************************************/
5857 /* Routine Name: ips_read_config */
5859 /* Routine Description: */
5861 /* Read the configuration on the adapter */
5863 /****************************************************************************/
5865 ips_read_config(ips_ha_t
*ha
, int intr
) {
5870 METHOD_TRACE("ips_read_config", 1);
5872 /* set defaults for initiator IDs */
5873 ha
->conf
->init_id
[0] = IPS_ADAPTER_ID
;
5874 for (i
= 1; i
< 4; i
++)
5875 ha
->conf
->init_id
[i
] = 7;
5877 scb
= &ha
->scbs
[ha
->max_cmds
-1];
5879 ips_init_scb(ha
, scb
);
5881 scb
->timeout
= ips_cmd_timeout
;
5882 scb
->cdb
[0] = IPS_CMD_READ_CONF
;
5884 scb
->cmd
.basic_io
.op_code
= IPS_CMD_READ_CONF
;
5885 scb
->cmd
.basic_io
.command_id
= IPS_COMMAND_ID(ha
, scb
);
5886 scb
->cmd
.basic_io
.sg_addr
= VIRT_TO_BUS(ha
->conf
);
5889 if (((ret
= ips_send_wait(ha
, scb
, ips_cmd_timeout
, intr
)) == IPS_FAILURE
) ||
5890 (ret
== IPS_SUCCESS_IMM
) ||
5891 ((scb
->basic_status
& IPS_GSC_STATUS_MASK
) > 1)) {
5893 memset(ha
->conf
, 0, sizeof(IPS_CONF
));
5895 /* reset initiator IDs */
5896 ha
->conf
->init_id
[0] = IPS_ADAPTER_ID
;
5897 for (i
= 1; i
< 4; i
++)
5898 ha
->conf
->init_id
[i
] = 7;
5906 /****************************************************************************/
5908 /* Routine Name: ips_readwrite_page5 */
5910 /* Routine Description: */
5912 /* Read nvram page 5 from the adapter */
5914 /****************************************************************************/
5916 ips_readwrite_page5(ips_ha_t
*ha
, int write
, int intr
) {
5920 METHOD_TRACE("ips_readwrite_page5", 1);
5922 scb
= &ha
->scbs
[ha
->max_cmds
-1];
5924 ips_init_scb(ha
, scb
);
5926 scb
->timeout
= ips_cmd_timeout
;
5927 scb
->cdb
[0] = IPS_CMD_RW_NVRAM_PAGE
;
5929 scb
->cmd
.nvram
.op_code
= IPS_CMD_RW_NVRAM_PAGE
;
5930 scb
->cmd
.nvram
.command_id
= IPS_COMMAND_ID(ha
, scb
);
5931 scb
->cmd
.nvram
.page
= 5;
5932 scb
->cmd
.nvram
.write
= write
;
5933 scb
->cmd
.nvram
.buffer_addr
= VIRT_TO_BUS(ha
->nvram
);
5934 scb
->cmd
.nvram
.reserved
= 0;
5935 scb
->cmd
.nvram
.reserved2
= 0;
5937 /* issue the command */
5938 if (((ret
= ips_send_wait(ha
, scb
, ips_cmd_timeout
, intr
)) == IPS_FAILURE
) ||
5939 (ret
== IPS_SUCCESS_IMM
) ||
5940 ((scb
->basic_status
& IPS_GSC_STATUS_MASK
) > 1)) {
5942 memset(ha
->nvram
, 0, sizeof(IPS_NVRAM_P5
));
5950 /****************************************************************************/
5952 /* Routine Name: ips_clear_adapter */
5954 /* Routine Description: */
5956 /* Clear the stripe lock tables */
5958 /****************************************************************************/
5960 ips_clear_adapter(ips_ha_t
*ha
, int intr
) {
5964 METHOD_TRACE("ips_clear_adapter", 1);
5966 scb
= &ha
->scbs
[ha
->max_cmds
-1];
5968 ips_init_scb(ha
, scb
);
5970 scb
->timeout
= ips_reset_timeout
;
5971 scb
->cdb
[0] = IPS_CMD_CONFIG_SYNC
;
5973 scb
->cmd
.config_sync
.op_code
= IPS_CMD_CONFIG_SYNC
;
5974 scb
->cmd
.config_sync
.command_id
= IPS_COMMAND_ID(ha
, scb
);
5975 scb
->cmd
.config_sync
.channel
= 0;
5976 scb
->cmd
.config_sync
.source_target
= IPS_POCL
;
5977 scb
->cmd
.config_sync
.reserved
= 0;
5978 scb
->cmd
.config_sync
.reserved2
= 0;
5979 scb
->cmd
.config_sync
.reserved3
= 0;
5982 if (((ret
= ips_send_wait(ha
, scb
, ips_reset_timeout
, intr
)) == IPS_FAILURE
) ||
5983 (ret
== IPS_SUCCESS_IMM
) ||
5984 ((scb
->basic_status
& IPS_GSC_STATUS_MASK
) > 1))
5987 /* send unlock stripe command */
5988 ips_init_scb(ha
, scb
);
5990 scb
->cdb
[0] = IPS_CMD_ERROR_TABLE
;
5991 scb
->timeout
= ips_reset_timeout
;
5993 scb
->cmd
.unlock_stripe
.op_code
= IPS_CMD_ERROR_TABLE
;
5994 scb
->cmd
.unlock_stripe
.command_id
= IPS_COMMAND_ID(ha
, scb
);
5995 scb
->cmd
.unlock_stripe
.log_drv
= 0;
5996 scb
->cmd
.unlock_stripe
.control
= IPS_CSL
;
5997 scb
->cmd
.unlock_stripe
.reserved
= 0;
5998 scb
->cmd
.unlock_stripe
.reserved2
= 0;
5999 scb
->cmd
.unlock_stripe
.reserved3
= 0;
6002 if (((ret
= ips_send_wait(ha
, scb
, ips_cmd_timeout
, intr
)) == IPS_FAILURE
) ||
6003 (ret
== IPS_SUCCESS_IMM
) ||
6004 ((scb
->basic_status
& IPS_GSC_STATUS_MASK
) > 1))
6010 /****************************************************************************/
6012 /* Routine Name: ips_ffdc_reset */
6014 /* Routine Description: */
6016 /* FFDC: write reset info */
6018 /****************************************************************************/
6020 ips_ffdc_reset(ips_ha_t
*ha
, int intr
) {
6023 METHOD_TRACE("ips_ffdc_reset", 1);
6025 scb
= &ha
->scbs
[ha
->max_cmds
-1];
6027 ips_init_scb(ha
, scb
);
6029 scb
->timeout
= ips_cmd_timeout
;
6030 scb
->cdb
[0] = IPS_CMD_FFDC
;
6031 scb
->cmd
.ffdc
.op_code
= IPS_CMD_FFDC
;
6032 scb
->cmd
.ffdc
.command_id
= IPS_COMMAND_ID(ha
, scb
);
6033 scb
->cmd
.ffdc
.reset_count
= ha
->reset_count
;
6034 scb
->cmd
.ffdc
.reset_type
= 0x80;
6036 /* convert time to what the card wants */
6037 ips_fix_ffdc_time(ha
, scb
, ha
->last_ffdc
);
6040 ips_send_wait(ha
, scb
, ips_cmd_timeout
, intr
);
6043 /****************************************************************************/
6045 /* Routine Name: ips_ffdc_time */
6047 /* Routine Description: */
6049 /* FFDC: write time info */
6051 /****************************************************************************/
6053 ips_ffdc_time(ips_ha_t
*ha
, int intr
) {
6056 METHOD_TRACE("ips_ffdc_time", 1);
6058 DEBUG_VAR(1, "(%s%d) Sending time update.",
6059 ips_name
, ha
->host_num
);
6061 scb
= &ha
->scbs
[ha
->max_cmds
-1];
6063 ips_init_scb(ha
, scb
);
6065 scb
->timeout
= ips_cmd_timeout
;
6066 scb
->cdb
[0] = IPS_CMD_FFDC
;
6067 scb
->cmd
.ffdc
.op_code
= IPS_CMD_FFDC
;
6068 scb
->cmd
.ffdc
.command_id
= IPS_COMMAND_ID(ha
, scb
);
6069 scb
->cmd
.ffdc
.reset_count
= 0;
6070 scb
->cmd
.ffdc
.reset_type
= 0x80;
6072 /* convert time to what the card wants */
6073 ips_fix_ffdc_time(ha
, scb
, ha
->last_ffdc
);
6076 ips_send_wait(ha
, scb
, ips_cmd_timeout
, intr
);
6079 /****************************************************************************/
6081 /* Routine Name: ips_fix_ffdc_time */
6083 /* Routine Description: */
6084 /* Adjust time_t to what the card wants */
6086 /****************************************************************************/
6088 ips_fix_ffdc_time(ips_ha_t
*ha
, ips_scb_t
*scb
, time_t current_time
) {
6094 int year_lengths
[2] = { IPS_DAYS_NORMAL_YEAR
, IPS_DAYS_LEAP_YEAR
};
6095 int month_lengths
[12][2] = { {31, 31},
6108 METHOD_TRACE("ips_fix_ffdc_time", 1);
6110 days
= current_time
/ IPS_SECS_DAY
;
6111 rem
= current_time
% IPS_SECS_DAY
;
6113 scb
->cmd
.ffdc
.hour
= (rem
/ IPS_SECS_HOUR
);
6114 rem
= rem
% IPS_SECS_HOUR
;
6115 scb
->cmd
.ffdc
.minute
= (rem
/ IPS_SECS_MIN
);
6116 scb
->cmd
.ffdc
.second
= (rem
% IPS_SECS_MIN
);
6118 year
= IPS_EPOCH_YEAR
;
6119 while (days
< 0 || days
>= year_lengths
[yleap
= IPS_IS_LEAP_YEAR(year
)]) {
6122 newy
= year
+ (days
/ IPS_DAYS_NORMAL_YEAR
);
6125 days
-= (newy
- year
) * IPS_DAYS_NORMAL_YEAR
+
6126 IPS_NUM_LEAP_YEARS_THROUGH(newy
- 1) -
6127 IPS_NUM_LEAP_YEARS_THROUGH(year
- 1);
6131 scb
->cmd
.ffdc
.yearH
= year
/ 100;
6132 scb
->cmd
.ffdc
.yearL
= year
% 100;
6134 for (i
= 0; days
>= month_lengths
[i
][yleap
]; ++i
)
6135 days
-= month_lengths
[i
][yleap
];
6137 scb
->cmd
.ffdc
.month
= i
+ 1;
6138 scb
->cmd
.ffdc
.day
= days
+ 1;
6141 /****************************************************************************
6142 * BIOS Flash Routines *
6143 ****************************************************************************/
6145 /****************************************************************************/
6147 /* Routine Name: ips_erase_bios */
6149 /* Routine Description: */
6150 /* Erase the BIOS on the adapter */
6152 /****************************************************************************/
6154 ips_erase_bios(ips_ha_t
*ha
) {
6158 METHOD_TRACE("ips_erase_bios", 1);
6160 /* Clear the status register */
6161 outl(0, ha
->io_addr
+ IPS_REG_FLAP
);
6162 if (ha
->revision_id
== IPS_REVID_TROMBONE64
)
6163 UDELAY(5); /* 5 us */
6165 outb(0x50, ha
->io_addr
+ IPS_REG_FLDP
);
6166 if (ha
->revision_id
== IPS_REVID_TROMBONE64
)
6167 UDELAY(5); /* 5 us */
6170 outb(0x20, ha
->io_addr
+ IPS_REG_FLDP
);
6171 if (ha
->revision_id
== IPS_REVID_TROMBONE64
)
6172 UDELAY(5); /* 5 us */
6175 outb(0xD0, ha
->io_addr
+ IPS_REG_FLDP
);
6176 if (ha
->revision_id
== IPS_REVID_TROMBONE64
)
6177 UDELAY(5); /* 5 us */
6180 outb(0x70, ha
->io_addr
+ IPS_REG_FLDP
);
6181 if (ha
->revision_id
== IPS_REVID_TROMBONE64
)
6182 UDELAY(5); /* 5 us */
6184 timeout
= 80000; /* 80 seconds */
6186 while (timeout
> 0) {
6187 if (ha
->revision_id
== IPS_REVID_TROMBONE64
) {
6188 outl(0, ha
->io_addr
+ IPS_REG_FLAP
);
6189 UDELAY(5); /* 5 us */
6192 status
= inb(ha
->io_addr
+ IPS_REG_FLDP
);
6201 /* check for timeout */
6205 /* try to suspend the erase */
6206 outb(0xB0, ha
->io_addr
+ IPS_REG_FLDP
);
6207 if (ha
->revision_id
== IPS_REVID_TROMBONE64
)
6208 UDELAY(5); /* 5 us */
6210 /* wait for 10 seconds */
6212 while (timeout
> 0) {
6213 if (ha
->revision_id
== IPS_REVID_TROMBONE64
) {
6214 outl(0, ha
->io_addr
+ IPS_REG_FLAP
);
6215 UDELAY(5); /* 5 us */
6218 status
= inb(ha
->io_addr
+ IPS_REG_FLDP
);
6230 /* check for valid VPP */
6235 /* check for succesful flash */
6237 /* sequence error */
6240 /* Otherwise, we were successful */
6242 outb(0x50, ha
->io_addr
+ IPS_REG_FLDP
);
6243 if (ha
->revision_id
== IPS_REVID_TROMBONE64
)
6244 UDELAY(5); /* 5 us */
6247 outb(0xFF, ha
->io_addr
+ IPS_REG_FLDP
);
6248 if (ha
->revision_id
== IPS_REVID_TROMBONE64
)
6249 UDELAY(5); /* 5 us */
6254 /****************************************************************************/
6256 /* Routine Name: ips_erase_bios_memio */
6258 /* Routine Description: */
6259 /* Erase the BIOS on the adapter */
6261 /****************************************************************************/
6263 ips_erase_bios_memio(ips_ha_t
*ha
) {
6267 METHOD_TRACE("ips_erase_bios_memio", 1);
6269 /* Clear the status register */
6270 writel(0, ha
->mem_ptr
+ IPS_REG_FLAP
);
6271 if (ha
->revision_id
== IPS_REVID_TROMBONE64
)
6272 UDELAY(5); /* 5 us */
6274 writeb(0x50, ha
->mem_ptr
+ IPS_REG_FLDP
);
6275 if (ha
->revision_id
== IPS_REVID_TROMBONE64
)
6276 UDELAY(5); /* 5 us */
6279 writeb(0x20, ha
->mem_ptr
+ IPS_REG_FLDP
);
6280 if (ha
->revision_id
== IPS_REVID_TROMBONE64
)
6281 UDELAY(5); /* 5 us */
6284 writeb(0xD0, ha
->mem_ptr
+ IPS_REG_FLDP
);
6285 if (ha
->revision_id
== IPS_REVID_TROMBONE64
)
6286 UDELAY(5); /* 5 us */
6289 writeb(0x70, ha
->mem_ptr
+ IPS_REG_FLDP
);
6290 if (ha
->revision_id
== IPS_REVID_TROMBONE64
)
6291 UDELAY(5); /* 5 us */
6293 timeout
= 80000; /* 80 seconds */
6295 while (timeout
> 0) {
6296 if (ha
->revision_id
== IPS_REVID_TROMBONE64
) {
6297 writel(0, ha
->mem_ptr
+ IPS_REG_FLAP
);
6298 UDELAY(5); /* 5 us */
6301 status
= readb(ha
->mem_ptr
+ IPS_REG_FLDP
);
6310 /* check for timeout */
6314 /* try to suspend the erase */
6315 writeb(0xB0, ha
->mem_ptr
+ IPS_REG_FLDP
);
6316 if (ha
->revision_id
== IPS_REVID_TROMBONE64
)
6317 UDELAY(5); /* 5 us */
6319 /* wait for 10 seconds */
6321 while (timeout
> 0) {
6322 if (ha
->revision_id
== IPS_REVID_TROMBONE64
) {
6323 writel(0, ha
->mem_ptr
+ IPS_REG_FLAP
);
6324 UDELAY(5); /* 5 us */
6327 status
= readb(ha
->mem_ptr
+ IPS_REG_FLDP
);
6339 /* check for valid VPP */
6344 /* check for succesful flash */
6346 /* sequence error */
6349 /* Otherwise, we were successful */
6351 writeb(0x50, ha
->mem_ptr
+ IPS_REG_FLDP
);
6352 if (ha
->revision_id
== IPS_REVID_TROMBONE64
)
6353 UDELAY(5); /* 5 us */
6356 writeb(0xFF, ha
->mem_ptr
+ IPS_REG_FLDP
);
6357 if (ha
->revision_id
== IPS_REVID_TROMBONE64
)
6358 UDELAY(5); /* 5 us */
6363 /****************************************************************************/
6365 /* Routine Name: ips_program_bios */
6367 /* Routine Description: */
6368 /* Program the BIOS on the adapter */
6370 /****************************************************************************/
6372 ips_program_bios(ips_ha_t
*ha
, char *buffer
, int buffersize
) {
6377 METHOD_TRACE("ips_program_bios", 1);
6379 for (i
= 0; i
< buffersize
; i
++) {
6381 outl(i
, ha
->io_addr
+ IPS_REG_FLAP
);
6382 if (ha
->revision_id
== IPS_REVID_TROMBONE64
)
6383 UDELAY(5); /* 5 us */
6385 outb(0x40, ha
->io_addr
+ IPS_REG_FLDP
);
6386 if (ha
->revision_id
== IPS_REVID_TROMBONE64
)
6387 UDELAY(5); /* 5 us */
6389 outb(buffer
[i
], ha
->io_addr
+ IPS_REG_FLDP
);
6390 if (ha
->revision_id
== IPS_REVID_TROMBONE64
)
6391 UDELAY(5); /* 5 us */
6393 /* wait up to one second */
6395 while (timeout
> 0) {
6396 if (ha
->revision_id
== IPS_REVID_TROMBONE64
) {
6397 outl(0, ha
->io_addr
+ IPS_REG_FLAP
);
6398 UDELAY(5); /* 5 us */
6401 status
= inb(ha
->io_addr
+ IPS_REG_FLDP
);
6412 outl(0, ha
->io_addr
+ IPS_REG_FLAP
);
6413 if (ha
->revision_id
== IPS_REVID_TROMBONE64
)
6414 UDELAY(5); /* 5 us */
6416 outb(0xFF, ha
->io_addr
+ IPS_REG_FLDP
);
6417 if (ha
->revision_id
== IPS_REVID_TROMBONE64
)
6418 UDELAY(5); /* 5 us */
6423 /* check the status */
6424 if (status
& 0x18) {
6425 /* programming error */
6426 outl(0, ha
->io_addr
+ IPS_REG_FLAP
);
6427 if (ha
->revision_id
== IPS_REVID_TROMBONE64
)
6428 UDELAY(5); /* 5 us */
6430 outb(0xFF, ha
->io_addr
+ IPS_REG_FLDP
);
6431 if (ha
->revision_id
== IPS_REVID_TROMBONE64
)
6432 UDELAY(5); /* 5 us */
6438 /* Enable reading */
6439 outl(0, ha
->io_addr
+ IPS_REG_FLAP
);
6440 if (ha
->revision_id
== IPS_REVID_TROMBONE64
)
6441 UDELAY(5); /* 5 us */
6443 outb(0xFF, ha
->io_addr
+ IPS_REG_FLDP
);
6444 if (ha
->revision_id
== IPS_REVID_TROMBONE64
)
6445 UDELAY(5); /* 5 us */
6450 /****************************************************************************/
6452 /* Routine Name: ips_program_bios_memio */
6454 /* Routine Description: */
6455 /* Program the BIOS on the adapter */
6457 /****************************************************************************/
6459 ips_program_bios_memio(ips_ha_t
*ha
, char *buffer
, int buffersize
) {
6464 METHOD_TRACE("ips_program_bios_memio", 1);
6466 for (i
= 0; i
< buffersize
; i
++) {
6468 writel(i
, ha
->mem_ptr
+ IPS_REG_FLAP
);
6469 if (ha
->revision_id
== IPS_REVID_TROMBONE64
)
6470 UDELAY(5); /* 5 us */
6472 writeb(0x40, ha
->mem_ptr
+ IPS_REG_FLDP
);
6473 if (ha
->revision_id
== IPS_REVID_TROMBONE64
)
6474 UDELAY(5); /* 5 us */
6476 writeb(buffer
[i
], ha
->mem_ptr
+ IPS_REG_FLDP
);
6477 if (ha
->revision_id
== IPS_REVID_TROMBONE64
)
6478 UDELAY(5); /* 5 us */
6480 /* wait up to one second */
6482 while (timeout
> 0) {
6483 if (ha
->revision_id
== IPS_REVID_TROMBONE64
) {
6484 writel(0, ha
->mem_ptr
+ IPS_REG_FLAP
);
6485 UDELAY(5); /* 5 us */
6488 status
= readb(ha
->mem_ptr
+ IPS_REG_FLDP
);
6499 writel(0, ha
->mem_ptr
+ IPS_REG_FLAP
);
6500 if (ha
->revision_id
== IPS_REVID_TROMBONE64
)
6501 UDELAY(5); /* 5 us */
6503 writeb(0xFF, ha
->mem_ptr
+ IPS_REG_FLDP
);
6504 if (ha
->revision_id
== IPS_REVID_TROMBONE64
)
6505 UDELAY(5); /* 5 us */
6510 /* check the status */
6511 if (status
& 0x18) {
6512 /* programming error */
6513 writel(0, ha
->mem_ptr
+ IPS_REG_FLAP
);
6514 if (ha
->revision_id
== IPS_REVID_TROMBONE64
)
6515 UDELAY(5); /* 5 us */
6517 writeb(0xFF, ha
->mem_ptr
+ IPS_REG_FLDP
);
6518 if (ha
->revision_id
== IPS_REVID_TROMBONE64
)
6519 UDELAY(5); /* 5 us */
6525 /* Enable reading */
6526 writel(0, ha
->mem_ptr
+ IPS_REG_FLAP
);
6527 if (ha
->revision_id
== IPS_REVID_TROMBONE64
)
6528 UDELAY(5); /* 5 us */
6530 writeb(0xFF, ha
->mem_ptr
+ IPS_REG_FLDP
);
6531 if (ha
->revision_id
== IPS_REVID_TROMBONE64
)
6532 UDELAY(5); /* 5 us */
6537 /****************************************************************************/
6539 /* Routine Name: ips_verify_bios */
6541 /* Routine Description: */
6542 /* Verify the BIOS on the adapter */
6544 /****************************************************************************/
6546 ips_verify_bios(ips_ha_t
*ha
, char *buffer
, int buffersize
) {
6550 METHOD_TRACE("ips_verify_bios", 1);
6553 outl(0, ha
->io_addr
+ IPS_REG_FLAP
);
6554 if (ha
->revision_id
== IPS_REVID_TROMBONE64
)
6555 UDELAY(5); /* 5 us */
6557 if (inb(ha
->io_addr
+ IPS_REG_FLDP
) != 0x55)
6560 outl(1, ha
->io_addr
+ IPS_REG_FLAP
);
6561 if (ha
->revision_id
== IPS_REVID_TROMBONE64
)
6562 UDELAY(5); /* 5 us */
6563 if (inb(ha
->io_addr
+ IPS_REG_FLDP
) != 0xAA)
6567 for (i
= 2; i
< buffersize
; i
++) {
6569 outl(i
, ha
->io_addr
+ IPS_REG_FLAP
);
6570 if (ha
->revision_id
== IPS_REVID_TROMBONE64
)
6571 UDELAY(5); /* 5 us */
6573 checksum
= (u8
) checksum
+ inb(ha
->io_addr
+ IPS_REG_FLDP
);
6584 /****************************************************************************/
6586 /* Routine Name: ips_verify_bios_memio */
6588 /* Routine Description: */
6589 /* Verify the BIOS on the adapter */
6591 /****************************************************************************/
6593 ips_verify_bios_memio(ips_ha_t
*ha
, char *buffer
, int buffersize
) {
6597 METHOD_TRACE("ips_verify_bios_memio", 1);
6600 writel(0, ha
->mem_ptr
+ IPS_REG_FLAP
);
6601 if (ha
->revision_id
== IPS_REVID_TROMBONE64
)
6602 UDELAY(5); /* 5 us */
6604 if (readb(ha
->mem_ptr
+ IPS_REG_FLDP
) != 0x55)
6607 writel(1, ha
->mem_ptr
+ IPS_REG_FLAP
);
6608 if (ha
->revision_id
== IPS_REVID_TROMBONE64
)
6609 UDELAY(5); /* 5 us */
6610 if (readb(ha
->mem_ptr
+ IPS_REG_FLDP
) != 0xAA)
6614 for (i
= 2; i
< buffersize
; i
++) {
6616 writel(i
, ha
->mem_ptr
+ IPS_REG_FLAP
);
6617 if (ha
->revision_id
== IPS_REVID_TROMBONE64
)
6618 UDELAY(5); /* 5 us */
6620 checksum
= (u8
) checksum
+ readb(ha
->mem_ptr
+ IPS_REG_FLDP
);
6631 static Scsi_Host_Template driver_template
= IPS
;
6632 #include "scsi_module.c"
6637 * Overrides for Emacs so that we almost follow Linus's tabbing style.
6638 * Emacs will notice this stuff at the end of the file and automatically
6639 * adjust the settings for this buffer only. This must remain at the end
6641 * ---------------------------------------------------------------------------
6644 * c-brace-imaginary-offset: 0
6645 * c-brace-offset: -2
6646 * c-argdecl-indent: 2
6647 * c-label-offset: -2
6648 * c-continued-statement-offset: 2
6649 * c-continued-brace-offset: 0
6650 * indent-tabs-mode: nil