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