blob: 78f2ff736c3eccfb2b9042a9229e040c72dd3f9d [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*****************************************************************************/
2/* ips.c -- driver for the Adaptec / IBM ServeRAID controller */
3/* */
4/* Written By: Keith Mitchell, IBM Corporation */
5/* Jack Hammer, Adaptec, Inc. */
6/* David Jeffery, Adaptec, Inc. */
7/* */
8/* Copyright (C) 2000 IBM Corporation */
9/* Copyright (C) 2002,2003 Adaptec, Inc. */
10/* */
11/* This program is free software; you can redistribute it and/or modify */
12/* it under the terms of the GNU General Public License as published by */
13/* the Free Software Foundation; either version 2 of the License, or */
14/* (at your option) any later version. */
15/* */
16/* This program is distributed in the hope that it will be useful, */
17/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
18/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
19/* GNU General Public License for more details. */
20/* */
21/* NO WARRANTY */
22/* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR */
23/* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT */
24/* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, */
25/* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is */
26/* solely responsible for determining the appropriateness of using and */
27/* distributing the Program and assumes all risks associated with its */
28/* exercise of rights under this Agreement, including but not limited to */
29/* the risks and costs of program errors, damage to or loss of data, */
30/* programs or equipment, and unavailability or interruption of operations. */
31/* */
32/* DISCLAIMER OF LIABILITY */
33/* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY */
34/* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL */
35/* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND */
36/* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR */
37/* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE */
38/* USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED */
39/* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES */
40/* */
41/* You should have received a copy of the GNU General Public License */
42/* along with this program; if not, write to the Free Software */
43/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
44/* */
45/* Bugs/Comments/Suggestions about this driver should be mailed to: */
46/* ipslinux@adaptec.com */
47/* */
48/* For system support issues, contact your local IBM Customer support. */
49/* Directions to find IBM Customer Support for each country can be found at: */
50/* http://www.ibm.com/planetwide/ */
51/* */
52/*****************************************************************************/
53
54/*****************************************************************************/
55/* Change Log */
56/* */
57/* 0.99.02 - Breakup commands that are bigger than 8 * the stripe size */
58/* 0.99.03 - Make interrupt routine handle all completed request on the */
59/* adapter not just the first one */
60/* - Make sure passthru commands get woken up if we run out of */
61/* SCBs */
62/* - Send all of the commands on the queue at once rather than */
63/* one at a time since the card will support it. */
64/* 0.99.04 - Fix race condition in the passthru mechanism -- this required */
65/* the interface to the utilities to change */
66/* - Fix error recovery code */
67/* 0.99.05 - Fix an oops when we get certain passthru commands */
68/* 1.00.00 - Initial Public Release */
69/* Functionally equivalent to 0.99.05 */
70/* 3.60.00 - Bump max commands to 128 for use with firmware 3.60 */
71/* - Change version to 3.60 to coincide with release numbering. */
72/* 3.60.01 - Remove bogus error check in passthru routine */
73/* 3.60.02 - Make DCDB direction based on lookup table */
74/* - Only allow one DCDB command to a SCSI ID at a time */
75/* 4.00.00 - Add support for ServeRAID 4 */
76/* 4.00.01 - Add support for First Failure Data Capture */
77/* 4.00.02 - Fix problem with PT DCDB with no buffer */
78/* 4.00.03 - Add alternative passthru interface */
79/* - Add ability to flash BIOS */
80/* 4.00.04 - Rename structures/constants to be prefixed with IPS_ */
81/* 4.00.05 - Remove wish_block from init routine */
82/* - Use linux/spinlock.h instead of asm/spinlock.h for kernels */
83/* 2.3.18 and later */
84/* - Sync with other changes from the 2.3 kernels */
85/* 4.00.06 - Fix timeout with initial FFDC command */
86/* 4.00.06a - Port to 2.4 (trivial) -- Christoph Hellwig <hch@infradead.org> */
87/* 4.10.00 - Add support for ServeRAID 4M/4L */
88/* 4.10.13 - Fix for dynamic unload and proc file system */
89/* 4.20.03 - Rename version to coincide with new release schedules */
90/* Performance fixes */
91/* Fix truncation of /proc files with cat */
92/* Merge in changes through kernel 2.4.0test1ac21 */
93/* 4.20.13 - Fix some failure cases / reset code */
94/* - Hook into the reboot_notifier to flush the controller cache */
95/* 4.50.01 - Fix problem when there is a hole in logical drive numbering */
96/* 4.70.09 - Use a Common ( Large Buffer ) for Flashing from the JCRM CD */
97/* - Add IPSSEND Flash Support */
98/* - Set Sense Data for Unknown SCSI Command */
99/* - Use Slot Number from NVRAM Page 5 */
100/* - Restore caller's DCDB Structure */
101/* 4.70.12 - Corrective actions for bad controller ( during initialization )*/
102/* 4.70.13 - Don't Send CDB's if we already know the device is not present */
103/* - Don't release HA Lock in ips_next() until SC taken off queue */
104/* - Unregister SCSI device in ips_release() */
105/* 4.70.15 - Fix Breakup for very large ( non-SG ) requests in ips_done() */
106/* 4.71.00 - Change all memory allocations to not use GFP_DMA flag */
107/* Code Clean-Up for 2.4.x kernel */
108/* 4.72.00 - Allow for a Scatter-Gather Element to exceed MAX_XFER Size */
109/* 4.72.01 - I/O Mapped Memory release ( so "insmod ips" does not Fail ) */
110/* - Don't Issue Internal FFDC Command if there are Active Commands */
111/* - Close Window for getting too many IOCTL's active */
112/* 4.80.00 - Make ia64 Safe */
113/* 4.80.04 - Eliminate calls to strtok() if 2.4.x or greater */
114/* - Adjustments to Device Queue Depth */
115/* 4.80.14 - Take all semaphores off stack */
116/* - Clean Up New_IOCTL path */
117/* 4.80.20 - Set max_sectors in Scsi_Host structure ( if >= 2.4.7 kernel ) */
118/* - 5 second delay needed after resetting an i960 adapter */
119/* 4.80.26 - Clean up potential code problems ( Arjan's recommendations ) */
120/* 4.90.01 - Version Matching for FirmWare, BIOS, and Driver */
121/* 4.90.05 - Use New PCI Architecture to facilitate Hot Plug Development */
122/* 4.90.08 - Increase Delays in Flashing ( Trombone Only - 4H ) */
123/* 4.90.08 - Data Corruption if First Scatter Gather Element is > 64K */
124/* 4.90.11 - Don't actually RESET unless it's physically required */
125/* - Remove unused compile options */
126/* 5.00.01 - Sarasota ( 5i ) adapters must always be scanned first */
127/* - Get rid on IOCTL_NEW_COMMAND code */
128/* - Add Extended DCDB Commands for Tape Support in 5I */
129/* 5.10.12 - use pci_dma interfaces, update for 2.5 kernel changes */
130/* 5.10.15 - remove unused code (sem, macros, etc.) */
131/* 5.30.00 - use __devexit_p() */
132/* 6.00.00 - Add 6x Adapters and Battery Flash */
133/* 6.10.00 - Remove 1G Addressing Limitations */
134/* 6.11.xx - Get VersionInfo buffer off the stack ! DDTS 60401 */
135/* 6.11.xx - Make Logical Drive Info structure safe for DMA DDTS 60639 */
Jack Hammerc1a15462005-07-26 10:20:33 -0400136/* 7.10.18 - Add highmem_io flag in SCSI Templete for 2.4 kernels */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700137/* - Fix path/name for scsi_hosts.h include for 2.6 kernels */
138/* - Fix sort order of 7k */
139/* - Remove 3 unused "inline" functions */
Jack Hammerc1a15462005-07-26 10:20:33 -0400140/* 7.12.xx - Use STATIC functions whereever possible */
141/* - Clean up deprecated MODULE_PARM calls */
Jack Hammera60768e2005-11-03 09:46:00 -0500142/* 7.12.05 - Remove Version Matching per IBM request */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700143/*****************************************************************************/
144
145/*
146 * Conditional Compilation directives for this driver:
147 *
148 * IPS_DEBUG - Turn on debugging info
149 *
150 * Parameters:
151 *
152 * debug:<number> - Set debug level to <number>
153 * NOTE: only works when IPS_DEBUG compile directive is used.
154 * 1 - Normal debug messages
155 * 2 - Verbose debug messages
156 * 11 - Method trace (non interrupt)
157 * 12 - Method trace (includes interrupt)
158 *
159 * noi2o - Don't use I2O Queues (ServeRAID 4 only)
160 * nommap - Don't use memory mapped I/O
161 * ioctlsize - Initial size of the IOCTL buffer
162 */
163
164#include <asm/io.h>
165#include <asm/byteorder.h>
166#include <asm/page.h>
167#include <linux/stddef.h>
168#include <linux/version.h>
169#include <linux/string.h>
170#include <linux/errno.h>
171#include <linux/kernel.h>
172#include <linux/ioport.h>
173#include <linux/slab.h>
174#include <linux/delay.h>
175#include <linux/pci.h>
176#include <linux/proc_fs.h>
177#include <linux/reboot.h>
178#include <linux/interrupt.h>
179
180#include <linux/blkdev.h>
181#include <linux/types.h>
Matthias Gehre910638a2006-03-28 01:56:48 -0800182#include <linux/dma-mapping.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700183
184#include <scsi/sg.h>
185
186#include "scsi.h"
187
188#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
189#include "hosts.h"
190#else
191#include <scsi/scsi_host.h>
192#endif
193
194#include "ips.h"
195
196#include <linux/module.h>
197
198#include <linux/stat.h>
199#include <linux/config.h>
200
201#include <linux/spinlock.h>
202#include <linux/init.h>
203
204#include <linux/smp.h>
205
206#ifdef MODULE
207static char *ips = NULL;
208module_param(ips, charp, 0);
209#endif
210
211/*
212 * DRIVER_VER
213 */
Jack Hammerc1a15462005-07-26 10:20:33 -0400214#define IPS_VERSION_HIGH "7.12"
Jack Hammera60768e2005-11-03 09:46:00 -0500215#define IPS_VERSION_LOW ".05 "
Linus Torvalds1da177e2005-04-16 15:20:36 -0700216
217#if !defined(__i386__) && !defined(__ia64__) && !defined(__x86_64__)
218#warning "This driver has only been tested on the x86/ia64/x86_64 platforms"
219#endif
220
221#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
222#include <linux/blk.h>
223#include "sd.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224#define IPS_LOCK_SAVE(lock,flags) spin_lock_irqsave(&io_request_lock,flags)
225#define IPS_UNLOCK_RESTORE(lock,flags) spin_unlock_irqrestore(&io_request_lock,flags)
226#ifndef __devexit_p
227#define __devexit_p(x) x
228#endif
229#else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700230#define IPS_LOCK_SAVE(lock,flags) do{spin_lock(lock);(void)flags;}while(0)
231#define IPS_UNLOCK_RESTORE(lock,flags) do{spin_unlock(lock);(void)flags;}while(0)
232#endif
233
234#define IPS_DMA_DIR(scb) ((!scb->scsi_cmd || ips_is_passthru(scb->scsi_cmd) || \
be7db052005-04-17 15:26:13 -0500235 DMA_NONE == scb->scsi_cmd->sc_data_direction) ? \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700236 PCI_DMA_BIDIRECTIONAL : \
be7db052005-04-17 15:26:13 -0500237 scb->scsi_cmd->sc_data_direction)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700238
239#ifdef IPS_DEBUG
240#define METHOD_TRACE(s, i) if (ips_debug >= (i+10)) printk(KERN_NOTICE s "\n");
241#define DEBUG(i, s) if (ips_debug >= i) printk(KERN_NOTICE s "\n");
242#define DEBUG_VAR(i, s, v...) if (ips_debug >= i) printk(KERN_NOTICE s "\n", v);
243#else
244#define METHOD_TRACE(s, i)
245#define DEBUG(i, s)
246#define DEBUG_VAR(i, s, v...)
247#endif
248
249/*
250 * Function prototypes
251 */
Christoph Hellwigd0be4a7d2005-10-31 18:31:40 +0100252static int ips_detect(struct scsi_host_template *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700253static int ips_release(struct Scsi_Host *);
254static int ips_eh_abort(Scsi_Cmnd *);
255static int ips_eh_reset(Scsi_Cmnd *);
256static int ips_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *));
257static const char *ips_info(struct Scsi_Host *);
258static irqreturn_t do_ipsintr(int, void *, struct pt_regs *);
259static int ips_hainit(ips_ha_t *);
260static int ips_map_status(ips_ha_t *, ips_scb_t *, ips_stat_t *);
261static int ips_send_wait(ips_ha_t *, ips_scb_t *, int, int);
262static int ips_send_cmd(ips_ha_t *, ips_scb_t *);
263static int ips_online(ips_ha_t *, ips_scb_t *);
264static int ips_inquiry(ips_ha_t *, ips_scb_t *);
265static int ips_rdcap(ips_ha_t *, ips_scb_t *);
266static int ips_msense(ips_ha_t *, ips_scb_t *);
267static int ips_reqsen(ips_ha_t *, ips_scb_t *);
268static int ips_deallocatescbs(ips_ha_t *, int);
269static int ips_allocatescbs(ips_ha_t *);
270static int ips_reset_copperhead(ips_ha_t *);
271static int ips_reset_copperhead_memio(ips_ha_t *);
272static int ips_reset_morpheus(ips_ha_t *);
273static int ips_issue_copperhead(ips_ha_t *, ips_scb_t *);
274static int ips_issue_copperhead_memio(ips_ha_t *, ips_scb_t *);
275static int ips_issue_i2o(ips_ha_t *, ips_scb_t *);
276static int ips_issue_i2o_memio(ips_ha_t *, ips_scb_t *);
277static int ips_isintr_copperhead(ips_ha_t *);
278static int ips_isintr_copperhead_memio(ips_ha_t *);
279static int ips_isintr_morpheus(ips_ha_t *);
280static int ips_wait(ips_ha_t *, int, int);
281static int ips_write_driver_status(ips_ha_t *, int);
282static int ips_read_adapter_status(ips_ha_t *, int);
283static int ips_read_subsystem_parameters(ips_ha_t *, int);
284static int ips_read_config(ips_ha_t *, int);
285static int ips_clear_adapter(ips_ha_t *, int);
286static int ips_readwrite_page5(ips_ha_t *, int, int);
287static int ips_init_copperhead(ips_ha_t *);
288static int ips_init_copperhead_memio(ips_ha_t *);
289static int ips_init_morpheus(ips_ha_t *);
290static int ips_isinit_copperhead(ips_ha_t *);
291static int ips_isinit_copperhead_memio(ips_ha_t *);
292static int ips_isinit_morpheus(ips_ha_t *);
293static int ips_erase_bios(ips_ha_t *);
294static int ips_program_bios(ips_ha_t *, char *, uint32_t, uint32_t);
295static int ips_verify_bios(ips_ha_t *, char *, uint32_t, uint32_t);
296static int ips_erase_bios_memio(ips_ha_t *);
297static int ips_program_bios_memio(ips_ha_t *, char *, uint32_t, uint32_t);
298static int ips_verify_bios_memio(ips_ha_t *, char *, uint32_t, uint32_t);
299static int ips_flash_copperhead(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
300static int ips_flash_bios(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
301static int ips_flash_firmware(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
302static void ips_free_flash_copperhead(ips_ha_t * ha);
303static void ips_get_bios_version(ips_ha_t *, int);
304static void ips_identify_controller(ips_ha_t *);
305static void ips_chkstatus(ips_ha_t *, IPS_STATUS *);
306static void ips_enable_int_copperhead(ips_ha_t *);
307static void ips_enable_int_copperhead_memio(ips_ha_t *);
308static void ips_enable_int_morpheus(ips_ha_t *);
309static int ips_intr_copperhead(ips_ha_t *);
310static int ips_intr_morpheus(ips_ha_t *);
311static void ips_next(ips_ha_t *, int);
312static void ipsintr_blocking(ips_ha_t *, struct ips_scb *);
313static void ipsintr_done(ips_ha_t *, struct ips_scb *);
314static void ips_done(ips_ha_t *, ips_scb_t *);
315static void ips_free(ips_ha_t *);
316static void ips_init_scb(ips_ha_t *, ips_scb_t *);
317static void ips_freescb(ips_ha_t *, ips_scb_t *);
318static void ips_setup_funclist(ips_ha_t *);
319static void ips_statinit(ips_ha_t *);
320static void ips_statinit_memio(ips_ha_t *);
321static void ips_fix_ffdc_time(ips_ha_t *, ips_scb_t *, time_t);
322static void ips_ffdc_reset(ips_ha_t *, int);
323static void ips_ffdc_time(ips_ha_t *);
324static uint32_t ips_statupd_copperhead(ips_ha_t *);
325static uint32_t ips_statupd_copperhead_memio(ips_ha_t *);
326static uint32_t ips_statupd_morpheus(ips_ha_t *);
327static ips_scb_t *ips_getscb(ips_ha_t *);
328static void ips_putq_scb_head(ips_scb_queue_t *, ips_scb_t *);
329static void ips_putq_wait_tail(ips_wait_queue_t *, Scsi_Cmnd *);
330static void ips_putq_copp_tail(ips_copp_queue_t *,
331 ips_copp_wait_item_t *);
332static ips_scb_t *ips_removeq_scb_head(ips_scb_queue_t *);
333static ips_scb_t *ips_removeq_scb(ips_scb_queue_t *, ips_scb_t *);
334static Scsi_Cmnd *ips_removeq_wait_head(ips_wait_queue_t *);
335static Scsi_Cmnd *ips_removeq_wait(ips_wait_queue_t *, Scsi_Cmnd *);
336static ips_copp_wait_item_t *ips_removeq_copp(ips_copp_queue_t *,
337 ips_copp_wait_item_t *);
338static ips_copp_wait_item_t *ips_removeq_copp_head(ips_copp_queue_t *);
339
340static int ips_is_passthru(Scsi_Cmnd *);
341static int ips_make_passthru(ips_ha_t *, Scsi_Cmnd *, ips_scb_t *, int);
342static int ips_usrcmd(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
343static void ips_cleanup_passthru(ips_ha_t *, ips_scb_t *);
344static void ips_scmd_buf_write(Scsi_Cmnd * scmd, void *data,
345 unsigned int count);
346static void ips_scmd_buf_read(Scsi_Cmnd * scmd, void *data, unsigned int count);
347
348static int ips_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);
349static int ips_host_info(ips_ha_t *, char *, off_t, int);
350static void copy_mem_info(IPS_INFOSTR *, char *, int);
351static int copy_info(IPS_INFOSTR *, char *, ...);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700352static int ips_abort_init(ips_ha_t * ha, int index);
353static int ips_init_phase2(int index);
354
355static int ips_init_phase1(struct pci_dev *pci_dev, int *indexPtr);
356static int ips_register_scsi(int index);
357
Jack Hammeree807c22005-08-29 10:44:34 -0400358static int ips_poll_for_flush_complete(ips_ha_t * ha);
359static void ips_flush_and_reset(ips_ha_t *ha);
360
Linus Torvalds1da177e2005-04-16 15:20:36 -0700361/*
362 * global variables
363 */
364static const char ips_name[] = "ips";
365static struct Scsi_Host *ips_sh[IPS_MAX_ADAPTERS]; /* Array of host controller structures */
366static ips_ha_t *ips_ha[IPS_MAX_ADAPTERS]; /* Array of HA structures */
367static unsigned int ips_next_controller;
368static unsigned int ips_num_controllers;
369static unsigned int ips_released_controllers;
370static int ips_hotplug;
371static int ips_cmd_timeout = 60;
372static int ips_reset_timeout = 60 * 5;
373static int ips_force_memio = 1; /* Always use Memory Mapped I/O */
374static int ips_force_i2o = 1; /* Always use I2O command delivery */
375static int ips_ioctlsize = IPS_IOCTL_SIZE; /* Size of the ioctl buffer */
376static int ips_cd_boot; /* Booting from Manager CD */
377static char *ips_FlashData = NULL; /* CD Boot - Flash Data Buffer */
378static dma_addr_t ips_flashbusaddr;
379static long ips_FlashDataInUse; /* CD Boot - Flash Data In Use Flag */
380static uint32_t MaxLiteCmds = 32; /* Max Active Cmds for a Lite Adapter */
Christoph Hellwigd0be4a7d2005-10-31 18:31:40 +0100381static struct scsi_host_template ips_driver_template = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700382 .detect = ips_detect,
383 .release = ips_release,
384 .info = ips_info,
385 .queuecommand = ips_queue,
386 .eh_abort_handler = ips_eh_abort,
387 .eh_host_reset_handler = ips_eh_reset,
388 .proc_name = "ips",
389#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
390 .proc_info = ips_proc_info,
391 .slave_configure = ips_slave_configure,
392#else
393 .proc_info = ips_proc24_info,
394 .select_queue_depths = ips_select_queue_depth,
395#endif
396 .bios_param = ips_biosparam,
397 .this_id = -1,
398 .sg_tablesize = IPS_MAX_SG,
399 .cmd_per_lun = 3,
400 .use_clustering = ENABLE_CLUSTERING,
401#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
402 .use_new_eh_code = 1,
403#endif
404#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) && LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
405 .highmem_io = 1,
406#endif
407};
408
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409
410/* This table describes all ServeRAID Adapters */
411static struct pci_device_id ips_pci_table[] = {
412 { 0x1014, 0x002E, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
413 { 0x1014, 0x01BD, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
414 { 0x9005, 0x0250, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
415 { 0, }
416};
417
418MODULE_DEVICE_TABLE( pci, ips_pci_table );
419
420static char ips_hot_plug_name[] = "ips";
421
422static int __devinit ips_insert_device(struct pci_dev *pci_dev, const struct pci_device_id *ent);
423static void __devexit ips_remove_device(struct pci_dev *pci_dev);
424
425static struct pci_driver ips_pci_driver = {
426 .name = ips_hot_plug_name,
427 .id_table = ips_pci_table,
428 .probe = ips_insert_device,
429 .remove = __devexit_p(ips_remove_device),
430};
431
432
433/*
434 * Necessary forward function protoypes
435 */
436static int ips_halt(struct notifier_block *nb, ulong event, void *buf);
437
438#define MAX_ADAPTER_NAME 15
439
440static char ips_adapter_name[][30] = {
441 "ServeRAID",
442 "ServeRAID II",
443 "ServeRAID on motherboard",
444 "ServeRAID on motherboard",
445 "ServeRAID 3H",
446 "ServeRAID 3L",
447 "ServeRAID 4H",
448 "ServeRAID 4M",
449 "ServeRAID 4L",
450 "ServeRAID 4Mx",
451 "ServeRAID 4Lx",
452 "ServeRAID 5i",
453 "ServeRAID 5i",
454 "ServeRAID 6M",
455 "ServeRAID 6i",
456 "ServeRAID 7t",
457 "ServeRAID 7k",
458 "ServeRAID 7M"
459};
460
461static struct notifier_block ips_notifier = {
462 ips_halt, NULL, 0
463};
464
465/*
466 * Direction table
467 */
468static char ips_command_direction[] = {
469 IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT,
470 IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK,
471 IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
472 IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_OUT,
473 IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_OUT,
474 IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_OUT,
475 IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_IN,
476 IPS_DATA_UNK, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK,
477 IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_UNK,
478 IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT,
479 IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_NONE,
480 IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT,
481 IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT,
482 IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_NONE,
483 IPS_DATA_UNK, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_UNK,
484 IPS_DATA_NONE, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK,
485 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
486 IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
487 IPS_DATA_IN, 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_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
502 IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_NONE,
503 IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_OUT,
504 IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_NONE,
505 IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_IN,
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_UNK,
515 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_OUT,
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 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK
520};
521
522
523/****************************************************************************/
524/* */
525/* Routine Name: ips_setup */
526/* */
527/* Routine Description: */
528/* */
529/* setup parameters to the driver */
530/* */
531/****************************************************************************/
532static int
533ips_setup(char *ips_str)
534{
535
536 int i;
537 char *key;
538 char *value;
539 IPS_OPTION options[] = {
540 {"noi2o", &ips_force_i2o, 0},
541 {"nommap", &ips_force_memio, 0},
542 {"ioctlsize", &ips_ioctlsize, IPS_IOCTL_SIZE},
543 {"cdboot", &ips_cd_boot, 0},
544 {"maxcmds", &MaxLiteCmds, 32},
545 };
546
547 /* Don't use strtok() anymore ( if 2.4 Kernel or beyond ) */
548 /* Search for value */
549 while ((key = strsep(&ips_str, ",."))) {
550 if (!*key)
551 continue;
552 value = strchr(key, ':');
553 if (value)
554 *value++ = '\0';
555 /*
556 * We now have key/value pairs.
557 * Update the variables
558 */
Tobias Klauser6391a112006-06-08 22:23:48 -0700559 for (i = 0; i < ARRAY_SIZE(options); i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700560 if (strnicmp
561 (key, options[i].option_name,
562 strlen(options[i].option_name)) == 0) {
563 if (value)
564 *options[i].option_flag =
565 simple_strtoul(value, NULL, 0);
566 else
567 *options[i].option_flag =
568 options[i].option_value;
569 break;
570 }
571 }
572 }
573
574 return (1);
575}
576
577__setup("ips=", ips_setup);
578
579/****************************************************************************/
580/* */
581/* Routine Name: ips_detect */
582/* */
583/* Routine Description: */
584/* */
585/* Detect and initialize the driver */
586/* */
587/* NOTE: this routine is called under the io_request_lock spinlock */
588/* */
589/****************************************************************************/
590static int
Christoph Hellwigd0be4a7d2005-10-31 18:31:40 +0100591ips_detect(struct scsi_host_template * SHT)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700592{
593 int i;
594
595 METHOD_TRACE("ips_detect", 1);
596
597#ifdef MODULE
598 if (ips)
599 ips_setup(ips);
600#endif
601
602 for (i = 0; i < ips_num_controllers; i++) {
603 if (ips_register_scsi(i))
604 ips_free(ips_ha[i]);
605 ips_released_controllers++;
606 }
607 ips_hotplug = 1;
608 return (ips_num_controllers);
609}
610
611/****************************************************************************/
612/* configure the function pointers to use the functions that will work */
613/* with the found version of the adapter */
614/****************************************************************************/
615static void
616ips_setup_funclist(ips_ha_t * ha)
617{
618
619 /*
620 * Setup Functions
621 */
622 if (IPS_IS_MORPHEUS(ha) || IPS_IS_MARCO(ha)) {
623 /* morpheus / marco / sebring */
624 ha->func.isintr = ips_isintr_morpheus;
625 ha->func.isinit = ips_isinit_morpheus;
626 ha->func.issue = ips_issue_i2o_memio;
627 ha->func.init = ips_init_morpheus;
628 ha->func.statupd = ips_statupd_morpheus;
629 ha->func.reset = ips_reset_morpheus;
630 ha->func.intr = ips_intr_morpheus;
631 ha->func.enableint = ips_enable_int_morpheus;
632 } else if (IPS_USE_MEMIO(ha)) {
633 /* copperhead w/MEMIO */
634 ha->func.isintr = ips_isintr_copperhead_memio;
635 ha->func.isinit = ips_isinit_copperhead_memio;
636 ha->func.init = ips_init_copperhead_memio;
637 ha->func.statupd = ips_statupd_copperhead_memio;
638 ha->func.statinit = ips_statinit_memio;
639 ha->func.reset = ips_reset_copperhead_memio;
640 ha->func.intr = ips_intr_copperhead;
641 ha->func.erasebios = ips_erase_bios_memio;
642 ha->func.programbios = ips_program_bios_memio;
643 ha->func.verifybios = ips_verify_bios_memio;
644 ha->func.enableint = ips_enable_int_copperhead_memio;
645 if (IPS_USE_I2O_DELIVER(ha))
646 ha->func.issue = ips_issue_i2o_memio;
647 else
648 ha->func.issue = ips_issue_copperhead_memio;
649 } else {
650 /* copperhead */
651 ha->func.isintr = ips_isintr_copperhead;
652 ha->func.isinit = ips_isinit_copperhead;
653 ha->func.init = ips_init_copperhead;
654 ha->func.statupd = ips_statupd_copperhead;
655 ha->func.statinit = ips_statinit;
656 ha->func.reset = ips_reset_copperhead;
657 ha->func.intr = ips_intr_copperhead;
658 ha->func.erasebios = ips_erase_bios;
659 ha->func.programbios = ips_program_bios;
660 ha->func.verifybios = ips_verify_bios;
661 ha->func.enableint = ips_enable_int_copperhead;
662
663 if (IPS_USE_I2O_DELIVER(ha))
664 ha->func.issue = ips_issue_i2o;
665 else
666 ha->func.issue = ips_issue_copperhead;
667 }
668}
669
670/****************************************************************************/
671/* */
672/* Routine Name: ips_release */
673/* */
674/* Routine Description: */
675/* */
676/* Remove a driver */
677/* */
678/****************************************************************************/
679static int
680ips_release(struct Scsi_Host *sh)
681{
682 ips_scb_t *scb;
683 ips_ha_t *ha;
684 int i;
685
686 METHOD_TRACE("ips_release", 1);
687
688 for (i = 0; i < IPS_MAX_ADAPTERS && ips_sh[i] != sh; i++) ;
689
690 if (i == IPS_MAX_ADAPTERS) {
691 printk(KERN_WARNING
692 "(%s) release, invalid Scsi_Host pointer.\n", ips_name);
693 BUG();
694 return (FALSE);
695 }
696
697 ha = IPS_HA(sh);
698
699 if (!ha)
700 return (FALSE);
701
702 /* flush the cache on the controller */
703 scb = &ha->scbs[ha->max_cmds - 1];
704
705 ips_init_scb(ha, scb);
706
707 scb->timeout = ips_cmd_timeout;
708 scb->cdb[0] = IPS_CMD_FLUSH;
709
710 scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH;
711 scb->cmd.flush_cache.command_id = IPS_COMMAND_ID(ha, scb);
712 scb->cmd.flush_cache.state = IPS_NORM_STATE;
713 scb->cmd.flush_cache.reserved = 0;
714 scb->cmd.flush_cache.reserved2 = 0;
715 scb->cmd.flush_cache.reserved3 = 0;
716 scb->cmd.flush_cache.reserved4 = 0;
717
718 IPS_PRINTK(KERN_WARNING, ha->pcidev, "Flushing Cache.\n");
719
720 /* send command */
721 if (ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_ON) == IPS_FAILURE)
722 IPS_PRINTK(KERN_WARNING, ha->pcidev, "Incomplete Flush.\n");
723
724 IPS_PRINTK(KERN_WARNING, ha->pcidev, "Flushing Complete.\n");
725
726 ips_sh[i] = NULL;
727 ips_ha[i] = NULL;
728
729 /* free extra memory */
730 ips_free(ha);
731
732 /* Free I/O Region */
733 if (ha->io_addr)
734 release_region(ha->io_addr, ha->io_len);
735
736 /* free IRQ */
737 free_irq(ha->irq, ha);
738
739 IPS_REMOVE_HOST(sh);
740 scsi_host_put(sh);
741
742 ips_released_controllers++;
743
744 return (FALSE);
745}
746
747/****************************************************************************/
748/* */
749/* Routine Name: ips_halt */
750/* */
751/* Routine Description: */
752/* */
753/* Perform cleanup when the system reboots */
754/* */
755/****************************************************************************/
756static int
757ips_halt(struct notifier_block *nb, ulong event, void *buf)
758{
759 ips_scb_t *scb;
760 ips_ha_t *ha;
761 int i;
762
763 if ((event != SYS_RESTART) && (event != SYS_HALT) &&
764 (event != SYS_POWER_OFF))
765 return (NOTIFY_DONE);
766
767 for (i = 0; i < ips_next_controller; i++) {
768 ha = (ips_ha_t *) ips_ha[i];
769
770 if (!ha)
771 continue;
772
773 if (!ha->active)
774 continue;
775
776 /* flush the cache on the controller */
777 scb = &ha->scbs[ha->max_cmds - 1];
778
779 ips_init_scb(ha, scb);
780
781 scb->timeout = ips_cmd_timeout;
782 scb->cdb[0] = IPS_CMD_FLUSH;
783
784 scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH;
785 scb->cmd.flush_cache.command_id = IPS_COMMAND_ID(ha, scb);
786 scb->cmd.flush_cache.state = IPS_NORM_STATE;
787 scb->cmd.flush_cache.reserved = 0;
788 scb->cmd.flush_cache.reserved2 = 0;
789 scb->cmd.flush_cache.reserved3 = 0;
790 scb->cmd.flush_cache.reserved4 = 0;
791
792 IPS_PRINTK(KERN_WARNING, ha->pcidev, "Flushing Cache.\n");
793
794 /* send command */
795 if (ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_ON) ==
796 IPS_FAILURE)
797 IPS_PRINTK(KERN_WARNING, ha->pcidev,
798 "Incomplete Flush.\n");
799 else
800 IPS_PRINTK(KERN_WARNING, ha->pcidev,
801 "Flushing Complete.\n");
802 }
803
804 return (NOTIFY_OK);
805}
806
807/****************************************************************************/
808/* */
809/* Routine Name: ips_eh_abort */
810/* */
811/* Routine Description: */
812/* */
813/* Abort a command (using the new error code stuff) */
814/* Note: this routine is called under the io_request_lock */
815/****************************************************************************/
816int
817ips_eh_abort(Scsi_Cmnd * SC)
818{
819 ips_ha_t *ha;
820 ips_copp_wait_item_t *item;
821 int ret;
Jeff Garzik 8fa728a2005-05-28 07:54:40 -0400822 unsigned long cpu_flags;
823 struct Scsi_Host *host;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700824
825 METHOD_TRACE("ips_eh_abort", 1);
826
827 if (!SC)
828 return (FAILED);
829
Jeff Garzik 8fa728a2005-05-28 07:54:40 -0400830 host = SC->device->host;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700831 ha = (ips_ha_t *) SC->device->host->hostdata;
832
833 if (!ha)
834 return (FAILED);
835
836 if (!ha->active)
837 return (FAILED);
838
Jeff Garzik 8fa728a2005-05-28 07:54:40 -0400839 IPS_LOCK_SAVE(host->host_lock, cpu_flags);
840
Linus Torvalds1da177e2005-04-16 15:20:36 -0700841 /* See if the command is on the copp queue */
842 item = ha->copp_waitlist.head;
843 while ((item) && (item->scsi_cmd != SC))
844 item = item->next;
845
846 if (item) {
847 /* Found it */
848 ips_removeq_copp(&ha->copp_waitlist, item);
849 ret = (SUCCESS);
850
851 /* See if the command is on the wait queue */
852 } else if (ips_removeq_wait(&ha->scb_waitlist, SC)) {
853 /* command not sent yet */
854 ret = (SUCCESS);
855 } else {
856 /* command must have already been sent */
857 ret = (FAILED);
858 }
Jeff Garzik 8fa728a2005-05-28 07:54:40 -0400859
860 IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700861 return ret;
862}
863
864/****************************************************************************/
865/* */
866/* Routine Name: ips_eh_reset */
867/* */
868/* Routine Description: */
869/* */
870/* Reset the controller (with new eh error code) */
871/* */
872/* NOTE: this routine is called under the io_request_lock spinlock */
873/* */
874/****************************************************************************/
875static int
Jeff Garzik df0ae242005-05-28 07:57:14 -0400876__ips_eh_reset(Scsi_Cmnd * SC)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700877{
878 int ret;
879 int i;
880 ips_ha_t *ha;
881 ips_scb_t *scb;
882 ips_copp_wait_item_t *item;
883
884 METHOD_TRACE("ips_eh_reset", 1);
885
886#ifdef NO_IPS_RESET
887 return (FAILED);
888#else
889
890 if (!SC) {
891 DEBUG(1, "Reset called with NULL scsi command");
892
893 return (FAILED);
894 }
895
896 ha = (ips_ha_t *) SC->device->host->hostdata;
897
898 if (!ha) {
899 DEBUG(1, "Reset called with NULL ha struct");
900
901 return (FAILED);
902 }
903
904 if (!ha->active)
905 return (FAILED);
906
907 /* See if the command is on the copp queue */
908 item = ha->copp_waitlist.head;
909 while ((item) && (item->scsi_cmd != SC))
910 item = item->next;
911
912 if (item) {
913 /* Found it */
914 ips_removeq_copp(&ha->copp_waitlist, item);
915 return (SUCCESS);
916 }
917
918 /* See if the command is on the wait queue */
919 if (ips_removeq_wait(&ha->scb_waitlist, SC)) {
920 /* command not sent yet */
921 return (SUCCESS);
922 }
923
924 /* An explanation for the casual observer: */
925 /* Part of the function of a RAID controller is automatic error */
926 /* detection and recovery. As such, the only problem that physically */
927 /* resetting an adapter will ever fix is when, for some reason, */
928 /* the driver is not successfully communicating with the adapter. */
929 /* Therefore, we will attempt to flush this adapter. If that succeeds, */
930 /* then there's no real purpose in a physical reset. This will complete */
931 /* much faster and avoids any problems that might be caused by a */
932 /* physical reset ( such as having to fail all the outstanding I/O's ). */
933
934 if (ha->ioctl_reset == 0) { /* IF Not an IOCTL Requested Reset */
935 scb = &ha->scbs[ha->max_cmds - 1];
936
937 ips_init_scb(ha, scb);
938
939 scb->timeout = ips_cmd_timeout;
940 scb->cdb[0] = IPS_CMD_FLUSH;
941
942 scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH;
943 scb->cmd.flush_cache.command_id = IPS_COMMAND_ID(ha, scb);
944 scb->cmd.flush_cache.state = IPS_NORM_STATE;
945 scb->cmd.flush_cache.reserved = 0;
946 scb->cmd.flush_cache.reserved2 = 0;
947 scb->cmd.flush_cache.reserved3 = 0;
948 scb->cmd.flush_cache.reserved4 = 0;
949
950 /* Attempt the flush command */
951 ret = ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_IORL);
952 if (ret == IPS_SUCCESS) {
953 IPS_PRINTK(KERN_NOTICE, ha->pcidev,
954 "Reset Request - Flushed Cache\n");
955 return (SUCCESS);
956 }
957 }
958
959 /* Either we can't communicate with the adapter or it's an IOCTL request */
960 /* from a utility. A physical reset is needed at this point. */
961
962 ha->ioctl_reset = 0; /* Reset the IOCTL Requested Reset Flag */
963
964 /*
965 * command must have already been sent
966 * reset the controller
967 */
968 IPS_PRINTK(KERN_NOTICE, ha->pcidev, "Resetting controller.\n");
969 ret = (*ha->func.reset) (ha);
970
971 if (!ret) {
972 Scsi_Cmnd *scsi_cmd;
973
974 IPS_PRINTK(KERN_NOTICE, ha->pcidev,
975 "Controller reset failed - controller now offline.\n");
976
977 /* Now fail all of the active commands */
978 DEBUG_VAR(1, "(%s%d) Failing active commands",
979 ips_name, ha->host_num);
980
981 while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) {
982 scb->scsi_cmd->result = DID_ERROR << 16;
983 scb->scsi_cmd->scsi_done(scb->scsi_cmd);
984 ips_freescb(ha, scb);
985 }
986
987 /* Now fail all of the pending commands */
988 DEBUG_VAR(1, "(%s%d) Failing pending commands",
989 ips_name, ha->host_num);
990
991 while ((scsi_cmd = ips_removeq_wait_head(&ha->scb_waitlist))) {
992 scsi_cmd->result = DID_ERROR;
993 scsi_cmd->scsi_done(scsi_cmd);
994 }
995
996 ha->active = FALSE;
997 return (FAILED);
998 }
999
1000 if (!ips_clear_adapter(ha, IPS_INTR_IORL)) {
1001 Scsi_Cmnd *scsi_cmd;
1002
1003 IPS_PRINTK(KERN_NOTICE, ha->pcidev,
1004 "Controller reset failed - controller now offline.\n");
1005
1006 /* Now fail all of the active commands */
1007 DEBUG_VAR(1, "(%s%d) Failing active commands",
1008 ips_name, ha->host_num);
1009
1010 while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) {
1011 scb->scsi_cmd->result = DID_ERROR << 16;
1012 scb->scsi_cmd->scsi_done(scb->scsi_cmd);
1013 ips_freescb(ha, scb);
1014 }
1015
1016 /* Now fail all of the pending commands */
1017 DEBUG_VAR(1, "(%s%d) Failing pending commands",
1018 ips_name, ha->host_num);
1019
1020 while ((scsi_cmd = ips_removeq_wait_head(&ha->scb_waitlist))) {
1021 scsi_cmd->result = DID_ERROR << 16;
1022 scsi_cmd->scsi_done(scsi_cmd);
1023 }
1024
1025 ha->active = FALSE;
1026 return (FAILED);
1027 }
1028
1029 /* FFDC */
1030 if (le32_to_cpu(ha->subsys->param[3]) & 0x300000) {
1031 struct timeval tv;
1032
1033 do_gettimeofday(&tv);
1034 ha->last_ffdc = tv.tv_sec;
1035 ha->reset_count++;
1036 ips_ffdc_reset(ha, IPS_INTR_IORL);
1037 }
1038
1039 /* Now fail all of the active commands */
1040 DEBUG_VAR(1, "(%s%d) Failing active commands", ips_name, ha->host_num);
1041
1042 while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) {
1043 scb->scsi_cmd->result =
1044 (DID_RESET << 16) | (SUGGEST_RETRY << 24);
1045 scb->scsi_cmd->scsi_done(scb->scsi_cmd);
1046 ips_freescb(ha, scb);
1047 }
1048
1049 /* Reset DCDB active command bits */
1050 for (i = 1; i < ha->nbus; i++)
1051 ha->dcdb_active[i - 1] = 0;
1052
1053 /* Reset the number of active IOCTLs */
1054 ha->num_ioctl = 0;
1055
1056 ips_next(ha, IPS_INTR_IORL);
1057
1058 return (SUCCESS);
1059#endif /* NO_IPS_RESET */
1060
1061}
1062
Jeff Garzik df0ae242005-05-28 07:57:14 -04001063static int
1064ips_eh_reset(Scsi_Cmnd * SC)
1065{
1066 int rc;
1067
1068 spin_lock_irq(SC->device->host->host_lock);
1069 rc = __ips_eh_reset(SC);
1070 spin_unlock_irq(SC->device->host->host_lock);
1071
1072 return rc;
1073}
1074
Linus Torvalds1da177e2005-04-16 15:20:36 -07001075/****************************************************************************/
1076/* */
1077/* Routine Name: ips_queue */
1078/* */
1079/* Routine Description: */
1080/* */
1081/* Send a command to the controller */
1082/* */
1083/* NOTE: */
1084/* Linux obtains io_request_lock before calling this function */
1085/* */
1086/****************************************************************************/
1087static int
1088ips_queue(Scsi_Cmnd * SC, void (*done) (Scsi_Cmnd *))
1089{
1090 ips_ha_t *ha;
1091 ips_passthru_t *pt;
1092
1093 METHOD_TRACE("ips_queue", 1);
1094
1095 ha = (ips_ha_t *) SC->device->host->hostdata;
1096
1097 if (!ha)
1098 return (1);
1099
1100 if (!ha->active)
1101 return (DID_ERROR);
1102
1103 if (ips_is_passthru(SC)) {
1104 if (ha->copp_waitlist.count == IPS_MAX_IOCTL_QUEUE) {
1105 SC->result = DID_BUS_BUSY << 16;
1106 done(SC);
1107
1108 return (0);
1109 }
1110 } else if (ha->scb_waitlist.count == IPS_MAX_QUEUE) {
1111 SC->result = DID_BUS_BUSY << 16;
1112 done(SC);
1113
1114 return (0);
1115 }
1116
1117 SC->scsi_done = done;
1118
1119 DEBUG_VAR(2, "(%s%d): ips_queue: cmd 0x%X (%d %d %d)",
1120 ips_name,
1121 ha->host_num,
1122 SC->cmnd[0],
1123 SC->device->channel, SC->device->id, SC->device->lun);
1124
1125 /* Check for command to initiator IDs */
Jeff Garzik422c0d62005-10-24 18:05:09 -04001126 if ((scmd_channel(SC) > 0)
1127 && (scmd_id(SC) == ha->ha_id[scmd_channel(SC)])) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001128 SC->result = DID_NO_CONNECT << 16;
1129 done(SC);
1130
1131 return (0);
1132 }
1133
1134 if (ips_is_passthru(SC)) {
1135
1136 ips_copp_wait_item_t *scratch;
1137
1138 /* A Reset IOCTL is only sent by the boot CD in extreme cases. */
1139 /* There can never be any system activity ( network or disk ), but check */
1140 /* anyway just as a good practice. */
1141 pt = (ips_passthru_t *) SC->request_buffer;
1142 if ((pt->CoppCP.cmd.reset.op_code == IPS_CMD_RESET_CHANNEL) &&
1143 (pt->CoppCP.cmd.reset.adapter_flag == 1)) {
1144 if (ha->scb_activelist.count != 0) {
1145 SC->result = DID_BUS_BUSY << 16;
1146 done(SC);
1147 return (0);
1148 }
1149 ha->ioctl_reset = 1; /* This reset request is from an IOCTL */
Mike Christieba3af0a2006-02-22 02:11:59 -06001150 __ips_eh_reset(SC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001151 SC->result = DID_OK << 16;
1152 SC->scsi_done(SC);
1153 return (0);
1154 }
1155
1156 /* allocate space for the scribble */
1157 scratch = kmalloc(sizeof (ips_copp_wait_item_t), GFP_ATOMIC);
1158
1159 if (!scratch) {
1160 SC->result = DID_ERROR << 16;
1161 done(SC);
1162
1163 return (0);
1164 }
1165
1166 scratch->scsi_cmd = SC;
1167 scratch->next = NULL;
1168
1169 ips_putq_copp_tail(&ha->copp_waitlist, scratch);
1170 } else {
1171 ips_putq_wait_tail(&ha->scb_waitlist, SC);
1172 }
1173
1174 ips_next(ha, IPS_INTR_IORL);
1175
1176 return (0);
1177}
1178
1179/****************************************************************************/
1180/* */
1181/* Routine Name: ips_biosparam */
1182/* */
1183/* Routine Description: */
1184/* */
1185/* Set bios geometry for the controller */
1186/* */
1187/****************************************************************************/
1188static int
1189#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
1190ips_biosparam(Disk * disk, kdev_t dev, int geom[])
1191{
1192 ips_ha_t *ha = (ips_ha_t *) disk->device->host->hostdata;
1193 unsigned long capacity = disk->capacity;
1194#else
1195ips_biosparam(struct scsi_device *sdev, struct block_device *bdev,
1196 sector_t capacity, int geom[])
1197{
1198 ips_ha_t *ha = (ips_ha_t *) sdev->host->hostdata;
1199#endif
1200 int heads;
1201 int sectors;
1202 int cylinders;
1203
1204 METHOD_TRACE("ips_biosparam", 1);
1205
1206 if (!ha)
1207 /* ?!?! host adater info invalid */
1208 return (0);
1209
1210 if (!ha->active)
1211 return (0);
1212
1213 if (!ips_read_adapter_status(ha, IPS_INTR_ON))
1214 /* ?!?! Enquiry command failed */
1215 return (0);
1216
1217 if ((capacity > 0x400000) && ((ha->enq->ucMiscFlag & 0x8) == 0)) {
1218 heads = IPS_NORM_HEADS;
1219 sectors = IPS_NORM_SECTORS;
1220 } else {
1221 heads = IPS_COMP_HEADS;
1222 sectors = IPS_COMP_SECTORS;
1223 }
1224
1225 cylinders = (unsigned long) capacity / (heads * sectors);
1226
1227 DEBUG_VAR(2, "Geometry: heads: %d, sectors: %d, cylinders: %d",
1228 heads, sectors, cylinders);
1229
1230 geom[0] = heads;
1231 geom[1] = sectors;
1232 geom[2] = cylinders;
1233
1234 return (0);
1235}
1236
1237#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
1238
1239/* ips_proc24_info is a wrapper around ips_proc_info *
1240 * for compatibility with the 2.4 scsi parameters */
1241static int
1242ips_proc24_info(char *buffer, char **start, off_t offset, int length,
1243 int hostno, int func)
1244{
1245 int i;
1246
1247 for (i = 0; i < ips_next_controller; i++) {
1248 if (ips_sh[i] && ips_sh[i]->host_no == hostno) {
1249 return ips_proc_info(ips_sh[i], buffer, start,
1250 offset, length, func);
1251 }
1252 }
1253 return -EINVAL;
1254}
1255
1256/****************************************************************************/
1257/* */
1258/* Routine Name: ips_select_queue_depth */
1259/* */
1260/* Routine Description: */
1261/* */
1262/* Select queue depths for the devices on the contoller */
1263/* */
1264/****************************************************************************/
1265static void
Christoph Hellwigf64a1812005-10-31 18:32:08 +01001266ips_select_queue_depth(struct Scsi_Host *host, struct scsi_device * scsi_devs)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001267{
Christoph Hellwigf64a1812005-10-31 18:32:08 +01001268 struct scsi_device *device;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001269 ips_ha_t *ha;
1270 int count = 0;
1271 int min;
1272
1273 ha = IPS_HA(host);
1274 min = ha->max_cmds / 4;
1275
1276 for (device = scsi_devs; device; device = device->next) {
1277 if (device->host == host) {
1278 if ((device->channel == 0) && (device->type == 0))
1279 count++;
1280 }
1281 }
1282
1283 for (device = scsi_devs; device; device = device->next) {
1284 if (device->host == host) {
1285 if ((device->channel == 0) && (device->type == 0)) {
1286 device->queue_depth =
1287 (ha->max_cmds - 1) / count;
1288 if (device->queue_depth < min)
1289 device->queue_depth = min;
1290 } else {
1291 device->queue_depth = 2;
1292 }
1293
1294 if (device->queue_depth < 2)
1295 device->queue_depth = 2;
1296 }
1297 }
1298}
1299
1300#else
1301/****************************************************************************/
1302/* */
1303/* Routine Name: ips_slave_configure */
1304/* */
1305/* Routine Description: */
1306/* */
1307/* Set queue depths on devices once scan is complete */
1308/* */
1309/****************************************************************************/
1310static int
Christoph Hellwigf64a1812005-10-31 18:32:08 +01001311ips_slave_configure(struct scsi_device * SDptr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001312{
1313 ips_ha_t *ha;
1314 int min;
1315
1316 ha = IPS_HA(SDptr->host);
1317 if (SDptr->tagged_supported && SDptr->type == TYPE_DISK) {
1318 min = ha->max_cmds / 2;
1319 if (ha->enq->ucLogDriveCount <= 2)
1320 min = ha->max_cmds - 1;
1321 scsi_adjust_queue_depth(SDptr, MSG_ORDERED_TAG, min);
1322 }
Jack Hammer560c26c2006-01-13 10:06:50 -05001323
1324 SDptr->skip_ms_page_8 = 1;
1325 SDptr->skip_ms_page_3f = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001326 return 0;
1327}
1328#endif
1329
1330/****************************************************************************/
1331/* */
1332/* Routine Name: do_ipsintr */
1333/* */
1334/* Routine Description: */
1335/* */
1336/* Wrapper for the interrupt handler */
1337/* */
1338/****************************************************************************/
1339static irqreturn_t
1340do_ipsintr(int irq, void *dev_id, struct pt_regs * regs)
1341{
1342 ips_ha_t *ha;
1343 unsigned long cpu_flags;
1344 struct Scsi_Host *host;
1345 int irqstatus;
1346
1347 METHOD_TRACE("do_ipsintr", 2);
1348
1349 ha = (ips_ha_t *) dev_id;
1350 if (!ha)
1351 return IRQ_NONE;
1352 host = ips_sh[ha->host_num];
1353 /* interrupt during initialization */
1354 if (!host) {
1355 (*ha->func.intr) (ha);
1356 return IRQ_HANDLED;
1357 }
1358
1359 IPS_LOCK_SAVE(host->host_lock, cpu_flags);
1360
1361 if (!ha->active) {
1362 IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags);
1363 return IRQ_HANDLED;
1364 }
1365
1366 irqstatus = (*ha->func.intr) (ha);
1367
1368 IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags);
1369
1370 /* start the next command */
1371 ips_next(ha, IPS_INTR_ON);
1372 return IRQ_RETVAL(irqstatus);
1373}
1374
1375/****************************************************************************/
1376/* */
1377/* Routine Name: ips_intr_copperhead */
1378/* */
1379/* Routine Description: */
1380/* */
1381/* Polling interrupt handler */
1382/* */
1383/* ASSUMES interrupts are disabled */
1384/* */
1385/****************************************************************************/
1386int
1387ips_intr_copperhead(ips_ha_t * ha)
1388{
1389 ips_stat_t *sp;
1390 ips_scb_t *scb;
1391 IPS_STATUS cstatus;
1392 int intrstatus;
1393
1394 METHOD_TRACE("ips_intr", 2);
1395
1396 if (!ha)
1397 return 0;
1398
1399 if (!ha->active)
1400 return 0;
1401
1402 intrstatus = (*ha->func.isintr) (ha);
1403
1404 if (!intrstatus) {
1405 /*
1406 * Unexpected/Shared interrupt
1407 */
1408
1409 return 0;
1410 }
1411
1412 while (TRUE) {
1413 sp = &ha->sp;
1414
1415 intrstatus = (*ha->func.isintr) (ha);
1416
1417 if (!intrstatus)
1418 break;
1419 else
1420 cstatus.value = (*ha->func.statupd) (ha);
1421
1422 if (cstatus.fields.command_id > (IPS_MAX_CMDS - 1)) {
1423 /* Spurious Interupt ? */
1424 continue;
1425 }
1426
1427 ips_chkstatus(ha, &cstatus);
1428 scb = (ips_scb_t *) sp->scb_addr;
1429
1430 /*
1431 * use the callback function to finish things up
1432 * NOTE: interrupts are OFF for this
1433 */
1434 (*scb->callback) (ha, scb);
1435 } /* end while */
1436 return 1;
1437}
1438
1439/****************************************************************************/
1440/* */
1441/* Routine Name: ips_intr_morpheus */
1442/* */
1443/* Routine Description: */
1444/* */
1445/* Polling interrupt handler */
1446/* */
1447/* ASSUMES interrupts are disabled */
1448/* */
1449/****************************************************************************/
1450int
1451ips_intr_morpheus(ips_ha_t * ha)
1452{
1453 ips_stat_t *sp;
1454 ips_scb_t *scb;
1455 IPS_STATUS cstatus;
1456 int intrstatus;
1457
1458 METHOD_TRACE("ips_intr_morpheus", 2);
1459
1460 if (!ha)
1461 return 0;
1462
1463 if (!ha->active)
1464 return 0;
1465
1466 intrstatus = (*ha->func.isintr) (ha);
1467
1468 if (!intrstatus) {
1469 /*
1470 * Unexpected/Shared interrupt
1471 */
1472
1473 return 0;
1474 }
1475
1476 while (TRUE) {
1477 sp = &ha->sp;
1478
1479 intrstatus = (*ha->func.isintr) (ha);
1480
1481 if (!intrstatus)
1482 break;
1483 else
1484 cstatus.value = (*ha->func.statupd) (ha);
1485
1486 if (cstatus.value == 0xffffffff)
1487 /* No more to process */
1488 break;
1489
1490 if (cstatus.fields.command_id > (IPS_MAX_CMDS - 1)) {
1491 IPS_PRINTK(KERN_WARNING, ha->pcidev,
1492 "Spurious interrupt; no ccb.\n");
1493
1494 continue;
1495 }
1496
1497 ips_chkstatus(ha, &cstatus);
1498 scb = (ips_scb_t *) sp->scb_addr;
1499
1500 /*
1501 * use the callback function to finish things up
1502 * NOTE: interrupts are OFF for this
1503 */
1504 (*scb->callback) (ha, scb);
1505 } /* end while */
1506 return 1;
1507}
1508
1509/****************************************************************************/
1510/* */
1511/* Routine Name: ips_info */
1512/* */
1513/* Routine Description: */
1514/* */
1515/* Return info about the driver */
1516/* */
1517/****************************************************************************/
1518static const char *
1519ips_info(struct Scsi_Host *SH)
1520{
1521 static char buffer[256];
1522 char *bp;
1523 ips_ha_t *ha;
1524
1525 METHOD_TRACE("ips_info", 1);
1526
1527 ha = IPS_HA(SH);
1528
1529 if (!ha)
1530 return (NULL);
1531
1532 bp = &buffer[0];
1533 memset(bp, 0, sizeof (buffer));
1534
1535 sprintf(bp, "%s%s%s Build %d", "IBM PCI ServeRAID ",
1536 IPS_VERSION_HIGH, IPS_VERSION_LOW, IPS_BUILD_IDENT);
1537
1538 if (ha->ad_type > 0 && ha->ad_type <= MAX_ADAPTER_NAME) {
1539 strcat(bp, " <");
1540 strcat(bp, ips_adapter_name[ha->ad_type - 1]);
1541 strcat(bp, ">");
1542 }
1543
1544 return (bp);
1545}
1546
1547/****************************************************************************/
1548/* */
1549/* Routine Name: ips_proc_info */
1550/* */
1551/* Routine Description: */
1552/* */
1553/* The passthru interface for the driver */
1554/* */
1555/****************************************************************************/
1556static int
1557ips_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
1558 int length, int func)
1559{
1560 int i;
1561 int ret;
1562 ips_ha_t *ha = NULL;
1563
1564 METHOD_TRACE("ips_proc_info", 1);
1565
1566 /* Find our host structure */
1567 for (i = 0; i < ips_next_controller; i++) {
1568 if (ips_sh[i]) {
1569 if (ips_sh[i] == host) {
1570 ha = (ips_ha_t *) ips_sh[i]->hostdata;
1571 break;
1572 }
1573 }
1574 }
1575
1576 if (!ha)
1577 return (-EINVAL);
1578
1579 if (func) {
1580 /* write */
1581 return (0);
1582 } else {
1583 /* read */
1584 if (start)
1585 *start = buffer;
1586
1587 ret = ips_host_info(ha, buffer, offset, length);
1588
1589 return (ret);
1590 }
1591}
1592
1593/*--------------------------------------------------------------------------*/
1594/* Helper Functions */
1595/*--------------------------------------------------------------------------*/
1596
1597/****************************************************************************/
1598/* */
1599/* Routine Name: ips_is_passthru */
1600/* */
1601/* Routine Description: */
1602/* */
1603/* Determine if the specified SCSI command is really a passthru command */
1604/* */
1605/****************************************************************************/
1606static int
1607ips_is_passthru(Scsi_Cmnd * SC)
1608{
Jack Hammera3632fa2005-10-25 14:13:03 -04001609 unsigned long flags;
1610
Linus Torvalds1da177e2005-04-16 15:20:36 -07001611 METHOD_TRACE("ips_is_passthru", 1);
1612
1613 if (!SC)
1614 return (0);
1615
1616 if ((SC->cmnd[0] == IPS_IOCTL_COMMAND) &&
1617 (SC->device->channel == 0) &&
1618 (SC->device->id == IPS_ADAPTER_ID) &&
1619 (SC->device->lun == 0) && SC->request_buffer) {
1620 if ((!SC->use_sg) && SC->request_bufflen &&
1621 (((char *) SC->request_buffer)[0] == 'C') &&
1622 (((char *) SC->request_buffer)[1] == 'O') &&
1623 (((char *) SC->request_buffer)[2] == 'P') &&
1624 (((char *) SC->request_buffer)[3] == 'P'))
1625 return 1;
1626 else if (SC->use_sg) {
1627 struct scatterlist *sg = SC->request_buffer;
Jack Hammera3632fa2005-10-25 14:13:03 -04001628 char *buffer;
1629
1630 /* kmap_atomic() ensures addressability of the user buffer.*/
1631 /* local_irq_save() protects the KM_IRQ0 address slot. */
1632 local_irq_save(flags);
1633 buffer = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001634 if (buffer && buffer[0] == 'C' && buffer[1] == 'O' &&
Jack Hammera3632fa2005-10-25 14:13:03 -04001635 buffer[2] == 'P' && buffer[3] == 'P') {
1636 kunmap_atomic(buffer - sg->offset, KM_IRQ0);
1637 local_irq_restore(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001638 return 1;
Jack Hammera3632fa2005-10-25 14:13:03 -04001639 }
1640 kunmap_atomic(buffer - sg->offset, KM_IRQ0);
1641 local_irq_restore(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001642 }
1643 }
1644 return 0;
1645}
1646
1647/****************************************************************************/
1648/* */
1649/* Routine Name: ips_alloc_passthru_buffer */
1650/* */
1651/* Routine Description: */
1652/* allocate a buffer large enough for the ioctl data if the ioctl buffer */
1653/* is too small or doesn't exist */
1654/****************************************************************************/
1655static int
1656ips_alloc_passthru_buffer(ips_ha_t * ha, int length)
1657{
1658 void *bigger_buf;
1659 dma_addr_t dma_busaddr;
1660
1661 if (ha->ioctl_data && length <= ha->ioctl_len)
1662 return 0;
1663 /* there is no buffer or it's not big enough, allocate a new one */
1664 bigger_buf = pci_alloc_consistent(ha->pcidev, length, &dma_busaddr);
1665 if (bigger_buf) {
1666 /* free the old memory */
1667 pci_free_consistent(ha->pcidev, ha->ioctl_len, ha->ioctl_data,
1668 ha->ioctl_busaddr);
1669 /* use the new memory */
1670 ha->ioctl_data = (char *) bigger_buf;
1671 ha->ioctl_len = length;
1672 ha->ioctl_busaddr = dma_busaddr;
1673 } else {
1674 return -1;
1675 }
1676 return 0;
1677}
1678
1679/****************************************************************************/
1680/* */
1681/* Routine Name: ips_make_passthru */
1682/* */
1683/* Routine Description: */
1684/* */
1685/* Make a passthru command out of the info in the Scsi block */
1686/* */
1687/****************************************************************************/
1688static int
1689ips_make_passthru(ips_ha_t * ha, Scsi_Cmnd * SC, ips_scb_t * scb, int intr)
1690{
1691 ips_passthru_t *pt;
1692 int length = 0;
1693 int ret;
1694
1695 METHOD_TRACE("ips_make_passthru", 1);
1696
1697 if (!SC->use_sg) {
1698 length = SC->request_bufflen;
1699 } else {
1700 struct scatterlist *sg = SC->request_buffer;
1701 int i;
1702 for (i = 0; i < SC->use_sg; i++)
1703 length += sg[i].length;
1704 }
1705 if (length < sizeof (ips_passthru_t)) {
1706 /* wrong size */
1707 DEBUG_VAR(1, "(%s%d) Passthru structure wrong size",
1708 ips_name, ha->host_num);
1709 return (IPS_FAILURE);
1710 }
1711 if (ips_alloc_passthru_buffer(ha, length)) {
1712 /* allocation failure! If ha->ioctl_data exists, use it to return
1713 some error codes. Return a failed command to the scsi layer. */
1714 if (ha->ioctl_data) {
1715 pt = (ips_passthru_t *) ha->ioctl_data;
1716 ips_scmd_buf_read(SC, pt, sizeof (ips_passthru_t));
1717 pt->BasicStatus = 0x0B;
1718 pt->ExtendedStatus = 0x00;
1719 ips_scmd_buf_write(SC, pt, sizeof (ips_passthru_t));
1720 }
1721 return IPS_FAILURE;
1722 }
1723 ha->ioctl_datasize = length;
1724
1725 ips_scmd_buf_read(SC, ha->ioctl_data, ha->ioctl_datasize);
1726 pt = (ips_passthru_t *) ha->ioctl_data;
1727
1728 /*
1729 * Some notes about the passthru interface used
1730 *
1731 * IF the scsi op_code == 0x0d then we assume
1732 * that the data came along with/goes with the
1733 * packet we received from the sg driver. In this
1734 * case the CmdBSize field of the pt structure is
1735 * used for the size of the buffer.
1736 */
1737
1738 switch (pt->CoppCmd) {
1739 case IPS_NUMCTRLS:
1740 memcpy(ha->ioctl_data + sizeof (ips_passthru_t),
1741 &ips_num_controllers, sizeof (int));
1742 ips_scmd_buf_write(SC, ha->ioctl_data,
1743 sizeof (ips_passthru_t) + sizeof (int));
1744 SC->result = DID_OK << 16;
1745
1746 return (IPS_SUCCESS_IMM);
1747
1748 case IPS_COPPUSRCMD:
1749 case IPS_COPPIOCCMD:
1750 if (SC->cmnd[0] == IPS_IOCTL_COMMAND) {
1751 if (length < (sizeof (ips_passthru_t) + pt->CmdBSize)) {
1752 /* wrong size */
1753 DEBUG_VAR(1,
1754 "(%s%d) Passthru structure wrong size",
1755 ips_name, ha->host_num);
1756
1757 return (IPS_FAILURE);
1758 }
1759
1760 if (ha->device_id == IPS_DEVICEID_COPPERHEAD &&
1761 pt->CoppCP.cmd.flashfw.op_code ==
1762 IPS_CMD_RW_BIOSFW) {
1763 ret = ips_flash_copperhead(ha, pt, scb);
1764 ips_scmd_buf_write(SC, ha->ioctl_data,
1765 sizeof (ips_passthru_t));
1766 return ret;
1767 }
1768 if (ips_usrcmd(ha, pt, scb))
1769 return (IPS_SUCCESS);
1770 else
1771 return (IPS_FAILURE);
1772 }
1773
1774 break;
1775
1776 } /* end switch */
1777
1778 return (IPS_FAILURE);
1779}
1780
1781/****************************************************************************/
1782/* Routine Name: ips_flash_copperhead */
1783/* Routine Description: */
1784/* Flash the BIOS/FW on a Copperhead style controller */
1785/****************************************************************************/
1786static int
1787ips_flash_copperhead(ips_ha_t * ha, ips_passthru_t * pt, ips_scb_t * scb)
1788{
1789 int datasize;
1790
1791 /* Trombone is the only copperhead that can do packet flash, but only
1792 * for firmware. No one said it had to make sence. */
1793 if (IPS_IS_TROMBONE(ha) && pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE) {
1794 if (ips_usrcmd(ha, pt, scb))
1795 return IPS_SUCCESS;
1796 else
1797 return IPS_FAILURE;
1798 }
1799 pt->BasicStatus = 0x0B;
1800 pt->ExtendedStatus = 0;
1801 scb->scsi_cmd->result = DID_OK << 16;
1802 /* IF it's OK to Use the "CD BOOT" Flash Buffer, then you can */
1803 /* avoid allocating a huge buffer per adapter ( which can fail ). */
1804 if (pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE &&
1805 pt->CoppCP.cmd.flashfw.direction == IPS_ERASE_BIOS) {
1806 pt->BasicStatus = 0;
1807 return ips_flash_bios(ha, pt, scb);
1808 } else if (pt->CoppCP.cmd.flashfw.packet_num == 0) {
1809 if (ips_FlashData && !test_and_set_bit(0, &ips_FlashDataInUse)){
1810 ha->flash_data = ips_FlashData;
1811 ha->flash_busaddr = ips_flashbusaddr;
1812 ha->flash_len = PAGE_SIZE << 7;
1813 ha->flash_datasize = 0;
1814 } else if (!ha->flash_data) {
1815 datasize = pt->CoppCP.cmd.flashfw.total_packets *
1816 pt->CoppCP.cmd.flashfw.count;
1817 ha->flash_data = pci_alloc_consistent(ha->pcidev,
1818 datasize,
1819 &ha->flash_busaddr);
1820 if (!ha->flash_data){
1821 printk(KERN_WARNING "Unable to allocate a flash buffer\n");
1822 return IPS_FAILURE;
1823 }
1824 ha->flash_datasize = 0;
1825 ha->flash_len = datasize;
1826 } else
1827 return IPS_FAILURE;
1828 } else {
1829 if (pt->CoppCP.cmd.flashfw.count + ha->flash_datasize >
1830 ha->flash_len) {
1831 ips_free_flash_copperhead(ha);
1832 IPS_PRINTK(KERN_WARNING, ha->pcidev,
1833 "failed size sanity check\n");
1834 return IPS_FAILURE;
1835 }
1836 }
1837 if (!ha->flash_data)
1838 return IPS_FAILURE;
1839 pt->BasicStatus = 0;
1840 memcpy(&ha->flash_data[ha->flash_datasize], pt + 1,
1841 pt->CoppCP.cmd.flashfw.count);
1842 ha->flash_datasize += pt->CoppCP.cmd.flashfw.count;
1843 if (pt->CoppCP.cmd.flashfw.packet_num ==
1844 pt->CoppCP.cmd.flashfw.total_packets - 1) {
1845 if (pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE)
1846 return ips_flash_bios(ha, pt, scb);
1847 else if (pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE)
1848 return ips_flash_firmware(ha, pt, scb);
1849 }
1850 return IPS_SUCCESS_IMM;
1851}
1852
1853/****************************************************************************/
1854/* Routine Name: ips_flash_bios */
1855/* Routine Description: */
1856/* flashes the bios of a copperhead adapter */
1857/****************************************************************************/
1858static int
1859ips_flash_bios(ips_ha_t * ha, ips_passthru_t * pt, ips_scb_t * scb)
1860{
1861
1862 if (pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE &&
1863 pt->CoppCP.cmd.flashfw.direction == IPS_WRITE_BIOS) {
1864 if ((!ha->func.programbios) || (!ha->func.erasebios) ||
1865 (!ha->func.verifybios))
1866 goto error;
1867 if ((*ha->func.erasebios) (ha)) {
1868 DEBUG_VAR(1,
1869 "(%s%d) flash bios failed - unable to erase flash",
1870 ips_name, ha->host_num);
1871 goto error;
1872 } else
1873 if ((*ha->func.programbios) (ha,
1874 ha->flash_data +
1875 IPS_BIOS_HEADER,
1876 ha->flash_datasize -
1877 IPS_BIOS_HEADER, 0)) {
1878 DEBUG_VAR(1,
1879 "(%s%d) flash bios failed - unable to flash",
1880 ips_name, ha->host_num);
1881 goto error;
1882 } else
1883 if ((*ha->func.verifybios) (ha,
1884 ha->flash_data +
1885 IPS_BIOS_HEADER,
1886 ha->flash_datasize -
1887 IPS_BIOS_HEADER, 0)) {
1888 DEBUG_VAR(1,
1889 "(%s%d) flash bios failed - unable to verify flash",
1890 ips_name, ha->host_num);
1891 goto error;
1892 }
1893 ips_free_flash_copperhead(ha);
1894 return IPS_SUCCESS_IMM;
1895 } else if (pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE &&
1896 pt->CoppCP.cmd.flashfw.direction == IPS_ERASE_BIOS) {
1897 if (!ha->func.erasebios)
1898 goto error;
1899 if ((*ha->func.erasebios) (ha)) {
1900 DEBUG_VAR(1,
1901 "(%s%d) flash bios failed - unable to erase flash",
1902 ips_name, ha->host_num);
1903 goto error;
1904 }
1905 return IPS_SUCCESS_IMM;
1906 }
1907 error:
1908 pt->BasicStatus = 0x0B;
1909 pt->ExtendedStatus = 0x00;
1910 ips_free_flash_copperhead(ha);
1911 return IPS_FAILURE;
1912}
1913
1914/****************************************************************************/
1915/* */
1916/* Routine Name: ips_fill_scb_sg_single */
1917/* */
1918/* Routine Description: */
1919/* Fill in a single scb sg_list element from an address */
1920/* return a -1 if a breakup occurred */
1921/****************************************************************************/
1922static int
1923ips_fill_scb_sg_single(ips_ha_t * ha, dma_addr_t busaddr,
1924 ips_scb_t * scb, int indx, unsigned int e_len)
1925{
1926
1927 int ret_val = 0;
1928
1929 if ((scb->data_len + e_len) > ha->max_xfer) {
1930 e_len = ha->max_xfer - scb->data_len;
1931 scb->breakup = indx;
1932 ++scb->sg_break;
1933 ret_val = -1;
1934 } else {
1935 scb->breakup = 0;
1936 scb->sg_break = 0;
1937 }
1938 if (IPS_USE_ENH_SGLIST(ha)) {
1939 scb->sg_list.enh_list[indx].address_lo =
1940 cpu_to_le32(pci_dma_lo32(busaddr));
1941 scb->sg_list.enh_list[indx].address_hi =
1942 cpu_to_le32(pci_dma_hi32(busaddr));
1943 scb->sg_list.enh_list[indx].length = cpu_to_le32(e_len);
1944 } else {
1945 scb->sg_list.std_list[indx].address =
1946 cpu_to_le32(pci_dma_lo32(busaddr));
1947 scb->sg_list.std_list[indx].length = cpu_to_le32(e_len);
1948 }
1949
1950 ++scb->sg_len;
1951 scb->data_len += e_len;
1952 return ret_val;
1953}
1954
1955/****************************************************************************/
1956/* Routine Name: ips_flash_firmware */
1957/* Routine Description: */
1958/* flashes the firmware of a copperhead adapter */
1959/****************************************************************************/
1960static int
1961ips_flash_firmware(ips_ha_t * ha, ips_passthru_t * pt, ips_scb_t * scb)
1962{
1963 IPS_SG_LIST sg_list;
1964 uint32_t cmd_busaddr;
1965
1966 if (pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE &&
1967 pt->CoppCP.cmd.flashfw.direction == IPS_WRITE_FW) {
1968 memset(&pt->CoppCP.cmd, 0, sizeof (IPS_HOST_COMMAND));
1969 pt->CoppCP.cmd.flashfw.op_code = IPS_CMD_DOWNLOAD;
1970 pt->CoppCP.cmd.flashfw.count = cpu_to_le32(ha->flash_datasize);
1971 } else {
1972 pt->BasicStatus = 0x0B;
1973 pt->ExtendedStatus = 0x00;
1974 ips_free_flash_copperhead(ha);
1975 return IPS_FAILURE;
1976 }
1977 /* Save the S/G list pointer so it doesn't get clobbered */
1978 sg_list.list = scb->sg_list.list;
1979 cmd_busaddr = scb->scb_busaddr;
1980 /* copy in the CP */
1981 memcpy(&scb->cmd, &pt->CoppCP.cmd, sizeof (IPS_IOCTL_CMD));
1982 /* FIX stuff that might be wrong */
1983 scb->sg_list.list = sg_list.list;
1984 scb->scb_busaddr = cmd_busaddr;
1985 scb->bus = scb->scsi_cmd->device->channel;
1986 scb->target_id = scb->scsi_cmd->device->id;
1987 scb->lun = scb->scsi_cmd->device->lun;
1988 scb->sg_len = 0;
1989 scb->data_len = 0;
1990 scb->flags = 0;
1991 scb->op_code = 0;
1992 scb->callback = ipsintr_done;
1993 scb->timeout = ips_cmd_timeout;
1994
1995 scb->data_len = ha->flash_datasize;
1996 scb->data_busaddr =
1997 pci_map_single(ha->pcidev, ha->flash_data, scb->data_len,
1998 IPS_DMA_DIR(scb));
1999 scb->flags |= IPS_SCB_MAP_SINGLE;
2000 scb->cmd.flashfw.command_id = IPS_COMMAND_ID(ha, scb);
2001 scb->cmd.flashfw.buffer_addr = cpu_to_le32(scb->data_busaddr);
2002 if (pt->TimeOut)
2003 scb->timeout = pt->TimeOut;
2004 scb->scsi_cmd->result = DID_OK << 16;
2005 return IPS_SUCCESS;
2006}
2007
2008/****************************************************************************/
2009/* Routine Name: ips_free_flash_copperhead */
2010/* Routine Description: */
2011/* release the memory resources used to hold the flash image */
2012/****************************************************************************/
2013static void
2014ips_free_flash_copperhead(ips_ha_t * ha)
2015{
2016 if (ha->flash_data == ips_FlashData)
2017 test_and_clear_bit(0, &ips_FlashDataInUse);
2018 else if (ha->flash_data)
2019 pci_free_consistent(ha->pcidev, ha->flash_len, ha->flash_data,
2020 ha->flash_busaddr);
2021 ha->flash_data = NULL;
2022}
2023
2024/****************************************************************************/
2025/* */
2026/* Routine Name: ips_usrcmd */
2027/* */
2028/* Routine Description: */
2029/* */
2030/* Process a user command and make it ready to send */
2031/* */
2032/****************************************************************************/
2033static int
2034ips_usrcmd(ips_ha_t * ha, ips_passthru_t * pt, ips_scb_t * scb)
2035{
2036 IPS_SG_LIST sg_list;
2037 uint32_t cmd_busaddr;
2038
2039 METHOD_TRACE("ips_usrcmd", 1);
2040
2041 if ((!scb) || (!pt) || (!ha))
2042 return (0);
2043
2044 /* Save the S/G list pointer so it doesn't get clobbered */
2045 sg_list.list = scb->sg_list.list;
2046 cmd_busaddr = scb->scb_busaddr;
2047 /* copy in the CP */
2048 memcpy(&scb->cmd, &pt->CoppCP.cmd, sizeof (IPS_IOCTL_CMD));
2049 memcpy(&scb->dcdb, &pt->CoppCP.dcdb, sizeof (IPS_DCDB_TABLE));
2050
2051 /* FIX stuff that might be wrong */
2052 scb->sg_list.list = sg_list.list;
2053 scb->scb_busaddr = cmd_busaddr;
2054 scb->bus = scb->scsi_cmd->device->channel;
2055 scb->target_id = scb->scsi_cmd->device->id;
2056 scb->lun = scb->scsi_cmd->device->lun;
2057 scb->sg_len = 0;
2058 scb->data_len = 0;
2059 scb->flags = 0;
2060 scb->op_code = 0;
2061 scb->callback = ipsintr_done;
2062 scb->timeout = ips_cmd_timeout;
2063 scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
2064
2065 /* we don't support DCDB/READ/WRITE Scatter Gather */
2066 if ((scb->cmd.basic_io.op_code == IPS_CMD_READ_SG) ||
2067 (scb->cmd.basic_io.op_code == IPS_CMD_WRITE_SG) ||
2068 (scb->cmd.basic_io.op_code == IPS_CMD_DCDB_SG))
2069 return (0);
2070
2071 if (pt->CmdBSize) {
2072 scb->data_len = pt->CmdBSize;
2073 scb->data_busaddr = ha->ioctl_busaddr + sizeof (ips_passthru_t);
2074 } else {
2075 scb->data_busaddr = 0L;
2076 }
2077
2078 if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)
2079 scb->cmd.dcdb.dcdb_address = cpu_to_le32(scb->scb_busaddr +
2080 (unsigned long) &scb->
2081 dcdb -
2082 (unsigned long) scb);
2083
2084 if (pt->CmdBSize) {
2085 if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)
2086 scb->dcdb.buffer_pointer =
2087 cpu_to_le32(scb->data_busaddr);
2088 else
2089 scb->cmd.basic_io.sg_addr =
2090 cpu_to_le32(scb->data_busaddr);
2091 }
2092
2093 /* set timeouts */
2094 if (pt->TimeOut) {
2095 scb->timeout = pt->TimeOut;
2096
2097 if (pt->TimeOut <= 10)
2098 scb->dcdb.cmd_attribute |= IPS_TIMEOUT10;
2099 else if (pt->TimeOut <= 60)
2100 scb->dcdb.cmd_attribute |= IPS_TIMEOUT60;
2101 else
2102 scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M;
2103 }
2104
2105 /* assume success */
2106 scb->scsi_cmd->result = DID_OK << 16;
2107
2108 /* success */
2109 return (1);
2110}
2111
2112/****************************************************************************/
2113/* */
2114/* Routine Name: ips_cleanup_passthru */
2115/* */
2116/* Routine Description: */
2117/* */
2118/* Cleanup after a passthru command */
2119/* */
2120/****************************************************************************/
2121static void
2122ips_cleanup_passthru(ips_ha_t * ha, ips_scb_t * scb)
2123{
2124 ips_passthru_t *pt;
2125
2126 METHOD_TRACE("ips_cleanup_passthru", 1);
2127
2128 if ((!scb) || (!scb->scsi_cmd) || (!scb->scsi_cmd->request_buffer)) {
2129 DEBUG_VAR(1, "(%s%d) couldn't cleanup after passthru",
2130 ips_name, ha->host_num);
2131
2132 return;
2133 }
2134 pt = (ips_passthru_t *) ha->ioctl_data;
2135
2136 /* Copy data back to the user */
2137 if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB) /* Copy DCDB Back to Caller's Area */
2138 memcpy(&pt->CoppCP.dcdb, &scb->dcdb, sizeof (IPS_DCDB_TABLE));
2139
2140 pt->BasicStatus = scb->basic_status;
2141 pt->ExtendedStatus = scb->extended_status;
2142 pt->AdapterType = ha->ad_type;
2143
2144 if (ha->device_id == IPS_DEVICEID_COPPERHEAD &&
2145 (scb->cmd.flashfw.op_code == IPS_CMD_DOWNLOAD ||
2146 scb->cmd.flashfw.op_code == IPS_CMD_RW_BIOSFW))
2147 ips_free_flash_copperhead(ha);
2148
2149 ips_scmd_buf_write(scb->scsi_cmd, ha->ioctl_data, ha->ioctl_datasize);
2150}
2151
2152/****************************************************************************/
2153/* */
2154/* Routine Name: ips_host_info */
2155/* */
2156/* Routine Description: */
2157/* */
2158/* The passthru interface for the driver */
2159/* */
2160/****************************************************************************/
2161static int
2162ips_host_info(ips_ha_t * ha, char *ptr, off_t offset, int len)
2163{
2164 IPS_INFOSTR info;
2165
2166 METHOD_TRACE("ips_host_info", 1);
2167
2168 info.buffer = ptr;
2169 info.length = len;
2170 info.offset = offset;
2171 info.pos = 0;
2172 info.localpos = 0;
2173
2174 copy_info(&info, "\nIBM ServeRAID General Information:\n\n");
2175
2176 if ((le32_to_cpu(ha->nvram->signature) == IPS_NVRAM_P5_SIG) &&
2177 (le16_to_cpu(ha->nvram->adapter_type) != 0))
2178 copy_info(&info, "\tController Type : %s\n",
2179 ips_adapter_name[ha->ad_type - 1]);
2180 else
2181 copy_info(&info,
2182 "\tController Type : Unknown\n");
2183
2184 if (ha->io_addr)
2185 copy_info(&info,
2186 "\tIO region : 0x%lx (%d bytes)\n",
2187 ha->io_addr, ha->io_len);
2188
2189 if (ha->mem_addr) {
2190 copy_info(&info,
2191 "\tMemory region : 0x%lx (%d bytes)\n",
2192 ha->mem_addr, ha->mem_len);
2193 copy_info(&info,
2194 "\tShared memory address : 0x%lx\n",
2195 ha->mem_ptr);
2196 }
2197
2198 copy_info(&info, "\tIRQ number : %d\n", ha->irq);
2199
2200 /* For the Next 3 lines Check for Binary 0 at the end and don't include it if it's there. */
2201 /* That keeps everything happy for "text" operations on the proc file. */
2202
2203 if (le32_to_cpu(ha->nvram->signature) == IPS_NVRAM_P5_SIG) {
2204 if (ha->nvram->bios_low[3] == 0) {
2205 copy_info(&info,
2206 "\tBIOS Version : %c%c%c%c%c%c%c\n",
2207 ha->nvram->bios_high[0], ha->nvram->bios_high[1],
2208 ha->nvram->bios_high[2], ha->nvram->bios_high[3],
2209 ha->nvram->bios_low[0], ha->nvram->bios_low[1],
2210 ha->nvram->bios_low[2]);
2211
2212 } else {
2213 copy_info(&info,
2214 "\tBIOS Version : %c%c%c%c%c%c%c%c\n",
2215 ha->nvram->bios_high[0], ha->nvram->bios_high[1],
2216 ha->nvram->bios_high[2], ha->nvram->bios_high[3],
2217 ha->nvram->bios_low[0], ha->nvram->bios_low[1],
2218 ha->nvram->bios_low[2], ha->nvram->bios_low[3]);
2219 }
2220
2221 }
2222
2223 if (ha->enq->CodeBlkVersion[7] == 0) {
2224 copy_info(&info,
2225 "\tFirmware Version : %c%c%c%c%c%c%c\n",
2226 ha->enq->CodeBlkVersion[0], ha->enq->CodeBlkVersion[1],
2227 ha->enq->CodeBlkVersion[2], ha->enq->CodeBlkVersion[3],
2228 ha->enq->CodeBlkVersion[4], ha->enq->CodeBlkVersion[5],
2229 ha->enq->CodeBlkVersion[6]);
2230 } else {
2231 copy_info(&info,
2232 "\tFirmware Version : %c%c%c%c%c%c%c%c\n",
2233 ha->enq->CodeBlkVersion[0], ha->enq->CodeBlkVersion[1],
2234 ha->enq->CodeBlkVersion[2], ha->enq->CodeBlkVersion[3],
2235 ha->enq->CodeBlkVersion[4], ha->enq->CodeBlkVersion[5],
2236 ha->enq->CodeBlkVersion[6], ha->enq->CodeBlkVersion[7]);
2237 }
2238
2239 if (ha->enq->BootBlkVersion[7] == 0) {
2240 copy_info(&info,
2241 "\tBoot Block Version : %c%c%c%c%c%c%c\n",
2242 ha->enq->BootBlkVersion[0], ha->enq->BootBlkVersion[1],
2243 ha->enq->BootBlkVersion[2], ha->enq->BootBlkVersion[3],
2244 ha->enq->BootBlkVersion[4], ha->enq->BootBlkVersion[5],
2245 ha->enq->BootBlkVersion[6]);
2246 } else {
2247 copy_info(&info,
2248 "\tBoot Block Version : %c%c%c%c%c%c%c%c\n",
2249 ha->enq->BootBlkVersion[0], ha->enq->BootBlkVersion[1],
2250 ha->enq->BootBlkVersion[2], ha->enq->BootBlkVersion[3],
2251 ha->enq->BootBlkVersion[4], ha->enq->BootBlkVersion[5],
2252 ha->enq->BootBlkVersion[6], ha->enq->BootBlkVersion[7]);
2253 }
2254
2255 copy_info(&info, "\tDriver Version : %s%s\n",
2256 IPS_VERSION_HIGH, IPS_VERSION_LOW);
2257
2258 copy_info(&info, "\tDriver Build : %d\n",
2259 IPS_BUILD_IDENT);
2260
2261 copy_info(&info, "\tMax Physical Devices : %d\n",
2262 ha->enq->ucMaxPhysicalDevices);
2263 copy_info(&info, "\tMax Active Commands : %d\n",
2264 ha->max_cmds);
2265 copy_info(&info, "\tCurrent Queued Commands : %d\n",
2266 ha->scb_waitlist.count);
2267 copy_info(&info, "\tCurrent Active Commands : %d\n",
2268 ha->scb_activelist.count - ha->num_ioctl);
2269 copy_info(&info, "\tCurrent Queued PT Commands : %d\n",
2270 ha->copp_waitlist.count);
2271 copy_info(&info, "\tCurrent Active PT Commands : %d\n",
2272 ha->num_ioctl);
2273
2274 copy_info(&info, "\n");
2275
2276 return (info.localpos);
2277}
2278
2279/****************************************************************************/
2280/* */
2281/* Routine Name: copy_mem_info */
2282/* */
2283/* Routine Description: */
2284/* */
2285/* Copy data into an IPS_INFOSTR structure */
2286/* */
2287/****************************************************************************/
2288static void
2289copy_mem_info(IPS_INFOSTR * info, char *data, int len)
2290{
2291 METHOD_TRACE("copy_mem_info", 1);
2292
2293 if (info->pos + len < info->offset) {
2294 info->pos += len;
2295 return;
2296 }
2297
2298 if (info->pos < info->offset) {
2299 data += (info->offset - info->pos);
2300 len -= (info->offset - info->pos);
2301 info->pos += (info->offset - info->pos);
2302 }
2303
2304 if (info->localpos + len > info->length)
2305 len = info->length - info->localpos;
2306
2307 if (len > 0) {
2308 memcpy(info->buffer + info->localpos, data, len);
2309 info->pos += len;
2310 info->localpos += len;
2311 }
2312}
2313
2314/****************************************************************************/
2315/* */
2316/* Routine Name: copy_info */
2317/* */
2318/* Routine Description: */
2319/* */
2320/* printf style wrapper for an info structure */
2321/* */
2322/****************************************************************************/
2323static int
2324copy_info(IPS_INFOSTR * info, char *fmt, ...)
2325{
2326 va_list args;
2327 char buf[128];
2328 int len;
2329
2330 METHOD_TRACE("copy_info", 1);
2331
2332 va_start(args, fmt);
2333 len = vsprintf(buf, fmt, args);
2334 va_end(args);
2335
2336 copy_mem_info(info, buf, len);
2337
2338 return (len);
2339}
2340
2341/****************************************************************************/
2342/* */
2343/* Routine Name: ips_identify_controller */
2344/* */
2345/* Routine Description: */
2346/* */
2347/* Identify this controller */
2348/* */
2349/****************************************************************************/
2350static void
2351ips_identify_controller(ips_ha_t * ha)
2352{
2353 METHOD_TRACE("ips_identify_controller", 1);
2354
2355 switch (ha->device_id) {
2356 case IPS_DEVICEID_COPPERHEAD:
2357 if (ha->revision_id <= IPS_REVID_SERVERAID) {
2358 ha->ad_type = IPS_ADTYPE_SERVERAID;
2359 } else if (ha->revision_id == IPS_REVID_SERVERAID2) {
2360 ha->ad_type = IPS_ADTYPE_SERVERAID2;
2361 } else if (ha->revision_id == IPS_REVID_NAVAJO) {
2362 ha->ad_type = IPS_ADTYPE_NAVAJO;
2363 } else if ((ha->revision_id == IPS_REVID_SERVERAID2)
2364 && (ha->slot_num == 0)) {
2365 ha->ad_type = IPS_ADTYPE_KIOWA;
2366 } else if ((ha->revision_id >= IPS_REVID_CLARINETP1) &&
2367 (ha->revision_id <= IPS_REVID_CLARINETP3)) {
2368 if (ha->enq->ucMaxPhysicalDevices == 15)
2369 ha->ad_type = IPS_ADTYPE_SERVERAID3L;
2370 else
2371 ha->ad_type = IPS_ADTYPE_SERVERAID3;
2372 } else if ((ha->revision_id >= IPS_REVID_TROMBONE32) &&
2373 (ha->revision_id <= IPS_REVID_TROMBONE64)) {
2374 ha->ad_type = IPS_ADTYPE_SERVERAID4H;
2375 }
2376 break;
2377
2378 case IPS_DEVICEID_MORPHEUS:
2379 switch (ha->subdevice_id) {
2380 case IPS_SUBDEVICEID_4L:
2381 ha->ad_type = IPS_ADTYPE_SERVERAID4L;
2382 break;
2383
2384 case IPS_SUBDEVICEID_4M:
2385 ha->ad_type = IPS_ADTYPE_SERVERAID4M;
2386 break;
2387
2388 case IPS_SUBDEVICEID_4MX:
2389 ha->ad_type = IPS_ADTYPE_SERVERAID4MX;
2390 break;
2391
2392 case IPS_SUBDEVICEID_4LX:
2393 ha->ad_type = IPS_ADTYPE_SERVERAID4LX;
2394 break;
2395
2396 case IPS_SUBDEVICEID_5I2:
2397 ha->ad_type = IPS_ADTYPE_SERVERAID5I2;
2398 break;
2399
2400 case IPS_SUBDEVICEID_5I1:
2401 ha->ad_type = IPS_ADTYPE_SERVERAID5I1;
2402 break;
2403 }
2404
2405 break;
2406
2407 case IPS_DEVICEID_MARCO:
2408 switch (ha->subdevice_id) {
2409 case IPS_SUBDEVICEID_6M:
2410 ha->ad_type = IPS_ADTYPE_SERVERAID6M;
2411 break;
2412 case IPS_SUBDEVICEID_6I:
2413 ha->ad_type = IPS_ADTYPE_SERVERAID6I;
2414 break;
2415 case IPS_SUBDEVICEID_7k:
2416 ha->ad_type = IPS_ADTYPE_SERVERAID7k;
2417 break;
2418 case IPS_SUBDEVICEID_7M:
2419 ha->ad_type = IPS_ADTYPE_SERVERAID7M;
2420 break;
2421 }
2422 break;
2423 }
2424}
2425
2426/****************************************************************************/
2427/* */
2428/* Routine Name: ips_get_bios_version */
2429/* */
2430/* Routine Description: */
2431/* */
2432/* Get the BIOS revision number */
2433/* */
2434/****************************************************************************/
2435static void
2436ips_get_bios_version(ips_ha_t * ha, int intr)
2437{
2438 ips_scb_t *scb;
2439 int ret;
2440 uint8_t major;
2441 uint8_t minor;
2442 uint8_t subminor;
2443 uint8_t *buffer;
2444 char hexDigits[] =
2445 { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C',
2446 'D', 'E', 'F' };
2447
2448 METHOD_TRACE("ips_get_bios_version", 1);
2449
2450 major = 0;
2451 minor = 0;
2452
2453 strncpy(ha->bios_version, " ?", 8);
2454
2455 if (ha->device_id == IPS_DEVICEID_COPPERHEAD) {
2456 if (IPS_USE_MEMIO(ha)) {
2457 /* Memory Mapped I/O */
2458
2459 /* test 1st byte */
2460 writel(0, ha->mem_ptr + IPS_REG_FLAP);
2461 if (ha->revision_id == IPS_REVID_TROMBONE64)
2462 udelay(25); /* 25 us */
2463
2464 if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0x55)
2465 return;
2466
2467 writel(1, ha->mem_ptr + IPS_REG_FLAP);
2468 if (ha->revision_id == IPS_REVID_TROMBONE64)
2469 udelay(25); /* 25 us */
2470
2471 if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0xAA)
2472 return;
2473
2474 /* Get Major version */
2475 writel(0x1FF, ha->mem_ptr + IPS_REG_FLAP);
2476 if (ha->revision_id == IPS_REVID_TROMBONE64)
2477 udelay(25); /* 25 us */
2478
2479 major = readb(ha->mem_ptr + IPS_REG_FLDP);
2480
2481 /* Get Minor version */
2482 writel(0x1FE, ha->mem_ptr + IPS_REG_FLAP);
2483 if (ha->revision_id == IPS_REVID_TROMBONE64)
2484 udelay(25); /* 25 us */
2485 minor = readb(ha->mem_ptr + IPS_REG_FLDP);
2486
2487 /* Get SubMinor version */
2488 writel(0x1FD, ha->mem_ptr + IPS_REG_FLAP);
2489 if (ha->revision_id == IPS_REVID_TROMBONE64)
2490 udelay(25); /* 25 us */
2491 subminor = readb(ha->mem_ptr + IPS_REG_FLDP);
2492
2493 } else {
2494 /* Programmed I/O */
2495
2496 /* test 1st byte */
2497 outl(0, ha->io_addr + IPS_REG_FLAP);
2498 if (ha->revision_id == IPS_REVID_TROMBONE64)
2499 udelay(25); /* 25 us */
2500
2501 if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55)
2502 return;
2503
2504 outl(cpu_to_le32(1), ha->io_addr + IPS_REG_FLAP);
2505 if (ha->revision_id == IPS_REVID_TROMBONE64)
2506 udelay(25); /* 25 us */
2507
2508 if (inb(ha->io_addr + IPS_REG_FLDP) != 0xAA)
2509 return;
2510
2511 /* Get Major version */
2512 outl(cpu_to_le32(0x1FF), ha->io_addr + IPS_REG_FLAP);
2513 if (ha->revision_id == IPS_REVID_TROMBONE64)
2514 udelay(25); /* 25 us */
2515
2516 major = inb(ha->io_addr + IPS_REG_FLDP);
2517
2518 /* Get Minor version */
2519 outl(cpu_to_le32(0x1FE), ha->io_addr + IPS_REG_FLAP);
2520 if (ha->revision_id == IPS_REVID_TROMBONE64)
2521 udelay(25); /* 25 us */
2522
2523 minor = inb(ha->io_addr + IPS_REG_FLDP);
2524
2525 /* Get SubMinor version */
2526 outl(cpu_to_le32(0x1FD), ha->io_addr + IPS_REG_FLAP);
2527 if (ha->revision_id == IPS_REVID_TROMBONE64)
2528 udelay(25); /* 25 us */
2529
2530 subminor = inb(ha->io_addr + IPS_REG_FLDP);
2531
2532 }
2533 } else {
2534 /* Morpheus Family - Send Command to the card */
2535
2536 buffer = ha->ioctl_data;
2537
2538 memset(buffer, 0, 0x1000);
2539
2540 scb = &ha->scbs[ha->max_cmds - 1];
2541
2542 ips_init_scb(ha, scb);
2543
2544 scb->timeout = ips_cmd_timeout;
2545 scb->cdb[0] = IPS_CMD_RW_BIOSFW;
2546
2547 scb->cmd.flashfw.op_code = IPS_CMD_RW_BIOSFW;
2548 scb->cmd.flashfw.command_id = IPS_COMMAND_ID(ha, scb);
2549 scb->cmd.flashfw.type = 1;
2550 scb->cmd.flashfw.direction = 0;
2551 scb->cmd.flashfw.count = cpu_to_le32(0x800);
2552 scb->cmd.flashfw.total_packets = 1;
2553 scb->cmd.flashfw.packet_num = 0;
2554 scb->data_len = 0x1000;
2555 scb->cmd.flashfw.buffer_addr = ha->ioctl_busaddr;
2556
2557 /* issue the command */
2558 if (((ret =
2559 ips_send_wait(ha, scb, ips_cmd_timeout,
2560 intr)) == IPS_FAILURE)
2561 || (ret == IPS_SUCCESS_IMM)
2562 || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) {
2563 /* Error occurred */
2564
2565 return;
2566 }
2567
2568 if ((buffer[0xC0] == 0x55) && (buffer[0xC1] == 0xAA)) {
2569 major = buffer[0x1ff + 0xC0]; /* Offset 0x1ff after the header (0xc0) */
2570 minor = buffer[0x1fe + 0xC0]; /* Offset 0x1fe after the header (0xc0) */
2571 subminor = buffer[0x1fd + 0xC0]; /* Offset 0x1fd after the header (0xc0) */
2572 } else {
2573 return;
2574 }
2575 }
2576
2577 ha->bios_version[0] = hexDigits[(major & 0xF0) >> 4];
2578 ha->bios_version[1] = '.';
2579 ha->bios_version[2] = hexDigits[major & 0x0F];
2580 ha->bios_version[3] = hexDigits[subminor];
2581 ha->bios_version[4] = '.';
2582 ha->bios_version[5] = hexDigits[(minor & 0xF0) >> 4];
2583 ha->bios_version[6] = hexDigits[minor & 0x0F];
2584 ha->bios_version[7] = 0;
2585}
2586
2587/****************************************************************************/
2588/* */
2589/* Routine Name: ips_hainit */
2590/* */
2591/* Routine Description: */
2592/* */
2593/* Initialize the controller */
2594/* */
2595/* NOTE: Assumes to be called from with a lock */
2596/* */
2597/****************************************************************************/
2598static int
2599ips_hainit(ips_ha_t * ha)
2600{
2601 int i;
2602 struct timeval tv;
2603
2604 METHOD_TRACE("ips_hainit", 1);
2605
2606 if (!ha)
2607 return (0);
2608
2609 if (ha->func.statinit)
2610 (*ha->func.statinit) (ha);
2611
2612 if (ha->func.enableint)
2613 (*ha->func.enableint) (ha);
2614
2615 /* Send FFDC */
2616 ha->reset_count = 1;
2617 do_gettimeofday(&tv);
2618 ha->last_ffdc = tv.tv_sec;
2619 ips_ffdc_reset(ha, IPS_INTR_IORL);
2620
2621 if (!ips_read_config(ha, IPS_INTR_IORL)) {
2622 IPS_PRINTK(KERN_WARNING, ha->pcidev,
2623 "unable to read config from controller.\n");
2624
2625 return (0);
2626 }
2627 /* end if */
2628 if (!ips_read_adapter_status(ha, IPS_INTR_IORL)) {
2629 IPS_PRINTK(KERN_WARNING, ha->pcidev,
2630 "unable to read controller status.\n");
2631
2632 return (0);
2633 }
2634
2635 /* Identify this controller */
2636 ips_identify_controller(ha);
2637
2638 if (!ips_read_subsystem_parameters(ha, IPS_INTR_IORL)) {
2639 IPS_PRINTK(KERN_WARNING, ha->pcidev,
2640 "unable to read subsystem parameters.\n");
2641
2642 return (0);
2643 }
2644
2645 /* write nvram user page 5 */
2646 if (!ips_write_driver_status(ha, IPS_INTR_IORL)) {
2647 IPS_PRINTK(KERN_WARNING, ha->pcidev,
2648 "unable to write driver info to controller.\n");
2649
2650 return (0);
2651 }
2652
2653 /* If there are Logical Drives and a Reset Occurred, then an EraseStripeLock is Needed */
2654 if ((ha->conf->ucLogDriveCount > 0) && (ha->requires_esl == 1))
2655 ips_clear_adapter(ha, IPS_INTR_IORL);
2656
2657 /* set limits on SID, LUN, BUS */
2658 ha->ntargets = IPS_MAX_TARGETS + 1;
2659 ha->nlun = 1;
2660 ha->nbus = (ha->enq->ucMaxPhysicalDevices / IPS_MAX_TARGETS) + 1;
2661
2662 switch (ha->conf->logical_drive[0].ucStripeSize) {
2663 case 4:
2664 ha->max_xfer = 0x10000;
2665 break;
2666
2667 case 5:
2668 ha->max_xfer = 0x20000;
2669 break;
2670
2671 case 6:
2672 ha->max_xfer = 0x40000;
2673 break;
2674
2675 case 7:
2676 default:
2677 ha->max_xfer = 0x80000;
2678 break;
2679 }
2680
2681 /* setup max concurrent commands */
2682 if (le32_to_cpu(ha->subsys->param[4]) & 0x1) {
2683 /* Use the new method */
2684 ha->max_cmds = ha->enq->ucConcurrentCmdCount;
2685 } else {
2686 /* use the old method */
2687 switch (ha->conf->logical_drive[0].ucStripeSize) {
2688 case 4:
2689 ha->max_cmds = 32;
2690 break;
2691
2692 case 5:
2693 ha->max_cmds = 16;
2694 break;
2695
2696 case 6:
2697 ha->max_cmds = 8;
2698 break;
2699
2700 case 7:
2701 default:
2702 ha->max_cmds = 4;
2703 break;
2704 }
2705 }
2706
2707 /* Limit the Active Commands on a Lite Adapter */
2708 if ((ha->ad_type == IPS_ADTYPE_SERVERAID3L) ||
2709 (ha->ad_type == IPS_ADTYPE_SERVERAID4L) ||
2710 (ha->ad_type == IPS_ADTYPE_SERVERAID4LX)) {
2711 if ((ha->max_cmds > MaxLiteCmds) && (MaxLiteCmds))
2712 ha->max_cmds = MaxLiteCmds;
2713 }
2714
2715 /* set controller IDs */
2716 ha->ha_id[0] = IPS_ADAPTER_ID;
2717 for (i = 1; i < ha->nbus; i++) {
2718 ha->ha_id[i] = ha->conf->init_id[i - 1] & 0x1f;
2719 ha->dcdb_active[i - 1] = 0;
2720 }
2721
2722 return (1);
2723}
2724
2725/****************************************************************************/
2726/* */
2727/* Routine Name: ips_next */
2728/* */
2729/* Routine Description: */
2730/* */
2731/* Take the next command off the queue and send it to the controller */
2732/* */
2733/****************************************************************************/
2734static void
2735ips_next(ips_ha_t * ha, int intr)
2736{
2737 ips_scb_t *scb;
2738 Scsi_Cmnd *SC;
2739 Scsi_Cmnd *p;
2740 Scsi_Cmnd *q;
2741 ips_copp_wait_item_t *item;
2742 int ret;
2743 unsigned long cpu_flags = 0;
2744 struct Scsi_Host *host;
2745 METHOD_TRACE("ips_next", 1);
2746
2747 if (!ha)
2748 return;
2749 host = ips_sh[ha->host_num];
2750 /*
2751 * Block access to the queue function so
2752 * this command won't time out
2753 */
2754 if (intr == IPS_INTR_ON)
2755 IPS_LOCK_SAVE(host->host_lock, cpu_flags);
2756
2757 if ((ha->subsys->param[3] & 0x300000)
2758 && (ha->scb_activelist.count == 0)) {
2759 struct timeval tv;
2760
2761 do_gettimeofday(&tv);
2762
2763 if (tv.tv_sec - ha->last_ffdc > IPS_SECS_8HOURS) {
2764 ha->last_ffdc = tv.tv_sec;
2765 ips_ffdc_time(ha);
2766 }
2767 }
2768
2769 /*
2770 * Send passthru commands
2771 * These have priority over normal I/O
2772 * but shouldn't affect performance too much
2773 * since we limit the number that can be active
2774 * on the card at any one time
2775 */
2776 while ((ha->num_ioctl < IPS_MAX_IOCTL) &&
2777 (ha->copp_waitlist.head) && (scb = ips_getscb(ha))) {
2778
2779 item = ips_removeq_copp_head(&ha->copp_waitlist);
2780 ha->num_ioctl++;
2781 if (intr == IPS_INTR_ON)
2782 IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags);
2783 scb->scsi_cmd = item->scsi_cmd;
2784 kfree(item);
2785
2786 ret = ips_make_passthru(ha, scb->scsi_cmd, scb, intr);
2787
2788 if (intr == IPS_INTR_ON)
2789 IPS_LOCK_SAVE(host->host_lock, cpu_flags);
2790 switch (ret) {
2791 case IPS_FAILURE:
2792 if (scb->scsi_cmd) {
2793 scb->scsi_cmd->result = DID_ERROR << 16;
2794 scb->scsi_cmd->scsi_done(scb->scsi_cmd);
2795 }
2796
2797 ips_freescb(ha, scb);
2798 break;
2799 case IPS_SUCCESS_IMM:
2800 if (scb->scsi_cmd) {
2801 scb->scsi_cmd->result = DID_OK << 16;
2802 scb->scsi_cmd->scsi_done(scb->scsi_cmd);
2803 }
2804
2805 ips_freescb(ha, scb);
2806 break;
2807 default:
2808 break;
2809 } /* end case */
2810
2811 if (ret != IPS_SUCCESS) {
2812 ha->num_ioctl--;
2813 continue;
2814 }
2815
2816 ret = ips_send_cmd(ha, scb);
2817
2818 if (ret == IPS_SUCCESS)
2819 ips_putq_scb_head(&ha->scb_activelist, scb);
2820 else
2821 ha->num_ioctl--;
2822
2823 switch (ret) {
2824 case IPS_FAILURE:
2825 if (scb->scsi_cmd) {
2826 scb->scsi_cmd->result = DID_ERROR << 16;
2827 }
2828
2829 ips_freescb(ha, scb);
2830 break;
2831 case IPS_SUCCESS_IMM:
2832 ips_freescb(ha, scb);
2833 break;
2834 default:
2835 break;
2836 } /* end case */
2837
2838 }
2839
2840 /*
2841 * Send "Normal" I/O commands
2842 */
2843
2844 p = ha->scb_waitlist.head;
2845 while ((p) && (scb = ips_getscb(ha))) {
Jeff Garzik422c0d62005-10-24 18:05:09 -04002846 if ((scmd_channel(p) > 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002847 && (ha->
Jeff Garzik422c0d62005-10-24 18:05:09 -04002848 dcdb_active[scmd_channel(p) -
2849 1] & (1 << scmd_id(p)))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002850 ips_freescb(ha, scb);
2851 p = (Scsi_Cmnd *) p->host_scribble;
2852 continue;
2853 }
2854
2855 q = p;
2856 SC = ips_removeq_wait(&ha->scb_waitlist, q);
2857
2858 if (intr == IPS_INTR_ON)
2859 IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags); /* Unlock HA after command is taken off queue */
2860
2861 SC->result = DID_OK;
2862 SC->host_scribble = NULL;
2863
2864 memset(SC->sense_buffer, 0, sizeof (SC->sense_buffer));
2865
2866 scb->target_id = SC->device->id;
2867 scb->lun = SC->device->lun;
2868 scb->bus = SC->device->channel;
2869 scb->scsi_cmd = SC;
2870 scb->breakup = 0;
2871 scb->data_len = 0;
2872 scb->callback = ipsintr_done;
2873 scb->timeout = ips_cmd_timeout;
2874 memset(&scb->cmd, 0, 16);
2875
2876 /* copy in the CDB */
2877 memcpy(scb->cdb, SC->cmnd, SC->cmd_len);
2878
2879 /* Now handle the data buffer */
2880 if (SC->use_sg) {
2881 struct scatterlist *sg;
2882 int i;
2883
2884 sg = SC->request_buffer;
2885 scb->sg_count = pci_map_sg(ha->pcidev, sg, SC->use_sg,
be7db052005-04-17 15:26:13 -05002886 SC->sc_data_direction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002887 scb->flags |= IPS_SCB_MAP_SG;
2888 for (i = 0; i < scb->sg_count; i++) {
2889 if (ips_fill_scb_sg_single
2890 (ha, sg_dma_address(&sg[i]), scb, i,
2891 sg_dma_len(&sg[i])) < 0)
2892 break;
2893 }
2894 scb->dcdb.transfer_length = scb->data_len;
2895 } else {
2896 if (SC->request_bufflen) {
2897 scb->data_busaddr =
2898 pci_map_single(ha->pcidev,
2899 SC->request_buffer,
2900 SC->request_bufflen,
be7db052005-04-17 15:26:13 -05002901 SC->sc_data_direction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002902 scb->flags |= IPS_SCB_MAP_SINGLE;
2903 ips_fill_scb_sg_single(ha, scb->data_busaddr,
2904 scb, 0,
2905 SC->request_bufflen);
2906 scb->dcdb.transfer_length = scb->data_len;
2907 } else {
2908 scb->data_busaddr = 0L;
2909 scb->sg_len = 0;
2910 scb->data_len = 0;
2911 scb->dcdb.transfer_length = 0;
2912 }
2913
2914 }
2915
2916 scb->dcdb.cmd_attribute =
2917 ips_command_direction[scb->scsi_cmd->cmnd[0]];
2918
2919 /* Allow a WRITE BUFFER Command to Have no Data */
2920 /* This is Used by Tape Flash Utilites */
2921 if ((scb->scsi_cmd->cmnd[0] == WRITE_BUFFER) && (scb->data_len == 0))
2922 scb->dcdb.cmd_attribute = 0;
2923
2924 if (!(scb->dcdb.cmd_attribute & 0x3))
2925 scb->dcdb.transfer_length = 0;
2926
2927 if (scb->data_len >= IPS_MAX_XFER) {
2928 scb->dcdb.cmd_attribute |= IPS_TRANSFER64K;
2929 scb->dcdb.transfer_length = 0;
2930 }
2931 if (intr == IPS_INTR_ON)
2932 IPS_LOCK_SAVE(host->host_lock, cpu_flags);
2933
2934 ret = ips_send_cmd(ha, scb);
2935
2936 switch (ret) {
2937 case IPS_SUCCESS:
2938 ips_putq_scb_head(&ha->scb_activelist, scb);
2939 break;
2940 case IPS_FAILURE:
2941 if (scb->scsi_cmd) {
2942 scb->scsi_cmd->result = DID_ERROR << 16;
2943 scb->scsi_cmd->scsi_done(scb->scsi_cmd);
2944 }
2945
2946 if (scb->bus)
2947 ha->dcdb_active[scb->bus - 1] &=
2948 ~(1 << scb->target_id);
2949
2950 ips_freescb(ha, scb);
2951 break;
2952 case IPS_SUCCESS_IMM:
2953 if (scb->scsi_cmd)
2954 scb->scsi_cmd->scsi_done(scb->scsi_cmd);
2955
2956 if (scb->bus)
2957 ha->dcdb_active[scb->bus - 1] &=
2958 ~(1 << scb->target_id);
2959
2960 ips_freescb(ha, scb);
2961 break;
2962 default:
2963 break;
2964 } /* end case */
2965
2966 p = (Scsi_Cmnd *) p->host_scribble;
2967
2968 } /* end while */
2969
2970 if (intr == IPS_INTR_ON)
2971 IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags);
2972}
2973
2974/****************************************************************************/
2975/* */
2976/* Routine Name: ips_putq_scb_head */
2977/* */
2978/* Routine Description: */
2979/* */
2980/* Add an item to the head of the queue */
2981/* */
2982/* ASSUMED to be called from within the HA lock */
2983/* */
2984/****************************************************************************/
2985static void
2986ips_putq_scb_head(ips_scb_queue_t * queue, ips_scb_t * item)
2987{
2988 METHOD_TRACE("ips_putq_scb_head", 1);
2989
2990 if (!item)
2991 return;
2992
2993 item->q_next = queue->head;
2994 queue->head = item;
2995
2996 if (!queue->tail)
2997 queue->tail = item;
2998
2999 queue->count++;
3000}
3001
3002/****************************************************************************/
3003/* */
3004/* Routine Name: ips_removeq_scb_head */
3005/* */
3006/* Routine Description: */
3007/* */
3008/* Remove the head of the queue */
3009/* */
3010/* ASSUMED to be called from within the HA lock */
3011/* */
3012/****************************************************************************/
3013static ips_scb_t *
3014ips_removeq_scb_head(ips_scb_queue_t * queue)
3015{
3016 ips_scb_t *item;
3017
3018 METHOD_TRACE("ips_removeq_scb_head", 1);
3019
3020 item = queue->head;
3021
3022 if (!item) {
3023 return (NULL);
3024 }
3025
3026 queue->head = item->q_next;
3027 item->q_next = NULL;
3028
3029 if (queue->tail == item)
3030 queue->tail = NULL;
3031
3032 queue->count--;
3033
3034 return (item);
3035}
3036
3037/****************************************************************************/
3038/* */
3039/* Routine Name: ips_removeq_scb */
3040/* */
3041/* Routine Description: */
3042/* */
3043/* Remove an item from a queue */
3044/* */
3045/* ASSUMED to be called from within the HA lock */
3046/* */
3047/****************************************************************************/
3048static ips_scb_t *
3049ips_removeq_scb(ips_scb_queue_t * queue, ips_scb_t * item)
3050{
3051 ips_scb_t *p;
3052
3053 METHOD_TRACE("ips_removeq_scb", 1);
3054
3055 if (!item)
3056 return (NULL);
3057
3058 if (item == queue->head) {
3059 return (ips_removeq_scb_head(queue));
3060 }
3061
3062 p = queue->head;
3063
3064 while ((p) && (item != p->q_next))
3065 p = p->q_next;
3066
3067 if (p) {
3068 /* found a match */
3069 p->q_next = item->q_next;
3070
3071 if (!item->q_next)
3072 queue->tail = p;
3073
3074 item->q_next = NULL;
3075 queue->count--;
3076
3077 return (item);
3078 }
3079
3080 return (NULL);
3081}
3082
3083/****************************************************************************/
3084/* */
3085/* Routine Name: ips_putq_wait_tail */
3086/* */
3087/* Routine Description: */
3088/* */
3089/* Add an item to the tail of the queue */
3090/* */
3091/* ASSUMED to be called from within the HA lock */
3092/* */
3093/****************************************************************************/
3094static void
3095ips_putq_wait_tail(ips_wait_queue_t * queue, Scsi_Cmnd * item)
3096{
3097 METHOD_TRACE("ips_putq_wait_tail", 1);
3098
3099 if (!item)
3100 return;
3101
3102 item->host_scribble = NULL;
3103
3104 if (queue->tail)
3105 queue->tail->host_scribble = (char *) item;
3106
3107 queue->tail = item;
3108
3109 if (!queue->head)
3110 queue->head = item;
3111
3112 queue->count++;
3113}
3114
3115/****************************************************************************/
3116/* */
3117/* Routine Name: ips_removeq_wait_head */
3118/* */
3119/* Routine Description: */
3120/* */
3121/* Remove the head of the queue */
3122/* */
3123/* ASSUMED to be called from within the HA lock */
3124/* */
3125/****************************************************************************/
3126static Scsi_Cmnd *
3127ips_removeq_wait_head(ips_wait_queue_t * queue)
3128{
3129 Scsi_Cmnd *item;
3130
3131 METHOD_TRACE("ips_removeq_wait_head", 1);
3132
3133 item = queue->head;
3134
3135 if (!item) {
3136 return (NULL);
3137 }
3138
3139 queue->head = (Scsi_Cmnd *) item->host_scribble;
3140 item->host_scribble = NULL;
3141
3142 if (queue->tail == item)
3143 queue->tail = NULL;
3144
3145 queue->count--;
3146
3147 return (item);
3148}
3149
3150/****************************************************************************/
3151/* */
3152/* Routine Name: ips_removeq_wait */
3153/* */
3154/* Routine Description: */
3155/* */
3156/* Remove an item from a queue */
3157/* */
3158/* ASSUMED to be called from within the HA lock */
3159/* */
3160/****************************************************************************/
3161static Scsi_Cmnd *
3162ips_removeq_wait(ips_wait_queue_t * queue, Scsi_Cmnd * item)
3163{
3164 Scsi_Cmnd *p;
3165
3166 METHOD_TRACE("ips_removeq_wait", 1);
3167
3168 if (!item)
3169 return (NULL);
3170
3171 if (item == queue->head) {
3172 return (ips_removeq_wait_head(queue));
3173 }
3174
3175 p = queue->head;
3176
3177 while ((p) && (item != (Scsi_Cmnd *) p->host_scribble))
3178 p = (Scsi_Cmnd *) p->host_scribble;
3179
3180 if (p) {
3181 /* found a match */
3182 p->host_scribble = item->host_scribble;
3183
3184 if (!item->host_scribble)
3185 queue->tail = p;
3186
3187 item->host_scribble = NULL;
3188 queue->count--;
3189
3190 return (item);
3191 }
3192
3193 return (NULL);
3194}
3195
3196/****************************************************************************/
3197/* */
3198/* Routine Name: ips_putq_copp_tail */
3199/* */
3200/* Routine Description: */
3201/* */
3202/* Add an item to the tail of the queue */
3203/* */
3204/* ASSUMED to be called from within the HA lock */
3205/* */
3206/****************************************************************************/
3207static void
3208ips_putq_copp_tail(ips_copp_queue_t * queue, ips_copp_wait_item_t * item)
3209{
3210 METHOD_TRACE("ips_putq_copp_tail", 1);
3211
3212 if (!item)
3213 return;
3214
3215 item->next = NULL;
3216
3217 if (queue->tail)
3218 queue->tail->next = item;
3219
3220 queue->tail = item;
3221
3222 if (!queue->head)
3223 queue->head = item;
3224
3225 queue->count++;
3226}
3227
3228/****************************************************************************/
3229/* */
3230/* Routine Name: ips_removeq_copp_head */
3231/* */
3232/* Routine Description: */
3233/* */
3234/* Remove the head of the queue */
3235/* */
3236/* ASSUMED to be called from within the HA lock */
3237/* */
3238/****************************************************************************/
3239static ips_copp_wait_item_t *
3240ips_removeq_copp_head(ips_copp_queue_t * queue)
3241{
3242 ips_copp_wait_item_t *item;
3243
3244 METHOD_TRACE("ips_removeq_copp_head", 1);
3245
3246 item = queue->head;
3247
3248 if (!item) {
3249 return (NULL);
3250 }
3251
3252 queue->head = item->next;
3253 item->next = NULL;
3254
3255 if (queue->tail == item)
3256 queue->tail = NULL;
3257
3258 queue->count--;
3259
3260 return (item);
3261}
3262
3263/****************************************************************************/
3264/* */
3265/* Routine Name: ips_removeq_copp */
3266/* */
3267/* Routine Description: */
3268/* */
3269/* Remove an item from a queue */
3270/* */
3271/* ASSUMED to be called from within the HA lock */
3272/* */
3273/****************************************************************************/
3274static ips_copp_wait_item_t *
3275ips_removeq_copp(ips_copp_queue_t * queue, ips_copp_wait_item_t * item)
3276{
3277 ips_copp_wait_item_t *p;
3278
3279 METHOD_TRACE("ips_removeq_copp", 1);
3280
3281 if (!item)
3282 return (NULL);
3283
3284 if (item == queue->head) {
3285 return (ips_removeq_copp_head(queue));
3286 }
3287
3288 p = queue->head;
3289
3290 while ((p) && (item != p->next))
3291 p = p->next;
3292
3293 if (p) {
3294 /* found a match */
3295 p->next = item->next;
3296
3297 if (!item->next)
3298 queue->tail = p;
3299
3300 item->next = NULL;
3301 queue->count--;
3302
3303 return (item);
3304 }
3305
3306 return (NULL);
3307}
3308
3309/****************************************************************************/
3310/* */
3311/* Routine Name: ipsintr_blocking */
3312/* */
3313/* Routine Description: */
3314/* */
3315/* Finalize an interrupt for internal commands */
3316/* */
3317/****************************************************************************/
3318static void
3319ipsintr_blocking(ips_ha_t * ha, ips_scb_t * scb)
3320{
3321 METHOD_TRACE("ipsintr_blocking", 2);
3322
3323 ips_freescb(ha, scb);
3324 if ((ha->waitflag == TRUE) && (ha->cmd_in_progress == scb->cdb[0])) {
3325 ha->waitflag = FALSE;
3326
3327 return;
3328 }
3329}
3330
3331/****************************************************************************/
3332/* */
3333/* Routine Name: ipsintr_done */
3334/* */
3335/* Routine Description: */
3336/* */
3337/* Finalize an interrupt for non-internal commands */
3338/* */
3339/****************************************************************************/
3340static void
3341ipsintr_done(ips_ha_t * ha, ips_scb_t * scb)
3342{
3343 METHOD_TRACE("ipsintr_done", 2);
3344
3345 if (!scb) {
3346 IPS_PRINTK(KERN_WARNING, ha->pcidev,
3347 "Spurious interrupt; scb NULL.\n");
3348
3349 return;
3350 }
3351
3352 if (scb->scsi_cmd == NULL) {
3353 /* unexpected interrupt */
3354 IPS_PRINTK(KERN_WARNING, ha->pcidev,
3355 "Spurious interrupt; scsi_cmd not set.\n");
3356
3357 return;
3358 }
3359
3360 ips_done(ha, scb);
3361}
3362
3363/****************************************************************************/
3364/* */
3365/* Routine Name: ips_done */
3366/* */
3367/* Routine Description: */
3368/* */
3369/* Do housekeeping on completed commands */
3370/* ASSUMED to be called form within the request lock */
3371/****************************************************************************/
3372static void
3373ips_done(ips_ha_t * ha, ips_scb_t * scb)
3374{
3375 int ret;
3376
3377 METHOD_TRACE("ips_done", 1);
3378
3379 if (!scb)
3380 return;
3381
3382 if ((scb->scsi_cmd) && (ips_is_passthru(scb->scsi_cmd))) {
3383 ips_cleanup_passthru(ha, scb);
3384 ha->num_ioctl--;
3385 } else {
3386 /*
3387 * Check to see if this command had too much
3388 * data and had to be broke up. If so, queue
3389 * the rest of the data and continue.
3390 */
3391 if ((scb->breakup) || (scb->sg_break)) {
3392 /* we had a data breakup */
3393 scb->data_len = 0;
3394
3395 if (scb->sg_count) {
3396 /* S/G request */
3397 struct scatterlist *sg;
3398 int ips_sg_index = 0;
3399 int sg_dma_index;
3400
3401 sg = scb->scsi_cmd->request_buffer;
3402
3403 /* Spin forward to last dma chunk */
3404 sg_dma_index = scb->breakup;
3405
3406 /* Take care of possible partial on last chunk */
3407 ips_fill_scb_sg_single(ha,
3408 sg_dma_address(&sg
3409 [sg_dma_index]),
3410 scb, ips_sg_index++,
3411 sg_dma_len(&sg
3412 [sg_dma_index]));
3413
3414 for (; sg_dma_index < scb->sg_count;
3415 sg_dma_index++) {
3416 if (ips_fill_scb_sg_single
3417 (ha,
3418 sg_dma_address(&sg[sg_dma_index]),
3419 scb, ips_sg_index++,
3420 sg_dma_len(&sg[sg_dma_index])) < 0)
3421 break;
3422
3423 }
3424
3425 } else {
3426 /* Non S/G Request */
3427 (void) ips_fill_scb_sg_single(ha,
3428 scb->
3429 data_busaddr +
3430 (scb->sg_break *
3431 ha->max_xfer),
3432 scb, 0,
3433 scb->scsi_cmd->
3434 request_bufflen -
3435 (scb->sg_break *
3436 ha->max_xfer));
3437 }
3438
3439 scb->dcdb.transfer_length = scb->data_len;
3440 scb->dcdb.cmd_attribute |=
3441 ips_command_direction[scb->scsi_cmd->cmnd[0]];
3442
3443 if (!(scb->dcdb.cmd_attribute & 0x3))
3444 scb->dcdb.transfer_length = 0;
3445
3446 if (scb->data_len >= IPS_MAX_XFER) {
3447 scb->dcdb.cmd_attribute |= IPS_TRANSFER64K;
3448 scb->dcdb.transfer_length = 0;
3449 }
3450
3451 ret = ips_send_cmd(ha, scb);
3452
3453 switch (ret) {
3454 case IPS_FAILURE:
3455 if (scb->scsi_cmd) {
3456 scb->scsi_cmd->result = DID_ERROR << 16;
3457 scb->scsi_cmd->scsi_done(scb->scsi_cmd);
3458 }
3459
3460 ips_freescb(ha, scb);
3461 break;
3462 case IPS_SUCCESS_IMM:
3463 if (scb->scsi_cmd) {
3464 scb->scsi_cmd->result = DID_ERROR << 16;
3465 scb->scsi_cmd->scsi_done(scb->scsi_cmd);
3466 }
3467
3468 ips_freescb(ha, scb);
3469 break;
3470 default:
3471 break;
3472 } /* end case */
3473
3474 return;
3475 }
3476 } /* end if passthru */
3477
3478 if (scb->bus) {
3479 ha->dcdb_active[scb->bus - 1] &= ~(1 << scb->target_id);
3480 }
3481
3482 scb->scsi_cmd->scsi_done(scb->scsi_cmd);
3483
3484 ips_freescb(ha, scb);
3485}
3486
3487/****************************************************************************/
3488/* */
3489/* Routine Name: ips_map_status */
3490/* */
3491/* Routine Description: */
3492/* */
3493/* Map Controller Error codes to Linux Error Codes */
3494/* */
3495/****************************************************************************/
3496static int
3497ips_map_status(ips_ha_t * ha, ips_scb_t * scb, ips_stat_t * sp)
3498{
3499 int errcode;
3500 int device_error;
3501 uint32_t transfer_len;
3502 IPS_DCDB_TABLE_TAPE *tapeDCDB;
Jack Hammera5b3c862006-01-31 13:17:55 -05003503 IPS_SCSI_INQ_DATA inquiryData;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003504
3505 METHOD_TRACE("ips_map_status", 1);
3506
3507 if (scb->bus) {
3508 DEBUG_VAR(2,
3509 "(%s%d) Physical device error (%d %d %d): %x %x, Sense Key: %x, ASC: %x, ASCQ: %x",
3510 ips_name, ha->host_num,
3511 scb->scsi_cmd->device->channel,
3512 scb->scsi_cmd->device->id, scb->scsi_cmd->device->lun,
3513 scb->basic_status, scb->extended_status,
3514 scb->extended_status ==
3515 IPS_ERR_CKCOND ? scb->dcdb.sense_info[2] & 0xf : 0,
3516 scb->extended_status ==
3517 IPS_ERR_CKCOND ? scb->dcdb.sense_info[12] : 0,
3518 scb->extended_status ==
3519 IPS_ERR_CKCOND ? scb->dcdb.sense_info[13] : 0);
3520 }
3521
3522 /* default driver error */
3523 errcode = DID_ERROR;
3524 device_error = 0;
3525
3526 switch (scb->basic_status & IPS_GSC_STATUS_MASK) {
3527 case IPS_CMD_TIMEOUT:
3528 errcode = DID_TIME_OUT;
3529 break;
3530
3531 case IPS_INVAL_OPCO:
3532 case IPS_INVAL_CMD_BLK:
3533 case IPS_INVAL_PARM_BLK:
3534 case IPS_LD_ERROR:
3535 case IPS_CMD_CMPLT_WERROR:
3536 break;
3537
3538 case IPS_PHYS_DRV_ERROR:
3539 switch (scb->extended_status) {
3540 case IPS_ERR_SEL_TO:
3541 if (scb->bus)
3542 errcode = DID_NO_CONNECT;
3543
3544 break;
3545
3546 case IPS_ERR_OU_RUN:
3547 if ((scb->cmd.dcdb.op_code == IPS_CMD_EXTENDED_DCDB) ||
3548 (scb->cmd.dcdb.op_code ==
3549 IPS_CMD_EXTENDED_DCDB_SG)) {
3550 tapeDCDB = (IPS_DCDB_TABLE_TAPE *) & scb->dcdb;
3551 transfer_len = tapeDCDB->transfer_length;
3552 } else {
3553 transfer_len =
3554 (uint32_t) scb->dcdb.transfer_length;
3555 }
3556
3557 if ((scb->bus) && (transfer_len < scb->data_len)) {
3558 /* Underrun - set default to no error */
3559 errcode = DID_OK;
3560
3561 /* Restrict access to physical DASD */
Jack Hammera5b3c862006-01-31 13:17:55 -05003562 if (scb->scsi_cmd->cmnd[0] == INQUIRY) {
3563 ips_scmd_buf_read(scb->scsi_cmd,
3564 &inquiryData, sizeof (inquiryData));
3565 if ((inquiryData.DeviceType & 0x1f) == TYPE_DISK) {
3566 errcode = DID_TIME_OUT;
3567 break;
3568 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003569 }
3570 } else
3571 errcode = DID_ERROR;
3572
3573 break;
3574
3575 case IPS_ERR_RECOVERY:
3576 /* don't fail recovered errors */
3577 if (scb->bus)
3578 errcode = DID_OK;
3579
3580 break;
3581
3582 case IPS_ERR_HOST_RESET:
3583 case IPS_ERR_DEV_RESET:
3584 errcode = DID_RESET;
3585 break;
3586
3587 case IPS_ERR_CKCOND:
3588 if (scb->bus) {
3589 if ((scb->cmd.dcdb.op_code ==
3590 IPS_CMD_EXTENDED_DCDB)
3591 || (scb->cmd.dcdb.op_code ==
3592 IPS_CMD_EXTENDED_DCDB_SG)) {
3593 tapeDCDB =
3594 (IPS_DCDB_TABLE_TAPE *) & scb->dcdb;
3595 memcpy(scb->scsi_cmd->sense_buffer,
3596 tapeDCDB->sense_info,
3597 sizeof (scb->scsi_cmd->
3598 sense_buffer));
3599 } else {
3600 memcpy(scb->scsi_cmd->sense_buffer,
3601 scb->dcdb.sense_info,
3602 sizeof (scb->scsi_cmd->
3603 sense_buffer));
3604 }
3605 device_error = 2; /* check condition */
3606 }
3607
3608 errcode = DID_OK;
3609
3610 break;
3611
3612 default:
3613 errcode = DID_ERROR;
3614 break;
3615
3616 } /* end switch */
3617 } /* end switch */
3618
3619 scb->scsi_cmd->result = device_error | (errcode << 16);
3620
3621 return (1);
3622}
3623
3624/****************************************************************************/
3625/* */
3626/* Routine Name: ips_send_wait */
3627/* */
3628/* Routine Description: */
3629/* */
3630/* Send a command to the controller and wait for it to return */
3631/* */
3632/* The FFDC Time Stamp use this function for the callback, but doesn't */
3633/* actually need to wait. */
3634/****************************************************************************/
3635static int
3636ips_send_wait(ips_ha_t * ha, ips_scb_t * scb, int timeout, int intr)
3637{
3638 int ret;
3639
3640 METHOD_TRACE("ips_send_wait", 1);
3641
3642 if (intr != IPS_FFDC) { /* Won't be Waiting if this is a Time Stamp */
3643 ha->waitflag = TRUE;
3644 ha->cmd_in_progress = scb->cdb[0];
3645 }
3646 scb->callback = ipsintr_blocking;
3647 ret = ips_send_cmd(ha, scb);
3648
3649 if ((ret == IPS_FAILURE) || (ret == IPS_SUCCESS_IMM))
3650 return (ret);
3651
3652 if (intr != IPS_FFDC) /* Don't Wait around if this is a Time Stamp */
3653 ret = ips_wait(ha, timeout, intr);
3654
3655 return (ret);
3656}
3657
3658/****************************************************************************/
3659/* */
3660/* Routine Name: ips_scmd_buf_write */
3661/* */
3662/* Routine Description: */
3663/* Write data to Scsi_Cmnd request_buffer at proper offsets */
3664/****************************************************************************/
3665static void
3666ips_scmd_buf_write(Scsi_Cmnd * scmd, void *data, unsigned
3667 int count)
3668{
3669 if (scmd->use_sg) {
3670 int i;
3671 unsigned int min_cnt, xfer_cnt;
3672 char *cdata = (char *) data;
Jack Hammera3632fa2005-10-25 14:13:03 -04003673 unsigned char *buffer;
3674 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003675 struct scatterlist *sg = scmd->request_buffer;
3676 for (i = 0, xfer_cnt = 0;
3677 (i < scmd->use_sg) && (xfer_cnt < count); i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003678 min_cnt = min(count - xfer_cnt, sg[i].length);
Jack Hammera3632fa2005-10-25 14:13:03 -04003679
3680 /* kmap_atomic() ensures addressability of the data buffer.*/
3681 /* local_irq_save() protects the KM_IRQ0 address slot. */
3682 local_irq_save(flags);
3683 buffer = kmap_atomic(sg[i].page, KM_IRQ0) + sg[i].offset;
3684 memcpy(buffer, &cdata[xfer_cnt], min_cnt);
3685 kunmap_atomic(buffer - sg[i].offset, KM_IRQ0);
3686 local_irq_restore(flags);
3687
Linus Torvalds1da177e2005-04-16 15:20:36 -07003688 xfer_cnt += min_cnt;
3689 }
3690
3691 } else {
3692 unsigned int min_cnt = min(count, scmd->request_bufflen);
3693 memcpy(scmd->request_buffer, data, min_cnt);
3694 }
3695}
3696
3697/****************************************************************************/
3698/* */
3699/* Routine Name: ips_scmd_buf_read */
3700/* */
3701/* Routine Description: */
3702/* Copy data from a Scsi_Cmnd to a new, linear buffer */
3703/****************************************************************************/
3704static void
3705ips_scmd_buf_read(Scsi_Cmnd * scmd, void *data, unsigned
3706 int count)
3707{
3708 if (scmd->use_sg) {
3709 int i;
3710 unsigned int min_cnt, xfer_cnt;
3711 char *cdata = (char *) data;
Jack Hammera3632fa2005-10-25 14:13:03 -04003712 unsigned char *buffer;
3713 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003714 struct scatterlist *sg = scmd->request_buffer;
3715 for (i = 0, xfer_cnt = 0;
3716 (i < scmd->use_sg) && (xfer_cnt < count); i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003717 min_cnt = min(count - xfer_cnt, sg[i].length);
Jack Hammera3632fa2005-10-25 14:13:03 -04003718
3719 /* kmap_atomic() ensures addressability of the data buffer.*/
3720 /* local_irq_save() protects the KM_IRQ0 address slot. */
3721 local_irq_save(flags);
3722 buffer = kmap_atomic(sg[i].page, KM_IRQ0) + sg[i].offset;
3723 memcpy(&cdata[xfer_cnt], buffer, min_cnt);
3724 kunmap_atomic(buffer - sg[i].offset, KM_IRQ0);
3725 local_irq_restore(flags);
3726
Linus Torvalds1da177e2005-04-16 15:20:36 -07003727 xfer_cnt += min_cnt;
3728 }
3729
3730 } else {
3731 unsigned int min_cnt = min(count, scmd->request_bufflen);
3732 memcpy(data, scmd->request_buffer, min_cnt);
3733 }
3734}
3735
3736/****************************************************************************/
3737/* */
3738/* Routine Name: ips_send_cmd */
3739/* */
3740/* Routine Description: */
3741/* */
3742/* Map SCSI commands to ServeRAID commands for logical drives */
3743/* */
3744/****************************************************************************/
3745static int
3746ips_send_cmd(ips_ha_t * ha, ips_scb_t * scb)
3747{
3748 int ret;
3749 char *sp;
3750 int device_error;
3751 IPS_DCDB_TABLE_TAPE *tapeDCDB;
3752 int TimeOut;
3753
3754 METHOD_TRACE("ips_send_cmd", 1);
3755
3756 ret = IPS_SUCCESS;
3757
3758 if (!scb->scsi_cmd) {
3759 /* internal command */
3760
3761 if (scb->bus > 0) {
3762 /* Controller commands can't be issued */
3763 /* to real devices -- fail them */
3764 if ((ha->waitflag == TRUE) &&
3765 (ha->cmd_in_progress == scb->cdb[0])) {
3766 ha->waitflag = FALSE;
3767 }
3768
3769 return (1);
3770 }
3771 } else if ((scb->bus == 0) && (!ips_is_passthru(scb->scsi_cmd))) {
3772 /* command to logical bus -- interpret */
3773 ret = IPS_SUCCESS_IMM;
3774
3775 switch (scb->scsi_cmd->cmnd[0]) {
3776 case ALLOW_MEDIUM_REMOVAL:
3777 case REZERO_UNIT:
3778 case ERASE:
3779 case WRITE_FILEMARKS:
3780 case SPACE:
3781 scb->scsi_cmd->result = DID_ERROR << 16;
3782 break;
3783
3784 case START_STOP:
3785 scb->scsi_cmd->result = DID_OK << 16;
3786
3787 case TEST_UNIT_READY:
3788 case INQUIRY:
3789 if (scb->target_id == IPS_ADAPTER_ID) {
3790 /*
3791 * Either we have a TUR
3792 * or we have a SCSI inquiry
3793 */
3794 if (scb->scsi_cmd->cmnd[0] == TEST_UNIT_READY)
3795 scb->scsi_cmd->result = DID_OK << 16;
3796
3797 if (scb->scsi_cmd->cmnd[0] == INQUIRY) {
3798 IPS_SCSI_INQ_DATA inquiry;
3799
3800 memset(&inquiry, 0,
3801 sizeof (IPS_SCSI_INQ_DATA));
3802
3803 inquiry.DeviceType =
3804 IPS_SCSI_INQ_TYPE_PROCESSOR;
3805 inquiry.DeviceTypeQualifier =
3806 IPS_SCSI_INQ_LU_CONNECTED;
3807 inquiry.Version = IPS_SCSI_INQ_REV2;
3808 inquiry.ResponseDataFormat =
3809 IPS_SCSI_INQ_RD_REV2;
3810 inquiry.AdditionalLength = 31;
3811 inquiry.Flags[0] =
3812 IPS_SCSI_INQ_Address16;
3813 inquiry.Flags[1] =
3814 IPS_SCSI_INQ_WBus16 |
3815 IPS_SCSI_INQ_Sync;
3816 strncpy(inquiry.VendorId, "IBM ",
3817 8);
3818 strncpy(inquiry.ProductId,
3819 "SERVERAID ", 16);
3820 strncpy(inquiry.ProductRevisionLevel,
3821 "1.00", 4);
3822
3823 ips_scmd_buf_write(scb->scsi_cmd,
3824 &inquiry,
3825 sizeof (inquiry));
3826
3827 scb->scsi_cmd->result = DID_OK << 16;
3828 }
3829 } else {
3830 scb->cmd.logical_info.op_code = IPS_CMD_GET_LD_INFO;
3831 scb->cmd.logical_info.command_id = IPS_COMMAND_ID(ha, scb);
3832 scb->cmd.logical_info.reserved = 0;
3833 scb->cmd.logical_info.reserved2 = 0;
3834 scb->data_len = sizeof (IPS_LD_INFO);
3835 scb->data_busaddr = ha->logical_drive_info_dma_addr;
3836 scb->flags = 0;
3837 scb->cmd.logical_info.buffer_addr = scb->data_busaddr;
3838 ret = IPS_SUCCESS;
3839 }
3840
3841 break;
3842
3843 case REQUEST_SENSE:
3844 ips_reqsen(ha, scb);
3845 scb->scsi_cmd->result = DID_OK << 16;
3846 break;
3847
3848 case READ_6:
3849 case WRITE_6:
3850 if (!scb->sg_len) {
3851 scb->cmd.basic_io.op_code =
3852 (scb->scsi_cmd->cmnd[0] ==
3853 READ_6) ? IPS_CMD_READ : IPS_CMD_WRITE;
3854 scb->cmd.basic_io.enhanced_sg = 0;
3855 scb->cmd.basic_io.sg_addr =
3856 cpu_to_le32(scb->data_busaddr);
3857 } else {
3858 scb->cmd.basic_io.op_code =
3859 (scb->scsi_cmd->cmnd[0] ==
3860 READ_6) ? IPS_CMD_READ_SG :
3861 IPS_CMD_WRITE_SG;
3862 scb->cmd.basic_io.enhanced_sg =
3863 IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0;
3864 scb->cmd.basic_io.sg_addr =
3865 cpu_to_le32(scb->sg_busaddr);
3866 }
3867
3868 scb->cmd.basic_io.segment_4G = 0;
3869 scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
3870 scb->cmd.basic_io.log_drv = scb->target_id;
3871 scb->cmd.basic_io.sg_count = scb->sg_len;
3872
3873 if (scb->cmd.basic_io.lba)
3874 scb->cmd.basic_io.lba =
3875 cpu_to_le32(le32_to_cpu
3876 (scb->cmd.basic_io.lba) +
3877 le16_to_cpu(scb->cmd.basic_io.
3878 sector_count));
3879 else
3880 scb->cmd.basic_io.lba =
3881 (((scb->scsi_cmd->
3882 cmnd[1] & 0x1f) << 16) | (scb->scsi_cmd->
3883 cmnd[2] << 8) |
3884 (scb->scsi_cmd->cmnd[3]));
3885
3886 scb->cmd.basic_io.sector_count =
3887 cpu_to_le16(scb->data_len / IPS_BLKSIZE);
3888
3889 if (le16_to_cpu(scb->cmd.basic_io.sector_count) == 0)
3890 scb->cmd.basic_io.sector_count =
3891 cpu_to_le16(256);
3892
3893 ret = IPS_SUCCESS;
3894 break;
3895
3896 case READ_10:
3897 case WRITE_10:
3898 if (!scb->sg_len) {
3899 scb->cmd.basic_io.op_code =
3900 (scb->scsi_cmd->cmnd[0] ==
3901 READ_10) ? IPS_CMD_READ : IPS_CMD_WRITE;
3902 scb->cmd.basic_io.enhanced_sg = 0;
3903 scb->cmd.basic_io.sg_addr =
3904 cpu_to_le32(scb->data_busaddr);
3905 } else {
3906 scb->cmd.basic_io.op_code =
3907 (scb->scsi_cmd->cmnd[0] ==
3908 READ_10) ? IPS_CMD_READ_SG :
3909 IPS_CMD_WRITE_SG;
3910 scb->cmd.basic_io.enhanced_sg =
3911 IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0;
3912 scb->cmd.basic_io.sg_addr =
3913 cpu_to_le32(scb->sg_busaddr);
3914 }
3915
3916 scb->cmd.basic_io.segment_4G = 0;
3917 scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
3918 scb->cmd.basic_io.log_drv = scb->target_id;
3919 scb->cmd.basic_io.sg_count = scb->sg_len;
3920
3921 if (scb->cmd.basic_io.lba)
3922 scb->cmd.basic_io.lba =
3923 cpu_to_le32(le32_to_cpu
3924 (scb->cmd.basic_io.lba) +
3925 le16_to_cpu(scb->cmd.basic_io.
3926 sector_count));
3927 else
3928 scb->cmd.basic_io.lba =
3929 ((scb->scsi_cmd->cmnd[2] << 24) | (scb->
3930 scsi_cmd->
3931 cmnd[3]
3932 << 16) |
3933 (scb->scsi_cmd->cmnd[4] << 8) | scb->
3934 scsi_cmd->cmnd[5]);
3935
3936 scb->cmd.basic_io.sector_count =
3937 cpu_to_le16(scb->data_len / IPS_BLKSIZE);
3938
3939 if (cpu_to_le16(scb->cmd.basic_io.sector_count) == 0) {
3940 /*
3941 * This is a null condition
3942 * we don't have to do anything
3943 * so just return
3944 */
3945 scb->scsi_cmd->result = DID_OK << 16;
3946 } else
3947 ret = IPS_SUCCESS;
3948
3949 break;
3950
3951 case RESERVE:
3952 case RELEASE:
3953 scb->scsi_cmd->result = DID_OK << 16;
3954 break;
3955
3956 case MODE_SENSE:
3957 scb->cmd.basic_io.op_code = IPS_CMD_ENQUIRY;
3958 scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
3959 scb->cmd.basic_io.segment_4G = 0;
3960 scb->cmd.basic_io.enhanced_sg = 0;
3961 scb->data_len = sizeof (*ha->enq);
3962 scb->cmd.basic_io.sg_addr = ha->enq_busaddr;
3963 ret = IPS_SUCCESS;
3964 break;
3965
3966 case READ_CAPACITY:
3967 scb->cmd.logical_info.op_code = IPS_CMD_GET_LD_INFO;
3968 scb->cmd.logical_info.command_id = IPS_COMMAND_ID(ha, scb);
3969 scb->cmd.logical_info.reserved = 0;
3970 scb->cmd.logical_info.reserved2 = 0;
3971 scb->cmd.logical_info.reserved3 = 0;
3972 scb->data_len = sizeof (IPS_LD_INFO);
3973 scb->data_busaddr = ha->logical_drive_info_dma_addr;
3974 scb->flags = 0;
3975 scb->cmd.logical_info.buffer_addr = scb->data_busaddr;
3976 ret = IPS_SUCCESS;
3977 break;
3978
3979 case SEND_DIAGNOSTIC:
3980 case REASSIGN_BLOCKS:
3981 case FORMAT_UNIT:
3982 case SEEK_10:
3983 case VERIFY:
3984 case READ_DEFECT_DATA:
3985 case READ_BUFFER:
3986 case WRITE_BUFFER:
3987 scb->scsi_cmd->result = DID_OK << 16;
3988 break;
3989
3990 default:
3991 /* Set the Return Info to appear like the Command was */
3992 /* attempted, a Check Condition occurred, and Sense */
3993 /* Data indicating an Invalid CDB OpCode is returned. */
3994 sp = (char *) scb->scsi_cmd->sense_buffer;
3995 memset(sp, 0, sizeof (scb->scsi_cmd->sense_buffer));
3996
3997 sp[0] = 0x70; /* Error Code */
3998 sp[2] = ILLEGAL_REQUEST; /* Sense Key 5 Illegal Req. */
3999 sp[7] = 0x0A; /* Additional Sense Length */
4000 sp[12] = 0x20; /* ASC = Invalid OpCode */
4001 sp[13] = 0x00; /* ASCQ */
4002
4003 device_error = 2; /* Indicate Check Condition */
4004 scb->scsi_cmd->result = device_error | (DID_OK << 16);
4005 break;
4006 } /* end switch */
4007 }
4008 /* end if */
4009 if (ret == IPS_SUCCESS_IMM)
4010 return (ret);
4011
4012 /* setup DCDB */
4013 if (scb->bus > 0) {
4014
4015 /* If we already know the Device is Not there, no need to attempt a Command */
4016 /* This also protects an NT FailOver Controller from getting CDB's sent to it */
4017 if (ha->conf->dev[scb->bus - 1][scb->target_id].ucState == 0) {
4018 scb->scsi_cmd->result = DID_NO_CONNECT << 16;
4019 return (IPS_SUCCESS_IMM);
4020 }
4021
4022 ha->dcdb_active[scb->bus - 1] |= (1 << scb->target_id);
4023 scb->cmd.dcdb.command_id = IPS_COMMAND_ID(ha, scb);
4024 scb->cmd.dcdb.dcdb_address = cpu_to_le32(scb->scb_busaddr +
4025 (unsigned long) &scb->
4026 dcdb -
4027 (unsigned long) scb);
4028 scb->cmd.dcdb.reserved = 0;
4029 scb->cmd.dcdb.reserved2 = 0;
4030 scb->cmd.dcdb.reserved3 = 0;
4031 scb->cmd.dcdb.segment_4G = 0;
4032 scb->cmd.dcdb.enhanced_sg = 0;
4033
4034 TimeOut = scb->scsi_cmd->timeout_per_command;
4035
4036 if (ha->subsys->param[4] & 0x00100000) { /* If NEW Tape DCDB is Supported */
4037 if (!scb->sg_len) {
4038 scb->cmd.dcdb.op_code = IPS_CMD_EXTENDED_DCDB;
4039 } else {
4040 scb->cmd.dcdb.op_code =
4041 IPS_CMD_EXTENDED_DCDB_SG;
4042 scb->cmd.dcdb.enhanced_sg =
4043 IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0;
4044 }
4045
4046 tapeDCDB = (IPS_DCDB_TABLE_TAPE *) & scb->dcdb; /* Use Same Data Area as Old DCDB Struct */
4047 tapeDCDB->device_address =
4048 ((scb->bus - 1) << 4) | scb->target_id;
4049 tapeDCDB->cmd_attribute |= IPS_DISCONNECT_ALLOWED;
4050 tapeDCDB->cmd_attribute &= ~IPS_TRANSFER64K; /* Always Turn OFF 64K Size Flag */
4051
4052 if (TimeOut) {
4053 if (TimeOut < (10 * HZ))
4054 tapeDCDB->cmd_attribute |= IPS_TIMEOUT10; /* TimeOut is 10 Seconds */
4055 else if (TimeOut < (60 * HZ))
4056 tapeDCDB->cmd_attribute |= IPS_TIMEOUT60; /* TimeOut is 60 Seconds */
4057 else if (TimeOut < (1200 * HZ))
4058 tapeDCDB->cmd_attribute |= IPS_TIMEOUT20M; /* TimeOut is 20 Minutes */
4059 }
4060
4061 tapeDCDB->cdb_length = scb->scsi_cmd->cmd_len;
4062 tapeDCDB->reserved_for_LUN = 0;
4063 tapeDCDB->transfer_length = scb->data_len;
4064 if (scb->cmd.dcdb.op_code == IPS_CMD_EXTENDED_DCDB_SG)
4065 tapeDCDB->buffer_pointer =
4066 cpu_to_le32(scb->sg_busaddr);
4067 else
4068 tapeDCDB->buffer_pointer =
4069 cpu_to_le32(scb->data_busaddr);
4070 tapeDCDB->sg_count = scb->sg_len;
4071 tapeDCDB->sense_length = sizeof (tapeDCDB->sense_info);
4072 tapeDCDB->scsi_status = 0;
4073 tapeDCDB->reserved = 0;
4074 memcpy(tapeDCDB->scsi_cdb, scb->scsi_cmd->cmnd,
4075 scb->scsi_cmd->cmd_len);
4076 } else {
4077 if (!scb->sg_len) {
4078 scb->cmd.dcdb.op_code = IPS_CMD_DCDB;
4079 } else {
4080 scb->cmd.dcdb.op_code = IPS_CMD_DCDB_SG;
4081 scb->cmd.dcdb.enhanced_sg =
4082 IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0;
4083 }
4084
4085 scb->dcdb.device_address =
4086 ((scb->bus - 1) << 4) | scb->target_id;
4087 scb->dcdb.cmd_attribute |= IPS_DISCONNECT_ALLOWED;
4088
4089 if (TimeOut) {
4090 if (TimeOut < (10 * HZ))
4091 scb->dcdb.cmd_attribute |= IPS_TIMEOUT10; /* TimeOut is 10 Seconds */
4092 else if (TimeOut < (60 * HZ))
4093 scb->dcdb.cmd_attribute |= IPS_TIMEOUT60; /* TimeOut is 60 Seconds */
4094 else if (TimeOut < (1200 * HZ))
4095 scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M; /* TimeOut is 20 Minutes */
4096 }
4097
4098 scb->dcdb.transfer_length = scb->data_len;
4099 if (scb->dcdb.cmd_attribute & IPS_TRANSFER64K)
4100 scb->dcdb.transfer_length = 0;
4101 if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB_SG)
4102 scb->dcdb.buffer_pointer =
4103 cpu_to_le32(scb->sg_busaddr);
4104 else
4105 scb->dcdb.buffer_pointer =
4106 cpu_to_le32(scb->data_busaddr);
4107 scb->dcdb.cdb_length = scb->scsi_cmd->cmd_len;
4108 scb->dcdb.sense_length = sizeof (scb->dcdb.sense_info);
4109 scb->dcdb.sg_count = scb->sg_len;
4110 scb->dcdb.reserved = 0;
4111 memcpy(scb->dcdb.scsi_cdb, scb->scsi_cmd->cmnd,
4112 scb->scsi_cmd->cmd_len);
4113 scb->dcdb.scsi_status = 0;
4114 scb->dcdb.reserved2[0] = 0;
4115 scb->dcdb.reserved2[1] = 0;
4116 scb->dcdb.reserved2[2] = 0;
4117 }
4118 }
4119
4120 return ((*ha->func.issue) (ha, scb));
4121}
4122
4123/****************************************************************************/
4124/* */
4125/* Routine Name: ips_chk_status */
4126/* */
4127/* Routine Description: */
4128/* */
4129/* Check the status of commands to logical drives */
4130/* Assumed to be called with the HA lock */
4131/****************************************************************************/
4132static void
4133ips_chkstatus(ips_ha_t * ha, IPS_STATUS * pstatus)
4134{
4135 ips_scb_t *scb;
4136 ips_stat_t *sp;
4137 uint8_t basic_status;
4138 uint8_t ext_status;
4139 int errcode;
Jack Hammera5b3c862006-01-31 13:17:55 -05004140 IPS_SCSI_INQ_DATA inquiryData;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004141
4142 METHOD_TRACE("ips_chkstatus", 1);
4143
4144 scb = &ha->scbs[pstatus->fields.command_id];
4145 scb->basic_status = basic_status =
4146 pstatus->fields.basic_status & IPS_BASIC_STATUS_MASK;
4147 scb->extended_status = ext_status = pstatus->fields.extended_status;
4148
4149 sp = &ha->sp;
4150 sp->residue_len = 0;
4151 sp->scb_addr = (void *) scb;
4152
4153 /* Remove the item from the active queue */
4154 ips_removeq_scb(&ha->scb_activelist, scb);
4155
4156 if (!scb->scsi_cmd)
4157 /* internal commands are handled in do_ipsintr */
4158 return;
4159
4160 DEBUG_VAR(2, "(%s%d) ips_chkstatus: cmd 0x%X id %d (%d %d %d)",
4161 ips_name,
4162 ha->host_num,
4163 scb->cdb[0],
4164 scb->cmd.basic_io.command_id,
4165 scb->bus, scb->target_id, scb->lun);
4166
4167 if ((scb->scsi_cmd) && (ips_is_passthru(scb->scsi_cmd)))
4168 /* passthru - just returns the raw result */
4169 return;
4170
4171 errcode = DID_OK;
4172
4173 if (((basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_SUCCESS) ||
4174 ((basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_RECOVERED_ERROR)) {
4175
4176 if (scb->bus == 0) {
4177 if ((basic_status & IPS_GSC_STATUS_MASK) ==
4178 IPS_CMD_RECOVERED_ERROR) {
4179 DEBUG_VAR(1,
4180 "(%s%d) Recovered Logical Drive Error OpCode: %x, BSB: %x, ESB: %x",
4181 ips_name, ha->host_num,
4182 scb->cmd.basic_io.op_code,
4183 basic_status, ext_status);
4184 }
4185
4186 switch (scb->scsi_cmd->cmnd[0]) {
4187 case ALLOW_MEDIUM_REMOVAL:
4188 case REZERO_UNIT:
4189 case ERASE:
4190 case WRITE_FILEMARKS:
4191 case SPACE:
4192 errcode = DID_ERROR;
4193 break;
4194
4195 case START_STOP:
4196 break;
4197
4198 case TEST_UNIT_READY:
4199 if (!ips_online(ha, scb)) {
4200 errcode = DID_TIME_OUT;
4201 }
4202 break;
4203
4204 case INQUIRY:
4205 if (ips_online(ha, scb)) {
4206 ips_inquiry(ha, scb);
4207 } else {
4208 errcode = DID_TIME_OUT;
4209 }
4210 break;
4211
4212 case REQUEST_SENSE:
4213 ips_reqsen(ha, scb);
4214 break;
4215
4216 case READ_6:
4217 case WRITE_6:
4218 case READ_10:
4219 case WRITE_10:
4220 case RESERVE:
4221 case RELEASE:
4222 break;
4223
4224 case MODE_SENSE:
4225 if (!ips_online(ha, scb)
4226 || !ips_msense(ha, scb)) {
4227 errcode = DID_ERROR;
4228 }
4229 break;
4230
4231 case READ_CAPACITY:
4232 if (ips_online(ha, scb))
4233 ips_rdcap(ha, scb);
4234 else {
4235 errcode = DID_TIME_OUT;
4236 }
4237 break;
4238
4239 case SEND_DIAGNOSTIC:
4240 case REASSIGN_BLOCKS:
4241 break;
4242
4243 case FORMAT_UNIT:
4244 errcode = DID_ERROR;
4245 break;
4246
4247 case SEEK_10:
4248 case VERIFY:
4249 case READ_DEFECT_DATA:
4250 case READ_BUFFER:
4251 case WRITE_BUFFER:
4252 break;
4253
4254 default:
4255 errcode = DID_ERROR;
4256 } /* end switch */
4257
4258 scb->scsi_cmd->result = errcode << 16;
4259 } else { /* bus == 0 */
4260 /* restrict access to physical drives */
Jack Hammera5b3c862006-01-31 13:17:55 -05004261 if (scb->scsi_cmd->cmnd[0] == INQUIRY) {
4262 ips_scmd_buf_read(scb->scsi_cmd,
4263 &inquiryData, sizeof (inquiryData));
4264 if ((inquiryData.DeviceType & 0x1f) == TYPE_DISK)
4265 scb->scsi_cmd->result = DID_TIME_OUT << 16;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004266 }
4267 } /* else */
4268 } else { /* recovered error / success */
4269 if (scb->bus == 0) {
4270 DEBUG_VAR(1,
4271 "(%s%d) Unrecovered Logical Drive Error OpCode: %x, BSB: %x, ESB: %x",
4272 ips_name, ha->host_num,
4273 scb->cmd.basic_io.op_code, basic_status,
4274 ext_status);
4275 }
4276
4277 ips_map_status(ha, scb, sp);
4278 } /* else */
4279}
4280
4281/****************************************************************************/
4282/* */
4283/* Routine Name: ips_online */
4284/* */
4285/* Routine Description: */
4286/* */
4287/* Determine if a logical drive is online */
4288/* */
4289/****************************************************************************/
4290static int
4291ips_online(ips_ha_t * ha, ips_scb_t * scb)
4292{
4293 METHOD_TRACE("ips_online", 1);
4294
4295 if (scb->target_id >= IPS_MAX_LD)
4296 return (0);
4297
4298 if ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1) {
4299 memset(ha->logical_drive_info, 0, sizeof (IPS_LD_INFO));
4300 return (0);
4301 }
4302
4303 if (ha->logical_drive_info->drive_info[scb->target_id].state !=
4304 IPS_LD_OFFLINE
4305 && ha->logical_drive_info->drive_info[scb->target_id].state !=
4306 IPS_LD_FREE
4307 && ha->logical_drive_info->drive_info[scb->target_id].state !=
4308 IPS_LD_CRS
4309 && ha->logical_drive_info->drive_info[scb->target_id].state !=
4310 IPS_LD_SYS)
4311 return (1);
4312 else
4313 return (0);
4314}
4315
4316/****************************************************************************/
4317/* */
4318/* Routine Name: ips_inquiry */
4319/* */
4320/* Routine Description: */
4321/* */
4322/* Simulate an inquiry command to a logical drive */
4323/* */
4324/****************************************************************************/
4325static int
4326ips_inquiry(ips_ha_t * ha, ips_scb_t * scb)
4327{
4328 IPS_SCSI_INQ_DATA inquiry;
4329
4330 METHOD_TRACE("ips_inquiry", 1);
4331
4332 memset(&inquiry, 0, sizeof (IPS_SCSI_INQ_DATA));
4333
4334 inquiry.DeviceType = IPS_SCSI_INQ_TYPE_DASD;
4335 inquiry.DeviceTypeQualifier = IPS_SCSI_INQ_LU_CONNECTED;
4336 inquiry.Version = IPS_SCSI_INQ_REV2;
4337 inquiry.ResponseDataFormat = IPS_SCSI_INQ_RD_REV2;
4338 inquiry.AdditionalLength = 31;
4339 inquiry.Flags[0] = IPS_SCSI_INQ_Address16;
4340 inquiry.Flags[1] =
4341 IPS_SCSI_INQ_WBus16 | IPS_SCSI_INQ_Sync | IPS_SCSI_INQ_CmdQue;
4342 strncpy(inquiry.VendorId, "IBM ", 8);
4343 strncpy(inquiry.ProductId, "SERVERAID ", 16);
4344 strncpy(inquiry.ProductRevisionLevel, "1.00", 4);
4345
4346 ips_scmd_buf_write(scb->scsi_cmd, &inquiry, sizeof (inquiry));
4347
4348 return (1);
4349}
4350
4351/****************************************************************************/
4352/* */
4353/* Routine Name: ips_rdcap */
4354/* */
4355/* Routine Description: */
4356/* */
4357/* Simulate a read capacity command to a logical drive */
4358/* */
4359/****************************************************************************/
4360static int
4361ips_rdcap(ips_ha_t * ha, ips_scb_t * scb)
4362{
4363 IPS_SCSI_CAPACITY cap;
4364
4365 METHOD_TRACE("ips_rdcap", 1);
4366
Christoph Hellwig5d5ff442006-06-03 13:21:13 +02004367 if (scb->scsi_cmd->request_bufflen < 8)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004368 return (0);
4369
4370 cap.lba =
4371 cpu_to_be32(le32_to_cpu
4372 (ha->logical_drive_info->
4373 drive_info[scb->target_id].sector_count) - 1);
4374 cap.len = cpu_to_be32((uint32_t) IPS_BLKSIZE);
4375
4376 ips_scmd_buf_write(scb->scsi_cmd, &cap, sizeof (cap));
4377
4378 return (1);
4379}
4380
4381/****************************************************************************/
4382/* */
4383/* Routine Name: ips_msense */
4384/* */
4385/* Routine Description: */
4386/* */
4387/* Simulate a mode sense command to a logical drive */
4388/* */
4389/****************************************************************************/
4390static int
4391ips_msense(ips_ha_t * ha, ips_scb_t * scb)
4392{
4393 uint16_t heads;
4394 uint16_t sectors;
4395 uint32_t cylinders;
4396 IPS_SCSI_MODE_PAGE_DATA mdata;
4397
4398 METHOD_TRACE("ips_msense", 1);
4399
4400 if (le32_to_cpu(ha->enq->ulDriveSize[scb->target_id]) > 0x400000 &&
4401 (ha->enq->ucMiscFlag & 0x8) == 0) {
4402 heads = IPS_NORM_HEADS;
4403 sectors = IPS_NORM_SECTORS;
4404 } else {
4405 heads = IPS_COMP_HEADS;
4406 sectors = IPS_COMP_SECTORS;
4407 }
4408
4409 cylinders =
4410 (le32_to_cpu(ha->enq->ulDriveSize[scb->target_id]) -
4411 1) / (heads * sectors);
4412
4413 memset(&mdata, 0, sizeof (IPS_SCSI_MODE_PAGE_DATA));
4414
4415 mdata.hdr.BlockDescLength = 8;
4416
4417 switch (scb->scsi_cmd->cmnd[2] & 0x3f) {
4418 case 0x03: /* page 3 */
4419 mdata.pdata.pg3.PageCode = 3;
4420 mdata.pdata.pg3.PageLength = sizeof (IPS_SCSI_MODE_PAGE3);
4421 mdata.hdr.DataLength =
4422 3 + mdata.hdr.BlockDescLength + mdata.pdata.pg3.PageLength;
4423 mdata.pdata.pg3.TracksPerZone = 0;
4424 mdata.pdata.pg3.AltSectorsPerZone = 0;
4425 mdata.pdata.pg3.AltTracksPerZone = 0;
4426 mdata.pdata.pg3.AltTracksPerVolume = 0;
4427 mdata.pdata.pg3.SectorsPerTrack = cpu_to_be16(sectors);
4428 mdata.pdata.pg3.BytesPerSector = cpu_to_be16(IPS_BLKSIZE);
4429 mdata.pdata.pg3.Interleave = cpu_to_be16(1);
4430 mdata.pdata.pg3.TrackSkew = 0;
4431 mdata.pdata.pg3.CylinderSkew = 0;
4432 mdata.pdata.pg3.flags = IPS_SCSI_MP3_SoftSector;
4433 break;
4434
4435 case 0x4:
4436 mdata.pdata.pg4.PageCode = 4;
4437 mdata.pdata.pg4.PageLength = sizeof (IPS_SCSI_MODE_PAGE4);
4438 mdata.hdr.DataLength =
4439 3 + mdata.hdr.BlockDescLength + mdata.pdata.pg4.PageLength;
4440 mdata.pdata.pg4.CylindersHigh =
4441 cpu_to_be16((cylinders >> 8) & 0xFFFF);
4442 mdata.pdata.pg4.CylindersLow = (cylinders & 0xFF);
4443 mdata.pdata.pg4.Heads = heads;
4444 mdata.pdata.pg4.WritePrecompHigh = 0;
4445 mdata.pdata.pg4.WritePrecompLow = 0;
4446 mdata.pdata.pg4.ReducedWriteCurrentHigh = 0;
4447 mdata.pdata.pg4.ReducedWriteCurrentLow = 0;
4448 mdata.pdata.pg4.StepRate = cpu_to_be16(1);
4449 mdata.pdata.pg4.LandingZoneHigh = 0;
4450 mdata.pdata.pg4.LandingZoneLow = 0;
4451 mdata.pdata.pg4.flags = 0;
4452 mdata.pdata.pg4.RotationalOffset = 0;
4453 mdata.pdata.pg4.MediumRotationRate = 0;
4454 break;
4455 case 0x8:
4456 mdata.pdata.pg8.PageCode = 8;
4457 mdata.pdata.pg8.PageLength = sizeof (IPS_SCSI_MODE_PAGE8);
4458 mdata.hdr.DataLength =
4459 3 + mdata.hdr.BlockDescLength + mdata.pdata.pg8.PageLength;
4460 /* everything else is left set to 0 */
4461 break;
4462
4463 default:
4464 return (0);
4465 } /* end switch */
4466
4467 ips_scmd_buf_write(scb->scsi_cmd, &mdata, sizeof (mdata));
4468
4469 return (1);
4470}
4471
4472/****************************************************************************/
4473/* */
4474/* Routine Name: ips_reqsen */
4475/* */
4476/* Routine Description: */
4477/* */
4478/* Simulate a request sense command to a logical drive */
4479/* */
4480/****************************************************************************/
4481static int
4482ips_reqsen(ips_ha_t * ha, ips_scb_t * scb)
4483{
4484 IPS_SCSI_REQSEN reqsen;
4485
4486 METHOD_TRACE("ips_reqsen", 1);
4487
4488 memset(&reqsen, 0, sizeof (IPS_SCSI_REQSEN));
4489
4490 reqsen.ResponseCode =
4491 IPS_SCSI_REQSEN_VALID | IPS_SCSI_REQSEN_CURRENT_ERR;
4492 reqsen.AdditionalLength = 10;
4493 reqsen.AdditionalSenseCode = IPS_SCSI_REQSEN_NO_SENSE;
4494 reqsen.AdditionalSenseCodeQual = IPS_SCSI_REQSEN_NO_SENSE;
4495
4496 ips_scmd_buf_write(scb->scsi_cmd, &reqsen, sizeof (reqsen));
4497
4498 return (1);
4499}
4500
4501/****************************************************************************/
4502/* */
4503/* Routine Name: ips_free */
4504/* */
4505/* Routine Description: */
4506/* */
4507/* Free any allocated space for this controller */
4508/* */
4509/****************************************************************************/
4510static void
4511ips_free(ips_ha_t * ha)
4512{
4513
4514 METHOD_TRACE("ips_free", 1);
4515
4516 if (ha) {
4517 if (ha->enq) {
4518 pci_free_consistent(ha->pcidev, sizeof(IPS_ENQ),
4519 ha->enq, ha->enq_busaddr);
4520 ha->enq = NULL;
4521 }
4522
Jesper Juhlc9475cb2005-11-07 01:01:26 -08004523 kfree(ha->conf);
4524 ha->conf = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004525
4526 if (ha->adapt) {
4527 pci_free_consistent(ha->pcidev,
4528 sizeof (IPS_ADAPTER) +
4529 sizeof (IPS_IO_CMD), ha->adapt,
4530 ha->adapt->hw_status_start);
4531 ha->adapt = NULL;
4532 }
4533
4534 if (ha->logical_drive_info) {
4535 pci_free_consistent(ha->pcidev,
4536 sizeof (IPS_LD_INFO),
4537 ha->logical_drive_info,
4538 ha->logical_drive_info_dma_addr);
4539 ha->logical_drive_info = NULL;
4540 }
4541
Jesper Juhlc9475cb2005-11-07 01:01:26 -08004542 kfree(ha->nvram);
4543 ha->nvram = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004544
Jesper Juhlc9475cb2005-11-07 01:01:26 -08004545 kfree(ha->subsys);
4546 ha->subsys = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004547
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 */
Jack Hammer15084a42006-01-24 14:43:41 -05005018 msleep(IPS_ONE_SEC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005019 }
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 */
Jack Hammer15084a42006-01-24 14:43:41 -05005044 msleep(IPS_ONE_SEC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005045 }
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 */
Jack Hammer15084a42006-01-24 14:43:41 -05005062 msleep(IPS_ONE_SEC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005063 }
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 */
Jack Hammer15084a42006-01-24 14:43:41 -05005112 msleep(IPS_ONE_SEC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005113 }
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 */
Jack Hammer15084a42006-01-24 14:43:41 -05005138 msleep(IPS_ONE_SEC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005139 }
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 */
Jack Hammer15084a42006-01-24 14:43:41 -05005156 msleep(IPS_ONE_SEC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005157 }
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 */
Jack Hammer15084a42006-01-24 14:43:41 -05005208 msleep(IPS_ONE_SEC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005209 }
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 */
Jack Hammer15084a42006-01-24 14:43:41 -05005234 msleep(IPS_ONE_SEC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005235 }
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 */
Jack Hammer15084a42006-01-24 14:43:41 -05005264 msleep(IPS_ONE_SEC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005265 }
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 */
Jack Hammer15084a42006-01-24 14:43:41 -05005324 msleep(IPS_ONE_SEC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005325
5326 outb(0, ha->io_addr + IPS_REG_SCPR);
5327
5328 /* Delay for 1 Second */
Jack Hammer15084a42006-01-24 14:43:41 -05005329 msleep(IPS_ONE_SEC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005330
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 */
Jack Hammer15084a42006-01-24 14:43:41 -05005369 msleep(IPS_ONE_SEC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005370
5371 writeb(0, ha->mem_ptr + IPS_REG_SCPR);
5372
5373 /* Delay for 1 Second */
Jack Hammer15084a42006-01-24 14:43:41 -05005374 msleep(IPS_ONE_SEC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005375
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 */
Jack Hammer15084a42006-01-24 14:43:41 -05005415 msleep(5 * IPS_ONE_SEC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005416
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
Andreas Mohrd6e05ed2006-06-26 18:35:02 +02006441 /* check for successful flash */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006442 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
Andreas Mohrd6e05ed2006-06-26 18:35:02 +02006553 /* check for successful flash */
Linus Torvalds1da177e2005-04-16 15:20:36 -07006554 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) &&
Matthias Gehre910638a2006-03-28 01:56:48 -08007288 !pci_set_dma_mask(ha->pcidev, DMA_64BIT_MASK)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07007289 (ha)->flags |= IPS_HA_ENH_SG;
7290 } else {
Matthias Gehre910638a2006-03-28 01:56:48 -08007291 if (pci_set_dma_mask(ha->pcidev, DMA_32BIT_MASK) != 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07007292 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 */