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