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