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