MOXA linux-2.6.x / linux-2.6.9-uc0 from sdlinux-moxaart.tgz
[linux-2.6.9-moxart.git] / drivers / scsi / ips.c
blobb2e7c233cf090db0841475491500d9f93437636c
1 /*****************************************************************************/
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 /*****************************************************************************/
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 */
136 /*****************************************************************************/
139 * Conditional Compilation directives for this driver:
141 * IPS_DEBUG - Turn on debugging info
143 * Parameters:
145 * debug:<number> - Set debug level to <number>
146 * NOTE: only works when IPS_DEBUG compile directive is used.
147 * 1 - Normal debug messages
148 * 2 - Verbose debug messages
149 * 11 - Method trace (non interrupt)
150 * 12 - Method trace (includes interrupt)
152 * noi2o - Don't use I2O Queues (ServeRAID 4 only)
153 * nommap - Don't use memory mapped I/O
154 * ioctlsize - Initial size of the IOCTL buffer
157 #include <asm/io.h>
158 #include <asm/byteorder.h>
159 #include <asm/page.h>
160 #include <linux/stddef.h>
161 #include <linux/version.h>
162 #include <linux/string.h>
163 #include <linux/errno.h>
164 #include <linux/kernel.h>
165 #include <linux/ioport.h>
166 #include <linux/slab.h>
167 #include <linux/delay.h>
168 #include <linux/pci.h>
169 #include <linux/proc_fs.h>
170 #include <linux/reboot.h>
171 #include <linux/interrupt.h>
173 #include <linux/blkdev.h>
174 #include <linux/types.h>
176 #include <scsi/sg.h>
178 #include "scsi.h"
179 #include <scsi/scsi_host.h>
180 #include "ips.h"
182 #include <linux/module.h>
184 #include <linux/stat.h>
185 #include <linux/config.h>
187 #include <linux/spinlock.h>
188 #include <linux/init.h>
190 #include <linux/smp.h>
192 #ifdef MODULE
193 static char *ips = NULL;
194 MODULE_PARM(ips, "s");
195 #endif
198 * DRIVER_VER
200 #define IPS_VERSION_HIGH "7.00"
201 #define IPS_VERSION_LOW ".15 "
203 #if !defined(__i386__) && !defined(__ia64__) && !defined(__x86_64__)
204 #warning "This driver has only been tested on the x86/ia64/x86_64 platforms"
205 #endif
207 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
208 #include <linux/blk.h>
209 #include "sd.h"
210 #define IPS_SG_ADDRESS(sg) ((sg)->address)
211 #define IPS_LOCK_SAVE(lock,flags) spin_lock_irqsave(&io_request_lock,flags)
212 #define IPS_UNLOCK_RESTORE(lock,flags) spin_unlock_irqrestore(&io_request_lock,flags)
213 #ifndef __devexit_p
214 #define __devexit_p(x) x
215 #endif
216 #else
217 #define IPS_SG_ADDRESS(sg) (page_address((sg)->page) ? \
218 page_address((sg)->page)+(sg)->offset : NULL)
219 #define IPS_LOCK_SAVE(lock,flags) do{spin_lock(lock);(void)flags;}while(0)
220 #define IPS_UNLOCK_RESTORE(lock,flags) do{spin_unlock(lock);(void)flags;}while(0)
221 #endif
223 #define IPS_DMA_DIR(scb) ((!scb->scsi_cmd || ips_is_passthru(scb->scsi_cmd) || \
224 SCSI_DATA_NONE == scb->scsi_cmd->sc_data_direction) ? \
225 PCI_DMA_BIDIRECTIONAL : \
226 scsi_to_pci_dma_dir(scb->scsi_cmd->sc_data_direction))
228 #ifdef IPS_DEBUG
229 #define METHOD_TRACE(s, i) if (ips_debug >= (i+10)) printk(KERN_NOTICE s "\n");
230 #define DEBUG(i, s) if (ips_debug >= i) printk(KERN_NOTICE s "\n");
231 #define DEBUG_VAR(i, s, v...) if (ips_debug >= i) printk(KERN_NOTICE s "\n", v);
232 #else
233 #define METHOD_TRACE(s, i)
234 #define DEBUG(i, s)
235 #define DEBUG_VAR(i, s, v...)
236 #endif
239 * global variables
241 static const char ips_name[] = "ips";
242 static struct Scsi_Host *ips_sh[IPS_MAX_ADAPTERS]; /* Array of host controller structures */
243 static ips_ha_t *ips_ha[IPS_MAX_ADAPTERS]; /* Array of HA structures */
244 static unsigned int ips_next_controller;
245 static unsigned int ips_num_controllers;
246 static unsigned int ips_released_controllers;
247 static int ips_hotplug;
248 static int ips_cmd_timeout = 60;
249 static int ips_reset_timeout = 60 * 5;
250 static int ips_force_memio = 1; /* Always use Memory Mapped I/O */
251 static int ips_force_i2o = 1; /* Always use I2O command delivery */
252 static int ips_ioctlsize = IPS_IOCTL_SIZE; /* Size of the ioctl buffer */
253 static int ips_cd_boot; /* Booting from Manager CD */
254 static char *ips_FlashData = NULL; /* CD Boot - Flash Data Buffer */
255 static dma_addr_t ips_flashbusaddr;
256 static long ips_FlashDataInUse; /* CD Boot - Flash Data In Use Flag */
257 static uint32_t MaxLiteCmds = 32; /* Max Active Cmds for a Lite Adapter */
258 static Scsi_Host_Template ips_driver_template = {
259 .detect = ips_detect,
260 .release = ips_release,
261 .info = ips_info,
262 .queuecommand = ips_queue,
263 .eh_abort_handler = ips_eh_abort,
264 .eh_host_reset_handler = ips_eh_reset,
265 .proc_name = "ips",
266 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
267 .proc_info = ips_proc_info,
268 .slave_configure = ips_slave_configure,
269 #else
270 .proc_info = ips_proc24_info,
271 .select_queue_depths = ips_select_queue_depth,
272 #endif
273 .bios_param = ips_biosparam,
274 .this_id = -1,
275 .sg_tablesize = IPS_MAX_SG,
276 .cmd_per_lun = 3,
277 .use_clustering = ENABLE_CLUSTERING,
278 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
279 .use_new_eh_code = 1,
280 #endif
283 IPS_DEFINE_COMPAT_TABLE( Compatable ); /* Version Compatability Table */
286 /* This table describes all ServeRAID Adapters */
287 static struct pci_device_id ips_pci_table[] = {
288 { 0x1014, 0x002E, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
289 { 0x1014, 0x01BD, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
290 { 0x9005, 0x0250, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
291 { 0, }
294 MODULE_DEVICE_TABLE( pci, ips_pci_table );
296 static char ips_hot_plug_name[] = "ips";
298 static int __devinit ips_insert_device(struct pci_dev *pci_dev, const struct pci_device_id *ent);
299 static void __devexit ips_remove_device(struct pci_dev *pci_dev);
301 struct pci_driver ips_pci_driver = {
302 .name = ips_hot_plug_name,
303 .id_table = ips_pci_table,
304 .probe = ips_insert_device,
305 .remove = __devexit_p(ips_remove_device),
310 * Necessary forward function protoypes
312 static int ips_halt(struct notifier_block *nb, ulong event, void *buf);
314 #define MAX_ADAPTER_NAME 15
316 static char ips_adapter_name[][30] = {
317 "ServeRAID",
318 "ServeRAID II",
319 "ServeRAID on motherboard",
320 "ServeRAID on motherboard",
321 "ServeRAID 3H",
322 "ServeRAID 3L",
323 "ServeRAID 4H",
324 "ServeRAID 4M",
325 "ServeRAID 4L",
326 "ServeRAID 4Mx",
327 "ServeRAID 4Lx",
328 "ServeRAID 5i",
329 "ServeRAID 5i",
330 "ServeRAID 6M",
331 "ServeRAID 6i",
332 "ServeRAID 7t",
333 "ServeRAID 7k",
334 "ServeRAID 7M"
337 static struct notifier_block ips_notifier = {
338 ips_halt, NULL, 0
342 * Direction table
344 static char ips_command_direction[] = {
345 IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT,
346 IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK,
347 IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
348 IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_OUT,
349 IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_OUT,
350 IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_OUT,
351 IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_IN,
352 IPS_DATA_UNK, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK,
353 IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_UNK,
354 IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT,
355 IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_NONE,
356 IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT,
357 IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT,
358 IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_NONE,
359 IPS_DATA_UNK, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_UNK,
360 IPS_DATA_NONE, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK,
361 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
362 IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
363 IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
364 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
365 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
366 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
367 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
368 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
369 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
370 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
371 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
372 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
373 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
374 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
375 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
376 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
377 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
378 IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_NONE,
379 IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_OUT,
380 IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_NONE,
381 IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_IN,
382 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
383 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
384 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
385 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
386 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
387 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
388 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
389 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
390 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
391 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_OUT,
392 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
393 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
394 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
395 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK
399 * Function prototypes
401 int ips_detect(Scsi_Host_Template *);
402 int ips_release(struct Scsi_Host *);
403 int ips_eh_abort(Scsi_Cmnd *);
404 int ips_eh_reset(Scsi_Cmnd *);
405 int ips_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *));
406 const char *ips_info(struct Scsi_Host *);
407 irqreturn_t do_ipsintr(int, void *, struct pt_regs *);
408 static int ips_hainit(ips_ha_t *);
409 static int ips_map_status(ips_ha_t *, ips_scb_t *, ips_stat_t *);
410 static int ips_send_wait(ips_ha_t *, ips_scb_t *, int, int);
411 static int ips_send_cmd(ips_ha_t *, ips_scb_t *);
412 static int ips_online(ips_ha_t *, ips_scb_t *);
413 static int ips_inquiry(ips_ha_t *, ips_scb_t *);
414 static int ips_rdcap(ips_ha_t *, ips_scb_t *);
415 static int ips_msense(ips_ha_t *, ips_scb_t *);
416 static int ips_reqsen(ips_ha_t *, ips_scb_t *);
417 static int ips_deallocatescbs(ips_ha_t *, int);
418 static int ips_allocatescbs(ips_ha_t *);
419 static int ips_reset_copperhead(ips_ha_t *);
420 static int ips_reset_copperhead_memio(ips_ha_t *);
421 static int ips_reset_morpheus(ips_ha_t *);
422 static int ips_issue_copperhead(ips_ha_t *, ips_scb_t *);
423 static int ips_issue_copperhead_memio(ips_ha_t *, ips_scb_t *);
424 static int ips_issue_i2o(ips_ha_t *, ips_scb_t *);
425 static int ips_issue_i2o_memio(ips_ha_t *, ips_scb_t *);
426 static int ips_isintr_copperhead(ips_ha_t *);
427 static int ips_isintr_copperhead_memio(ips_ha_t *);
428 static int ips_isintr_morpheus(ips_ha_t *);
429 static int ips_wait(ips_ha_t *, int, int);
430 static int ips_write_driver_status(ips_ha_t *, int);
431 static int ips_read_adapter_status(ips_ha_t *, int);
432 static int ips_read_subsystem_parameters(ips_ha_t *, int);
433 static int ips_read_config(ips_ha_t *, int);
434 static int ips_clear_adapter(ips_ha_t *, int);
435 static int ips_readwrite_page5(ips_ha_t *, int, int);
436 static int ips_init_copperhead(ips_ha_t *);
437 static int ips_init_copperhead_memio(ips_ha_t *);
438 static int ips_init_morpheus(ips_ha_t *);
439 static int ips_isinit_copperhead(ips_ha_t *);
440 static int ips_isinit_copperhead_memio(ips_ha_t *);
441 static int ips_isinit_morpheus(ips_ha_t *);
442 static int ips_erase_bios(ips_ha_t *);
443 static int ips_program_bios(ips_ha_t *, char *, uint32_t, uint32_t);
444 static int ips_verify_bios(ips_ha_t *, char *, uint32_t, uint32_t);
445 static int ips_erase_bios_memio(ips_ha_t *);
446 static int ips_program_bios_memio(ips_ha_t *, char *, uint32_t, uint32_t);
447 static int ips_verify_bios_memio(ips_ha_t *, char *, uint32_t, uint32_t);
448 static int ips_flash_copperhead(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
449 static int ips_flash_bios(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
450 static int ips_flash_firmware(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
451 static void ips_free_flash_copperhead(ips_ha_t * ha);
452 static void ips_get_bios_version(ips_ha_t *, int);
453 static void ips_identify_controller(ips_ha_t *);
454 static void ips_chkstatus(ips_ha_t *, IPS_STATUS *);
455 static void ips_enable_int_copperhead(ips_ha_t *);
456 static void ips_enable_int_copperhead_memio(ips_ha_t *);
457 static void ips_enable_int_morpheus(ips_ha_t *);
458 static int ips_intr_copperhead(ips_ha_t *);
459 static int ips_intr_morpheus(ips_ha_t *);
460 static void ips_next(ips_ha_t *, int);
461 static void ipsintr_blocking(ips_ha_t *, struct ips_scb *);
462 static void ipsintr_done(ips_ha_t *, struct ips_scb *);
463 static void ips_done(ips_ha_t *, ips_scb_t *);
464 static void ips_free(ips_ha_t *);
465 static void ips_init_scb(ips_ha_t *, ips_scb_t *);
466 static void ips_freescb(ips_ha_t *, ips_scb_t *);
467 static void ips_setup_funclist(ips_ha_t *);
468 static void ips_statinit(ips_ha_t *);
469 static void ips_statinit_memio(ips_ha_t *);
470 static void ips_fix_ffdc_time(ips_ha_t *, ips_scb_t *, time_t);
471 static void ips_ffdc_reset(ips_ha_t *, int);
472 static void ips_ffdc_time(ips_ha_t *);
473 static uint32_t ips_statupd_copperhead(ips_ha_t *);
474 static uint32_t ips_statupd_copperhead_memio(ips_ha_t *);
475 static uint32_t ips_statupd_morpheus(ips_ha_t *);
476 static ips_scb_t *ips_getscb(ips_ha_t *);
477 static void ips_putq_scb_head(ips_scb_queue_t *, ips_scb_t *);
478 static void ips_putq_wait_tail(ips_wait_queue_t *, Scsi_Cmnd *);
479 static void ips_putq_copp_tail(ips_copp_queue_t *,
480 ips_copp_wait_item_t *);
481 static ips_scb_t *ips_removeq_scb_head(ips_scb_queue_t *);
482 static ips_scb_t *ips_removeq_scb(ips_scb_queue_t *, ips_scb_t *);
483 static Scsi_Cmnd *ips_removeq_wait_head(ips_wait_queue_t *);
484 static Scsi_Cmnd *ips_removeq_wait(ips_wait_queue_t *, Scsi_Cmnd *);
485 static ips_copp_wait_item_t *ips_removeq_copp(ips_copp_queue_t *,
486 ips_copp_wait_item_t *);
487 static ips_copp_wait_item_t *ips_removeq_copp_head(ips_copp_queue_t *);
489 static int ips_is_passthru(Scsi_Cmnd *);
490 static int ips_make_passthru(ips_ha_t *, Scsi_Cmnd *, ips_scb_t *, int);
491 static int ips_usrcmd(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
492 static void ips_cleanup_passthru(ips_ha_t *, ips_scb_t *);
493 static void ips_scmd_buf_write(Scsi_Cmnd * scmd, void *data,
494 unsigned int count);
495 static void ips_scmd_buf_read(Scsi_Cmnd * scmd, void *data, unsigned int count);
497 int ips_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);
498 static int ips_host_info(ips_ha_t *, char *, off_t, int);
499 static void copy_mem_info(IPS_INFOSTR *, char *, int);
500 static int copy_info(IPS_INFOSTR *, char *, ...);
501 static int ips_get_version_info(ips_ha_t * ha, dma_addr_t, int intr);
502 static void ips_version_check(ips_ha_t * ha, int intr);
503 static int ips_abort_init(ips_ha_t * ha, int index);
504 static int ips_init_phase2(int index);
506 static int ips_init_phase1(struct pci_dev *pci_dev, int *indexPtr);
507 static int ips_register_scsi(int index);
508 /*--------------------------------------------------------------------------*/
509 /* Exported Functions */
510 /*--------------------------------------------------------------------------*/
512 /****************************************************************************/
513 /* */
514 /* Routine Name: ips_setup */
515 /* */
516 /* Routine Description: */
517 /* */
518 /* setup parameters to the driver */
519 /* */
520 /****************************************************************************/
521 static int
522 ips_setup(char *ips_str)
525 int i;
526 char *key;
527 char *value;
528 IPS_OPTION options[] = {
529 {"noi2o", &ips_force_i2o, 0},
530 {"nommap", &ips_force_memio, 0},
531 {"ioctlsize", &ips_ioctlsize, IPS_IOCTL_SIZE},
532 {"cdboot", &ips_cd_boot, 0},
533 {"maxcmds", &MaxLiteCmds, 32},
536 /* Don't use strtok() anymore ( if 2.4 Kernel or beyond ) */
537 /* Search for value */
538 while ((key = strsep(&ips_str, ",."))) {
539 if (!*key)
540 continue;
541 value = strchr(key, ':');
542 if (value)
543 *value++ = '\0';
545 * We now have key/value pairs.
546 * Update the variables
548 for (i = 0; i < (sizeof (options) / sizeof (options[0])); i++) {
549 if (strnicmp
550 (key, options[i].option_name,
551 strlen(options[i].option_name)) == 0) {
552 if (value)
553 *options[i].option_flag =
554 simple_strtoul(value, NULL, 0);
555 else
556 *options[i].option_flag =
557 options[i].option_value;
558 break;
563 return (1);
566 __setup("ips=", ips_setup);
568 /****************************************************************************/
569 /* */
570 /* Routine Name: ips_detect */
571 /* */
572 /* Routine Description: */
573 /* */
574 /* Detect and initialize the driver */
575 /* */
576 /* NOTE: this routine is called under the io_request_lock spinlock */
577 /* */
578 /****************************************************************************/
580 ips_detect(Scsi_Host_Template * SHT)
582 int i;
584 METHOD_TRACE("ips_detect", 1);
586 #ifdef MODULE
587 if (ips)
588 ips_setup(ips);
589 #endif
591 for (i = 0; i < ips_num_controllers; i++) {
592 if (ips_register_scsi(i))
593 ips_free(ips_ha[i]);
594 ips_released_controllers++;
596 ips_hotplug = 1;
597 return (ips_num_controllers);
600 /****************************************************************************/
601 /* configure the function pointers to use the functions that will work */
602 /* with the found version of the adapter */
603 /****************************************************************************/
604 static void
605 ips_setup_funclist(ips_ha_t * ha)
609 * Setup Functions
611 if (IPS_IS_MORPHEUS(ha) || IPS_IS_MARCO(ha)) {
612 /* morpheus / marco / sebring */
613 ha->func.isintr = ips_isintr_morpheus;
614 ha->func.isinit = ips_isinit_morpheus;
615 ha->func.issue = ips_issue_i2o_memio;
616 ha->func.init = ips_init_morpheus;
617 ha->func.statupd = ips_statupd_morpheus;
618 ha->func.reset = ips_reset_morpheus;
619 ha->func.intr = ips_intr_morpheus;
620 ha->func.enableint = ips_enable_int_morpheus;
621 } else if (IPS_USE_MEMIO(ha)) {
622 /* copperhead w/MEMIO */
623 ha->func.isintr = ips_isintr_copperhead_memio;
624 ha->func.isinit = ips_isinit_copperhead_memio;
625 ha->func.init = ips_init_copperhead_memio;
626 ha->func.statupd = ips_statupd_copperhead_memio;
627 ha->func.statinit = ips_statinit_memio;
628 ha->func.reset = ips_reset_copperhead_memio;
629 ha->func.intr = ips_intr_copperhead;
630 ha->func.erasebios = ips_erase_bios_memio;
631 ha->func.programbios = ips_program_bios_memio;
632 ha->func.verifybios = ips_verify_bios_memio;
633 ha->func.enableint = ips_enable_int_copperhead_memio;
634 if (IPS_USE_I2O_DELIVER(ha))
635 ha->func.issue = ips_issue_i2o_memio;
636 else
637 ha->func.issue = ips_issue_copperhead_memio;
638 } else {
639 /* copperhead */
640 ha->func.isintr = ips_isintr_copperhead;
641 ha->func.isinit = ips_isinit_copperhead;
642 ha->func.init = ips_init_copperhead;
643 ha->func.statupd = ips_statupd_copperhead;
644 ha->func.statinit = ips_statinit;
645 ha->func.reset = ips_reset_copperhead;
646 ha->func.intr = ips_intr_copperhead;
647 ha->func.erasebios = ips_erase_bios;
648 ha->func.programbios = ips_program_bios;
649 ha->func.verifybios = ips_verify_bios;
650 ha->func.enableint = ips_enable_int_copperhead;
652 if (IPS_USE_I2O_DELIVER(ha))
653 ha->func.issue = ips_issue_i2o;
654 else
655 ha->func.issue = ips_issue_copperhead;
659 /****************************************************************************/
660 /* */
661 /* Routine Name: ips_release */
662 /* */
663 /* Routine Description: */
664 /* */
665 /* Remove a driver */
666 /* */
667 /****************************************************************************/
669 ips_release(struct Scsi_Host *sh)
671 ips_scb_t *scb;
672 ips_ha_t *ha;
673 int i;
675 METHOD_TRACE("ips_release", 1);
677 for (i = 0; i < IPS_MAX_ADAPTERS && ips_sh[i] != sh; i++) ;
679 if (i == IPS_MAX_ADAPTERS) {
680 printk(KERN_WARNING
681 "(%s) release, invalid Scsi_Host pointer.\n", ips_name);
682 BUG();
683 return (FALSE);
686 ha = IPS_HA(sh);
688 if (!ha)
689 return (FALSE);
691 /* flush the cache on the controller */
692 scb = &ha->scbs[ha->max_cmds - 1];
694 ips_init_scb(ha, scb);
696 scb->timeout = ips_cmd_timeout;
697 scb->cdb[0] = IPS_CMD_FLUSH;
699 scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH;
700 scb->cmd.flush_cache.command_id = IPS_COMMAND_ID(ha, scb);
701 scb->cmd.flush_cache.state = IPS_NORM_STATE;
702 scb->cmd.flush_cache.reserved = 0;
703 scb->cmd.flush_cache.reserved2 = 0;
704 scb->cmd.flush_cache.reserved3 = 0;
705 scb->cmd.flush_cache.reserved4 = 0;
707 IPS_PRINTK(KERN_WARNING, ha->pcidev, "Flushing Cache.\n");
709 /* send command */
710 if (ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_ON) == IPS_FAILURE)
711 IPS_PRINTK(KERN_WARNING, ha->pcidev, "Incomplete Flush.\n");
713 IPS_PRINTK(KERN_WARNING, ha->pcidev, "Flushing Complete.\n");
715 ips_sh[i] = NULL;
716 ips_ha[i] = NULL;
718 /* free extra memory */
719 ips_free(ha);
721 /* Free I/O Region */
722 if (ha->io_addr)
723 release_region(ha->io_addr, ha->io_len);
725 /* free IRQ */
726 free_irq(ha->irq, ha);
728 IPS_REMOVE_HOST(sh);
729 scsi_host_put(sh);
731 ips_released_controllers++;
733 return (FALSE);
736 /****************************************************************************/
737 /* */
738 /* Routine Name: ips_halt */
739 /* */
740 /* Routine Description: */
741 /* */
742 /* Perform cleanup when the system reboots */
743 /* */
744 /****************************************************************************/
745 static int
746 ips_halt(struct notifier_block *nb, ulong event, void *buf)
748 ips_scb_t *scb;
749 ips_ha_t *ha;
750 int i;
752 if ((event != SYS_RESTART) && (event != SYS_HALT) &&
753 (event != SYS_POWER_OFF))
754 return (NOTIFY_DONE);
756 for (i = 0; i < ips_next_controller; i++) {
757 ha = (ips_ha_t *) ips_ha[i];
759 if (!ha)
760 continue;
762 if (!ha->active)
763 continue;
765 /* flush the cache on the controller */
766 scb = &ha->scbs[ha->max_cmds - 1];
768 ips_init_scb(ha, scb);
770 scb->timeout = ips_cmd_timeout;
771 scb->cdb[0] = IPS_CMD_FLUSH;
773 scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH;
774 scb->cmd.flush_cache.command_id = IPS_COMMAND_ID(ha, scb);
775 scb->cmd.flush_cache.state = IPS_NORM_STATE;
776 scb->cmd.flush_cache.reserved = 0;
777 scb->cmd.flush_cache.reserved2 = 0;
778 scb->cmd.flush_cache.reserved3 = 0;
779 scb->cmd.flush_cache.reserved4 = 0;
781 IPS_PRINTK(KERN_WARNING, ha->pcidev, "Flushing Cache.\n");
783 /* send command */
784 if (ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_ON) ==
785 IPS_FAILURE)
786 IPS_PRINTK(KERN_WARNING, ha->pcidev,
787 "Incomplete Flush.\n");
788 else
789 IPS_PRINTK(KERN_WARNING, ha->pcidev,
790 "Flushing Complete.\n");
793 return (NOTIFY_OK);
796 /****************************************************************************/
797 /* */
798 /* Routine Name: ips_eh_abort */
799 /* */
800 /* Routine Description: */
801 /* */
802 /* Abort a command (using the new error code stuff) */
803 /* Note: this routine is called under the io_request_lock */
804 /****************************************************************************/
806 ips_eh_abort(Scsi_Cmnd * SC)
808 ips_ha_t *ha;
809 ips_copp_wait_item_t *item;
810 int ret;
812 METHOD_TRACE("ips_eh_abort", 1);
814 if (!SC)
815 return (FAILED);
817 ha = (ips_ha_t *) SC->device->host->hostdata;
819 if (!ha)
820 return (FAILED);
822 if (!ha->active)
823 return (FAILED);
825 if (SC->serial_number != SC->serial_number_at_timeout) {
826 /* HMM, looks like a bogus command */
827 DEBUG(1, "Abort called with bogus scsi command");
829 return (FAILED);
832 /* See if the command is on the copp queue */
833 item = ha->copp_waitlist.head;
834 while ((item) && (item->scsi_cmd != SC))
835 item = item->next;
837 if (item) {
838 /* Found it */
839 ips_removeq_copp(&ha->copp_waitlist, item);
840 ret = (SUCCESS);
842 /* See if the command is on the wait queue */
843 } else if (ips_removeq_wait(&ha->scb_waitlist, SC)) {
844 /* command not sent yet */
845 ret = (SUCCESS);
846 } else {
847 /* command must have already been sent */
848 ret = (FAILED);
850 return ret;
853 /****************************************************************************/
854 /* */
855 /* Routine Name: ips_eh_reset */
856 /* */
857 /* Routine Description: */
858 /* */
859 /* Reset the controller (with new eh error code) */
860 /* */
861 /* NOTE: this routine is called under the io_request_lock spinlock */
862 /* */
863 /****************************************************************************/
865 ips_eh_reset(Scsi_Cmnd * SC)
867 int ret;
868 int i;
869 ips_ha_t *ha;
870 ips_scb_t *scb;
871 ips_copp_wait_item_t *item;
873 METHOD_TRACE("ips_eh_reset", 1);
875 #ifdef NO_IPS_RESET
876 return (FAILED);
877 #else
879 if (!SC) {
880 DEBUG(1, "Reset called with NULL scsi command");
882 return (FAILED);
885 ha = (ips_ha_t *) SC->device->host->hostdata;
887 if (!ha) {
888 DEBUG(1, "Reset called with NULL ha struct");
890 return (FAILED);
893 if (!ha->active)
894 return (FAILED);
896 /* See if the command is on the copp queue */
897 item = ha->copp_waitlist.head;
898 while ((item) && (item->scsi_cmd != SC))
899 item = item->next;
901 if (item) {
902 /* Found it */
903 ips_removeq_copp(&ha->copp_waitlist, item);
904 return (SUCCESS);
907 /* See if the command is on the wait queue */
908 if (ips_removeq_wait(&ha->scb_waitlist, SC)) {
909 /* command not sent yet */
910 return (SUCCESS);
913 /* An explanation for the casual observer: */
914 /* Part of the function of a RAID controller is automatic error */
915 /* detection and recovery. As such, the only problem that physically */
916 /* resetting an adapter will ever fix is when, for some reason, */
917 /* the driver is not successfully communicating with the adapter. */
918 /* Therefore, we will attempt to flush this adapter. If that succeeds, */
919 /* then there's no real purpose in a physical reset. This will complete */
920 /* much faster and avoids any problems that might be caused by a */
921 /* physical reset ( such as having to fail all the outstanding I/O's ). */
923 if (ha->ioctl_reset == 0) { /* IF Not an IOCTL Requested Reset */
924 scb = &ha->scbs[ha->max_cmds - 1];
926 ips_init_scb(ha, scb);
928 scb->timeout = ips_cmd_timeout;
929 scb->cdb[0] = IPS_CMD_FLUSH;
931 scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH;
932 scb->cmd.flush_cache.command_id = IPS_COMMAND_ID(ha, scb);
933 scb->cmd.flush_cache.state = IPS_NORM_STATE;
934 scb->cmd.flush_cache.reserved = 0;
935 scb->cmd.flush_cache.reserved2 = 0;
936 scb->cmd.flush_cache.reserved3 = 0;
937 scb->cmd.flush_cache.reserved4 = 0;
939 /* Attempt the flush command */
940 ret = ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_IORL);
941 if (ret == IPS_SUCCESS) {
942 IPS_PRINTK(KERN_NOTICE, ha->pcidev,
943 "Reset Request - Flushed Cache\n");
944 return (SUCCESS);
948 /* Either we can't communicate with the adapter or it's an IOCTL request */
949 /* from a utility. A physical reset is needed at this point. */
951 ha->ioctl_reset = 0; /* Reset the IOCTL Requested Reset Flag */
954 * command must have already been sent
955 * reset the controller
957 IPS_PRINTK(KERN_NOTICE, ha->pcidev, "Resetting controller.\n");
958 ret = (*ha->func.reset) (ha);
960 if (!ret) {
961 Scsi_Cmnd *scsi_cmd;
963 IPS_PRINTK(KERN_NOTICE, ha->pcidev,
964 "Controller reset failed - controller now offline.\n");
966 /* Now fail all of the active commands */
967 DEBUG_VAR(1, "(%s%d) Failing active commands",
968 ips_name, ha->host_num);
970 while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) {
971 scb->scsi_cmd->result = DID_ERROR << 16;
972 scb->scsi_cmd->scsi_done(scb->scsi_cmd);
973 ips_freescb(ha, scb);
976 /* Now fail all of the pending commands */
977 DEBUG_VAR(1, "(%s%d) Failing pending commands",
978 ips_name, ha->host_num);
980 while ((scsi_cmd = ips_removeq_wait_head(&ha->scb_waitlist))) {
981 scsi_cmd->result = DID_ERROR;
982 scsi_cmd->scsi_done(scsi_cmd);
985 ha->active = FALSE;
986 return (FAILED);
989 if (!ips_clear_adapter(ha, IPS_INTR_IORL)) {
990 Scsi_Cmnd *scsi_cmd;
992 IPS_PRINTK(KERN_NOTICE, ha->pcidev,
993 "Controller reset failed - controller now offline.\n");
995 /* Now fail all of the active commands */
996 DEBUG_VAR(1, "(%s%d) Failing active commands",
997 ips_name, ha->host_num);
999 while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) {
1000 scb->scsi_cmd->result = DID_ERROR << 16;
1001 scb->scsi_cmd->scsi_done(scb->scsi_cmd);
1002 ips_freescb(ha, scb);
1005 /* Now fail all of the pending commands */
1006 DEBUG_VAR(1, "(%s%d) Failing pending commands",
1007 ips_name, ha->host_num);
1009 while ((scsi_cmd = ips_removeq_wait_head(&ha->scb_waitlist))) {
1010 scsi_cmd->result = DID_ERROR << 16;
1011 scsi_cmd->scsi_done(scsi_cmd);
1014 ha->active = FALSE;
1015 return (FAILED);
1018 /* FFDC */
1019 if (le32_to_cpu(ha->subsys->param[3]) & 0x300000) {
1020 struct timeval tv;
1022 do_gettimeofday(&tv);
1023 ha->last_ffdc = tv.tv_sec;
1024 ha->reset_count++;
1025 ips_ffdc_reset(ha, IPS_INTR_IORL);
1028 /* Now fail all of the active commands */
1029 DEBUG_VAR(1, "(%s%d) Failing active commands", ips_name, ha->host_num);
1031 while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) {
1032 scb->scsi_cmd->result =
1033 (DID_RESET << 16) | (SUGGEST_RETRY << 24);
1034 scb->scsi_cmd->scsi_done(scb->scsi_cmd);
1035 ips_freescb(ha, scb);
1038 /* Reset DCDB active command bits */
1039 for (i = 1; i < ha->nbus; i++)
1040 ha->dcdb_active[i - 1] = 0;
1042 /* Reset the number of active IOCTLs */
1043 ha->num_ioctl = 0;
1045 ips_next(ha, IPS_INTR_IORL);
1047 return (SUCCESS);
1048 #endif /* NO_IPS_RESET */
1052 /****************************************************************************/
1053 /* */
1054 /* Routine Name: ips_queue */
1055 /* */
1056 /* Routine Description: */
1057 /* */
1058 /* Send a command to the controller */
1059 /* */
1060 /* NOTE: */
1061 /* Linux obtains io_request_lock before calling this function */
1062 /* */
1063 /****************************************************************************/
1065 ips_queue(Scsi_Cmnd * SC, void (*done) (Scsi_Cmnd *))
1067 ips_ha_t *ha;
1068 ips_passthru_t *pt;
1070 METHOD_TRACE("ips_queue", 1);
1072 ha = (ips_ha_t *) SC->device->host->hostdata;
1074 if (!ha)
1075 return (1);
1077 if (!ha->active)
1078 return (DID_ERROR);
1080 if (ips_is_passthru(SC)) {
1081 if (ha->copp_waitlist.count == IPS_MAX_IOCTL_QUEUE) {
1082 SC->result = DID_BUS_BUSY << 16;
1083 done(SC);
1085 return (0);
1087 } else if (ha->scb_waitlist.count == IPS_MAX_QUEUE) {
1088 SC->result = DID_BUS_BUSY << 16;
1089 done(SC);
1091 return (0);
1094 SC->scsi_done = done;
1096 DEBUG_VAR(2, "(%s%d): ips_queue: cmd 0x%X (%d %d %d)",
1097 ips_name,
1098 ha->host_num,
1099 SC->cmnd[0],
1100 SC->device->channel, SC->device->id, SC->device->lun);
1102 /* Check for command to initiator IDs */
1103 if ((SC->device->channel > 0)
1104 && (SC->device->id == ha->ha_id[SC->device->channel])) {
1105 SC->result = DID_NO_CONNECT << 16;
1106 done(SC);
1108 return (0);
1111 if (ips_is_passthru(SC)) {
1113 ips_copp_wait_item_t *scratch;
1115 /* A Reset IOCTL is only sent by the boot CD in extreme cases. */
1116 /* There can never be any system activity ( network or disk ), but check */
1117 /* anyway just as a good practice. */
1118 pt = (ips_passthru_t *) SC->request_buffer;
1119 if ((pt->CoppCP.cmd.reset.op_code == IPS_CMD_RESET_CHANNEL) &&
1120 (pt->CoppCP.cmd.reset.adapter_flag == 1)) {
1121 if (ha->scb_activelist.count != 0) {
1122 SC->result = DID_BUS_BUSY << 16;
1123 done(SC);
1124 return (0);
1126 ha->ioctl_reset = 1; /* This reset request is from an IOCTL */
1127 ips_eh_reset(SC);
1128 SC->result = DID_OK << 16;
1129 SC->scsi_done(SC);
1130 return (0);
1133 /* allocate space for the scribble */
1134 scratch = kmalloc(sizeof (ips_copp_wait_item_t), GFP_ATOMIC);
1136 if (!scratch) {
1137 SC->result = DID_ERROR << 16;
1138 done(SC);
1140 return (0);
1143 scratch->scsi_cmd = SC;
1144 scratch->next = NULL;
1146 ips_putq_copp_tail(&ha->copp_waitlist, scratch);
1147 } else {
1148 ips_putq_wait_tail(&ha->scb_waitlist, SC);
1151 ips_next(ha, IPS_INTR_IORL);
1153 return (0);
1156 /****************************************************************************/
1157 /* */
1158 /* Routine Name: ips_biosparam */
1159 /* */
1160 /* Routine Description: */
1161 /* */
1162 /* Set bios geometry for the controller */
1163 /* */
1164 /****************************************************************************/
1165 static int
1166 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
1167 ips_biosparam(Disk * disk, kdev_t dev, int geom[])
1169 ips_ha_t *ha = (ips_ha_t *) disk->device->host->hostdata;
1170 unsigned long capacity = disk->capacity;
1171 #else
1172 ips_biosparam(struct scsi_device *sdev, struct block_device *bdev,
1173 sector_t capacity, int geom[])
1175 ips_ha_t *ha = (ips_ha_t *) sdev->host->hostdata;
1176 #endif
1177 int heads;
1178 int sectors;
1179 int cylinders;
1181 METHOD_TRACE("ips_biosparam", 1);
1183 if (!ha)
1184 /* ?!?! host adater info invalid */
1185 return (0);
1187 if (!ha->active)
1188 return (0);
1190 if (!ips_read_adapter_status(ha, IPS_INTR_ON))
1191 /* ?!?! Enquiry command failed */
1192 return (0);
1194 if ((capacity > 0x400000) && ((ha->enq->ucMiscFlag & 0x8) == 0)) {
1195 heads = IPS_NORM_HEADS;
1196 sectors = IPS_NORM_SECTORS;
1197 } else {
1198 heads = IPS_COMP_HEADS;
1199 sectors = IPS_COMP_SECTORS;
1202 cylinders = (unsigned long) capacity / (heads * sectors);
1204 DEBUG_VAR(2, "Geometry: heads: %d, sectors: %d, cylinders: %d",
1205 heads, sectors, cylinders);
1207 geom[0] = heads;
1208 geom[1] = sectors;
1209 geom[2] = cylinders;
1211 return (0);
1214 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
1216 /* ips_proc24_info is a wrapper around ips_proc_info *
1217 * for compatibility with the 2.4 scsi parameters */
1218 static int
1219 ips_proc24_info(char *buffer, char **start, off_t offset, int length,
1220 int hostno, int func)
1222 int i;
1224 for (i = 0; i < ips_next_controller; i++) {
1225 if (ips_sh[i] && ips_sh[i]->host_no == hostno) {
1226 return ips_proc_info(ips_sh[i], buffer, start,
1227 offset, length, func);
1230 return -EINVAL;
1233 /****************************************************************************/
1234 /* */
1235 /* Routine Name: ips_select_queue_depth */
1236 /* */
1237 /* Routine Description: */
1238 /* */
1239 /* Select queue depths for the devices on the contoller */
1240 /* */
1241 /****************************************************************************/
1242 static void
1243 ips_select_queue_depth(struct Scsi_Host *host, Scsi_Device * scsi_devs)
1245 Scsi_Device *device;
1246 ips_ha_t *ha;
1247 int count = 0;
1248 int min;
1250 ha = IPS_HA(host);
1251 min = ha->max_cmds / 4;
1253 for (device = scsi_devs; device; device = device->next) {
1254 if (device->host == host) {
1255 if ((device->channel == 0) && (device->type == 0))
1256 count++;
1260 for (device = scsi_devs; device; device = device->next) {
1261 if (device->host == host) {
1262 if ((device->channel == 0) && (device->type == 0)) {
1263 device->queue_depth =
1264 (ha->max_cmds - 1) / count;
1265 if (device->queue_depth < min)
1266 device->queue_depth = min;
1267 } else {
1268 device->queue_depth = 2;
1271 if (device->queue_depth < 2)
1272 device->queue_depth = 2;
1277 #else
1278 /****************************************************************************/
1279 /* */
1280 /* Routine Name: ips_slave_configure */
1281 /* */
1282 /* Routine Description: */
1283 /* */
1284 /* Set queue depths on devices once scan is complete */
1285 /* */
1286 /****************************************************************************/
1288 ips_slave_configure(Scsi_Device * SDptr)
1290 ips_ha_t *ha;
1291 int min;
1293 ha = IPS_HA(SDptr->host);
1294 if (SDptr->tagged_supported && SDptr->type == TYPE_DISK) {
1295 min = ha->max_cmds / 2;
1296 if (ha->enq->ucLogDriveCount <= 2)
1297 min = ha->max_cmds - 1;
1298 scsi_adjust_queue_depth(SDptr, MSG_ORDERED_TAG, min);
1300 return 0;
1302 #endif
1304 /****************************************************************************/
1305 /* */
1306 /* Routine Name: do_ipsintr */
1307 /* */
1308 /* Routine Description: */
1309 /* */
1310 /* Wrapper for the interrupt handler */
1311 /* */
1312 /****************************************************************************/
1313 irqreturn_t
1314 do_ipsintr(int irq, void *dev_id, struct pt_regs * regs)
1316 ips_ha_t *ha;
1317 unsigned long cpu_flags;
1318 struct Scsi_Host *host;
1319 int irqstatus;
1321 METHOD_TRACE("do_ipsintr", 2);
1323 ha = (ips_ha_t *) dev_id;
1324 if (!ha)
1325 return IRQ_NONE;
1326 host = ips_sh[ha->host_num];
1327 /* interrupt during initialization */
1328 if (!host) {
1329 (*ha->func.intr) (ha);
1330 return IRQ_HANDLED;
1333 IPS_LOCK_SAVE(host->host_lock, cpu_flags);
1335 if (!ha->active) {
1336 IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags);
1337 return IRQ_HANDLED;
1340 irqstatus = (*ha->func.intr) (ha);
1342 IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags);
1344 /* start the next command */
1345 ips_next(ha, IPS_INTR_ON);
1346 return IRQ_RETVAL(irqstatus);
1349 /****************************************************************************/
1350 /* */
1351 /* Routine Name: ips_intr_copperhead */
1352 /* */
1353 /* Routine Description: */
1354 /* */
1355 /* Polling interrupt handler */
1356 /* */
1357 /* ASSUMES interrupts are disabled */
1358 /* */
1359 /****************************************************************************/
1361 ips_intr_copperhead(ips_ha_t * ha)
1363 ips_stat_t *sp;
1364 ips_scb_t *scb;
1365 IPS_STATUS cstatus;
1366 int intrstatus;
1368 METHOD_TRACE("ips_intr", 2);
1370 if (!ha)
1371 return 0;
1373 if (!ha->active)
1374 return 0;
1376 intrstatus = (*ha->func.isintr) (ha);
1378 if (!intrstatus) {
1380 * Unexpected/Shared interrupt
1383 return 0;
1386 while (TRUE) {
1387 sp = &ha->sp;
1389 intrstatus = (*ha->func.isintr) (ha);
1391 if (!intrstatus)
1392 break;
1393 else
1394 cstatus.value = (*ha->func.statupd) (ha);
1396 if (cstatus.fields.command_id > (IPS_MAX_CMDS - 1)) {
1397 /* Spurious Interupt ? */
1398 continue;
1401 ips_chkstatus(ha, &cstatus);
1402 scb = (ips_scb_t *) sp->scb_addr;
1405 * use the callback function to finish things up
1406 * NOTE: interrupts are OFF for this
1408 (*scb->callback) (ha, scb);
1409 } /* end while */
1410 return 1;
1413 /****************************************************************************/
1414 /* */
1415 /* Routine Name: ips_intr_morpheus */
1416 /* */
1417 /* Routine Description: */
1418 /* */
1419 /* Polling interrupt handler */
1420 /* */
1421 /* ASSUMES interrupts are disabled */
1422 /* */
1423 /****************************************************************************/
1425 ips_intr_morpheus(ips_ha_t * ha)
1427 ips_stat_t *sp;
1428 ips_scb_t *scb;
1429 IPS_STATUS cstatus;
1430 int intrstatus;
1432 METHOD_TRACE("ips_intr_morpheus", 2);
1434 if (!ha)
1435 return 0;
1437 if (!ha->active)
1438 return 0;
1440 intrstatus = (*ha->func.isintr) (ha);
1442 if (!intrstatus) {
1444 * Unexpected/Shared interrupt
1447 return 0;
1450 while (TRUE) {
1451 sp = &ha->sp;
1453 intrstatus = (*ha->func.isintr) (ha);
1455 if (!intrstatus)
1456 break;
1457 else
1458 cstatus.value = (*ha->func.statupd) (ha);
1460 if (cstatus.value == 0xffffffff)
1461 /* No more to process */
1462 break;
1464 if (cstatus.fields.command_id > (IPS_MAX_CMDS - 1)) {
1465 IPS_PRINTK(KERN_WARNING, ha->pcidev,
1466 "Spurious interrupt; no ccb.\n");
1468 continue;
1471 ips_chkstatus(ha, &cstatus);
1472 scb = (ips_scb_t *) sp->scb_addr;
1475 * use the callback function to finish things up
1476 * NOTE: interrupts are OFF for this
1478 (*scb->callback) (ha, scb);
1479 } /* end while */
1480 return 1;
1483 /****************************************************************************/
1484 /* */
1485 /* Routine Name: ips_info */
1486 /* */
1487 /* Routine Description: */
1488 /* */
1489 /* Return info about the driver */
1490 /* */
1491 /****************************************************************************/
1492 const char *
1493 ips_info(struct Scsi_Host *SH)
1495 static char buffer[256];
1496 char *bp;
1497 ips_ha_t *ha;
1499 METHOD_TRACE("ips_info", 1);
1501 ha = IPS_HA(SH);
1503 if (!ha)
1504 return (NULL);
1506 bp = &buffer[0];
1507 memset(bp, 0, sizeof (buffer));
1509 sprintf(bp, "%s%s%s Build %d", "IBM PCI ServeRAID ",
1510 IPS_VERSION_HIGH, IPS_VERSION_LOW, IPS_BUILD_IDENT);
1512 if (ha->ad_type > 0 && ha->ad_type <= MAX_ADAPTER_NAME) {
1513 strcat(bp, " <");
1514 strcat(bp, ips_adapter_name[ha->ad_type - 1]);
1515 strcat(bp, ">");
1518 return (bp);
1521 /****************************************************************************/
1522 /* */
1523 /* Routine Name: ips_proc_info */
1524 /* */
1525 /* Routine Description: */
1526 /* */
1527 /* The passthru interface for the driver */
1528 /* */
1529 /****************************************************************************/
1531 ips_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
1532 int length, int func)
1534 int i;
1535 int ret;
1536 ips_ha_t *ha = NULL;
1538 METHOD_TRACE("ips_proc_info", 1);
1540 /* Find our host structure */
1541 for (i = 0; i < ips_next_controller; i++) {
1542 if (ips_sh[i]) {
1543 if (ips_sh[i] == host) {
1544 ha = (ips_ha_t *) ips_sh[i]->hostdata;
1545 break;
1550 if (!ha)
1551 return (-EINVAL);
1553 if (func) {
1554 /* write */
1555 return (0);
1556 } else {
1557 /* read */
1558 if (start)
1559 *start = buffer;
1561 ret = ips_host_info(ha, buffer, offset, length);
1563 return (ret);
1567 /*--------------------------------------------------------------------------*/
1568 /* Helper Functions */
1569 /*--------------------------------------------------------------------------*/
1571 /****************************************************************************/
1572 /* */
1573 /* Routine Name: ips_is_passthru */
1574 /* */
1575 /* Routine Description: */
1576 /* */
1577 /* Determine if the specified SCSI command is really a passthru command */
1578 /* */
1579 /****************************************************************************/
1580 static int
1581 ips_is_passthru(Scsi_Cmnd * SC)
1583 METHOD_TRACE("ips_is_passthru", 1);
1585 if (!SC)
1586 return (0);
1588 if ((SC->cmnd[0] == IPS_IOCTL_COMMAND) &&
1589 (SC->device->channel == 0) &&
1590 (SC->device->id == IPS_ADAPTER_ID) &&
1591 (SC->device->lun == 0) && SC->request_buffer) {
1592 if ((!SC->use_sg) && SC->request_bufflen &&
1593 (((char *) SC->request_buffer)[0] == 'C') &&
1594 (((char *) SC->request_buffer)[1] == 'O') &&
1595 (((char *) SC->request_buffer)[2] == 'P') &&
1596 (((char *) SC->request_buffer)[3] == 'P'))
1597 return 1;
1598 else if (SC->use_sg) {
1599 struct scatterlist *sg = SC->request_buffer;
1600 char *buffer = IPS_SG_ADDRESS(sg);
1601 if (buffer && buffer[0] == 'C' && buffer[1] == 'O' &&
1602 buffer[2] == 'P' && buffer[3] == 'P')
1603 return 1;
1606 return 0;
1609 /****************************************************************************/
1610 /* */
1611 /* Routine Name: ips_alloc_passthru_buffer */
1612 /* */
1613 /* Routine Description: */
1614 /* allocate a buffer large enough for the ioctl data if the ioctl buffer */
1615 /* is too small or doesn't exist */
1616 /****************************************************************************/
1617 static int
1618 ips_alloc_passthru_buffer(ips_ha_t * ha, int length)
1620 void *bigger_buf;
1621 dma_addr_t dma_busaddr;
1623 if (ha->ioctl_data && length <= ha->ioctl_len)
1624 return 0;
1625 /* there is no buffer or it's not big enough, allocate a new one */
1626 bigger_buf = pci_alloc_consistent(ha->pcidev, length, &dma_busaddr);
1627 if (bigger_buf) {
1628 /* free the old memory */
1629 pci_free_consistent(ha->pcidev, ha->ioctl_len, ha->ioctl_data,
1630 ha->ioctl_busaddr);
1631 /* use the new memory */
1632 ha->ioctl_data = (char *) bigger_buf;
1633 ha->ioctl_len = length;
1634 ha->ioctl_busaddr = dma_busaddr;
1635 } else {
1636 return -1;
1638 return 0;
1641 /****************************************************************************/
1642 /* */
1643 /* Routine Name: ips_make_passthru */
1644 /* */
1645 /* Routine Description: */
1646 /* */
1647 /* Make a passthru command out of the info in the Scsi block */
1648 /* */
1649 /****************************************************************************/
1650 static int
1651 ips_make_passthru(ips_ha_t * ha, Scsi_Cmnd * SC, ips_scb_t * scb, int intr)
1653 ips_passthru_t *pt;
1654 int length = 0;
1655 int ret;
1657 METHOD_TRACE("ips_make_passthru", 1);
1659 if (!SC->use_sg) {
1660 length = SC->request_bufflen;
1661 } else {
1662 struct scatterlist *sg = SC->request_buffer;
1663 int i;
1664 for (i = 0; i < SC->use_sg; i++)
1665 length += sg[i].length;
1667 if (length < sizeof (ips_passthru_t)) {
1668 /* wrong size */
1669 DEBUG_VAR(1, "(%s%d) Passthru structure wrong size",
1670 ips_name, ha->host_num);
1671 return (IPS_FAILURE);
1673 if (ips_alloc_passthru_buffer(ha, length)) {
1674 /* allocation failure! If ha->ioctl_data exists, use it to return
1675 some error codes. Return a failed command to the scsi layer. */
1676 if (ha->ioctl_data) {
1677 pt = (ips_passthru_t *) ha->ioctl_data;
1678 ips_scmd_buf_read(SC, pt, sizeof (ips_passthru_t));
1679 pt->BasicStatus = 0x0B;
1680 pt->ExtendedStatus = 0x00;
1681 ips_scmd_buf_write(SC, pt, sizeof (ips_passthru_t));
1683 return IPS_FAILURE;
1685 ha->ioctl_datasize = length;
1687 ips_scmd_buf_read(SC, ha->ioctl_data, ha->ioctl_datasize);
1688 pt = (ips_passthru_t *) ha->ioctl_data;
1691 * Some notes about the passthru interface used
1693 * IF the scsi op_code == 0x0d then we assume
1694 * that the data came along with/goes with the
1695 * packet we received from the sg driver. In this
1696 * case the CmdBSize field of the pt structure is
1697 * used for the size of the buffer.
1700 switch (pt->CoppCmd) {
1701 case IPS_NUMCTRLS:
1702 memcpy(ha->ioctl_data + sizeof (ips_passthru_t),
1703 &ips_num_controllers, sizeof (int));
1704 ips_scmd_buf_write(SC, ha->ioctl_data,
1705 sizeof (ips_passthru_t) + sizeof (int));
1706 SC->result = DID_OK << 16;
1708 return (IPS_SUCCESS_IMM);
1710 case IPS_COPPUSRCMD:
1711 case IPS_COPPIOCCMD:
1712 if (SC->cmnd[0] == IPS_IOCTL_COMMAND) {
1713 if (length < (sizeof (ips_passthru_t) + pt->CmdBSize)) {
1714 /* wrong size */
1715 DEBUG_VAR(1,
1716 "(%s%d) Passthru structure wrong size",
1717 ips_name, ha->host_num);
1719 return (IPS_FAILURE);
1722 if (ha->device_id == IPS_DEVICEID_COPPERHEAD &&
1723 pt->CoppCP.cmd.flashfw.op_code ==
1724 IPS_CMD_RW_BIOSFW) {
1725 ret = ips_flash_copperhead(ha, pt, scb);
1726 ips_scmd_buf_write(SC, ha->ioctl_data,
1727 sizeof (ips_passthru_t));
1728 return ret;
1730 if (ips_usrcmd(ha, pt, scb))
1731 return (IPS_SUCCESS);
1732 else
1733 return (IPS_FAILURE);
1736 break;
1738 } /* end switch */
1740 return (IPS_FAILURE);
1743 /****************************************************************************/
1744 /* Routine Name: ips_flash_copperhead */
1745 /* Routine Description: */
1746 /* Flash the BIOS/FW on a Copperhead style controller */
1747 /****************************************************************************/
1748 static int
1749 ips_flash_copperhead(ips_ha_t * ha, ips_passthru_t * pt, ips_scb_t * scb)
1751 int datasize;
1753 /* Trombone is the only copperhead that can do packet flash, but only
1754 * for firmware. No one said it had to make sence. */
1755 if (IPS_IS_TROMBONE(ha) && pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE) {
1756 if (ips_usrcmd(ha, pt, scb))
1757 return IPS_SUCCESS;
1758 else
1759 return IPS_FAILURE;
1761 pt->BasicStatus = 0x0B;
1762 pt->ExtendedStatus = 0;
1763 scb->scsi_cmd->result = DID_OK << 16;
1764 /* IF it's OK to Use the "CD BOOT" Flash Buffer, then you can */
1765 /* avoid allocating a huge buffer per adapter ( which can fail ). */
1766 if (pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE &&
1767 pt->CoppCP.cmd.flashfw.direction == IPS_ERASE_BIOS) {
1768 pt->BasicStatus = 0;
1769 return ips_flash_bios(ha, pt, scb);
1770 } else if (pt->CoppCP.cmd.flashfw.packet_num == 0) {
1771 if (ips_FlashData && !test_and_set_bit(0, &ips_FlashDataInUse)){
1772 ha->flash_data = ips_FlashData;
1773 ha->flash_busaddr = ips_flashbusaddr;
1774 ha->flash_len = PAGE_SIZE << 7;
1775 ha->flash_datasize = 0;
1776 } else if (!ha->flash_data) {
1777 datasize = pt->CoppCP.cmd.flashfw.total_packets *
1778 pt->CoppCP.cmd.flashfw.count;
1779 ha->flash_data = pci_alloc_consistent(ha->pcidev,
1780 datasize,
1781 &ha->flash_busaddr);
1782 if (!ha->flash_data){
1783 printk(KERN_WARNING "Unable to allocate a flash buffer\n");
1784 return IPS_FAILURE;
1786 ha->flash_datasize = 0;
1787 ha->flash_len = datasize;
1788 } else
1789 return IPS_FAILURE;
1790 } else {
1791 if (pt->CoppCP.cmd.flashfw.count + ha->flash_datasize >
1792 ha->flash_len) {
1793 ips_free_flash_copperhead(ha);
1794 IPS_PRINTK(KERN_WARNING, ha->pcidev,
1795 "failed size sanity check\n");
1796 return IPS_FAILURE;
1799 if (!ha->flash_data)
1800 return IPS_FAILURE;
1801 pt->BasicStatus = 0;
1802 memcpy(&ha->flash_data[ha->flash_datasize], pt + 1,
1803 pt->CoppCP.cmd.flashfw.count);
1804 ha->flash_datasize += pt->CoppCP.cmd.flashfw.count;
1805 if (pt->CoppCP.cmd.flashfw.packet_num ==
1806 pt->CoppCP.cmd.flashfw.total_packets - 1) {
1807 if (pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE)
1808 return ips_flash_bios(ha, pt, scb);
1809 else if (pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE)
1810 return ips_flash_firmware(ha, pt, scb);
1812 return IPS_SUCCESS_IMM;
1815 /****************************************************************************/
1816 /* Routine Name: ips_flash_bios */
1817 /* Routine Description: */
1818 /* flashes the bios of a copperhead adapter */
1819 /****************************************************************************/
1820 static int
1821 ips_flash_bios(ips_ha_t * ha, ips_passthru_t * pt, ips_scb_t * scb)
1824 if (pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE &&
1825 pt->CoppCP.cmd.flashfw.direction == IPS_WRITE_BIOS) {
1826 if ((!ha->func.programbios) || (!ha->func.erasebios) ||
1827 (!ha->func.verifybios))
1828 goto error;
1829 if ((*ha->func.erasebios) (ha)) {
1830 DEBUG_VAR(1,
1831 "(%s%d) flash bios failed - unable to erase flash",
1832 ips_name, ha->host_num);
1833 goto error;
1834 } else
1835 if ((*ha->func.programbios) (ha,
1836 ha->flash_data +
1837 IPS_BIOS_HEADER,
1838 ha->flash_datasize -
1839 IPS_BIOS_HEADER, 0)) {
1840 DEBUG_VAR(1,
1841 "(%s%d) flash bios failed - unable to flash",
1842 ips_name, ha->host_num);
1843 goto error;
1844 } else
1845 if ((*ha->func.verifybios) (ha,
1846 ha->flash_data +
1847 IPS_BIOS_HEADER,
1848 ha->flash_datasize -
1849 IPS_BIOS_HEADER, 0)) {
1850 DEBUG_VAR(1,
1851 "(%s%d) flash bios failed - unable to verify flash",
1852 ips_name, ha->host_num);
1853 goto error;
1855 ips_free_flash_copperhead(ha);
1856 return IPS_SUCCESS_IMM;
1857 } else if (pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE &&
1858 pt->CoppCP.cmd.flashfw.direction == IPS_ERASE_BIOS) {
1859 if (!ha->func.erasebios)
1860 goto error;
1861 if ((*ha->func.erasebios) (ha)) {
1862 DEBUG_VAR(1,
1863 "(%s%d) flash bios failed - unable to erase flash",
1864 ips_name, ha->host_num);
1865 goto error;
1867 return IPS_SUCCESS_IMM;
1869 error:
1870 pt->BasicStatus = 0x0B;
1871 pt->ExtendedStatus = 0x00;
1872 ips_free_flash_copperhead(ha);
1873 return IPS_FAILURE;
1876 /****************************************************************************/
1877 /* */
1878 /* Routine Name: ips_fill_scb_sg_single */
1879 /* */
1880 /* Routine Description: */
1881 /* Fill in a single scb sg_list element from an address */
1882 /* return a -1 if a breakup occurred */
1883 /****************************************************************************/
1884 static int
1885 ips_fill_scb_sg_single(ips_ha_t * ha, dma_addr_t busaddr,
1886 ips_scb_t * scb, int indx, unsigned int e_len)
1889 int ret_val = 0;
1891 if ((scb->data_len + e_len) > ha->max_xfer) {
1892 e_len = ha->max_xfer - scb->data_len;
1893 scb->breakup = indx;
1894 ++scb->sg_break;
1895 ret_val = -1;
1896 } else {
1897 scb->breakup = 0;
1898 scb->sg_break = 0;
1900 if (IPS_USE_ENH_SGLIST(ha)) {
1901 scb->sg_list.enh_list[indx].address_lo =
1902 cpu_to_le32(pci_dma_lo32(busaddr));
1903 scb->sg_list.enh_list[indx].address_hi =
1904 cpu_to_le32(pci_dma_hi32(busaddr));
1905 scb->sg_list.enh_list[indx].length = cpu_to_le32(e_len);
1906 } else {
1907 scb->sg_list.std_list[indx].address =
1908 cpu_to_le32(pci_dma_lo32(busaddr));
1909 scb->sg_list.std_list[indx].length = cpu_to_le32(e_len);
1912 ++scb->sg_len;
1913 scb->data_len += e_len;
1914 return ret_val;
1917 /****************************************************************************/
1918 /* Routine Name: ips_flash_firmware */
1919 /* Routine Description: */
1920 /* flashes the firmware of a copperhead adapter */
1921 /****************************************************************************/
1922 static int
1923 ips_flash_firmware(ips_ha_t * ha, ips_passthru_t * pt, ips_scb_t * scb)
1925 IPS_SG_LIST sg_list;
1926 uint32_t cmd_busaddr;
1928 if (pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE &&
1929 pt->CoppCP.cmd.flashfw.direction == IPS_WRITE_FW) {
1930 memset(&pt->CoppCP.cmd, 0, sizeof (IPS_HOST_COMMAND));
1931 pt->CoppCP.cmd.flashfw.op_code = IPS_CMD_DOWNLOAD;
1932 pt->CoppCP.cmd.flashfw.count = cpu_to_le32(ha->flash_datasize);
1933 } else {
1934 pt->BasicStatus = 0x0B;
1935 pt->ExtendedStatus = 0x00;
1936 ips_free_flash_copperhead(ha);
1937 return IPS_FAILURE;
1939 /* Save the S/G list pointer so it doesn't get clobbered */
1940 sg_list.list = scb->sg_list.list;
1941 cmd_busaddr = scb->scb_busaddr;
1942 /* copy in the CP */
1943 memcpy(&scb->cmd, &pt->CoppCP.cmd, sizeof (IPS_IOCTL_CMD));
1944 /* FIX stuff that might be wrong */
1945 scb->sg_list.list = sg_list.list;
1946 scb->scb_busaddr = cmd_busaddr;
1947 scb->bus = scb->scsi_cmd->device->channel;
1948 scb->target_id = scb->scsi_cmd->device->id;
1949 scb->lun = scb->scsi_cmd->device->lun;
1950 scb->sg_len = 0;
1951 scb->data_len = 0;
1952 scb->flags = 0;
1953 scb->op_code = 0;
1954 scb->callback = ipsintr_done;
1955 scb->timeout = ips_cmd_timeout;
1957 scb->data_len = ha->flash_datasize;
1958 scb->data_busaddr =
1959 pci_map_single(ha->pcidev, ha->flash_data, scb->data_len,
1960 IPS_DMA_DIR(scb));
1961 scb->flags |= IPS_SCB_MAP_SINGLE;
1962 scb->cmd.flashfw.command_id = IPS_COMMAND_ID(ha, scb);
1963 scb->cmd.flashfw.buffer_addr = cpu_to_le32(scb->data_busaddr);
1964 if (pt->TimeOut)
1965 scb->timeout = pt->TimeOut;
1966 scb->scsi_cmd->result = DID_OK << 16;
1967 return IPS_SUCCESS;
1970 /****************************************************************************/
1971 /* Routine Name: ips_free_flash_copperhead */
1972 /* Routine Description: */
1973 /* release the memory resources used to hold the flash image */
1974 /****************************************************************************/
1975 static void
1976 ips_free_flash_copperhead(ips_ha_t * ha)
1978 if (ha->flash_data == ips_FlashData)
1979 test_and_clear_bit(0, &ips_FlashDataInUse);
1980 else if (ha->flash_data)
1981 pci_free_consistent(ha->pcidev, ha->flash_len, ha->flash_data,
1982 ha->flash_busaddr);
1983 ha->flash_data = NULL;
1986 /****************************************************************************/
1987 /* */
1988 /* Routine Name: ips_usrcmd */
1989 /* */
1990 /* Routine Description: */
1991 /* */
1992 /* Process a user command and make it ready to send */
1993 /* */
1994 /****************************************************************************/
1995 static int
1996 ips_usrcmd(ips_ha_t * ha, ips_passthru_t * pt, ips_scb_t * scb)
1998 IPS_SG_LIST sg_list;
1999 uint32_t cmd_busaddr;
2001 METHOD_TRACE("ips_usrcmd", 1);
2003 if ((!scb) || (!pt) || (!ha))
2004 return (0);
2006 /* Save the S/G list pointer so it doesn't get clobbered */
2007 sg_list.list = scb->sg_list.list;
2008 cmd_busaddr = scb->scb_busaddr;
2009 /* copy in the CP */
2010 memcpy(&scb->cmd, &pt->CoppCP.cmd, sizeof (IPS_IOCTL_CMD));
2011 memcpy(&scb->dcdb, &pt->CoppCP.dcdb, sizeof (IPS_DCDB_TABLE));
2013 /* FIX stuff that might be wrong */
2014 scb->sg_list.list = sg_list.list;
2015 scb->scb_busaddr = cmd_busaddr;
2016 scb->bus = scb->scsi_cmd->device->channel;
2017 scb->target_id = scb->scsi_cmd->device->id;
2018 scb->lun = scb->scsi_cmd->device->lun;
2019 scb->sg_len = 0;
2020 scb->data_len = 0;
2021 scb->flags = 0;
2022 scb->op_code = 0;
2023 scb->callback = ipsintr_done;
2024 scb->timeout = ips_cmd_timeout;
2025 scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
2027 /* we don't support DCDB/READ/WRITE Scatter Gather */
2028 if ((scb->cmd.basic_io.op_code == IPS_CMD_READ_SG) ||
2029 (scb->cmd.basic_io.op_code == IPS_CMD_WRITE_SG) ||
2030 (scb->cmd.basic_io.op_code == IPS_CMD_DCDB_SG))
2031 return (0);
2033 if (pt->CmdBSize) {
2034 scb->data_len = pt->CmdBSize;
2035 scb->data_busaddr = ha->ioctl_busaddr + sizeof (ips_passthru_t);
2036 } else {
2037 scb->data_busaddr = 0L;
2040 if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)
2041 scb->cmd.dcdb.dcdb_address = cpu_to_le32(scb->scb_busaddr +
2042 (unsigned long) &scb->
2043 dcdb -
2044 (unsigned long) scb);
2046 if (pt->CmdBSize) {
2047 if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)
2048 scb->dcdb.buffer_pointer =
2049 cpu_to_le32(scb->data_busaddr);
2050 else
2051 scb->cmd.basic_io.sg_addr =
2052 cpu_to_le32(scb->data_busaddr);
2055 /* set timeouts */
2056 if (pt->TimeOut) {
2057 scb->timeout = pt->TimeOut;
2059 if (pt->TimeOut <= 10)
2060 scb->dcdb.cmd_attribute |= IPS_TIMEOUT10;
2061 else if (pt->TimeOut <= 60)
2062 scb->dcdb.cmd_attribute |= IPS_TIMEOUT60;
2063 else
2064 scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M;
2067 /* assume success */
2068 scb->scsi_cmd->result = DID_OK << 16;
2070 /* success */
2071 return (1);
2074 /****************************************************************************/
2075 /* */
2076 /* Routine Name: ips_cleanup_passthru */
2077 /* */
2078 /* Routine Description: */
2079 /* */
2080 /* Cleanup after a passthru command */
2081 /* */
2082 /****************************************************************************/
2083 static void
2084 ips_cleanup_passthru(ips_ha_t * ha, ips_scb_t * scb)
2086 ips_passthru_t *pt;
2088 METHOD_TRACE("ips_cleanup_passthru", 1);
2090 if ((!scb) || (!scb->scsi_cmd) || (!scb->scsi_cmd->request_buffer)) {
2091 DEBUG_VAR(1, "(%s%d) couldn't cleanup after passthru",
2092 ips_name, ha->host_num);
2094 return;
2096 pt = (ips_passthru_t *) ha->ioctl_data;
2098 /* Copy data back to the user */
2099 if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB) /* Copy DCDB Back to Caller's Area */
2100 memcpy(&pt->CoppCP.dcdb, &scb->dcdb, sizeof (IPS_DCDB_TABLE));
2102 pt->BasicStatus = scb->basic_status;
2103 pt->ExtendedStatus = scb->extended_status;
2104 pt->AdapterType = ha->ad_type;
2106 if (ha->device_id == IPS_DEVICEID_COPPERHEAD &&
2107 (scb->cmd.flashfw.op_code == IPS_CMD_DOWNLOAD ||
2108 scb->cmd.flashfw.op_code == IPS_CMD_RW_BIOSFW))
2109 ips_free_flash_copperhead(ha);
2111 ips_scmd_buf_write(scb->scsi_cmd, ha->ioctl_data, ha->ioctl_datasize);
2114 /****************************************************************************/
2115 /* */
2116 /* Routine Name: ips_host_info */
2117 /* */
2118 /* Routine Description: */
2119 /* */
2120 /* The passthru interface for the driver */
2121 /* */
2122 /****************************************************************************/
2123 static int
2124 ips_host_info(ips_ha_t * ha, char *ptr, off_t offset, int len)
2126 IPS_INFOSTR info;
2128 METHOD_TRACE("ips_host_info", 1);
2130 info.buffer = ptr;
2131 info.length = len;
2132 info.offset = offset;
2133 info.pos = 0;
2134 info.localpos = 0;
2136 copy_info(&info, "\nIBM ServeRAID General Information:\n\n");
2138 if ((le32_to_cpu(ha->nvram->signature) == IPS_NVRAM_P5_SIG) &&
2139 (le16_to_cpu(ha->nvram->adapter_type) != 0))
2140 copy_info(&info, "\tController Type : %s\n",
2141 ips_adapter_name[ha->ad_type - 1]);
2142 else
2143 copy_info(&info,
2144 "\tController Type : Unknown\n");
2146 if (ha->io_addr)
2147 copy_info(&info,
2148 "\tIO region : 0x%lx (%d bytes)\n",
2149 ha->io_addr, ha->io_len);
2151 if (ha->mem_addr) {
2152 copy_info(&info,
2153 "\tMemory region : 0x%lx (%d bytes)\n",
2154 ha->mem_addr, ha->mem_len);
2155 copy_info(&info,
2156 "\tShared memory address : 0x%lx\n",
2157 ha->mem_ptr);
2160 copy_info(&info, "\tIRQ number : %d\n", ha->irq);
2162 /* For the Next 3 lines Check for Binary 0 at the end and don't include it if it's there. */
2163 /* That keeps everything happy for "text" operations on the proc file. */
2165 if (le32_to_cpu(ha->nvram->signature) == IPS_NVRAM_P5_SIG) {
2166 if (ha->nvram->bios_low[3] == 0) {
2167 copy_info(&info,
2168 "\tBIOS Version : %c%c%c%c%c%c%c\n",
2169 ha->nvram->bios_high[0], ha->nvram->bios_high[1],
2170 ha->nvram->bios_high[2], ha->nvram->bios_high[3],
2171 ha->nvram->bios_low[0], ha->nvram->bios_low[1],
2172 ha->nvram->bios_low[2]);
2174 } else {
2175 copy_info(&info,
2176 "\tBIOS Version : %c%c%c%c%c%c%c%c\n",
2177 ha->nvram->bios_high[0], ha->nvram->bios_high[1],
2178 ha->nvram->bios_high[2], ha->nvram->bios_high[3],
2179 ha->nvram->bios_low[0], ha->nvram->bios_low[1],
2180 ha->nvram->bios_low[2], ha->nvram->bios_low[3]);
2185 if (ha->enq->CodeBlkVersion[7] == 0) {
2186 copy_info(&info,
2187 "\tFirmware Version : %c%c%c%c%c%c%c\n",
2188 ha->enq->CodeBlkVersion[0], ha->enq->CodeBlkVersion[1],
2189 ha->enq->CodeBlkVersion[2], ha->enq->CodeBlkVersion[3],
2190 ha->enq->CodeBlkVersion[4], ha->enq->CodeBlkVersion[5],
2191 ha->enq->CodeBlkVersion[6]);
2192 } else {
2193 copy_info(&info,
2194 "\tFirmware Version : %c%c%c%c%c%c%c%c\n",
2195 ha->enq->CodeBlkVersion[0], ha->enq->CodeBlkVersion[1],
2196 ha->enq->CodeBlkVersion[2], ha->enq->CodeBlkVersion[3],
2197 ha->enq->CodeBlkVersion[4], ha->enq->CodeBlkVersion[5],
2198 ha->enq->CodeBlkVersion[6], ha->enq->CodeBlkVersion[7]);
2201 if (ha->enq->BootBlkVersion[7] == 0) {
2202 copy_info(&info,
2203 "\tBoot Block Version : %c%c%c%c%c%c%c\n",
2204 ha->enq->BootBlkVersion[0], ha->enq->BootBlkVersion[1],
2205 ha->enq->BootBlkVersion[2], ha->enq->BootBlkVersion[3],
2206 ha->enq->BootBlkVersion[4], ha->enq->BootBlkVersion[5],
2207 ha->enq->BootBlkVersion[6]);
2208 } else {
2209 copy_info(&info,
2210 "\tBoot Block Version : %c%c%c%c%c%c%c%c\n",
2211 ha->enq->BootBlkVersion[0], ha->enq->BootBlkVersion[1],
2212 ha->enq->BootBlkVersion[2], ha->enq->BootBlkVersion[3],
2213 ha->enq->BootBlkVersion[4], ha->enq->BootBlkVersion[5],
2214 ha->enq->BootBlkVersion[6], ha->enq->BootBlkVersion[7]);
2217 copy_info(&info, "\tDriver Version : %s%s\n",
2218 IPS_VERSION_HIGH, IPS_VERSION_LOW);
2220 copy_info(&info, "\tDriver Build : %d\n",
2221 IPS_BUILD_IDENT);
2223 copy_info(&info, "\tMax Physical Devices : %d\n",
2224 ha->enq->ucMaxPhysicalDevices);
2225 copy_info(&info, "\tMax Active Commands : %d\n",
2226 ha->max_cmds);
2227 copy_info(&info, "\tCurrent Queued Commands : %d\n",
2228 ha->scb_waitlist.count);
2229 copy_info(&info, "\tCurrent Active Commands : %d\n",
2230 ha->scb_activelist.count - ha->num_ioctl);
2231 copy_info(&info, "\tCurrent Queued PT Commands : %d\n",
2232 ha->copp_waitlist.count);
2233 copy_info(&info, "\tCurrent Active PT Commands : %d\n",
2234 ha->num_ioctl);
2236 copy_info(&info, "\n");
2238 return (info.localpos);
2241 /****************************************************************************/
2242 /* */
2243 /* Routine Name: copy_mem_info */
2244 /* */
2245 /* Routine Description: */
2246 /* */
2247 /* Copy data into an IPS_INFOSTR structure */
2248 /* */
2249 /****************************************************************************/
2250 static void
2251 copy_mem_info(IPS_INFOSTR * info, char *data, int len)
2253 METHOD_TRACE("copy_mem_info", 1);
2255 if (info->pos + len < info->offset) {
2256 info->pos += len;
2257 return;
2260 if (info->pos < info->offset) {
2261 data += (info->offset - info->pos);
2262 len -= (info->offset - info->pos);
2263 info->pos += (info->offset - info->pos);
2266 if (info->localpos + len > info->length)
2267 len = info->length - info->localpos;
2269 if (len > 0) {
2270 memcpy(info->buffer + info->localpos, data, len);
2271 info->pos += len;
2272 info->localpos += len;
2276 /****************************************************************************/
2277 /* */
2278 /* Routine Name: copy_info */
2279 /* */
2280 /* Routine Description: */
2281 /* */
2282 /* printf style wrapper for an info structure */
2283 /* */
2284 /****************************************************************************/
2285 static int
2286 copy_info(IPS_INFOSTR * info, char *fmt, ...)
2288 va_list args;
2289 char buf[128];
2290 int len;
2292 METHOD_TRACE("copy_info", 1);
2294 va_start(args, fmt);
2295 len = vsprintf(buf, fmt, args);
2296 va_end(args);
2298 copy_mem_info(info, buf, len);
2300 return (len);
2303 /****************************************************************************/
2304 /* */
2305 /* Routine Name: ips_identify_controller */
2306 /* */
2307 /* Routine Description: */
2308 /* */
2309 /* Identify this controller */
2310 /* */
2311 /****************************************************************************/
2312 static void
2313 ips_identify_controller(ips_ha_t * ha)
2315 METHOD_TRACE("ips_identify_controller", 1);
2317 switch (ha->device_id) {
2318 case IPS_DEVICEID_COPPERHEAD:
2319 if (ha->revision_id <= IPS_REVID_SERVERAID) {
2320 ha->ad_type = IPS_ADTYPE_SERVERAID;
2321 } else if (ha->revision_id == IPS_REVID_SERVERAID2) {
2322 ha->ad_type = IPS_ADTYPE_SERVERAID2;
2323 } else if (ha->revision_id == IPS_REVID_NAVAJO) {
2324 ha->ad_type = IPS_ADTYPE_NAVAJO;
2325 } else if ((ha->revision_id == IPS_REVID_SERVERAID2)
2326 && (ha->slot_num == 0)) {
2327 ha->ad_type = IPS_ADTYPE_KIOWA;
2328 } else if ((ha->revision_id >= IPS_REVID_CLARINETP1) &&
2329 (ha->revision_id <= IPS_REVID_CLARINETP3)) {
2330 if (ha->enq->ucMaxPhysicalDevices == 15)
2331 ha->ad_type = IPS_ADTYPE_SERVERAID3L;
2332 else
2333 ha->ad_type = IPS_ADTYPE_SERVERAID3;
2334 } else if ((ha->revision_id >= IPS_REVID_TROMBONE32) &&
2335 (ha->revision_id <= IPS_REVID_TROMBONE64)) {
2336 ha->ad_type = IPS_ADTYPE_SERVERAID4H;
2338 break;
2340 case IPS_DEVICEID_MORPHEUS:
2341 switch (ha->subdevice_id) {
2342 case IPS_SUBDEVICEID_4L:
2343 ha->ad_type = IPS_ADTYPE_SERVERAID4L;
2344 break;
2346 case IPS_SUBDEVICEID_4M:
2347 ha->ad_type = IPS_ADTYPE_SERVERAID4M;
2348 break;
2350 case IPS_SUBDEVICEID_4MX:
2351 ha->ad_type = IPS_ADTYPE_SERVERAID4MX;
2352 break;
2354 case IPS_SUBDEVICEID_4LX:
2355 ha->ad_type = IPS_ADTYPE_SERVERAID4LX;
2356 break;
2358 case IPS_SUBDEVICEID_5I2:
2359 ha->ad_type = IPS_ADTYPE_SERVERAID5I2;
2360 break;
2362 case IPS_SUBDEVICEID_5I1:
2363 ha->ad_type = IPS_ADTYPE_SERVERAID5I1;
2364 break;
2367 break;
2369 case IPS_DEVICEID_MARCO:
2370 switch (ha->subdevice_id) {
2371 case IPS_SUBDEVICEID_6M:
2372 ha->ad_type = IPS_ADTYPE_SERVERAID6M;
2373 break;
2374 case IPS_SUBDEVICEID_6I:
2375 ha->ad_type = IPS_ADTYPE_SERVERAID6I;
2376 break;
2377 case IPS_SUBDEVICEID_7k:
2378 ha->ad_type = IPS_ADTYPE_SERVERAID7k;
2379 break;
2380 case IPS_SUBDEVICEID_7M:
2381 ha->ad_type = IPS_ADTYPE_SERVERAID7M;
2382 break;
2384 break;
2388 /****************************************************************************/
2389 /* */
2390 /* Routine Name: ips_get_bios_version */
2391 /* */
2392 /* Routine Description: */
2393 /* */
2394 /* Get the BIOS revision number */
2395 /* */
2396 /****************************************************************************/
2397 static void
2398 ips_get_bios_version(ips_ha_t * ha, int intr)
2400 ips_scb_t *scb;
2401 int ret;
2402 uint8_t major;
2403 uint8_t minor;
2404 uint8_t subminor;
2405 uint8_t *buffer;
2406 char hexDigits[] =
2407 { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C',
2408 'D', 'E', 'F' };
2410 METHOD_TRACE("ips_get_bios_version", 1);
2412 major = 0;
2413 minor = 0;
2415 strncpy(ha->bios_version, " ?", 8);
2417 if (ha->device_id == IPS_DEVICEID_COPPERHEAD) {
2418 if (IPS_USE_MEMIO(ha)) {
2419 /* Memory Mapped I/O */
2421 /* test 1st byte */
2422 writel(0, ha->mem_ptr + IPS_REG_FLAP);
2423 if (ha->revision_id == IPS_REVID_TROMBONE64)
2424 udelay(25); /* 25 us */
2426 if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0x55)
2427 return;
2429 writel(1, ha->mem_ptr + IPS_REG_FLAP);
2430 if (ha->revision_id == IPS_REVID_TROMBONE64)
2431 udelay(25); /* 25 us */
2433 if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0xAA)
2434 return;
2436 /* Get Major version */
2437 writel(0x1FF, ha->mem_ptr + IPS_REG_FLAP);
2438 if (ha->revision_id == IPS_REVID_TROMBONE64)
2439 udelay(25); /* 25 us */
2441 major = readb(ha->mem_ptr + IPS_REG_FLDP);
2443 /* Get Minor version */
2444 writel(0x1FE, ha->mem_ptr + IPS_REG_FLAP);
2445 if (ha->revision_id == IPS_REVID_TROMBONE64)
2446 udelay(25); /* 25 us */
2447 minor = readb(ha->mem_ptr + IPS_REG_FLDP);
2449 /* Get SubMinor version */
2450 writel(0x1FD, ha->mem_ptr + IPS_REG_FLAP);
2451 if (ha->revision_id == IPS_REVID_TROMBONE64)
2452 udelay(25); /* 25 us */
2453 subminor = readb(ha->mem_ptr + IPS_REG_FLDP);
2455 } else {
2456 /* Programmed I/O */
2458 /* test 1st byte */
2459 outl(0, ha->io_addr + IPS_REG_FLAP);
2460 if (ha->revision_id == IPS_REVID_TROMBONE64)
2461 udelay(25); /* 25 us */
2463 if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55)
2464 return;
2466 outl(cpu_to_le32(1), ha->io_addr + IPS_REG_FLAP);
2467 if (ha->revision_id == IPS_REVID_TROMBONE64)
2468 udelay(25); /* 25 us */
2470 if (inb(ha->io_addr + IPS_REG_FLDP) != 0xAA)
2471 return;
2473 /* Get Major version */
2474 outl(cpu_to_le32(0x1FF), ha->io_addr + IPS_REG_FLAP);
2475 if (ha->revision_id == IPS_REVID_TROMBONE64)
2476 udelay(25); /* 25 us */
2478 major = inb(ha->io_addr + IPS_REG_FLDP);
2480 /* Get Minor version */
2481 outl(cpu_to_le32(0x1FE), ha->io_addr + IPS_REG_FLAP);
2482 if (ha->revision_id == IPS_REVID_TROMBONE64)
2483 udelay(25); /* 25 us */
2485 minor = inb(ha->io_addr + IPS_REG_FLDP);
2487 /* Get SubMinor version */
2488 outl(cpu_to_le32(0x1FD), ha->io_addr + IPS_REG_FLAP);
2489 if (ha->revision_id == IPS_REVID_TROMBONE64)
2490 udelay(25); /* 25 us */
2492 subminor = inb(ha->io_addr + IPS_REG_FLDP);
2495 } else {
2496 /* Morpheus Family - Send Command to the card */
2498 buffer = ha->ioctl_data;
2500 memset(buffer, 0, 0x1000);
2502 scb = &ha->scbs[ha->max_cmds - 1];
2504 ips_init_scb(ha, scb);
2506 scb->timeout = ips_cmd_timeout;
2507 scb->cdb[0] = IPS_CMD_RW_BIOSFW;
2509 scb->cmd.flashfw.op_code = IPS_CMD_RW_BIOSFW;
2510 scb->cmd.flashfw.command_id = IPS_COMMAND_ID(ha, scb);
2511 scb->cmd.flashfw.type = 1;
2512 scb->cmd.flashfw.direction = 0;
2513 scb->cmd.flashfw.count = cpu_to_le32(0x800);
2514 scb->cmd.flashfw.total_packets = 1;
2515 scb->cmd.flashfw.packet_num = 0;
2516 scb->data_len = 0x1000;
2517 scb->cmd.flashfw.buffer_addr = ha->ioctl_busaddr;
2519 /* issue the command */
2520 if (((ret =
2521 ips_send_wait(ha, scb, ips_cmd_timeout,
2522 intr)) == IPS_FAILURE)
2523 || (ret == IPS_SUCCESS_IMM)
2524 || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) {
2525 /* Error occurred */
2527 return;
2530 if ((buffer[0xC0] == 0x55) && (buffer[0xC1] == 0xAA)) {
2531 major = buffer[0x1ff + 0xC0]; /* Offset 0x1ff after the header (0xc0) */
2532 minor = buffer[0x1fe + 0xC0]; /* Offset 0x1fe after the header (0xc0) */
2533 subminor = buffer[0x1fd + 0xC0]; /* Offset 0x1fd after the header (0xc0) */
2534 } else {
2535 return;
2539 ha->bios_version[0] = hexDigits[(major & 0xF0) >> 4];
2540 ha->bios_version[1] = '.';
2541 ha->bios_version[2] = hexDigits[major & 0x0F];
2542 ha->bios_version[3] = hexDigits[subminor];
2543 ha->bios_version[4] = '.';
2544 ha->bios_version[5] = hexDigits[(minor & 0xF0) >> 4];
2545 ha->bios_version[6] = hexDigits[minor & 0x0F];
2546 ha->bios_version[7] = 0;
2549 /****************************************************************************/
2550 /* */
2551 /* Routine Name: ips_hainit */
2552 /* */
2553 /* Routine Description: */
2554 /* */
2555 /* Initialize the controller */
2556 /* */
2557 /* NOTE: Assumes to be called from with a lock */
2558 /* */
2559 /****************************************************************************/
2560 static int
2561 ips_hainit(ips_ha_t * ha)
2563 int i;
2564 struct timeval tv;
2566 METHOD_TRACE("ips_hainit", 1);
2568 if (!ha)
2569 return (0);
2571 if (ha->func.statinit)
2572 (*ha->func.statinit) (ha);
2574 if (ha->func.enableint)
2575 (*ha->func.enableint) (ha);
2577 /* Send FFDC */
2578 ha->reset_count = 1;
2579 do_gettimeofday(&tv);
2580 ha->last_ffdc = tv.tv_sec;
2581 ips_ffdc_reset(ha, IPS_INTR_IORL);
2583 if (!ips_read_config(ha, IPS_INTR_IORL)) {
2584 IPS_PRINTK(KERN_WARNING, ha->pcidev,
2585 "unable to read config from controller.\n");
2587 return (0);
2589 /* end if */
2590 if (!ips_read_adapter_status(ha, IPS_INTR_IORL)) {
2591 IPS_PRINTK(KERN_WARNING, ha->pcidev,
2592 "unable to read controller status.\n");
2594 return (0);
2597 /* Identify this controller */
2598 ips_identify_controller(ha);
2600 if (!ips_read_subsystem_parameters(ha, IPS_INTR_IORL)) {
2601 IPS_PRINTK(KERN_WARNING, ha->pcidev,
2602 "unable to read subsystem parameters.\n");
2604 return (0);
2607 /* write nvram user page 5 */
2608 if (!ips_write_driver_status(ha, IPS_INTR_IORL)) {
2609 IPS_PRINTK(KERN_WARNING, ha->pcidev,
2610 "unable to write driver info to controller.\n");
2612 return (0);
2615 /* If there are Logical Drives and a Reset Occurred, then an EraseStripeLock is Needed */
2616 if ((ha->conf->ucLogDriveCount > 0) && (ha->requires_esl == 1))
2617 ips_clear_adapter(ha, IPS_INTR_IORL);
2619 /* set limits on SID, LUN, BUS */
2620 ha->ntargets = IPS_MAX_TARGETS + 1;
2621 ha->nlun = 1;
2622 ha->nbus = (ha->enq->ucMaxPhysicalDevices / IPS_MAX_TARGETS) + 1;
2624 switch (ha->conf->logical_drive[0].ucStripeSize) {
2625 case 4:
2626 ha->max_xfer = 0x10000;
2627 break;
2629 case 5:
2630 ha->max_xfer = 0x20000;
2631 break;
2633 case 6:
2634 ha->max_xfer = 0x40000;
2635 break;
2637 case 7:
2638 default:
2639 ha->max_xfer = 0x80000;
2640 break;
2643 /* setup max concurrent commands */
2644 if (le32_to_cpu(ha->subsys->param[4]) & 0x1) {
2645 /* Use the new method */
2646 ha->max_cmds = ha->enq->ucConcurrentCmdCount;
2647 } else {
2648 /* use the old method */
2649 switch (ha->conf->logical_drive[0].ucStripeSize) {
2650 case 4:
2651 ha->max_cmds = 32;
2652 break;
2654 case 5:
2655 ha->max_cmds = 16;
2656 break;
2658 case 6:
2659 ha->max_cmds = 8;
2660 break;
2662 case 7:
2663 default:
2664 ha->max_cmds = 4;
2665 break;
2669 /* Limit the Active Commands on a Lite Adapter */
2670 if ((ha->ad_type == IPS_ADTYPE_SERVERAID3L) ||
2671 (ha->ad_type == IPS_ADTYPE_SERVERAID4L) ||
2672 (ha->ad_type == IPS_ADTYPE_SERVERAID4LX)) {
2673 if ((ha->max_cmds > MaxLiteCmds) && (MaxLiteCmds))
2674 ha->max_cmds = MaxLiteCmds;
2677 /* set controller IDs */
2678 ha->ha_id[0] = IPS_ADAPTER_ID;
2679 for (i = 1; i < ha->nbus; i++) {
2680 ha->ha_id[i] = ha->conf->init_id[i - 1] & 0x1f;
2681 ha->dcdb_active[i - 1] = 0;
2684 return (1);
2687 /****************************************************************************/
2688 /* */
2689 /* Routine Name: ips_next */
2690 /* */
2691 /* Routine Description: */
2692 /* */
2693 /* Take the next command off the queue and send it to the controller */
2694 /* */
2695 /****************************************************************************/
2696 static void
2697 ips_next(ips_ha_t * ha, int intr)
2699 ips_scb_t *scb;
2700 Scsi_Cmnd *SC;
2701 Scsi_Cmnd *p;
2702 Scsi_Cmnd *q;
2703 ips_copp_wait_item_t *item;
2704 int ret;
2705 unsigned long cpu_flags = 0;
2706 struct Scsi_Host *host;
2707 METHOD_TRACE("ips_next", 1);
2709 if (!ha)
2710 return;
2711 host = ips_sh[ha->host_num];
2713 * Block access to the queue function so
2714 * this command won't time out
2716 if (intr == IPS_INTR_ON)
2717 IPS_LOCK_SAVE(host->host_lock, cpu_flags);
2719 if ((ha->subsys->param[3] & 0x300000)
2720 && (ha->scb_activelist.count == 0)) {
2721 struct timeval tv;
2723 do_gettimeofday(&tv);
2725 if (tv.tv_sec - ha->last_ffdc > IPS_SECS_8HOURS) {
2726 ha->last_ffdc = tv.tv_sec;
2727 ips_ffdc_time(ha);
2732 * Send passthru commands
2733 * These have priority over normal I/O
2734 * but shouldn't affect performance too much
2735 * since we limit the number that can be active
2736 * on the card at any one time
2738 while ((ha->num_ioctl < IPS_MAX_IOCTL) &&
2739 (ha->copp_waitlist.head) && (scb = ips_getscb(ha))) {
2741 item = ips_removeq_copp_head(&ha->copp_waitlist);
2742 ha->num_ioctl++;
2743 if (intr == IPS_INTR_ON)
2744 IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags);
2745 scb->scsi_cmd = item->scsi_cmd;
2746 kfree(item);
2748 ret = ips_make_passthru(ha, scb->scsi_cmd, scb, intr);
2750 if (intr == IPS_INTR_ON)
2751 IPS_LOCK_SAVE(host->host_lock, cpu_flags);
2752 switch (ret) {
2753 case IPS_FAILURE:
2754 if (scb->scsi_cmd) {
2755 scb->scsi_cmd->result = DID_ERROR << 16;
2756 scb->scsi_cmd->scsi_done(scb->scsi_cmd);
2759 ips_freescb(ha, scb);
2760 break;
2761 case IPS_SUCCESS_IMM:
2762 if (scb->scsi_cmd) {
2763 scb->scsi_cmd->result = DID_OK << 16;
2764 scb->scsi_cmd->scsi_done(scb->scsi_cmd);
2767 ips_freescb(ha, scb);
2768 break;
2769 default:
2770 break;
2771 } /* end case */
2773 if (ret != IPS_SUCCESS) {
2774 ha->num_ioctl--;
2775 continue;
2778 ret = ips_send_cmd(ha, scb);
2780 if (ret == IPS_SUCCESS)
2781 ips_putq_scb_head(&ha->scb_activelist, scb);
2782 else
2783 ha->num_ioctl--;
2785 switch (ret) {
2786 case IPS_FAILURE:
2787 if (scb->scsi_cmd) {
2788 scb->scsi_cmd->result = DID_ERROR << 16;
2791 ips_freescb(ha, scb);
2792 break;
2793 case IPS_SUCCESS_IMM:
2794 ips_freescb(ha, scb);
2795 break;
2796 default:
2797 break;
2798 } /* end case */
2803 * Send "Normal" I/O commands
2806 p = ha->scb_waitlist.head;
2807 while ((p) && (scb = ips_getscb(ha))) {
2808 if ((p->device->channel > 0)
2809 && (ha->
2810 dcdb_active[p->device->channel -
2811 1] & (1 << p->device->id))) {
2812 ips_freescb(ha, scb);
2813 p = (Scsi_Cmnd *) p->host_scribble;
2814 continue;
2817 q = p;
2818 SC = ips_removeq_wait(&ha->scb_waitlist, q);
2820 if (intr == IPS_INTR_ON)
2821 IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags); /* Unlock HA after command is taken off queue */
2823 SC->result = DID_OK;
2824 SC->host_scribble = NULL;
2826 memset(SC->sense_buffer, 0, sizeof (SC->sense_buffer));
2828 scb->target_id = SC->device->id;
2829 scb->lun = SC->device->lun;
2830 scb->bus = SC->device->channel;
2831 scb->scsi_cmd = SC;
2832 scb->breakup = 0;
2833 scb->data_len = 0;
2834 scb->callback = ipsintr_done;
2835 scb->timeout = ips_cmd_timeout;
2836 memset(&scb->cmd, 0, 16);
2838 /* copy in the CDB */
2839 memcpy(scb->cdb, SC->cmnd, SC->cmd_len);
2841 /* Now handle the data buffer */
2842 if (SC->use_sg) {
2843 struct scatterlist *sg;
2844 int i;
2846 sg = SC->request_buffer;
2847 scb->sg_count = pci_map_sg(ha->pcidev, sg, SC->use_sg,
2848 scsi_to_pci_dma_dir(SC->
2849 sc_data_direction));
2850 scb->flags |= IPS_SCB_MAP_SG;
2851 for (i = 0; i < scb->sg_count; i++) {
2852 if (ips_fill_scb_sg_single
2853 (ha, sg_dma_address(&sg[i]), scb, i,
2854 sg_dma_len(&sg[i])) < 0)
2855 break;
2857 scb->dcdb.transfer_length = scb->data_len;
2858 } else {
2859 if (SC->request_bufflen) {
2860 scb->data_busaddr =
2861 pci_map_single(ha->pcidev,
2862 SC->request_buffer,
2863 SC->request_bufflen,
2864 scsi_to_pci_dma_dir(SC->
2865 sc_data_direction));
2866 scb->flags |= IPS_SCB_MAP_SINGLE;
2867 ips_fill_scb_sg_single(ha, scb->data_busaddr,
2868 scb, 0,
2869 SC->request_bufflen);
2870 scb->dcdb.transfer_length = scb->data_len;
2871 } else {
2872 scb->data_busaddr = 0L;
2873 scb->sg_len = 0;
2874 scb->data_len = 0;
2875 scb->dcdb.transfer_length = 0;
2880 scb->dcdb.cmd_attribute =
2881 ips_command_direction[scb->scsi_cmd->cmnd[0]];
2883 /* Allow a WRITE BUFFER Command to Have no Data */
2884 /* This is Used by Tape Flash Utilites */
2885 if ((scb->scsi_cmd->cmnd[0] == WRITE_BUFFER) && (scb->data_len == 0))
2886 scb->dcdb.cmd_attribute = 0;
2888 if (!(scb->dcdb.cmd_attribute & 0x3))
2889 scb->dcdb.transfer_length = 0;
2891 if (scb->data_len >= IPS_MAX_XFER) {
2892 scb->dcdb.cmd_attribute |= IPS_TRANSFER64K;
2893 scb->dcdb.transfer_length = 0;
2895 if (intr == IPS_INTR_ON)
2896 IPS_LOCK_SAVE(host->host_lock, cpu_flags);
2898 ret = ips_send_cmd(ha, scb);
2900 switch (ret) {
2901 case IPS_SUCCESS:
2902 ips_putq_scb_head(&ha->scb_activelist, scb);
2903 break;
2904 case IPS_FAILURE:
2905 if (scb->scsi_cmd) {
2906 scb->scsi_cmd->result = DID_ERROR << 16;
2907 scb->scsi_cmd->scsi_done(scb->scsi_cmd);
2910 if (scb->bus)
2911 ha->dcdb_active[scb->bus - 1] &=
2912 ~(1 << scb->target_id);
2914 ips_freescb(ha, scb);
2915 break;
2916 case IPS_SUCCESS_IMM:
2917 if (scb->scsi_cmd)
2918 scb->scsi_cmd->scsi_done(scb->scsi_cmd);
2920 if (scb->bus)
2921 ha->dcdb_active[scb->bus - 1] &=
2922 ~(1 << scb->target_id);
2924 ips_freescb(ha, scb);
2925 break;
2926 default:
2927 break;
2928 } /* end case */
2930 p = (Scsi_Cmnd *) p->host_scribble;
2932 } /* end while */
2934 if (intr == IPS_INTR_ON)
2935 IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags);
2938 /****************************************************************************/
2939 /* */
2940 /* Routine Name: ips_putq_scb_head */
2941 /* */
2942 /* Routine Description: */
2943 /* */
2944 /* Add an item to the head of the queue */
2945 /* */
2946 /* ASSUMED to be called from within the HA lock */
2947 /* */
2948 /****************************************************************************/
2949 static void
2950 ips_putq_scb_head(ips_scb_queue_t * queue, ips_scb_t * item)
2952 METHOD_TRACE("ips_putq_scb_head", 1);
2954 if (!item)
2955 return;
2957 item->q_next = queue->head;
2958 queue->head = item;
2960 if (!queue->tail)
2961 queue->tail = item;
2963 queue->count++;
2966 /****************************************************************************/
2967 /* */
2968 /* Routine Name: ips_removeq_scb_head */
2969 /* */
2970 /* Routine Description: */
2971 /* */
2972 /* Remove the head of the queue */
2973 /* */
2974 /* ASSUMED to be called from within the HA lock */
2975 /* */
2976 /****************************************************************************/
2977 static ips_scb_t *
2978 ips_removeq_scb_head(ips_scb_queue_t * queue)
2980 ips_scb_t *item;
2982 METHOD_TRACE("ips_removeq_scb_head", 1);
2984 item = queue->head;
2986 if (!item) {
2987 return (NULL);
2990 queue->head = item->q_next;
2991 item->q_next = NULL;
2993 if (queue->tail == item)
2994 queue->tail = NULL;
2996 queue->count--;
2998 return (item);
3001 /****************************************************************************/
3002 /* */
3003 /* Routine Name: ips_removeq_scb */
3004 /* */
3005 /* Routine Description: */
3006 /* */
3007 /* Remove an item from a queue */
3008 /* */
3009 /* ASSUMED to be called from within the HA lock */
3010 /* */
3011 /****************************************************************************/
3012 static ips_scb_t *
3013 ips_removeq_scb(ips_scb_queue_t * queue, ips_scb_t * item)
3015 ips_scb_t *p;
3017 METHOD_TRACE("ips_removeq_scb", 1);
3019 if (!item)
3020 return (NULL);
3022 if (item == queue->head) {
3023 return (ips_removeq_scb_head(queue));
3026 p = queue->head;
3028 while ((p) && (item != p->q_next))
3029 p = p->q_next;
3031 if (p) {
3032 /* found a match */
3033 p->q_next = item->q_next;
3035 if (!item->q_next)
3036 queue->tail = p;
3038 item->q_next = NULL;
3039 queue->count--;
3041 return (item);
3044 return (NULL);
3047 /****************************************************************************/
3048 /* */
3049 /* Routine Name: ips_putq_wait_tail */
3050 /* */
3051 /* Routine Description: */
3052 /* */
3053 /* Add an item to the tail of the queue */
3054 /* */
3055 /* ASSUMED to be called from within the HA lock */
3056 /* */
3057 /****************************************************************************/
3058 static void
3059 ips_putq_wait_tail(ips_wait_queue_t * queue, Scsi_Cmnd * item)
3061 METHOD_TRACE("ips_putq_wait_tail", 1);
3063 if (!item)
3064 return;
3066 item->host_scribble = NULL;
3068 if (queue->tail)
3069 queue->tail->host_scribble = (char *) item;
3071 queue->tail = item;
3073 if (!queue->head)
3074 queue->head = item;
3076 queue->count++;
3079 /****************************************************************************/
3080 /* */
3081 /* Routine Name: ips_removeq_wait_head */
3082 /* */
3083 /* Routine Description: */
3084 /* */
3085 /* Remove the head of the queue */
3086 /* */
3087 /* ASSUMED to be called from within the HA lock */
3088 /* */
3089 /****************************************************************************/
3090 static Scsi_Cmnd *
3091 ips_removeq_wait_head(ips_wait_queue_t * queue)
3093 Scsi_Cmnd *item;
3095 METHOD_TRACE("ips_removeq_wait_head", 1);
3097 item = queue->head;
3099 if (!item) {
3100 return (NULL);
3103 queue->head = (Scsi_Cmnd *) item->host_scribble;
3104 item->host_scribble = NULL;
3106 if (queue->tail == item)
3107 queue->tail = NULL;
3109 queue->count--;
3111 return (item);
3114 /****************************************************************************/
3115 /* */
3116 /* Routine Name: ips_removeq_wait */
3117 /* */
3118 /* Routine Description: */
3119 /* */
3120 /* Remove an item from a queue */
3121 /* */
3122 /* ASSUMED to be called from within the HA lock */
3123 /* */
3124 /****************************************************************************/
3125 static Scsi_Cmnd *
3126 ips_removeq_wait(ips_wait_queue_t * queue, Scsi_Cmnd * item)
3128 Scsi_Cmnd *p;
3130 METHOD_TRACE("ips_removeq_wait", 1);
3132 if (!item)
3133 return (NULL);
3135 if (item == queue->head) {
3136 return (ips_removeq_wait_head(queue));
3139 p = queue->head;
3141 while ((p) && (item != (Scsi_Cmnd *) p->host_scribble))
3142 p = (Scsi_Cmnd *) p->host_scribble;
3144 if (p) {
3145 /* found a match */
3146 p->host_scribble = item->host_scribble;
3148 if (!item->host_scribble)
3149 queue->tail = p;
3151 item->host_scribble = NULL;
3152 queue->count--;
3154 return (item);
3157 return (NULL);
3160 /****************************************************************************/
3161 /* */
3162 /* Routine Name: ips_putq_copp_tail */
3163 /* */
3164 /* Routine Description: */
3165 /* */
3166 /* Add an item to the tail of the queue */
3167 /* */
3168 /* ASSUMED to be called from within the HA lock */
3169 /* */
3170 /****************************************************************************/
3171 static void
3172 ips_putq_copp_tail(ips_copp_queue_t * queue, ips_copp_wait_item_t * item)
3174 METHOD_TRACE("ips_putq_copp_tail", 1);
3176 if (!item)
3177 return;
3179 item->next = NULL;
3181 if (queue->tail)
3182 queue->tail->next = item;
3184 queue->tail = item;
3186 if (!queue->head)
3187 queue->head = item;
3189 queue->count++;
3192 /****************************************************************************/
3193 /* */
3194 /* Routine Name: ips_removeq_copp_head */
3195 /* */
3196 /* Routine Description: */
3197 /* */
3198 /* Remove the head of the queue */
3199 /* */
3200 /* ASSUMED to be called from within the HA lock */
3201 /* */
3202 /****************************************************************************/
3203 static ips_copp_wait_item_t *
3204 ips_removeq_copp_head(ips_copp_queue_t * queue)
3206 ips_copp_wait_item_t *item;
3208 METHOD_TRACE("ips_removeq_copp_head", 1);
3210 item = queue->head;
3212 if (!item) {
3213 return (NULL);
3216 queue->head = item->next;
3217 item->next = NULL;
3219 if (queue->tail == item)
3220 queue->tail = NULL;
3222 queue->count--;
3224 return (item);
3227 /****************************************************************************/
3228 /* */
3229 /* Routine Name: ips_removeq_copp */
3230 /* */
3231 /* Routine Description: */
3232 /* */
3233 /* Remove an item from a queue */
3234 /* */
3235 /* ASSUMED to be called from within the HA lock */
3236 /* */
3237 /****************************************************************************/
3238 static ips_copp_wait_item_t *
3239 ips_removeq_copp(ips_copp_queue_t * queue, ips_copp_wait_item_t * item)
3241 ips_copp_wait_item_t *p;
3243 METHOD_TRACE("ips_removeq_copp", 1);
3245 if (!item)
3246 return (NULL);
3248 if (item == queue->head) {
3249 return (ips_removeq_copp_head(queue));
3252 p = queue->head;
3254 while ((p) && (item != p->next))
3255 p = p->next;
3257 if (p) {
3258 /* found a match */
3259 p->next = item->next;
3261 if (!item->next)
3262 queue->tail = p;
3264 item->next = NULL;
3265 queue->count--;
3267 return (item);
3270 return (NULL);
3273 /****************************************************************************/
3274 /* */
3275 /* Routine Name: ipsintr_blocking */
3276 /* */
3277 /* Routine Description: */
3278 /* */
3279 /* Finalize an interrupt for internal commands */
3280 /* */
3281 /****************************************************************************/
3282 static void
3283 ipsintr_blocking(ips_ha_t * ha, ips_scb_t * scb)
3285 METHOD_TRACE("ipsintr_blocking", 2);
3287 ips_freescb(ha, scb);
3288 if ((ha->waitflag == TRUE) && (ha->cmd_in_progress == scb->cdb[0])) {
3289 ha->waitflag = FALSE;
3291 return;
3295 /****************************************************************************/
3296 /* */
3297 /* Routine Name: ipsintr_done */
3298 /* */
3299 /* Routine Description: */
3300 /* */
3301 /* Finalize an interrupt for non-internal commands */
3302 /* */
3303 /****************************************************************************/
3304 static void
3305 ipsintr_done(ips_ha_t * ha, ips_scb_t * scb)
3307 METHOD_TRACE("ipsintr_done", 2);
3309 if (!scb) {
3310 IPS_PRINTK(KERN_WARNING, ha->pcidev,
3311 "Spurious interrupt; scb NULL.\n");
3313 return;
3316 if (scb->scsi_cmd == NULL) {
3317 /* unexpected interrupt */
3318 IPS_PRINTK(KERN_WARNING, ha->pcidev,
3319 "Spurious interrupt; scsi_cmd not set.\n");
3321 return;
3324 ips_done(ha, scb);
3327 /****************************************************************************/
3328 /* */
3329 /* Routine Name: ips_done */
3330 /* */
3331 /* Routine Description: */
3332 /* */
3333 /* Do housekeeping on completed commands */
3334 /* ASSUMED to be called form within the request lock */
3335 /****************************************************************************/
3336 static void
3337 ips_done(ips_ha_t * ha, ips_scb_t * scb)
3339 int ret;
3341 METHOD_TRACE("ips_done", 1);
3343 if (!scb)
3344 return;
3346 if ((scb->scsi_cmd) && (ips_is_passthru(scb->scsi_cmd))) {
3347 ips_cleanup_passthru(ha, scb);
3348 ha->num_ioctl--;
3349 } else {
3351 * Check to see if this command had too much
3352 * data and had to be broke up. If so, queue
3353 * the rest of the data and continue.
3355 if ((scb->breakup) || (scb->sg_break)) {
3356 /* we had a data breakup */
3357 scb->data_len = 0;
3359 if (scb->sg_count) {
3360 /* S/G request */
3361 struct scatterlist *sg;
3362 int ips_sg_index = 0;
3363 int sg_dma_index;
3365 sg = scb->scsi_cmd->request_buffer;
3367 /* Spin forward to last dma chunk */
3368 sg_dma_index = scb->breakup;
3370 /* Take care of possible partial on last chunk */
3371 ips_fill_scb_sg_single(ha,
3372 sg_dma_address(&sg
3373 [sg_dma_index]),
3374 scb, ips_sg_index++,
3375 sg_dma_len(&sg
3376 [sg_dma_index]));
3378 for (; sg_dma_index < scb->sg_count;
3379 sg_dma_index++) {
3380 if (ips_fill_scb_sg_single
3381 (ha,
3382 sg_dma_address(&sg[sg_dma_index]),
3383 scb, ips_sg_index++,
3384 sg_dma_len(&sg[sg_dma_index])) < 0)
3385 break;
3389 } else {
3390 /* Non S/G Request */
3391 (void) ips_fill_scb_sg_single(ha,
3392 scb->
3393 data_busaddr +
3394 (scb->sg_break *
3395 ha->max_xfer),
3396 scb, 0,
3397 scb->scsi_cmd->
3398 request_bufflen -
3399 (scb->sg_break *
3400 ha->max_xfer));
3403 scb->dcdb.transfer_length = scb->data_len;
3404 scb->dcdb.cmd_attribute |=
3405 ips_command_direction[scb->scsi_cmd->cmnd[0]];
3407 if (!(scb->dcdb.cmd_attribute & 0x3))
3408 scb->dcdb.transfer_length = 0;
3410 if (scb->data_len >= IPS_MAX_XFER) {
3411 scb->dcdb.cmd_attribute |= IPS_TRANSFER64K;
3412 scb->dcdb.transfer_length = 0;
3415 ret = ips_send_cmd(ha, scb);
3417 switch (ret) {
3418 case IPS_FAILURE:
3419 if (scb->scsi_cmd) {
3420 scb->scsi_cmd->result = DID_ERROR << 16;
3421 scb->scsi_cmd->scsi_done(scb->scsi_cmd);
3424 ips_freescb(ha, scb);
3425 break;
3426 case IPS_SUCCESS_IMM:
3427 if (scb->scsi_cmd) {
3428 scb->scsi_cmd->result = DID_ERROR << 16;
3429 scb->scsi_cmd->scsi_done(scb->scsi_cmd);
3432 ips_freescb(ha, scb);
3433 break;
3434 default:
3435 break;
3436 } /* end case */
3438 return;
3440 } /* end if passthru */
3442 if (scb->bus) {
3443 ha->dcdb_active[scb->bus - 1] &= ~(1 << scb->target_id);
3446 scb->scsi_cmd->scsi_done(scb->scsi_cmd);
3448 ips_freescb(ha, scb);
3451 /****************************************************************************/
3452 /* */
3453 /* Routine Name: ips_map_status */
3454 /* */
3455 /* Routine Description: */
3456 /* */
3457 /* Map Controller Error codes to Linux Error Codes */
3458 /* */
3459 /****************************************************************************/
3460 static int
3461 ips_map_status(ips_ha_t * ha, ips_scb_t * scb, ips_stat_t * sp)
3463 int errcode;
3464 int device_error;
3465 uint32_t transfer_len;
3466 IPS_DCDB_TABLE_TAPE *tapeDCDB;
3468 METHOD_TRACE("ips_map_status", 1);
3470 if (scb->bus) {
3471 DEBUG_VAR(2,
3472 "(%s%d) Physical device error (%d %d %d): %x %x, Sense Key: %x, ASC: %x, ASCQ: %x",
3473 ips_name, ha->host_num,
3474 scb->scsi_cmd->device->channel,
3475 scb->scsi_cmd->device->id, scb->scsi_cmd->device->lun,
3476 scb->basic_status, scb->extended_status,
3477 scb->extended_status ==
3478 IPS_ERR_CKCOND ? scb->dcdb.sense_info[2] & 0xf : 0,
3479 scb->extended_status ==
3480 IPS_ERR_CKCOND ? scb->dcdb.sense_info[12] : 0,
3481 scb->extended_status ==
3482 IPS_ERR_CKCOND ? scb->dcdb.sense_info[13] : 0);
3485 /* default driver error */
3486 errcode = DID_ERROR;
3487 device_error = 0;
3489 switch (scb->basic_status & IPS_GSC_STATUS_MASK) {
3490 case IPS_CMD_TIMEOUT:
3491 errcode = DID_TIME_OUT;
3492 break;
3494 case IPS_INVAL_OPCO:
3495 case IPS_INVAL_CMD_BLK:
3496 case IPS_INVAL_PARM_BLK:
3497 case IPS_LD_ERROR:
3498 case IPS_CMD_CMPLT_WERROR:
3499 break;
3501 case IPS_PHYS_DRV_ERROR:
3502 switch (scb->extended_status) {
3503 case IPS_ERR_SEL_TO:
3504 if (scb->bus)
3505 errcode = DID_NO_CONNECT;
3507 break;
3509 case IPS_ERR_OU_RUN:
3510 if ((scb->cmd.dcdb.op_code == IPS_CMD_EXTENDED_DCDB) ||
3511 (scb->cmd.dcdb.op_code ==
3512 IPS_CMD_EXTENDED_DCDB_SG)) {
3513 tapeDCDB = (IPS_DCDB_TABLE_TAPE *) & scb->dcdb;
3514 transfer_len = tapeDCDB->transfer_length;
3515 } else {
3516 transfer_len =
3517 (uint32_t) scb->dcdb.transfer_length;
3520 if ((scb->bus) && (transfer_len < scb->data_len)) {
3521 /* Underrun - set default to no error */
3522 errcode = DID_OK;
3524 /* Restrict access to physical DASD */
3525 if ((scb->scsi_cmd->cmnd[0] == INQUIRY) &&
3526 ((((char *) scb->scsi_cmd->
3527 buffer)[0] & 0x1f) == TYPE_DISK)) {
3528 /* underflow -- no error */
3529 /* restrict access to physical DASD */
3530 errcode = DID_TIME_OUT;
3531 break;
3533 } else
3534 errcode = DID_ERROR;
3536 break;
3538 case IPS_ERR_RECOVERY:
3539 /* don't fail recovered errors */
3540 if (scb->bus)
3541 errcode = DID_OK;
3543 break;
3545 case IPS_ERR_HOST_RESET:
3546 case IPS_ERR_DEV_RESET:
3547 errcode = DID_RESET;
3548 break;
3550 case IPS_ERR_CKCOND:
3551 if (scb->bus) {
3552 if ((scb->cmd.dcdb.op_code ==
3553 IPS_CMD_EXTENDED_DCDB)
3554 || (scb->cmd.dcdb.op_code ==
3555 IPS_CMD_EXTENDED_DCDB_SG)) {
3556 tapeDCDB =
3557 (IPS_DCDB_TABLE_TAPE *) & scb->dcdb;
3558 memcpy(scb->scsi_cmd->sense_buffer,
3559 tapeDCDB->sense_info,
3560 sizeof (scb->scsi_cmd->
3561 sense_buffer));
3562 } else {
3563 memcpy(scb->scsi_cmd->sense_buffer,
3564 scb->dcdb.sense_info,
3565 sizeof (scb->scsi_cmd->
3566 sense_buffer));
3568 device_error = 2; /* check condition */
3571 errcode = DID_OK;
3573 break;
3575 default:
3576 errcode = DID_ERROR;
3577 break;
3579 } /* end switch */
3580 } /* end switch */
3582 scb->scsi_cmd->result = device_error | (errcode << 16);
3584 return (1);
3587 /****************************************************************************/
3588 /* */
3589 /* Routine Name: ips_send_wait */
3590 /* */
3591 /* Routine Description: */
3592 /* */
3593 /* Send a command to the controller and wait for it to return */
3594 /* */
3595 /* The FFDC Time Stamp use this function for the callback, but doesn't */
3596 /* actually need to wait. */
3597 /****************************************************************************/
3598 static int
3599 ips_send_wait(ips_ha_t * ha, ips_scb_t * scb, int timeout, int intr)
3601 int ret;
3603 METHOD_TRACE("ips_send_wait", 1);
3605 if (intr != IPS_FFDC) { /* Won't be Waiting if this is a Time Stamp */
3606 ha->waitflag = TRUE;
3607 ha->cmd_in_progress = scb->cdb[0];
3609 scb->callback = ipsintr_blocking;
3610 ret = ips_send_cmd(ha, scb);
3612 if ((ret == IPS_FAILURE) || (ret == IPS_SUCCESS_IMM))
3613 return (ret);
3615 if (intr != IPS_FFDC) /* Don't Wait around if this is a Time Stamp */
3616 ret = ips_wait(ha, timeout, intr);
3618 return (ret);
3621 /****************************************************************************/
3622 /* */
3623 /* Routine Name: ips_scmd_buf_write */
3624 /* */
3625 /* Routine Description: */
3626 /* Write data to Scsi_Cmnd request_buffer at proper offsets */
3627 /****************************************************************************/
3628 static void
3629 ips_scmd_buf_write(Scsi_Cmnd * scmd, void *data, unsigned
3630 int count)
3632 if (scmd->use_sg) {
3633 int i;
3634 unsigned int min_cnt, xfer_cnt;
3635 char *cdata = (char *) data;
3636 struct scatterlist *sg = scmd->request_buffer;
3637 for (i = 0, xfer_cnt = 0;
3638 (i < scmd->use_sg) && (xfer_cnt < count); i++) {
3639 if (!IPS_SG_ADDRESS(&sg[i]))
3640 return;
3641 min_cnt = min(count - xfer_cnt, sg[i].length);
3642 memcpy(IPS_SG_ADDRESS(&sg[i]), &cdata[xfer_cnt],
3643 min_cnt);
3644 xfer_cnt += min_cnt;
3647 } else {
3648 unsigned int min_cnt = min(count, scmd->request_bufflen);
3649 memcpy(scmd->request_buffer, data, min_cnt);
3653 /****************************************************************************/
3654 /* */
3655 /* Routine Name: ips_scmd_buf_read */
3656 /* */
3657 /* Routine Description: */
3658 /* Copy data from a Scsi_Cmnd to a new, linear buffer */
3659 /****************************************************************************/
3660 static void
3661 ips_scmd_buf_read(Scsi_Cmnd * scmd, void *data, unsigned
3662 int count)
3664 if (scmd->use_sg) {
3665 int i;
3666 unsigned int min_cnt, xfer_cnt;
3667 char *cdata = (char *) data;
3668 struct scatterlist *sg = scmd->request_buffer;
3669 for (i = 0, xfer_cnt = 0;
3670 (i < scmd->use_sg) && (xfer_cnt < count); i++) {
3671 if (!IPS_SG_ADDRESS(&sg[i]))
3672 return;
3673 min_cnt = min(count - xfer_cnt, sg[i].length);
3674 memcpy(&cdata[xfer_cnt], IPS_SG_ADDRESS(&sg[i]),
3675 min_cnt);
3676 xfer_cnt += min_cnt;
3679 } else {
3680 unsigned int min_cnt = min(count, scmd->request_bufflen);
3681 memcpy(data, scmd->request_buffer, min_cnt);
3685 /****************************************************************************/
3686 /* */
3687 /* Routine Name: ips_send_cmd */
3688 /* */
3689 /* Routine Description: */
3690 /* */
3691 /* Map SCSI commands to ServeRAID commands for logical drives */
3692 /* */
3693 /****************************************************************************/
3694 static int
3695 ips_send_cmd(ips_ha_t * ha, ips_scb_t * scb)
3697 int ret;
3698 char *sp;
3699 int device_error;
3700 IPS_DCDB_TABLE_TAPE *tapeDCDB;
3701 int TimeOut;
3703 METHOD_TRACE("ips_send_cmd", 1);
3705 ret = IPS_SUCCESS;
3707 if (!scb->scsi_cmd) {
3708 /* internal command */
3710 if (scb->bus > 0) {
3711 /* Controller commands can't be issued */
3712 /* to real devices -- fail them */
3713 if ((ha->waitflag == TRUE) &&
3714 (ha->cmd_in_progress == scb->cdb[0])) {
3715 ha->waitflag = FALSE;
3718 return (1);
3720 } else if ((scb->bus == 0) && (!ips_is_passthru(scb->scsi_cmd))) {
3721 /* command to logical bus -- interpret */
3722 ret = IPS_SUCCESS_IMM;
3724 switch (scb->scsi_cmd->cmnd[0]) {
3725 case ALLOW_MEDIUM_REMOVAL:
3726 case REZERO_UNIT:
3727 case ERASE:
3728 case WRITE_FILEMARKS:
3729 case SPACE:
3730 scb->scsi_cmd->result = DID_ERROR << 16;
3731 break;
3733 case START_STOP:
3734 scb->scsi_cmd->result = DID_OK << 16;
3736 case TEST_UNIT_READY:
3737 case INQUIRY:
3738 if (scb->target_id == IPS_ADAPTER_ID) {
3740 * Either we have a TUR
3741 * or we have a SCSI inquiry
3743 if (scb->scsi_cmd->cmnd[0] == TEST_UNIT_READY)
3744 scb->scsi_cmd->result = DID_OK << 16;
3746 if (scb->scsi_cmd->cmnd[0] == INQUIRY) {
3747 IPS_SCSI_INQ_DATA inquiry;
3749 memset(&inquiry, 0,
3750 sizeof (IPS_SCSI_INQ_DATA));
3752 inquiry.DeviceType =
3753 IPS_SCSI_INQ_TYPE_PROCESSOR;
3754 inquiry.DeviceTypeQualifier =
3755 IPS_SCSI_INQ_LU_CONNECTED;
3756 inquiry.Version = IPS_SCSI_INQ_REV2;
3757 inquiry.ResponseDataFormat =
3758 IPS_SCSI_INQ_RD_REV2;
3759 inquiry.AdditionalLength = 31;
3760 inquiry.Flags[0] =
3761 IPS_SCSI_INQ_Address16;
3762 inquiry.Flags[1] =
3763 IPS_SCSI_INQ_WBus16 |
3764 IPS_SCSI_INQ_Sync;
3765 strncpy(inquiry.VendorId, "IBM ",
3767 strncpy(inquiry.ProductId,
3768 "SERVERAID ", 16);
3769 strncpy(inquiry.ProductRevisionLevel,
3770 "1.00", 4);
3772 ips_scmd_buf_write(scb->scsi_cmd,
3773 &inquiry,
3774 sizeof (inquiry));
3776 scb->scsi_cmd->result = DID_OK << 16;
3778 } else {
3779 scb->cmd.logical_info.op_code = IPS_CMD_GET_LD_INFO;
3780 scb->cmd.logical_info.command_id = IPS_COMMAND_ID(ha, scb);
3781 scb->cmd.logical_info.reserved = 0;
3782 scb->cmd.logical_info.reserved2 = 0;
3783 scb->data_len = sizeof (IPS_LD_INFO);
3784 scb->data_busaddr = ha->logical_drive_info_dma_addr;
3785 scb->flags = 0;
3786 scb->cmd.logical_info.buffer_addr = scb->data_busaddr;
3787 ret = IPS_SUCCESS;
3790 break;
3792 case REQUEST_SENSE:
3793 ips_reqsen(ha, scb);
3794 scb->scsi_cmd->result = DID_OK << 16;
3795 break;
3797 case READ_6:
3798 case WRITE_6:
3799 if (!scb->sg_len) {
3800 scb->cmd.basic_io.op_code =
3801 (scb->scsi_cmd->cmnd[0] ==
3802 READ_6) ? IPS_CMD_READ : IPS_CMD_WRITE;
3803 scb->cmd.basic_io.enhanced_sg = 0;
3804 scb->cmd.basic_io.sg_addr =
3805 cpu_to_le32(scb->data_busaddr);
3806 } else {
3807 scb->cmd.basic_io.op_code =
3808 (scb->scsi_cmd->cmnd[0] ==
3809 READ_6) ? IPS_CMD_READ_SG :
3810 IPS_CMD_WRITE_SG;
3811 scb->cmd.basic_io.enhanced_sg =
3812 IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0;
3813 scb->cmd.basic_io.sg_addr =
3814 cpu_to_le32(scb->sg_busaddr);
3817 scb->cmd.basic_io.segment_4G = 0;
3818 scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
3819 scb->cmd.basic_io.log_drv = scb->target_id;
3820 scb->cmd.basic_io.sg_count = scb->sg_len;
3822 if (scb->cmd.basic_io.lba)
3823 scb->cmd.basic_io.lba =
3824 cpu_to_le32(le32_to_cpu
3825 (scb->cmd.basic_io.lba) +
3826 le16_to_cpu(scb->cmd.basic_io.
3827 sector_count));
3828 else
3829 scb->cmd.basic_io.lba =
3830 (((scb->scsi_cmd->
3831 cmnd[1] & 0x1f) << 16) | (scb->scsi_cmd->
3832 cmnd[2] << 8) |
3833 (scb->scsi_cmd->cmnd[3]));
3835 scb->cmd.basic_io.sector_count =
3836 cpu_to_le16(scb->data_len / IPS_BLKSIZE);
3838 if (le16_to_cpu(scb->cmd.basic_io.sector_count) == 0)
3839 scb->cmd.basic_io.sector_count =
3840 cpu_to_le16(256);
3842 ret = IPS_SUCCESS;
3843 break;
3845 case READ_10:
3846 case WRITE_10:
3847 if (!scb->sg_len) {
3848 scb->cmd.basic_io.op_code =
3849 (scb->scsi_cmd->cmnd[0] ==
3850 READ_10) ? IPS_CMD_READ : IPS_CMD_WRITE;
3851 scb->cmd.basic_io.enhanced_sg = 0;
3852 scb->cmd.basic_io.sg_addr =
3853 cpu_to_le32(scb->data_busaddr);
3854 } else {
3855 scb->cmd.basic_io.op_code =
3856 (scb->scsi_cmd->cmnd[0] ==
3857 READ_10) ? IPS_CMD_READ_SG :
3858 IPS_CMD_WRITE_SG;
3859 scb->cmd.basic_io.enhanced_sg =
3860 IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0;
3861 scb->cmd.basic_io.sg_addr =
3862 cpu_to_le32(scb->sg_busaddr);
3865 scb->cmd.basic_io.segment_4G = 0;
3866 scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
3867 scb->cmd.basic_io.log_drv = scb->target_id;
3868 scb->cmd.basic_io.sg_count = scb->sg_len;
3870 if (scb->cmd.basic_io.lba)
3871 scb->cmd.basic_io.lba =
3872 cpu_to_le32(le32_to_cpu
3873 (scb->cmd.basic_io.lba) +
3874 le16_to_cpu(scb->cmd.basic_io.
3875 sector_count));
3876 else
3877 scb->cmd.basic_io.lba =
3878 ((scb->scsi_cmd->cmnd[2] << 24) | (scb->
3879 scsi_cmd->
3880 cmnd[3]
3881 << 16) |
3882 (scb->scsi_cmd->cmnd[4] << 8) | scb->
3883 scsi_cmd->cmnd[5]);
3885 scb->cmd.basic_io.sector_count =
3886 cpu_to_le16(scb->data_len / IPS_BLKSIZE);
3888 if (cpu_to_le16(scb->cmd.basic_io.sector_count) == 0) {
3890 * This is a null condition
3891 * we don't have to do anything
3892 * so just return
3894 scb->scsi_cmd->result = DID_OK << 16;
3895 } else
3896 ret = IPS_SUCCESS;
3898 break;
3900 case RESERVE:
3901 case RELEASE:
3902 scb->scsi_cmd->result = DID_OK << 16;
3903 break;
3905 case MODE_SENSE:
3906 scb->cmd.basic_io.op_code = IPS_CMD_ENQUIRY;
3907 scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
3908 scb->cmd.basic_io.segment_4G = 0;
3909 scb->cmd.basic_io.enhanced_sg = 0;
3910 scb->data_len = sizeof (*ha->enq);
3911 scb->cmd.basic_io.sg_addr = ha->enq_busaddr;
3912 ret = IPS_SUCCESS;
3913 break;
3915 case READ_CAPACITY:
3916 scb->cmd.logical_info.op_code = IPS_CMD_GET_LD_INFO;
3917 scb->cmd.logical_info.command_id = IPS_COMMAND_ID(ha, scb);
3918 scb->cmd.logical_info.reserved = 0;
3919 scb->cmd.logical_info.reserved2 = 0;
3920 scb->cmd.logical_info.reserved3 = 0;
3921 scb->data_len = sizeof (IPS_LD_INFO);
3922 scb->data_busaddr = ha->logical_drive_info_dma_addr;
3923 scb->flags = 0;
3924 scb->cmd.logical_info.buffer_addr = scb->data_busaddr;
3925 ret = IPS_SUCCESS;
3926 break;
3928 case SEND_DIAGNOSTIC:
3929 case REASSIGN_BLOCKS:
3930 case FORMAT_UNIT:
3931 case SEEK_10:
3932 case VERIFY:
3933 case READ_DEFECT_DATA:
3934 case READ_BUFFER:
3935 case WRITE_BUFFER:
3936 scb->scsi_cmd->result = DID_OK << 16;
3937 break;
3939 default:
3940 /* Set the Return Info to appear like the Command was */
3941 /* attempted, a Check Condition occurred, and Sense */
3942 /* Data indicating an Invalid CDB OpCode is returned. */
3943 sp = (char *) scb->scsi_cmd->sense_buffer;
3944 memset(sp, 0, sizeof (scb->scsi_cmd->sense_buffer));
3946 sp[0] = 0x70; /* Error Code */
3947 sp[2] = ILLEGAL_REQUEST; /* Sense Key 5 Illegal Req. */
3948 sp[7] = 0x0A; /* Additional Sense Length */
3949 sp[12] = 0x20; /* ASC = Invalid OpCode */
3950 sp[13] = 0x00; /* ASCQ */
3952 device_error = 2; /* Indicate Check Condition */
3953 scb->scsi_cmd->result = device_error | (DID_OK << 16);
3954 break;
3955 } /* end switch */
3957 /* end if */
3958 if (ret == IPS_SUCCESS_IMM)
3959 return (ret);
3961 /* setup DCDB */
3962 if (scb->bus > 0) {
3964 /* If we already know the Device is Not there, no need to attempt a Command */
3965 /* This also protects an NT FailOver Controller from getting CDB's sent to it */
3966 if (ha->conf->dev[scb->bus - 1][scb->target_id].ucState == 0) {
3967 scb->scsi_cmd->result = DID_NO_CONNECT << 16;
3968 return (IPS_SUCCESS_IMM);
3971 ha->dcdb_active[scb->bus - 1] |= (1 << scb->target_id);
3972 scb->cmd.dcdb.command_id = IPS_COMMAND_ID(ha, scb);
3973 scb->cmd.dcdb.dcdb_address = cpu_to_le32(scb->scb_busaddr +
3974 (unsigned long) &scb->
3975 dcdb -
3976 (unsigned long) scb);
3977 scb->cmd.dcdb.reserved = 0;
3978 scb->cmd.dcdb.reserved2 = 0;
3979 scb->cmd.dcdb.reserved3 = 0;
3980 scb->cmd.dcdb.segment_4G = 0;
3981 scb->cmd.dcdb.enhanced_sg = 0;
3983 TimeOut = scb->scsi_cmd->timeout_per_command;
3985 if (ha->subsys->param[4] & 0x00100000) { /* If NEW Tape DCDB is Supported */
3986 if (!scb->sg_len) {
3987 scb->cmd.dcdb.op_code = IPS_CMD_EXTENDED_DCDB;
3988 } else {
3989 scb->cmd.dcdb.op_code =
3990 IPS_CMD_EXTENDED_DCDB_SG;
3991 scb->cmd.dcdb.enhanced_sg =
3992 IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0;
3995 tapeDCDB = (IPS_DCDB_TABLE_TAPE *) & scb->dcdb; /* Use Same Data Area as Old DCDB Struct */
3996 tapeDCDB->device_address =
3997 ((scb->bus - 1) << 4) | scb->target_id;
3998 tapeDCDB->cmd_attribute |= IPS_DISCONNECT_ALLOWED;
3999 tapeDCDB->cmd_attribute &= ~IPS_TRANSFER64K; /* Always Turn OFF 64K Size Flag */
4001 if (TimeOut) {
4002 if (TimeOut < (10 * HZ))
4003 tapeDCDB->cmd_attribute |= IPS_TIMEOUT10; /* TimeOut is 10 Seconds */
4004 else if (TimeOut < (60 * HZ))
4005 tapeDCDB->cmd_attribute |= IPS_TIMEOUT60; /* TimeOut is 60 Seconds */
4006 else if (TimeOut < (1200 * HZ))
4007 tapeDCDB->cmd_attribute |= IPS_TIMEOUT20M; /* TimeOut is 20 Minutes */
4010 tapeDCDB->cdb_length = scb->scsi_cmd->cmd_len;
4011 tapeDCDB->reserved_for_LUN = 0;
4012 tapeDCDB->transfer_length = scb->data_len;
4013 if (scb->cmd.dcdb.op_code == IPS_CMD_EXTENDED_DCDB_SG)
4014 tapeDCDB->buffer_pointer =
4015 cpu_to_le32(scb->sg_busaddr);
4016 else
4017 tapeDCDB->buffer_pointer =
4018 cpu_to_le32(scb->data_busaddr);
4019 tapeDCDB->sg_count = scb->sg_len;
4020 tapeDCDB->sense_length = sizeof (tapeDCDB->sense_info);
4021 tapeDCDB->scsi_status = 0;
4022 tapeDCDB->reserved = 0;
4023 memcpy(tapeDCDB->scsi_cdb, scb->scsi_cmd->cmnd,
4024 scb->scsi_cmd->cmd_len);
4025 } else {
4026 if (!scb->sg_len) {
4027 scb->cmd.dcdb.op_code = IPS_CMD_DCDB;
4028 } else {
4029 scb->cmd.dcdb.op_code = IPS_CMD_DCDB_SG;
4030 scb->cmd.dcdb.enhanced_sg =
4031 IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0;
4034 scb->dcdb.device_address =
4035 ((scb->bus - 1) << 4) | scb->target_id;
4036 scb->dcdb.cmd_attribute |= IPS_DISCONNECT_ALLOWED;
4038 if (TimeOut) {
4039 if (TimeOut < (10 * HZ))
4040 scb->dcdb.cmd_attribute |= IPS_TIMEOUT10; /* TimeOut is 10 Seconds */
4041 else if (TimeOut < (60 * HZ))
4042 scb->dcdb.cmd_attribute |= IPS_TIMEOUT60; /* TimeOut is 60 Seconds */
4043 else if (TimeOut < (1200 * HZ))
4044 scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M; /* TimeOut is 20 Minutes */
4047 scb->dcdb.transfer_length = scb->data_len;
4048 if (scb->dcdb.cmd_attribute & IPS_TRANSFER64K)
4049 scb->dcdb.transfer_length = 0;
4050 if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB_SG)
4051 scb->dcdb.buffer_pointer =
4052 cpu_to_le32(scb->sg_busaddr);
4053 else
4054 scb->dcdb.buffer_pointer =
4055 cpu_to_le32(scb->data_busaddr);
4056 scb->dcdb.cdb_length = scb->scsi_cmd->cmd_len;
4057 scb->dcdb.sense_length = sizeof (scb->dcdb.sense_info);
4058 scb->dcdb.sg_count = scb->sg_len;
4059 scb->dcdb.reserved = 0;
4060 memcpy(scb->dcdb.scsi_cdb, scb->scsi_cmd->cmnd,
4061 scb->scsi_cmd->cmd_len);
4062 scb->dcdb.scsi_status = 0;
4063 scb->dcdb.reserved2[0] = 0;
4064 scb->dcdb.reserved2[1] = 0;
4065 scb->dcdb.reserved2[2] = 0;
4069 return ((*ha->func.issue) (ha, scb));
4072 /****************************************************************************/
4073 /* */
4074 /* Routine Name: ips_chk_status */
4075 /* */
4076 /* Routine Description: */
4077 /* */
4078 /* Check the status of commands to logical drives */
4079 /* Assumed to be called with the HA lock */
4080 /****************************************************************************/
4081 static void
4082 ips_chkstatus(ips_ha_t * ha, IPS_STATUS * pstatus)
4084 ips_scb_t *scb;
4085 ips_stat_t *sp;
4086 uint8_t basic_status;
4087 uint8_t ext_status;
4088 int errcode;
4090 METHOD_TRACE("ips_chkstatus", 1);
4092 scb = &ha->scbs[pstatus->fields.command_id];
4093 scb->basic_status = basic_status =
4094 pstatus->fields.basic_status & IPS_BASIC_STATUS_MASK;
4095 scb->extended_status = ext_status = pstatus->fields.extended_status;
4097 sp = &ha->sp;
4098 sp->residue_len = 0;
4099 sp->scb_addr = (void *) scb;
4101 /* Remove the item from the active queue */
4102 ips_removeq_scb(&ha->scb_activelist, scb);
4104 if (!scb->scsi_cmd)
4105 /* internal commands are handled in do_ipsintr */
4106 return;
4108 DEBUG_VAR(2, "(%s%d) ips_chkstatus: cmd 0x%X id %d (%d %d %d)",
4109 ips_name,
4110 ha->host_num,
4111 scb->cdb[0],
4112 scb->cmd.basic_io.command_id,
4113 scb->bus, scb->target_id, scb->lun);
4115 if ((scb->scsi_cmd) && (ips_is_passthru(scb->scsi_cmd)))
4116 /* passthru - just returns the raw result */
4117 return;
4119 errcode = DID_OK;
4121 if (((basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_SUCCESS) ||
4122 ((basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_RECOVERED_ERROR)) {
4124 if (scb->bus == 0) {
4125 if ((basic_status & IPS_GSC_STATUS_MASK) ==
4126 IPS_CMD_RECOVERED_ERROR) {
4127 DEBUG_VAR(1,
4128 "(%s%d) Recovered Logical Drive Error OpCode: %x, BSB: %x, ESB: %x",
4129 ips_name, ha->host_num,
4130 scb->cmd.basic_io.op_code,
4131 basic_status, ext_status);
4134 switch (scb->scsi_cmd->cmnd[0]) {
4135 case ALLOW_MEDIUM_REMOVAL:
4136 case REZERO_UNIT:
4137 case ERASE:
4138 case WRITE_FILEMARKS:
4139 case SPACE:
4140 errcode = DID_ERROR;
4141 break;
4143 case START_STOP:
4144 break;
4146 case TEST_UNIT_READY:
4147 if (!ips_online(ha, scb)) {
4148 errcode = DID_TIME_OUT;
4150 break;
4152 case INQUIRY:
4153 if (ips_online(ha, scb)) {
4154 ips_inquiry(ha, scb);
4155 } else {
4156 errcode = DID_TIME_OUT;
4158 break;
4160 case REQUEST_SENSE:
4161 ips_reqsen(ha, scb);
4162 break;
4164 case READ_6:
4165 case WRITE_6:
4166 case READ_10:
4167 case WRITE_10:
4168 case RESERVE:
4169 case RELEASE:
4170 break;
4172 case MODE_SENSE:
4173 if (!ips_online(ha, scb)
4174 || !ips_msense(ha, scb)) {
4175 errcode = DID_ERROR;
4177 break;
4179 case READ_CAPACITY:
4180 if (ips_online(ha, scb))
4181 ips_rdcap(ha, scb);
4182 else {
4183 errcode = DID_TIME_OUT;
4185 break;
4187 case SEND_DIAGNOSTIC:
4188 case REASSIGN_BLOCKS:
4189 break;
4191 case FORMAT_UNIT:
4192 errcode = DID_ERROR;
4193 break;
4195 case SEEK_10:
4196 case VERIFY:
4197 case READ_DEFECT_DATA:
4198 case READ_BUFFER:
4199 case WRITE_BUFFER:
4200 break;
4202 default:
4203 errcode = DID_ERROR;
4204 } /* end switch */
4206 scb->scsi_cmd->result = errcode << 16;
4207 } else { /* bus == 0 */
4208 /* restrict access to physical drives */
4209 if ((scb->scsi_cmd->cmnd[0] == INQUIRY) &&
4210 ((((char *) scb->scsi_cmd->buffer)[0] & 0x1f) ==
4211 TYPE_DISK)) {
4213 scb->scsi_cmd->result = DID_TIME_OUT << 16;
4215 } /* else */
4216 } else { /* recovered error / success */
4217 if (scb->bus == 0) {
4218 DEBUG_VAR(1,
4219 "(%s%d) Unrecovered Logical Drive Error OpCode: %x, BSB: %x, ESB: %x",
4220 ips_name, ha->host_num,
4221 scb->cmd.basic_io.op_code, basic_status,
4222 ext_status);
4225 ips_map_status(ha, scb, sp);
4226 } /* else */
4229 /****************************************************************************/
4230 /* */
4231 /* Routine Name: ips_online */
4232 /* */
4233 /* Routine Description: */
4234 /* */
4235 /* Determine if a logical drive is online */
4236 /* */
4237 /****************************************************************************/
4238 static int
4239 ips_online(ips_ha_t * ha, ips_scb_t * scb)
4241 METHOD_TRACE("ips_online", 1);
4243 if (scb->target_id >= IPS_MAX_LD)
4244 return (0);
4246 if ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1) {
4247 memset(ha->logical_drive_info, 0, sizeof (IPS_LD_INFO));
4248 return (0);
4251 if (ha->logical_drive_info->drive_info[scb->target_id].state !=
4252 IPS_LD_OFFLINE
4253 && ha->logical_drive_info->drive_info[scb->target_id].state !=
4254 IPS_LD_FREE
4255 && ha->logical_drive_info->drive_info[scb->target_id].state !=
4256 IPS_LD_CRS
4257 && ha->logical_drive_info->drive_info[scb->target_id].state !=
4258 IPS_LD_SYS)
4259 return (1);
4260 else
4261 return (0);
4264 /****************************************************************************/
4265 /* */
4266 /* Routine Name: ips_inquiry */
4267 /* */
4268 /* Routine Description: */
4269 /* */
4270 /* Simulate an inquiry command to a logical drive */
4271 /* */
4272 /****************************************************************************/
4273 static int
4274 ips_inquiry(ips_ha_t * ha, ips_scb_t * scb)
4276 IPS_SCSI_INQ_DATA inquiry;
4278 METHOD_TRACE("ips_inquiry", 1);
4280 memset(&inquiry, 0, sizeof (IPS_SCSI_INQ_DATA));
4282 inquiry.DeviceType = IPS_SCSI_INQ_TYPE_DASD;
4283 inquiry.DeviceTypeQualifier = IPS_SCSI_INQ_LU_CONNECTED;
4284 inquiry.Version = IPS_SCSI_INQ_REV2;
4285 inquiry.ResponseDataFormat = IPS_SCSI_INQ_RD_REV2;
4286 inquiry.AdditionalLength = 31;
4287 inquiry.Flags[0] = IPS_SCSI_INQ_Address16;
4288 inquiry.Flags[1] =
4289 IPS_SCSI_INQ_WBus16 | IPS_SCSI_INQ_Sync | IPS_SCSI_INQ_CmdQue;
4290 strncpy(inquiry.VendorId, "IBM ", 8);
4291 strncpy(inquiry.ProductId, "SERVERAID ", 16);
4292 strncpy(inquiry.ProductRevisionLevel, "1.00", 4);
4294 ips_scmd_buf_write(scb->scsi_cmd, &inquiry, sizeof (inquiry));
4296 return (1);
4299 /****************************************************************************/
4300 /* */
4301 /* Routine Name: ips_rdcap */
4302 /* */
4303 /* Routine Description: */
4304 /* */
4305 /* Simulate a read capacity command to a logical drive */
4306 /* */
4307 /****************************************************************************/
4308 static int
4309 ips_rdcap(ips_ha_t * ha, ips_scb_t * scb)
4311 IPS_SCSI_CAPACITY cap;
4313 METHOD_TRACE("ips_rdcap", 1);
4315 if (scb->scsi_cmd->bufflen < 8)
4316 return (0);
4318 cap.lba =
4319 cpu_to_be32(le32_to_cpu
4320 (ha->logical_drive_info->
4321 drive_info[scb->target_id].sector_count) - 1);
4322 cap.len = cpu_to_be32((uint32_t) IPS_BLKSIZE);
4324 ips_scmd_buf_write(scb->scsi_cmd, &cap, sizeof (cap));
4326 return (1);
4329 /****************************************************************************/
4330 /* */
4331 /* Routine Name: ips_msense */
4332 /* */
4333 /* Routine Description: */
4334 /* */
4335 /* Simulate a mode sense command to a logical drive */
4336 /* */
4337 /****************************************************************************/
4338 static int
4339 ips_msense(ips_ha_t * ha, ips_scb_t * scb)
4341 uint16_t heads;
4342 uint16_t sectors;
4343 uint32_t cylinders;
4344 IPS_SCSI_MODE_PAGE_DATA mdata;
4346 METHOD_TRACE("ips_msense", 1);
4348 if (le32_to_cpu(ha->enq->ulDriveSize[scb->target_id]) > 0x400000 &&
4349 (ha->enq->ucMiscFlag & 0x8) == 0) {
4350 heads = IPS_NORM_HEADS;
4351 sectors = IPS_NORM_SECTORS;
4352 } else {
4353 heads = IPS_COMP_HEADS;
4354 sectors = IPS_COMP_SECTORS;
4357 cylinders =
4358 (le32_to_cpu(ha->enq->ulDriveSize[scb->target_id]) -
4359 1) / (heads * sectors);
4361 memset(&mdata, 0, sizeof (IPS_SCSI_MODE_PAGE_DATA));
4363 mdata.hdr.BlockDescLength = 8;
4365 switch (scb->scsi_cmd->cmnd[2] & 0x3f) {
4366 case 0x03: /* page 3 */
4367 mdata.pdata.pg3.PageCode = 3;
4368 mdata.pdata.pg3.PageLength = sizeof (IPS_SCSI_MODE_PAGE3);
4369 mdata.hdr.DataLength =
4370 3 + mdata.hdr.BlockDescLength + mdata.pdata.pg3.PageLength;
4371 mdata.pdata.pg3.TracksPerZone = 0;
4372 mdata.pdata.pg3.AltSectorsPerZone = 0;
4373 mdata.pdata.pg3.AltTracksPerZone = 0;
4374 mdata.pdata.pg3.AltTracksPerVolume = 0;
4375 mdata.pdata.pg3.SectorsPerTrack = cpu_to_be16(sectors);
4376 mdata.pdata.pg3.BytesPerSector = cpu_to_be16(IPS_BLKSIZE);
4377 mdata.pdata.pg3.Interleave = cpu_to_be16(1);
4378 mdata.pdata.pg3.TrackSkew = 0;
4379 mdata.pdata.pg3.CylinderSkew = 0;
4380 mdata.pdata.pg3.flags = IPS_SCSI_MP3_SoftSector;
4381 break;
4383 case 0x4:
4384 mdata.pdata.pg4.PageCode = 4;
4385 mdata.pdata.pg4.PageLength = sizeof (IPS_SCSI_MODE_PAGE4);
4386 mdata.hdr.DataLength =
4387 3 + mdata.hdr.BlockDescLength + mdata.pdata.pg4.PageLength;
4388 mdata.pdata.pg4.CylindersHigh =
4389 cpu_to_be16((cylinders >> 8) & 0xFFFF);
4390 mdata.pdata.pg4.CylindersLow = (cylinders & 0xFF);
4391 mdata.pdata.pg4.Heads = heads;
4392 mdata.pdata.pg4.WritePrecompHigh = 0;
4393 mdata.pdata.pg4.WritePrecompLow = 0;
4394 mdata.pdata.pg4.ReducedWriteCurrentHigh = 0;
4395 mdata.pdata.pg4.ReducedWriteCurrentLow = 0;
4396 mdata.pdata.pg4.StepRate = cpu_to_be16(1);
4397 mdata.pdata.pg4.LandingZoneHigh = 0;
4398 mdata.pdata.pg4.LandingZoneLow = 0;
4399 mdata.pdata.pg4.flags = 0;
4400 mdata.pdata.pg4.RotationalOffset = 0;
4401 mdata.pdata.pg4.MediumRotationRate = 0;
4402 break;
4403 case 0x8:
4404 mdata.pdata.pg8.PageCode = 8;
4405 mdata.pdata.pg8.PageLength = sizeof (IPS_SCSI_MODE_PAGE8);
4406 mdata.hdr.DataLength =
4407 3 + mdata.hdr.BlockDescLength + mdata.pdata.pg8.PageLength;
4408 /* everything else is left set to 0 */
4409 break;
4411 default:
4412 return (0);
4413 } /* end switch */
4415 ips_scmd_buf_write(scb->scsi_cmd, &mdata, sizeof (mdata));
4417 return (1);
4420 /****************************************************************************/
4421 /* */
4422 /* Routine Name: ips_reqsen */
4423 /* */
4424 /* Routine Description: */
4425 /* */
4426 /* Simulate a request sense command to a logical drive */
4427 /* */
4428 /****************************************************************************/
4429 static int
4430 ips_reqsen(ips_ha_t * ha, ips_scb_t * scb)
4432 IPS_SCSI_REQSEN reqsen;
4434 METHOD_TRACE("ips_reqsen", 1);
4436 memset(&reqsen, 0, sizeof (IPS_SCSI_REQSEN));
4438 reqsen.ResponseCode =
4439 IPS_SCSI_REQSEN_VALID | IPS_SCSI_REQSEN_CURRENT_ERR;
4440 reqsen.AdditionalLength = 10;
4441 reqsen.AdditionalSenseCode = IPS_SCSI_REQSEN_NO_SENSE;
4442 reqsen.AdditionalSenseCodeQual = IPS_SCSI_REQSEN_NO_SENSE;
4444 ips_scmd_buf_write(scb->scsi_cmd, &reqsen, sizeof (reqsen));
4446 return (1);
4449 /****************************************************************************/
4450 /* */
4451 /* Routine Name: ips_free */
4452 /* */
4453 /* Routine Description: */
4454 /* */
4455 /* Free any allocated space for this controller */
4456 /* */
4457 /****************************************************************************/
4458 static void
4459 ips_free(ips_ha_t * ha)
4462 METHOD_TRACE("ips_free", 1);
4464 if (ha) {
4465 if (ha->enq) {
4466 pci_free_consistent(ha->pcidev, sizeof(IPS_ENQ),
4467 ha->enq, ha->enq_busaddr);
4468 ha->enq = NULL;
4471 if (ha->conf) {
4472 kfree(ha->conf);
4473 ha->conf = NULL;
4476 if (ha->adapt) {
4477 pci_free_consistent(ha->pcidev,
4478 sizeof (IPS_ADAPTER) +
4479 sizeof (IPS_IO_CMD), ha->adapt,
4480 ha->adapt->hw_status_start);
4481 ha->adapt = NULL;
4484 if (ha->logical_drive_info) {
4485 pci_free_consistent(ha->pcidev,
4486 sizeof (IPS_LD_INFO),
4487 ha->logical_drive_info,
4488 ha->logical_drive_info_dma_addr);
4489 ha->logical_drive_info = NULL;
4492 if (ha->nvram) {
4493 kfree(ha->nvram);
4494 ha->nvram = NULL;
4497 if (ha->subsys) {
4498 kfree(ha->subsys);
4499 ha->subsys = NULL;
4502 if (ha->ioctl_data) {
4503 pci_free_consistent(ha->pcidev, ha->ioctl_len,
4504 ha->ioctl_data, ha->ioctl_busaddr);
4505 ha->ioctl_data = NULL;
4506 ha->ioctl_datasize = 0;
4507 ha->ioctl_len = 0;
4509 ips_deallocatescbs(ha, ha->max_cmds);
4511 /* free memory mapped (if applicable) */
4512 if (ha->mem_ptr) {
4513 iounmap(ha->ioremap_ptr);
4514 ha->ioremap_ptr = NULL;
4515 ha->mem_ptr = NULL;
4518 if (ha->mem_addr)
4519 release_mem_region(ha->mem_addr, ha->mem_len);
4520 ha->mem_addr = 0;
4525 /****************************************************************************/
4526 /* */
4527 /* Routine Name: ips_deallocatescbs */
4528 /* */
4529 /* Routine Description: */
4530 /* */
4531 /* Free the command blocks */
4532 /* */
4533 /****************************************************************************/
4534 static int
4535 ips_deallocatescbs(ips_ha_t * ha, int cmds)
4537 if (ha->scbs) {
4538 pci_free_consistent(ha->pcidev,
4539 IPS_SGLIST_SIZE(ha) * IPS_MAX_SG * cmds,
4540 ha->scbs->sg_list.list,
4541 ha->scbs->sg_busaddr);
4542 pci_free_consistent(ha->pcidev, sizeof (ips_scb_t) * cmds,
4543 ha->scbs, ha->scbs->scb_busaddr);
4544 ha->scbs = NULL;
4545 } /* end if */
4546 return 1;
4549 /****************************************************************************/
4550 /* */
4551 /* Routine Name: ips_allocatescbs */
4552 /* */
4553 /* Routine Description: */
4554 /* */
4555 /* Allocate the command blocks */
4556 /* */
4557 /****************************************************************************/
4558 static int
4559 ips_allocatescbs(ips_ha_t * ha)
4561 ips_scb_t *scb_p;
4562 IPS_SG_LIST ips_sg;
4563 int i;
4564 dma_addr_t command_dma, sg_dma;
4566 METHOD_TRACE("ips_allocatescbs", 1);
4568 /* Allocate memory for the SCBs */
4569 ha->scbs =
4570 pci_alloc_consistent(ha->pcidev, ha->max_cmds * sizeof (ips_scb_t),
4571 &command_dma);
4572 if (ha->scbs == NULL)
4573 return 0;
4574 ips_sg.list =
4575 pci_alloc_consistent(ha->pcidev,
4576 IPS_SGLIST_SIZE(ha) * IPS_MAX_SG *
4577 ha->max_cmds, &sg_dma);
4578 if (ips_sg.list == NULL) {
4579 pci_free_consistent(ha->pcidev,
4580 ha->max_cmds * sizeof (ips_scb_t), ha->scbs,
4581 command_dma);
4582 return 0;
4585 memset(ha->scbs, 0, ha->max_cmds * sizeof (ips_scb_t));
4587 for (i = 0; i < ha->max_cmds; i++) {
4588 scb_p = &ha->scbs[i];
4589 scb_p->scb_busaddr = command_dma + sizeof (ips_scb_t) * i;
4590 /* set up S/G list */
4591 if (IPS_USE_ENH_SGLIST(ha)) {
4592 scb_p->sg_list.enh_list =
4593 ips_sg.enh_list + i * IPS_MAX_SG;
4594 scb_p->sg_busaddr =
4595 sg_dma + IPS_SGLIST_SIZE(ha) * IPS_MAX_SG * i;
4596 } else {
4597 scb_p->sg_list.std_list =
4598 ips_sg.std_list + i * IPS_MAX_SG;
4599 scb_p->sg_busaddr =
4600 sg_dma + IPS_SGLIST_SIZE(ha) * IPS_MAX_SG * i;
4603 /* add to the free list */
4604 if (i < ha->max_cmds - 1) {
4605 scb_p->q_next = ha->scb_freelist;
4606 ha->scb_freelist = scb_p;
4610 /* success */
4611 return (1);
4614 /****************************************************************************/
4615 /* */
4616 /* Routine Name: ips_init_scb */
4617 /* */
4618 /* Routine Description: */
4619 /* */
4620 /* Initialize a CCB to default values */
4621 /* */
4622 /****************************************************************************/
4623 static void
4624 ips_init_scb(ips_ha_t * ha, ips_scb_t * scb)
4626 IPS_SG_LIST sg_list;
4627 uint32_t cmd_busaddr, sg_busaddr;
4628 METHOD_TRACE("ips_init_scb", 1);
4630 if (scb == NULL)
4631 return;
4633 sg_list.list = scb->sg_list.list;
4634 cmd_busaddr = scb->scb_busaddr;
4635 sg_busaddr = scb->sg_busaddr;
4636 /* zero fill */
4637 memset(scb, 0, sizeof (ips_scb_t));
4638 memset(ha->dummy, 0, sizeof (IPS_IO_CMD));
4640 /* Initialize dummy command bucket */
4641 ha->dummy->op_code = 0xFF;
4642 ha->dummy->ccsar = cpu_to_le32(ha->adapt->hw_status_start
4643 + sizeof (IPS_ADAPTER));
4644 ha->dummy->command_id = IPS_MAX_CMDS;
4646 /* set bus address of scb */
4647 scb->scb_busaddr = cmd_busaddr;
4648 scb->sg_busaddr = sg_busaddr;
4649 scb->sg_list.list = sg_list.list;
4651 /* Neptune Fix */
4652 scb->cmd.basic_io.cccr = cpu_to_le32((uint32_t) IPS_BIT_ILE);
4653 scb->cmd.basic_io.ccsar = cpu_to_le32(ha->adapt->hw_status_start
4654 + sizeof (IPS_ADAPTER));
4657 /****************************************************************************/
4658 /* */
4659 /* Routine Name: ips_get_scb */
4660 /* */
4661 /* Routine Description: */
4662 /* */
4663 /* Initialize a CCB to default values */
4664 /* */
4665 /* ASSUMED to be callled from within a lock */
4666 /* */
4667 /****************************************************************************/
4668 static ips_scb_t *
4669 ips_getscb(ips_ha_t * ha)
4671 ips_scb_t *scb;
4673 METHOD_TRACE("ips_getscb", 1);
4675 if ((scb = ha->scb_freelist) == NULL) {
4677 return (NULL);
4680 ha->scb_freelist = scb->q_next;
4681 scb->flags = 0;
4682 scb->q_next = NULL;
4684 ips_init_scb(ha, scb);
4686 return (scb);
4689 /****************************************************************************/
4690 /* */
4691 /* Routine Name: ips_free_scb */
4692 /* */
4693 /* Routine Description: */
4694 /* */
4695 /* Return an unused CCB back to the free list */
4696 /* */
4697 /* ASSUMED to be called from within a lock */
4698 /* */
4699 /****************************************************************************/
4700 static void
4701 ips_freescb(ips_ha_t * ha, ips_scb_t * scb)
4704 METHOD_TRACE("ips_freescb", 1);
4705 if (scb->flags & IPS_SCB_MAP_SG)
4706 pci_unmap_sg(ha->pcidev, scb->scsi_cmd->request_buffer,
4707 scb->scsi_cmd->use_sg, IPS_DMA_DIR(scb));
4708 else if (scb->flags & IPS_SCB_MAP_SINGLE)
4709 pci_unmap_single(ha->pcidev, scb->data_busaddr, scb->data_len,
4710 IPS_DMA_DIR(scb));
4712 /* check to make sure this is not our "special" scb */
4713 if (IPS_COMMAND_ID(ha, scb) < (ha->max_cmds - 1)) {
4714 scb->q_next = ha->scb_freelist;
4715 ha->scb_freelist = scb;
4719 /****************************************************************************/
4720 /* */
4721 /* Routine Name: ips_isinit_copperhead */
4722 /* */
4723 /* Routine Description: */
4724 /* */
4725 /* Is controller initialized ? */
4726 /* */
4727 /****************************************************************************/
4728 static int
4729 ips_isinit_copperhead(ips_ha_t * ha)
4731 uint8_t scpr;
4732 uint8_t isr;
4734 METHOD_TRACE("ips_isinit_copperhead", 1);
4736 isr = inb(ha->io_addr + IPS_REG_HISR);
4737 scpr = inb(ha->io_addr + IPS_REG_SCPR);
4739 if (((isr & IPS_BIT_EI) == 0) && ((scpr & IPS_BIT_EBM) == 0))
4740 return (0);
4741 else
4742 return (1);
4745 /****************************************************************************/
4746 /* */
4747 /* Routine Name: ips_isinit_copperhead_memio */
4748 /* */
4749 /* Routine Description: */
4750 /* */
4751 /* Is controller initialized ? */
4752 /* */
4753 /****************************************************************************/
4754 static int
4755 ips_isinit_copperhead_memio(ips_ha_t * ha)
4757 uint8_t isr = 0;
4758 uint8_t scpr;
4760 METHOD_TRACE("ips_is_init_copperhead_memio", 1);
4762 isr = readb(ha->mem_ptr + IPS_REG_HISR);
4763 scpr = readb(ha->mem_ptr + IPS_REG_SCPR);
4765 if (((isr & IPS_BIT_EI) == 0) && ((scpr & IPS_BIT_EBM) == 0))
4766 return (0);
4767 else
4768 return (1);
4771 /****************************************************************************/
4772 /* */
4773 /* Routine Name: ips_isinit_morpheus */
4774 /* */
4775 /* Routine Description: */
4776 /* */
4777 /* Is controller initialized ? */
4778 /* */
4779 /****************************************************************************/
4780 static int
4781 ips_isinit_morpheus(ips_ha_t * ha)
4783 uint32_t post;
4784 uint32_t bits;
4786 METHOD_TRACE("ips_is_init_morpheus", 1);
4788 post = readl(ha->mem_ptr + IPS_REG_I960_MSG0);
4789 bits = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
4791 if (post == 0)
4792 return (0);
4793 else if (bits & 0x3)
4794 return (0);
4795 else
4796 return (1);
4799 /****************************************************************************/
4800 /* */
4801 /* Routine Name: ips_enable_int_copperhead */
4802 /* */
4803 /* Routine Description: */
4804 /* Turn on interrupts */
4805 /* */
4806 /****************************************************************************/
4807 static void
4808 ips_enable_int_copperhead(ips_ha_t * ha)
4810 METHOD_TRACE("ips_enable_int_copperhead", 1);
4812 outb(ha->io_addr + IPS_REG_HISR, IPS_BIT_EI);
4813 inb(ha->io_addr + IPS_REG_HISR); /*Ensure PCI Posting Completes*/
4816 /****************************************************************************/
4817 /* */
4818 /* Routine Name: ips_enable_int_copperhead_memio */
4819 /* */
4820 /* Routine Description: */
4821 /* Turn on interrupts */
4822 /* */
4823 /****************************************************************************/
4824 static void
4825 ips_enable_int_copperhead_memio(ips_ha_t * ha)
4827 METHOD_TRACE("ips_enable_int_copperhead_memio", 1);
4829 writeb(IPS_BIT_EI, ha->mem_ptr + IPS_REG_HISR);
4830 readb(ha->mem_ptr + IPS_REG_HISR); /*Ensure PCI Posting Completes*/
4833 /****************************************************************************/
4834 /* */
4835 /* Routine Name: ips_enable_int_morpheus */
4836 /* */
4837 /* Routine Description: */
4838 /* Turn on interrupts */
4839 /* */
4840 /****************************************************************************/
4841 static void
4842 ips_enable_int_morpheus(ips_ha_t * ha)
4844 uint32_t Oimr;
4846 METHOD_TRACE("ips_enable_int_morpheus", 1);
4848 Oimr = readl(ha->mem_ptr + IPS_REG_I960_OIMR);
4849 Oimr &= ~0x08;
4850 writel(Oimr, ha->mem_ptr + IPS_REG_I960_OIMR);
4851 readl(ha->mem_ptr + IPS_REG_I960_OIMR); /*Ensure PCI Posting Completes*/
4854 /****************************************************************************/
4855 /* */
4856 /* Routine Name: ips_init_copperhead */
4857 /* */
4858 /* Routine Description: */
4859 /* */
4860 /* Initialize a copperhead controller */
4861 /* */
4862 /****************************************************************************/
4863 static int
4864 ips_init_copperhead(ips_ha_t * ha)
4866 uint8_t Isr;
4867 uint8_t Cbsp;
4868 uint8_t PostByte[IPS_MAX_POST_BYTES];
4869 uint8_t ConfigByte[IPS_MAX_CONFIG_BYTES];
4870 int i, j;
4872 METHOD_TRACE("ips_init_copperhead", 1);
4874 for (i = 0; i < IPS_MAX_POST_BYTES; i++) {
4875 for (j = 0; j < 45; j++) {
4876 Isr = inb(ha->io_addr + IPS_REG_HISR);
4877 if (Isr & IPS_BIT_GHI)
4878 break;
4880 /* Delay for 1 Second */
4881 MDELAY(IPS_ONE_SEC);
4884 if (j >= 45)
4885 /* error occurred */
4886 return (0);
4888 PostByte[i] = inb(ha->io_addr + IPS_REG_ISPR);
4889 outb(Isr, ha->io_addr + IPS_REG_HISR);
4892 if (PostByte[0] < IPS_GOOD_POST_STATUS) {
4893 IPS_PRINTK(KERN_WARNING, ha->pcidev,
4894 "reset controller fails (post status %x %x).\n",
4895 PostByte[0], PostByte[1]);
4897 return (0);
4900 for (i = 0; i < IPS_MAX_CONFIG_BYTES; i++) {
4901 for (j = 0; j < 240; j++) {
4902 Isr = inb(ha->io_addr + IPS_REG_HISR);
4903 if (Isr & IPS_BIT_GHI)
4904 break;
4906 /* Delay for 1 Second */
4907 MDELAY(IPS_ONE_SEC);
4910 if (j >= 240)
4911 /* error occurred */
4912 return (0);
4914 ConfigByte[i] = inb(ha->io_addr + IPS_REG_ISPR);
4915 outb(Isr, ha->io_addr + IPS_REG_HISR);
4918 for (i = 0; i < 240; i++) {
4919 Cbsp = inb(ha->io_addr + IPS_REG_CBSP);
4921 if ((Cbsp & IPS_BIT_OP) == 0)
4922 break;
4924 /* Delay for 1 Second */
4925 MDELAY(IPS_ONE_SEC);
4928 if (i >= 240)
4929 /* reset failed */
4930 return (0);
4932 /* setup CCCR */
4933 outl(cpu_to_le32(0x1010), ha->io_addr + IPS_REG_CCCR);
4935 /* Enable busmastering */
4936 outb(IPS_BIT_EBM, ha->io_addr + IPS_REG_SCPR);
4938 if (ha->revision_id == IPS_REVID_TROMBONE64)
4939 /* fix for anaconda64 */
4940 outl(0, ha->io_addr + IPS_REG_NDAE);
4942 /* Enable interrupts */
4943 outb(IPS_BIT_EI, ha->io_addr + IPS_REG_HISR);
4945 return (1);
4948 /****************************************************************************/
4949 /* */
4950 /* Routine Name: ips_init_copperhead_memio */
4951 /* */
4952 /* Routine Description: */
4953 /* */
4954 /* Initialize a copperhead controller with memory mapped I/O */
4955 /* */
4956 /****************************************************************************/
4957 static int
4958 ips_init_copperhead_memio(ips_ha_t * ha)
4960 uint8_t Isr = 0;
4961 uint8_t Cbsp;
4962 uint8_t PostByte[IPS_MAX_POST_BYTES];
4963 uint8_t ConfigByte[IPS_MAX_CONFIG_BYTES];
4964 int i, j;
4966 METHOD_TRACE("ips_init_copperhead_memio", 1);
4968 for (i = 0; i < IPS_MAX_POST_BYTES; i++) {
4969 for (j = 0; j < 45; j++) {
4970 Isr = readb(ha->mem_ptr + IPS_REG_HISR);
4971 if (Isr & IPS_BIT_GHI)
4972 break;
4974 /* Delay for 1 Second */
4975 MDELAY(IPS_ONE_SEC);
4978 if (j >= 45)
4979 /* error occurred */
4980 return (0);
4982 PostByte[i] = readb(ha->mem_ptr + IPS_REG_ISPR);
4983 writeb(Isr, ha->mem_ptr + IPS_REG_HISR);
4986 if (PostByte[0] < IPS_GOOD_POST_STATUS) {
4987 IPS_PRINTK(KERN_WARNING, ha->pcidev,
4988 "reset controller fails (post status %x %x).\n",
4989 PostByte[0], PostByte[1]);
4991 return (0);
4994 for (i = 0; i < IPS_MAX_CONFIG_BYTES; i++) {
4995 for (j = 0; j < 240; j++) {
4996 Isr = readb(ha->mem_ptr + IPS_REG_HISR);
4997 if (Isr & IPS_BIT_GHI)
4998 break;
5000 /* Delay for 1 Second */
5001 MDELAY(IPS_ONE_SEC);
5004 if (j >= 240)
5005 /* error occurred */
5006 return (0);
5008 ConfigByte[i] = readb(ha->mem_ptr + IPS_REG_ISPR);
5009 writeb(Isr, ha->mem_ptr + IPS_REG_HISR);
5012 for (i = 0; i < 240; i++) {
5013 Cbsp = readb(ha->mem_ptr + IPS_REG_CBSP);
5015 if ((Cbsp & IPS_BIT_OP) == 0)
5016 break;
5018 /* Delay for 1 Second */
5019 MDELAY(IPS_ONE_SEC);
5022 if (i >= 240)
5023 /* error occurred */
5024 return (0);
5026 /* setup CCCR */
5027 writel(0x1010, ha->mem_ptr + IPS_REG_CCCR);
5029 /* Enable busmastering */
5030 writeb(IPS_BIT_EBM, ha->mem_ptr + IPS_REG_SCPR);
5032 if (ha->revision_id == IPS_REVID_TROMBONE64)
5033 /* fix for anaconda64 */
5034 writel(0, ha->mem_ptr + IPS_REG_NDAE);
5036 /* Enable interrupts */
5037 writeb(IPS_BIT_EI, ha->mem_ptr + IPS_REG_HISR);
5039 /* if we get here then everything went OK */
5040 return (1);
5043 /****************************************************************************/
5044 /* */
5045 /* Routine Name: ips_init_morpheus */
5046 /* */
5047 /* Routine Description: */
5048 /* */
5049 /* Initialize a morpheus controller */
5050 /* */
5051 /****************************************************************************/
5052 static int
5053 ips_init_morpheus(ips_ha_t * ha)
5055 uint32_t Post;
5056 uint32_t Config;
5057 uint32_t Isr;
5058 uint32_t Oimr;
5059 int i;
5061 METHOD_TRACE("ips_init_morpheus", 1);
5063 /* Wait up to 45 secs for Post */
5064 for (i = 0; i < 45; i++) {
5065 Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
5067 if (Isr & IPS_BIT_I960_MSG0I)
5068 break;
5070 /* Delay for 1 Second */
5071 MDELAY(IPS_ONE_SEC);
5074 if (i >= 45) {
5075 /* error occurred */
5076 IPS_PRINTK(KERN_WARNING, ha->pcidev,
5077 "timeout waiting for post.\n");
5079 return (0);
5082 Post = readl(ha->mem_ptr + IPS_REG_I960_MSG0);
5084 if (Post == 0x4F00) { /* If Flashing the Battery PIC */
5085 IPS_PRINTK(KERN_WARNING, ha->pcidev,
5086 "Flashing Battery PIC, Please wait ...\n");
5088 /* Clear the interrupt bit */
5089 Isr = (uint32_t) IPS_BIT_I960_MSG0I;
5090 writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR);
5092 for (i = 0; i < 120; i++) { /* Wait Up to 2 Min. for Completion */
5093 Post = readl(ha->mem_ptr + IPS_REG_I960_MSG0);
5094 if (Post != 0x4F00)
5095 break;
5096 /* Delay for 1 Second */
5097 MDELAY(IPS_ONE_SEC);
5100 if (i >= 120) {
5101 IPS_PRINTK(KERN_WARNING, ha->pcidev,
5102 "timeout waiting for Battery PIC Flash\n");
5103 return (0);
5108 /* Clear the interrupt bit */
5109 Isr = (uint32_t) IPS_BIT_I960_MSG0I;
5110 writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR);
5112 if (Post < (IPS_GOOD_POST_STATUS << 8)) {
5113 IPS_PRINTK(KERN_WARNING, ha->pcidev,
5114 "reset controller fails (post status %x).\n", Post);
5116 return (0);
5119 /* Wait up to 240 secs for config bytes */
5120 for (i = 0; i < 240; i++) {
5121 Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
5123 if (Isr & IPS_BIT_I960_MSG1I)
5124 break;
5126 /* Delay for 1 Second */
5127 MDELAY(IPS_ONE_SEC);
5130 if (i >= 240) {
5131 /* error occurred */
5132 IPS_PRINTK(KERN_WARNING, ha->pcidev,
5133 "timeout waiting for config.\n");
5135 return (0);
5138 Config = readl(ha->mem_ptr + IPS_REG_I960_MSG1);
5140 /* Clear interrupt bit */
5141 Isr = (uint32_t) IPS_BIT_I960_MSG1I;
5142 writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR);
5144 /* Turn on the interrupts */
5145 Oimr = readl(ha->mem_ptr + IPS_REG_I960_OIMR);
5146 Oimr &= ~0x8;
5147 writel(Oimr, ha->mem_ptr + IPS_REG_I960_OIMR);
5149 /* if we get here then everything went OK */
5151 /* Since we did a RESET, an EraseStripeLock may be needed */
5152 if (Post == 0xEF10) {
5153 if ((Config == 0x000F) || (Config == 0x0009))
5154 ha->requires_esl = 1;
5157 return (1);
5160 /****************************************************************************/
5161 /* */
5162 /* Routine Name: ips_reset_copperhead */
5163 /* */
5164 /* Routine Description: */
5165 /* */
5166 /* Reset the controller */
5167 /* */
5168 /****************************************************************************/
5169 static int
5170 ips_reset_copperhead(ips_ha_t * ha)
5172 int reset_counter;
5174 METHOD_TRACE("ips_reset_copperhead", 1);
5176 DEBUG_VAR(1, "(%s%d) ips_reset_copperhead: io addr: %x, irq: %d",
5177 ips_name, ha->host_num, ha->io_addr, ha->irq);
5179 reset_counter = 0;
5181 while (reset_counter < 2) {
5182 reset_counter++;
5184 outb(IPS_BIT_RST, ha->io_addr + IPS_REG_SCPR);
5186 /* Delay for 1 Second */
5187 MDELAY(IPS_ONE_SEC);
5189 outb(0, ha->io_addr + IPS_REG_SCPR);
5191 /* Delay for 1 Second */
5192 MDELAY(IPS_ONE_SEC);
5194 if ((*ha->func.init) (ha))
5195 break;
5196 else if (reset_counter >= 2) {
5198 return (0);
5202 return (1);
5205 /****************************************************************************/
5206 /* */
5207 /* Routine Name: ips_reset_copperhead_memio */
5208 /* */
5209 /* Routine Description: */
5210 /* */
5211 /* Reset the controller */
5212 /* */
5213 /****************************************************************************/
5214 static int
5215 ips_reset_copperhead_memio(ips_ha_t * ha)
5217 int reset_counter;
5219 METHOD_TRACE("ips_reset_copperhead_memio", 1);
5221 DEBUG_VAR(1, "(%s%d) ips_reset_copperhead_memio: mem addr: %x, irq: %d",
5222 ips_name, ha->host_num, ha->mem_addr, ha->irq);
5224 reset_counter = 0;
5226 while (reset_counter < 2) {
5227 reset_counter++;
5229 writeb(IPS_BIT_RST, ha->mem_ptr + IPS_REG_SCPR);
5231 /* Delay for 1 Second */
5232 MDELAY(IPS_ONE_SEC);
5234 writeb(0, ha->mem_ptr + IPS_REG_SCPR);
5236 /* Delay for 1 Second */
5237 MDELAY(IPS_ONE_SEC);
5239 if ((*ha->func.init) (ha))
5240 break;
5241 else if (reset_counter >= 2) {
5243 return (0);
5247 return (1);
5250 /****************************************************************************/
5251 /* */
5252 /* Routine Name: ips_reset_morpheus */
5253 /* */
5254 /* Routine Description: */
5255 /* */
5256 /* Reset the controller */
5257 /* */
5258 /****************************************************************************/
5259 static int
5260 ips_reset_morpheus(ips_ha_t * ha)
5262 int reset_counter;
5263 uint8_t junk;
5265 METHOD_TRACE("ips_reset_morpheus", 1);
5267 DEBUG_VAR(1, "(%s%d) ips_reset_morpheus: mem addr: %x, irq: %d",
5268 ips_name, ha->host_num, ha->mem_addr, ha->irq);
5270 reset_counter = 0;
5272 while (reset_counter < 2) {
5273 reset_counter++;
5275 writel(0x80000000, ha->mem_ptr + IPS_REG_I960_IDR);
5277 /* Delay for 5 Seconds */
5278 MDELAY(5 * IPS_ONE_SEC);
5280 /* Do a PCI config read to wait for adapter */
5281 pci_read_config_byte(ha->pcidev, 4, &junk);
5283 if ((*ha->func.init) (ha))
5284 break;
5285 else if (reset_counter >= 2) {
5287 return (0);
5291 return (1);
5294 /****************************************************************************/
5295 /* */
5296 /* Routine Name: ips_statinit */
5297 /* */
5298 /* Routine Description: */
5299 /* */
5300 /* Initialize the status queues on the controller */
5301 /* */
5302 /****************************************************************************/
5303 static void
5304 ips_statinit(ips_ha_t * ha)
5306 uint32_t phys_status_start;
5308 METHOD_TRACE("ips_statinit", 1);
5310 ha->adapt->p_status_start = ha->adapt->status;
5311 ha->adapt->p_status_end = ha->adapt->status + IPS_MAX_CMDS;
5312 ha->adapt->p_status_tail = ha->adapt->status;
5314 phys_status_start = ha->adapt->hw_status_start;
5315 outl(cpu_to_le32(phys_status_start), ha->io_addr + IPS_REG_SQSR);
5316 outl(cpu_to_le32(phys_status_start + IPS_STATUS_Q_SIZE),
5317 ha->io_addr + IPS_REG_SQER);
5318 outl(cpu_to_le32(phys_status_start + IPS_STATUS_SIZE),
5319 ha->io_addr + IPS_REG_SQHR);
5320 outl(cpu_to_le32(phys_status_start), ha->io_addr + IPS_REG_SQTR);
5322 ha->adapt->hw_status_tail = phys_status_start;
5325 /****************************************************************************/
5326 /* */
5327 /* Routine Name: ips_statinit_memio */
5328 /* */
5329 /* Routine Description: */
5330 /* */
5331 /* Initialize the status queues on the controller */
5332 /* */
5333 /****************************************************************************/
5334 static void
5335 ips_statinit_memio(ips_ha_t * ha)
5337 uint32_t phys_status_start;
5339 METHOD_TRACE("ips_statinit_memio", 1);
5341 ha->adapt->p_status_start = ha->adapt->status;
5342 ha->adapt->p_status_end = ha->adapt->status + IPS_MAX_CMDS;
5343 ha->adapt->p_status_tail = ha->adapt->status;
5345 phys_status_start = ha->adapt->hw_status_start;
5346 writel(phys_status_start, ha->mem_ptr + IPS_REG_SQSR);
5347 writel(phys_status_start + IPS_STATUS_Q_SIZE,
5348 ha->mem_ptr + IPS_REG_SQER);
5349 writel(phys_status_start + IPS_STATUS_SIZE, ha->mem_ptr + IPS_REG_SQHR);
5350 writel(phys_status_start, ha->mem_ptr + IPS_REG_SQTR);
5352 ha->adapt->hw_status_tail = phys_status_start;
5355 /****************************************************************************/
5356 /* */
5357 /* Routine Name: ips_statupd_copperhead */
5358 /* */
5359 /* Routine Description: */
5360 /* */
5361 /* Remove an element from the status queue */
5362 /* */
5363 /****************************************************************************/
5364 static uint32_t
5365 ips_statupd_copperhead(ips_ha_t * ha)
5367 METHOD_TRACE("ips_statupd_copperhead", 1);
5369 if (ha->adapt->p_status_tail != ha->adapt->p_status_end) {
5370 ha->adapt->p_status_tail++;
5371 ha->adapt->hw_status_tail += sizeof (IPS_STATUS);
5372 } else {
5373 ha->adapt->p_status_tail = ha->adapt->p_status_start;
5374 ha->adapt->hw_status_tail = ha->adapt->hw_status_start;
5377 outl(cpu_to_le32(ha->adapt->hw_status_tail),
5378 ha->io_addr + IPS_REG_SQTR);
5380 return (ha->adapt->p_status_tail->value);
5383 /****************************************************************************/
5384 /* */
5385 /* Routine Name: ips_statupd_copperhead_memio */
5386 /* */
5387 /* Routine Description: */
5388 /* */
5389 /* Remove an element from the status queue */
5390 /* */
5391 /****************************************************************************/
5392 static uint32_t
5393 ips_statupd_copperhead_memio(ips_ha_t * ha)
5395 METHOD_TRACE("ips_statupd_copperhead_memio", 1);
5397 if (ha->adapt->p_status_tail != ha->adapt->p_status_end) {
5398 ha->adapt->p_status_tail++;
5399 ha->adapt->hw_status_tail += sizeof (IPS_STATUS);
5400 } else {
5401 ha->adapt->p_status_tail = ha->adapt->p_status_start;
5402 ha->adapt->hw_status_tail = ha->adapt->hw_status_start;
5405 writel(ha->adapt->hw_status_tail, ha->mem_ptr + IPS_REG_SQTR);
5407 return (ha->adapt->p_status_tail->value);
5410 /****************************************************************************/
5411 /* */
5412 /* Routine Name: ips_statupd_morpheus */
5413 /* */
5414 /* Routine Description: */
5415 /* */
5416 /* Remove an element from the status queue */
5417 /* */
5418 /****************************************************************************/
5419 static uint32_t
5420 ips_statupd_morpheus(ips_ha_t * ha)
5422 uint32_t val;
5424 METHOD_TRACE("ips_statupd_morpheus", 1);
5426 val = readl(ha->mem_ptr + IPS_REG_I2O_OUTMSGQ);
5428 return (val);
5431 /****************************************************************************/
5432 /* */
5433 /* Routine Name: ips_issue_copperhead */
5434 /* */
5435 /* Routine Description: */
5436 /* */
5437 /* Send a command down to the controller */
5438 /* */
5439 /****************************************************************************/
5440 static int
5441 ips_issue_copperhead(ips_ha_t * ha, ips_scb_t * scb)
5443 uint32_t TimeOut;
5444 uint32_t val;
5446 METHOD_TRACE("ips_issue_copperhead", 1);
5448 if (scb->scsi_cmd) {
5449 DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)",
5450 ips_name,
5451 ha->host_num,
5452 scb->cdb[0],
5453 scb->cmd.basic_io.command_id,
5454 scb->bus, scb->target_id, scb->lun);
5455 } else {
5456 DEBUG_VAR(2, KERN_NOTICE "(%s%d) ips_issue: logical cmd id %d",
5457 ips_name, ha->host_num, scb->cmd.basic_io.command_id);
5460 TimeOut = 0;
5462 while ((val =
5463 le32_to_cpu(inl(ha->io_addr + IPS_REG_CCCR))) & IPS_BIT_SEM) {
5464 udelay(1000);
5466 if (++TimeOut >= IPS_SEM_TIMEOUT) {
5467 if (!(val & IPS_BIT_START_STOP))
5468 break;
5470 IPS_PRINTK(KERN_WARNING, ha->pcidev,
5471 "ips_issue val [0x%x].\n", val);
5472 IPS_PRINTK(KERN_WARNING, ha->pcidev,
5473 "ips_issue semaphore chk timeout.\n");
5475 return (IPS_FAILURE);
5476 } /* end if */
5477 } /* end while */
5479 outl(cpu_to_le32(scb->scb_busaddr), ha->io_addr + IPS_REG_CCSAR);
5480 outw(cpu_to_le32(IPS_BIT_START_CMD), ha->io_addr + IPS_REG_CCCR);
5482 return (IPS_SUCCESS);
5485 /****************************************************************************/
5486 /* */
5487 /* Routine Name: ips_issue_copperhead_memio */
5488 /* */
5489 /* Routine Description: */
5490 /* */
5491 /* Send a command down to the controller */
5492 /* */
5493 /****************************************************************************/
5494 static int
5495 ips_issue_copperhead_memio(ips_ha_t * ha, ips_scb_t * scb)
5497 uint32_t TimeOut;
5498 uint32_t val;
5500 METHOD_TRACE("ips_issue_copperhead_memio", 1);
5502 if (scb->scsi_cmd) {
5503 DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)",
5504 ips_name,
5505 ha->host_num,
5506 scb->cdb[0],
5507 scb->cmd.basic_io.command_id,
5508 scb->bus, scb->target_id, scb->lun);
5509 } else {
5510 DEBUG_VAR(2, "(%s%d) ips_issue: logical cmd id %d",
5511 ips_name, ha->host_num, scb->cmd.basic_io.command_id);
5514 TimeOut = 0;
5516 while ((val = readl(ha->mem_ptr + IPS_REG_CCCR)) & IPS_BIT_SEM) {
5517 udelay(1000);
5519 if (++TimeOut >= IPS_SEM_TIMEOUT) {
5520 if (!(val & IPS_BIT_START_STOP))
5521 break;
5523 IPS_PRINTK(KERN_WARNING, ha->pcidev,
5524 "ips_issue val [0x%x].\n", val);
5525 IPS_PRINTK(KERN_WARNING, ha->pcidev,
5526 "ips_issue semaphore chk timeout.\n");
5528 return (IPS_FAILURE);
5529 } /* end if */
5530 } /* end while */
5532 writel(scb->scb_busaddr, ha->mem_ptr + IPS_REG_CCSAR);
5533 writel(IPS_BIT_START_CMD, ha->mem_ptr + IPS_REG_CCCR);
5535 return (IPS_SUCCESS);
5538 /****************************************************************************/
5539 /* */
5540 /* Routine Name: ips_issue_i2o */
5541 /* */
5542 /* Routine Description: */
5543 /* */
5544 /* Send a command down to the controller */
5545 /* */
5546 /****************************************************************************/
5547 static int
5548 ips_issue_i2o(ips_ha_t * ha, ips_scb_t * scb)
5551 METHOD_TRACE("ips_issue_i2o", 1);
5553 if (scb->scsi_cmd) {
5554 DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)",
5555 ips_name,
5556 ha->host_num,
5557 scb->cdb[0],
5558 scb->cmd.basic_io.command_id,
5559 scb->bus, scb->target_id, scb->lun);
5560 } else {
5561 DEBUG_VAR(2, "(%s%d) ips_issue: logical cmd id %d",
5562 ips_name, ha->host_num, scb->cmd.basic_io.command_id);
5565 outl(cpu_to_le32(scb->scb_busaddr), ha->io_addr + IPS_REG_I2O_INMSGQ);
5567 return (IPS_SUCCESS);
5570 /****************************************************************************/
5571 /* */
5572 /* Routine Name: ips_issue_i2o_memio */
5573 /* */
5574 /* Routine Description: */
5575 /* */
5576 /* Send a command down to the controller */
5577 /* */
5578 /****************************************************************************/
5579 static int
5580 ips_issue_i2o_memio(ips_ha_t * ha, ips_scb_t * scb)
5583 METHOD_TRACE("ips_issue_i2o_memio", 1);
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, "(%s%d) ips_issue: logical cmd id %d",
5594 ips_name, ha->host_num, scb->cmd.basic_io.command_id);
5597 writel(scb->scb_busaddr, ha->mem_ptr + IPS_REG_I2O_INMSGQ);
5599 return (IPS_SUCCESS);
5602 /****************************************************************************/
5603 /* */
5604 /* Routine Name: ips_isintr_copperhead */
5605 /* */
5606 /* Routine Description: */
5607 /* */
5608 /* Test to see if an interrupt is for us */
5609 /* */
5610 /****************************************************************************/
5611 static int
5612 ips_isintr_copperhead(ips_ha_t * ha)
5614 uint8_t Isr;
5616 METHOD_TRACE("ips_isintr_copperhead", 2);
5618 Isr = inb(ha->io_addr + IPS_REG_HISR);
5620 if (Isr == 0xFF)
5621 /* ?!?! Nothing really there */
5622 return (0);
5624 if (Isr & IPS_BIT_SCE)
5625 return (1);
5626 else if (Isr & (IPS_BIT_SQO | IPS_BIT_GHI)) {
5627 /* status queue overflow or GHI */
5628 /* just clear the interrupt */
5629 outb(Isr, ha->io_addr + IPS_REG_HISR);
5632 return (0);
5635 /****************************************************************************/
5636 /* */
5637 /* Routine Name: ips_isintr_copperhead_memio */
5638 /* */
5639 /* Routine Description: */
5640 /* */
5641 /* Test to see if an interrupt is for us */
5642 /* */
5643 /****************************************************************************/
5644 static int
5645 ips_isintr_copperhead_memio(ips_ha_t * ha)
5647 uint8_t Isr;
5649 METHOD_TRACE("ips_isintr_memio", 2);
5651 Isr = readb(ha->mem_ptr + IPS_REG_HISR);
5653 if (Isr == 0xFF)
5654 /* ?!?! Nothing really there */
5655 return (0);
5657 if (Isr & IPS_BIT_SCE)
5658 return (1);
5659 else if (Isr & (IPS_BIT_SQO | IPS_BIT_GHI)) {
5660 /* status queue overflow or GHI */
5661 /* just clear the interrupt */
5662 writeb(Isr, ha->mem_ptr + IPS_REG_HISR);
5665 return (0);
5668 /****************************************************************************/
5669 /* */
5670 /* Routine Name: ips_isintr_morpheus */
5671 /* */
5672 /* Routine Description: */
5673 /* */
5674 /* Test to see if an interrupt is for us */
5675 /* */
5676 /****************************************************************************/
5677 static int
5678 ips_isintr_morpheus(ips_ha_t * ha)
5680 uint32_t Isr;
5682 METHOD_TRACE("ips_isintr_morpheus", 2);
5684 Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
5686 if (Isr & IPS_BIT_I2O_OPQI)
5687 return (1);
5688 else
5689 return (0);
5692 /****************************************************************************/
5693 /* */
5694 /* Routine Name: ips_wait */
5695 /* */
5696 /* Routine Description: */
5697 /* */
5698 /* Wait for a command to complete */
5699 /* */
5700 /****************************************************************************/
5701 static int
5702 ips_wait(ips_ha_t * ha, int time, int intr)
5704 int ret;
5705 int done;
5707 METHOD_TRACE("ips_wait", 1);
5709 ret = IPS_FAILURE;
5710 done = FALSE;
5712 time *= IPS_ONE_SEC; /* convert seconds */
5714 while ((time > 0) && (!done)) {
5715 if (intr == IPS_INTR_ON) {
5716 if (ha->waitflag == FALSE) {
5717 ret = IPS_SUCCESS;
5718 done = TRUE;
5719 break;
5721 } else if (intr == IPS_INTR_IORL) {
5722 if (ha->waitflag == FALSE) {
5724 * controller generated an interrupt to
5725 * acknowledge completion of the command
5726 * and ips_intr() has serviced the interrupt.
5728 ret = IPS_SUCCESS;
5729 done = TRUE;
5730 break;
5734 * NOTE: we already have the io_request_lock so
5735 * even if we get an interrupt it won't get serviced
5736 * until after we finish.
5739 (*ha->func.intr) (ha);
5742 /* This looks like a very evil loop, but it only does this during start-up */
5743 udelay(1000);
5744 time--;
5747 return (ret);
5750 /****************************************************************************/
5751 /* */
5752 /* Routine Name: ips_write_driver_status */
5753 /* */
5754 /* Routine Description: */
5755 /* */
5756 /* Write OS/Driver version to Page 5 of the nvram on the controller */
5757 /* */
5758 /****************************************************************************/
5759 static int
5760 ips_write_driver_status(ips_ha_t * ha, int intr)
5762 METHOD_TRACE("ips_write_driver_status", 1);
5764 if (!ips_readwrite_page5(ha, FALSE, intr)) {
5765 IPS_PRINTK(KERN_WARNING, ha->pcidev,
5766 "unable to read NVRAM page 5.\n");
5768 return (0);
5771 /* check to make sure the page has a valid */
5772 /* signature */
5773 if (le32_to_cpu(ha->nvram->signature) != IPS_NVRAM_P5_SIG) {
5774 DEBUG_VAR(1,
5775 "(%s%d) NVRAM page 5 has an invalid signature: %X.",
5776 ips_name, ha->host_num, ha->nvram->signature);
5777 ha->nvram->signature = IPS_NVRAM_P5_SIG;
5780 DEBUG_VAR(2,
5781 "(%s%d) Ad Type: %d, Ad Slot: %d, BIOS: %c%c%c%c %c%c%c%c.",
5782 ips_name, ha->host_num, le16_to_cpu(ha->nvram->adapter_type),
5783 ha->nvram->adapter_slot, ha->nvram->bios_high[0],
5784 ha->nvram->bios_high[1], ha->nvram->bios_high[2],
5785 ha->nvram->bios_high[3], ha->nvram->bios_low[0],
5786 ha->nvram->bios_low[1], ha->nvram->bios_low[2],
5787 ha->nvram->bios_low[3]);
5789 ips_get_bios_version(ha, intr);
5791 /* change values (as needed) */
5792 ha->nvram->operating_system = IPS_OS_LINUX;
5793 ha->nvram->adapter_type = ha->ad_type;
5794 strncpy((char *) ha->nvram->driver_high, IPS_VERSION_HIGH, 4);
5795 strncpy((char *) ha->nvram->driver_low, IPS_VERSION_LOW, 4);
5796 strncpy((char *) ha->nvram->bios_high, ha->bios_version, 4);
5797 strncpy((char *) ha->nvram->bios_low, ha->bios_version + 4, 4);
5799 ips_version_check(ha, intr); /* Check BIOS/FW/Driver Versions */
5801 /* now update the page */
5802 if (!ips_readwrite_page5(ha, TRUE, intr)) {
5803 IPS_PRINTK(KERN_WARNING, ha->pcidev,
5804 "unable to write NVRAM page 5.\n");
5806 return (0);
5809 /* IF NVRAM Page 5 is OK, Use it for Slot Number Info Because Linux Doesn't Do Slots */
5810 ha->slot_num = ha->nvram->adapter_slot;
5812 return (1);
5815 /****************************************************************************/
5816 /* */
5817 /* Routine Name: ips_read_adapter_status */
5818 /* */
5819 /* Routine Description: */
5820 /* */
5821 /* Do an Inquiry command to the adapter */
5822 /* */
5823 /****************************************************************************/
5824 static int
5825 ips_read_adapter_status(ips_ha_t * ha, int intr)
5827 ips_scb_t *scb;
5828 int ret;
5830 METHOD_TRACE("ips_read_adapter_status", 1);
5832 scb = &ha->scbs[ha->max_cmds - 1];
5834 ips_init_scb(ha, scb);
5836 scb->timeout = ips_cmd_timeout;
5837 scb->cdb[0] = IPS_CMD_ENQUIRY;
5839 scb->cmd.basic_io.op_code = IPS_CMD_ENQUIRY;
5840 scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
5841 scb->cmd.basic_io.sg_count = 0;
5842 scb->cmd.basic_io.lba = 0;
5843 scb->cmd.basic_io.sector_count = 0;
5844 scb->cmd.basic_io.log_drv = 0;
5845 scb->data_len = sizeof (*ha->enq);
5846 scb->cmd.basic_io.sg_addr = ha->enq_busaddr;
5848 /* send command */
5849 if (((ret =
5850 ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE)
5851 || (ret == IPS_SUCCESS_IMM)
5852 || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1))
5853 return (0);
5855 return (1);
5858 /****************************************************************************/
5859 /* */
5860 /* Routine Name: ips_read_subsystem_parameters */
5861 /* */
5862 /* Routine Description: */
5863 /* */
5864 /* Read subsystem parameters from the adapter */
5865 /* */
5866 /****************************************************************************/
5867 static int
5868 ips_read_subsystem_parameters(ips_ha_t * ha, int intr)
5870 ips_scb_t *scb;
5871 int ret;
5873 METHOD_TRACE("ips_read_subsystem_parameters", 1);
5875 scb = &ha->scbs[ha->max_cmds - 1];
5877 ips_init_scb(ha, scb);
5879 scb->timeout = ips_cmd_timeout;
5880 scb->cdb[0] = IPS_CMD_GET_SUBSYS;
5882 scb->cmd.basic_io.op_code = IPS_CMD_GET_SUBSYS;
5883 scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
5884 scb->cmd.basic_io.sg_count = 0;
5885 scb->cmd.basic_io.lba = 0;
5886 scb->cmd.basic_io.sector_count = 0;
5887 scb->cmd.basic_io.log_drv = 0;
5888 scb->data_len = sizeof (*ha->subsys);
5889 scb->cmd.basic_io.sg_addr = ha->ioctl_busaddr;
5891 /* send command */
5892 if (((ret =
5893 ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE)
5894 || (ret == IPS_SUCCESS_IMM)
5895 || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1))
5896 return (0);
5898 memcpy(ha->subsys, ha->ioctl_data, sizeof(*ha->subsys));
5899 return (1);
5902 /****************************************************************************/
5903 /* */
5904 /* Routine Name: ips_read_config */
5905 /* */
5906 /* Routine Description: */
5907 /* */
5908 /* Read the configuration on the adapter */
5909 /* */
5910 /****************************************************************************/
5911 static int
5912 ips_read_config(ips_ha_t * ha, int intr)
5914 ips_scb_t *scb;
5915 int i;
5916 int ret;
5918 METHOD_TRACE("ips_read_config", 1);
5920 /* set defaults for initiator IDs */
5921 for (i = 0; i < 4; i++)
5922 ha->conf->init_id[i] = 7;
5924 scb = &ha->scbs[ha->max_cmds - 1];
5926 ips_init_scb(ha, scb);
5928 scb->timeout = ips_cmd_timeout;
5929 scb->cdb[0] = IPS_CMD_READ_CONF;
5931 scb->cmd.basic_io.op_code = IPS_CMD_READ_CONF;
5932 scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
5933 scb->data_len = sizeof (*ha->conf);
5934 scb->cmd.basic_io.sg_addr = ha->ioctl_busaddr;
5936 /* send command */
5937 if (((ret =
5938 ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE)
5939 || (ret == IPS_SUCCESS_IMM)
5940 || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) {
5942 memset(ha->conf, 0, sizeof (IPS_CONF));
5944 /* reset initiator IDs */
5945 for (i = 0; i < 4; i++)
5946 ha->conf->init_id[i] = 7;
5948 /* Allow Completed with Errors, so JCRM can access the Adapter to fix the problems */
5949 if ((scb->basic_status & IPS_GSC_STATUS_MASK) ==
5950 IPS_CMD_CMPLT_WERROR)
5951 return (1);
5953 return (0);
5956 memcpy(ha->conf, ha->ioctl_data, sizeof(*ha->conf));
5957 return (1);
5960 /****************************************************************************/
5961 /* */
5962 /* Routine Name: ips_readwrite_page5 */
5963 /* */
5964 /* Routine Description: */
5965 /* */
5966 /* Read nvram page 5 from the adapter */
5967 /* */
5968 /****************************************************************************/
5969 static int
5970 ips_readwrite_page5(ips_ha_t * ha, int write, int intr)
5972 ips_scb_t *scb;
5973 int ret;
5975 METHOD_TRACE("ips_readwrite_page5", 1);
5977 scb = &ha->scbs[ha->max_cmds - 1];
5979 ips_init_scb(ha, scb);
5981 scb->timeout = ips_cmd_timeout;
5982 scb->cdb[0] = IPS_CMD_RW_NVRAM_PAGE;
5984 scb->cmd.nvram.op_code = IPS_CMD_RW_NVRAM_PAGE;
5985 scb->cmd.nvram.command_id = IPS_COMMAND_ID(ha, scb);
5986 scb->cmd.nvram.page = 5;
5987 scb->cmd.nvram.write = write;
5988 scb->cmd.nvram.reserved = 0;
5989 scb->cmd.nvram.reserved2 = 0;
5990 scb->data_len = sizeof (*ha->nvram);
5991 scb->cmd.nvram.buffer_addr = ha->ioctl_busaddr;
5992 if (write)
5993 memcpy(ha->ioctl_data, ha->nvram, sizeof(*ha->nvram));
5995 /* issue the command */
5996 if (((ret =
5997 ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE)
5998 || (ret == IPS_SUCCESS_IMM)
5999 || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) {
6001 memset(ha->nvram, 0, sizeof (IPS_NVRAM_P5));
6003 return (0);
6005 if (!write)
6006 memcpy(ha->nvram, ha->ioctl_data, sizeof(*ha->nvram));
6007 return (1);
6010 /****************************************************************************/
6011 /* */
6012 /* Routine Name: ips_clear_adapter */
6013 /* */
6014 /* Routine Description: */
6015 /* */
6016 /* Clear the stripe lock tables */
6017 /* */
6018 /****************************************************************************/
6019 static int
6020 ips_clear_adapter(ips_ha_t * ha, int intr)
6022 ips_scb_t *scb;
6023 int ret;
6025 METHOD_TRACE("ips_clear_adapter", 1);
6027 scb = &ha->scbs[ha->max_cmds - 1];
6029 ips_init_scb(ha, scb);
6031 scb->timeout = ips_reset_timeout;
6032 scb->cdb[0] = IPS_CMD_CONFIG_SYNC;
6034 scb->cmd.config_sync.op_code = IPS_CMD_CONFIG_SYNC;
6035 scb->cmd.config_sync.command_id = IPS_COMMAND_ID(ha, scb);
6036 scb->cmd.config_sync.channel = 0;
6037 scb->cmd.config_sync.source_target = IPS_POCL;
6038 scb->cmd.config_sync.reserved = 0;
6039 scb->cmd.config_sync.reserved2 = 0;
6040 scb->cmd.config_sync.reserved3 = 0;
6042 /* issue command */
6043 if (((ret =
6044 ips_send_wait(ha, scb, ips_reset_timeout, intr)) == IPS_FAILURE)
6045 || (ret == IPS_SUCCESS_IMM)
6046 || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1))
6047 return (0);
6049 /* send unlock stripe command */
6050 ips_init_scb(ha, scb);
6052 scb->cdb[0] = IPS_CMD_ERROR_TABLE;
6053 scb->timeout = ips_reset_timeout;
6055 scb->cmd.unlock_stripe.op_code = IPS_CMD_ERROR_TABLE;
6056 scb->cmd.unlock_stripe.command_id = IPS_COMMAND_ID(ha, scb);
6057 scb->cmd.unlock_stripe.log_drv = 0;
6058 scb->cmd.unlock_stripe.control = IPS_CSL;
6059 scb->cmd.unlock_stripe.reserved = 0;
6060 scb->cmd.unlock_stripe.reserved2 = 0;
6061 scb->cmd.unlock_stripe.reserved3 = 0;
6063 /* issue command */
6064 if (((ret =
6065 ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE)
6066 || (ret == IPS_SUCCESS_IMM)
6067 || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1))
6068 return (0);
6070 return (1);
6073 /****************************************************************************/
6074 /* */
6075 /* Routine Name: ips_ffdc_reset */
6076 /* */
6077 /* Routine Description: */
6078 /* */
6079 /* FFDC: write reset info */
6080 /* */
6081 /****************************************************************************/
6082 static void
6083 ips_ffdc_reset(ips_ha_t * ha, int intr)
6085 ips_scb_t *scb;
6087 METHOD_TRACE("ips_ffdc_reset", 1);
6089 scb = &ha->scbs[ha->max_cmds - 1];
6091 ips_init_scb(ha, scb);
6093 scb->timeout = ips_cmd_timeout;
6094 scb->cdb[0] = IPS_CMD_FFDC;
6095 scb->cmd.ffdc.op_code = IPS_CMD_FFDC;
6096 scb->cmd.ffdc.command_id = IPS_COMMAND_ID(ha, scb);
6097 scb->cmd.ffdc.reset_count = ha->reset_count;
6098 scb->cmd.ffdc.reset_type = 0x80;
6100 /* convert time to what the card wants */
6101 ips_fix_ffdc_time(ha, scb, ha->last_ffdc);
6103 /* issue command */
6104 ips_send_wait(ha, scb, ips_cmd_timeout, intr);
6107 /****************************************************************************/
6108 /* */
6109 /* Routine Name: ips_ffdc_time */
6110 /* */
6111 /* Routine Description: */
6112 /* */
6113 /* FFDC: write time info */
6114 /* */
6115 /****************************************************************************/
6116 static void
6117 ips_ffdc_time(ips_ha_t * ha)
6119 ips_scb_t *scb;
6121 METHOD_TRACE("ips_ffdc_time", 1);
6123 DEBUG_VAR(1, "(%s%d) Sending time update.", ips_name, ha->host_num);
6125 scb = &ha->scbs[ha->max_cmds - 1];
6127 ips_init_scb(ha, scb);
6129 scb->timeout = ips_cmd_timeout;
6130 scb->cdb[0] = IPS_CMD_FFDC;
6131 scb->cmd.ffdc.op_code = IPS_CMD_FFDC;
6132 scb->cmd.ffdc.command_id = IPS_COMMAND_ID(ha, scb);
6133 scb->cmd.ffdc.reset_count = 0;
6134 scb->cmd.ffdc.reset_type = 0;
6136 /* convert time to what the card wants */
6137 ips_fix_ffdc_time(ha, scb, ha->last_ffdc);
6139 /* issue command */
6140 ips_send_wait(ha, scb, ips_cmd_timeout, IPS_FFDC);
6143 /****************************************************************************/
6144 /* */
6145 /* Routine Name: ips_fix_ffdc_time */
6146 /* */
6147 /* Routine Description: */
6148 /* Adjust time_t to what the card wants */
6149 /* */
6150 /****************************************************************************/
6151 static void
6152 ips_fix_ffdc_time(ips_ha_t * ha, ips_scb_t * scb, time_t current_time)
6154 long days;
6155 long rem;
6156 int i;
6157 int year;
6158 int yleap;
6159 int year_lengths[2] = { IPS_DAYS_NORMAL_YEAR, IPS_DAYS_LEAP_YEAR };
6160 int month_lengths[12][2] = { {31, 31},
6161 {28, 29},
6162 {31, 31},
6163 {30, 30},
6164 {31, 31},
6165 {30, 30},
6166 {31, 31},
6167 {31, 31},
6168 {30, 30},
6169 {31, 31},
6170 {30, 30},
6171 {31, 31}
6174 METHOD_TRACE("ips_fix_ffdc_time", 1);
6176 days = current_time / IPS_SECS_DAY;
6177 rem = current_time % IPS_SECS_DAY;
6179 scb->cmd.ffdc.hour = (rem / IPS_SECS_HOUR);
6180 rem = rem % IPS_SECS_HOUR;
6181 scb->cmd.ffdc.minute = (rem / IPS_SECS_MIN);
6182 scb->cmd.ffdc.second = (rem % IPS_SECS_MIN);
6184 year = IPS_EPOCH_YEAR;
6185 while (days < 0 || days >= year_lengths[yleap = IPS_IS_LEAP_YEAR(year)]) {
6186 int newy;
6188 newy = year + (days / IPS_DAYS_NORMAL_YEAR);
6189 if (days < 0)
6190 --newy;
6191 days -= (newy - year) * IPS_DAYS_NORMAL_YEAR +
6192 IPS_NUM_LEAP_YEARS_THROUGH(newy - 1) -
6193 IPS_NUM_LEAP_YEARS_THROUGH(year - 1);
6194 year = newy;
6197 scb->cmd.ffdc.yearH = year / 100;
6198 scb->cmd.ffdc.yearL = year % 100;
6200 for (i = 0; days >= month_lengths[i][yleap]; ++i)
6201 days -= month_lengths[i][yleap];
6203 scb->cmd.ffdc.month = i + 1;
6204 scb->cmd.ffdc.day = days + 1;
6207 /****************************************************************************
6208 * BIOS Flash Routines *
6209 ****************************************************************************/
6211 /****************************************************************************/
6212 /* */
6213 /* Routine Name: ips_erase_bios */
6214 /* */
6215 /* Routine Description: */
6216 /* Erase the BIOS on the adapter */
6217 /* */
6218 /****************************************************************************/
6219 static int
6220 ips_erase_bios(ips_ha_t * ha)
6222 int timeout;
6223 uint8_t status = 0;
6225 METHOD_TRACE("ips_erase_bios", 1);
6227 status = 0;
6229 /* Clear the status register */
6230 outl(0, ha->io_addr + IPS_REG_FLAP);
6231 if (ha->revision_id == IPS_REVID_TROMBONE64)
6232 udelay(25); /* 25 us */
6234 outb(0x50, ha->io_addr + IPS_REG_FLDP);
6235 if (ha->revision_id == IPS_REVID_TROMBONE64)
6236 udelay(25); /* 25 us */
6238 /* Erase Setup */
6239 outb(0x20, ha->io_addr + IPS_REG_FLDP);
6240 if (ha->revision_id == IPS_REVID_TROMBONE64)
6241 udelay(25); /* 25 us */
6243 /* Erase Confirm */
6244 outb(0xD0, ha->io_addr + IPS_REG_FLDP);
6245 if (ha->revision_id == IPS_REVID_TROMBONE64)
6246 udelay(25); /* 25 us */
6248 /* Erase Status */
6249 outb(0x70, ha->io_addr + IPS_REG_FLDP);
6250 if (ha->revision_id == IPS_REVID_TROMBONE64)
6251 udelay(25); /* 25 us */
6253 timeout = 80000; /* 80 seconds */
6255 while (timeout > 0) {
6256 if (ha->revision_id == IPS_REVID_TROMBONE64) {
6257 outl(0, ha->io_addr + IPS_REG_FLAP);
6258 udelay(25); /* 25 us */
6261 status = inb(ha->io_addr + IPS_REG_FLDP);
6263 if (status & 0x80)
6264 break;
6266 MDELAY(1);
6267 timeout--;
6270 /* check for timeout */
6271 if (timeout <= 0) {
6272 /* timeout */
6274 /* try to suspend the erase */
6275 outb(0xB0, ha->io_addr + IPS_REG_FLDP);
6276 if (ha->revision_id == IPS_REVID_TROMBONE64)
6277 udelay(25); /* 25 us */
6279 /* wait for 10 seconds */
6280 timeout = 10000;
6281 while (timeout > 0) {
6282 if (ha->revision_id == IPS_REVID_TROMBONE64) {
6283 outl(0, ha->io_addr + IPS_REG_FLAP);
6284 udelay(25); /* 25 us */
6287 status = inb(ha->io_addr + IPS_REG_FLDP);
6289 if (status & 0xC0)
6290 break;
6292 MDELAY(1);
6293 timeout--;
6296 return (1);
6299 /* check for valid VPP */
6300 if (status & 0x08)
6301 /* VPP failure */
6302 return (1);
6304 /* check for succesful flash */
6305 if (status & 0x30)
6306 /* sequence error */
6307 return (1);
6309 /* Otherwise, we were successful */
6310 /* clear status */
6311 outb(0x50, ha->io_addr + IPS_REG_FLDP);
6312 if (ha->revision_id == IPS_REVID_TROMBONE64)
6313 udelay(25); /* 25 us */
6315 /* enable reads */
6316 outb(0xFF, ha->io_addr + IPS_REG_FLDP);
6317 if (ha->revision_id == IPS_REVID_TROMBONE64)
6318 udelay(25); /* 25 us */
6320 return (0);
6323 /****************************************************************************/
6324 /* */
6325 /* Routine Name: ips_erase_bios_memio */
6326 /* */
6327 /* Routine Description: */
6328 /* Erase the BIOS on the adapter */
6329 /* */
6330 /****************************************************************************/
6331 static int
6332 ips_erase_bios_memio(ips_ha_t * ha)
6334 int timeout;
6335 uint8_t status;
6337 METHOD_TRACE("ips_erase_bios_memio", 1);
6339 status = 0;
6341 /* Clear the status register */
6342 writel(0, ha->mem_ptr + IPS_REG_FLAP);
6343 if (ha->revision_id == IPS_REVID_TROMBONE64)
6344 udelay(25); /* 25 us */
6346 writeb(0x50, ha->mem_ptr + IPS_REG_FLDP);
6347 if (ha->revision_id == IPS_REVID_TROMBONE64)
6348 udelay(25); /* 25 us */
6350 /* Erase Setup */
6351 writeb(0x20, ha->mem_ptr + IPS_REG_FLDP);
6352 if (ha->revision_id == IPS_REVID_TROMBONE64)
6353 udelay(25); /* 25 us */
6355 /* Erase Confirm */
6356 writeb(0xD0, ha->mem_ptr + IPS_REG_FLDP);
6357 if (ha->revision_id == IPS_REVID_TROMBONE64)
6358 udelay(25); /* 25 us */
6360 /* Erase Status */
6361 writeb(0x70, ha->mem_ptr + IPS_REG_FLDP);
6362 if (ha->revision_id == IPS_REVID_TROMBONE64)
6363 udelay(25); /* 25 us */
6365 timeout = 80000; /* 80 seconds */
6367 while (timeout > 0) {
6368 if (ha->revision_id == IPS_REVID_TROMBONE64) {
6369 writel(0, ha->mem_ptr + IPS_REG_FLAP);
6370 udelay(25); /* 25 us */
6373 status = readb(ha->mem_ptr + IPS_REG_FLDP);
6375 if (status & 0x80)
6376 break;
6378 MDELAY(1);
6379 timeout--;
6382 /* check for timeout */
6383 if (timeout <= 0) {
6384 /* timeout */
6386 /* try to suspend the erase */
6387 writeb(0xB0, ha->mem_ptr + IPS_REG_FLDP);
6388 if (ha->revision_id == IPS_REVID_TROMBONE64)
6389 udelay(25); /* 25 us */
6391 /* wait for 10 seconds */
6392 timeout = 10000;
6393 while (timeout > 0) {
6394 if (ha->revision_id == IPS_REVID_TROMBONE64) {
6395 writel(0, ha->mem_ptr + IPS_REG_FLAP);
6396 udelay(25); /* 25 us */
6399 status = readb(ha->mem_ptr + IPS_REG_FLDP);
6401 if (status & 0xC0)
6402 break;
6404 MDELAY(1);
6405 timeout--;
6408 return (1);
6411 /* check for valid VPP */
6412 if (status & 0x08)
6413 /* VPP failure */
6414 return (1);
6416 /* check for succesful flash */
6417 if (status & 0x30)
6418 /* sequence error */
6419 return (1);
6421 /* Otherwise, we were successful */
6422 /* clear status */
6423 writeb(0x50, ha->mem_ptr + IPS_REG_FLDP);
6424 if (ha->revision_id == IPS_REVID_TROMBONE64)
6425 udelay(25); /* 25 us */
6427 /* enable reads */
6428 writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP);
6429 if (ha->revision_id == IPS_REVID_TROMBONE64)
6430 udelay(25); /* 25 us */
6432 return (0);
6435 /****************************************************************************/
6436 /* */
6437 /* Routine Name: ips_program_bios */
6438 /* */
6439 /* Routine Description: */
6440 /* Program the BIOS on the adapter */
6441 /* */
6442 /****************************************************************************/
6443 static int
6444 ips_program_bios(ips_ha_t * ha, char *buffer, uint32_t buffersize,
6445 uint32_t offset)
6447 int i;
6448 int timeout;
6449 uint8_t status = 0;
6451 METHOD_TRACE("ips_program_bios", 1);
6453 status = 0;
6455 for (i = 0; i < buffersize; i++) {
6456 /* write a byte */
6457 outl(cpu_to_le32(i + offset), ha->io_addr + IPS_REG_FLAP);
6458 if (ha->revision_id == IPS_REVID_TROMBONE64)
6459 udelay(25); /* 25 us */
6461 outb(0x40, ha->io_addr + IPS_REG_FLDP);
6462 if (ha->revision_id == IPS_REVID_TROMBONE64)
6463 udelay(25); /* 25 us */
6465 outb(buffer[i], ha->io_addr + IPS_REG_FLDP);
6466 if (ha->revision_id == IPS_REVID_TROMBONE64)
6467 udelay(25); /* 25 us */
6469 /* wait up to one second */
6470 timeout = 1000;
6471 while (timeout > 0) {
6472 if (ha->revision_id == IPS_REVID_TROMBONE64) {
6473 outl(0, ha->io_addr + IPS_REG_FLAP);
6474 udelay(25); /* 25 us */
6477 status = inb(ha->io_addr + IPS_REG_FLDP);
6479 if (status & 0x80)
6480 break;
6482 MDELAY(1);
6483 timeout--;
6486 if (timeout == 0) {
6487 /* timeout error */
6488 outl(0, ha->io_addr + IPS_REG_FLAP);
6489 if (ha->revision_id == IPS_REVID_TROMBONE64)
6490 udelay(25); /* 25 us */
6492 outb(0xFF, ha->io_addr + IPS_REG_FLDP);
6493 if (ha->revision_id == IPS_REVID_TROMBONE64)
6494 udelay(25); /* 25 us */
6496 return (1);
6499 /* check the status */
6500 if (status & 0x18) {
6501 /* programming error */
6502 outl(0, ha->io_addr + IPS_REG_FLAP);
6503 if (ha->revision_id == IPS_REVID_TROMBONE64)
6504 udelay(25); /* 25 us */
6506 outb(0xFF, ha->io_addr + IPS_REG_FLDP);
6507 if (ha->revision_id == IPS_REVID_TROMBONE64)
6508 udelay(25); /* 25 us */
6510 return (1);
6512 } /* end for */
6514 /* Enable reading */
6515 outl(0, ha->io_addr + IPS_REG_FLAP);
6516 if (ha->revision_id == IPS_REVID_TROMBONE64)
6517 udelay(25); /* 25 us */
6519 outb(0xFF, ha->io_addr + IPS_REG_FLDP);
6520 if (ha->revision_id == IPS_REVID_TROMBONE64)
6521 udelay(25); /* 25 us */
6523 return (0);
6526 /****************************************************************************/
6527 /* */
6528 /* Routine Name: ips_program_bios_memio */
6529 /* */
6530 /* Routine Description: */
6531 /* Program the BIOS on the adapter */
6532 /* */
6533 /****************************************************************************/
6534 static int
6535 ips_program_bios_memio(ips_ha_t * ha, char *buffer, uint32_t buffersize,
6536 uint32_t offset)
6538 int i;
6539 int timeout;
6540 uint8_t status = 0;
6542 METHOD_TRACE("ips_program_bios_memio", 1);
6544 status = 0;
6546 for (i = 0; i < buffersize; i++) {
6547 /* write a byte */
6548 writel(i + offset, ha->mem_ptr + IPS_REG_FLAP);
6549 if (ha->revision_id == IPS_REVID_TROMBONE64)
6550 udelay(25); /* 25 us */
6552 writeb(0x40, ha->mem_ptr + IPS_REG_FLDP);
6553 if (ha->revision_id == IPS_REVID_TROMBONE64)
6554 udelay(25); /* 25 us */
6556 writeb(buffer[i], ha->mem_ptr + IPS_REG_FLDP);
6557 if (ha->revision_id == IPS_REVID_TROMBONE64)
6558 udelay(25); /* 25 us */
6560 /* wait up to one second */
6561 timeout = 1000;
6562 while (timeout > 0) {
6563 if (ha->revision_id == IPS_REVID_TROMBONE64) {
6564 writel(0, ha->mem_ptr + IPS_REG_FLAP);
6565 udelay(25); /* 25 us */
6568 status = readb(ha->mem_ptr + IPS_REG_FLDP);
6570 if (status & 0x80)
6571 break;
6573 MDELAY(1);
6574 timeout--;
6577 if (timeout == 0) {
6578 /* timeout error */
6579 writel(0, ha->mem_ptr + IPS_REG_FLAP);
6580 if (ha->revision_id == IPS_REVID_TROMBONE64)
6581 udelay(25); /* 25 us */
6583 writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP);
6584 if (ha->revision_id == IPS_REVID_TROMBONE64)
6585 udelay(25); /* 25 us */
6587 return (1);
6590 /* check the status */
6591 if (status & 0x18) {
6592 /* programming error */
6593 writel(0, ha->mem_ptr + IPS_REG_FLAP);
6594 if (ha->revision_id == IPS_REVID_TROMBONE64)
6595 udelay(25); /* 25 us */
6597 writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP);
6598 if (ha->revision_id == IPS_REVID_TROMBONE64)
6599 udelay(25); /* 25 us */
6601 return (1);
6603 } /* end for */
6605 /* Enable reading */
6606 writel(0, ha->mem_ptr + IPS_REG_FLAP);
6607 if (ha->revision_id == IPS_REVID_TROMBONE64)
6608 udelay(25); /* 25 us */
6610 writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP);
6611 if (ha->revision_id == IPS_REVID_TROMBONE64)
6612 udelay(25); /* 25 us */
6614 return (0);
6617 /****************************************************************************/
6618 /* */
6619 /* Routine Name: ips_verify_bios */
6620 /* */
6621 /* Routine Description: */
6622 /* Verify the BIOS on the adapter */
6623 /* */
6624 /****************************************************************************/
6625 static int
6626 ips_verify_bios(ips_ha_t * ha, char *buffer, uint32_t buffersize,
6627 uint32_t offset)
6629 uint8_t checksum;
6630 int i;
6632 METHOD_TRACE("ips_verify_bios", 1);
6634 /* test 1st byte */
6635 outl(0, ha->io_addr + IPS_REG_FLAP);
6636 if (ha->revision_id == IPS_REVID_TROMBONE64)
6637 udelay(25); /* 25 us */
6639 if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55)
6640 return (1);
6642 outl(cpu_to_le32(1), ha->io_addr + IPS_REG_FLAP);
6643 if (ha->revision_id == IPS_REVID_TROMBONE64)
6644 udelay(25); /* 25 us */
6645 if (inb(ha->io_addr + IPS_REG_FLDP) != 0xAA)
6646 return (1);
6648 checksum = 0xff;
6649 for (i = 2; i < buffersize; i++) {
6651 outl(cpu_to_le32(i + offset), ha->io_addr + IPS_REG_FLAP);
6652 if (ha->revision_id == IPS_REVID_TROMBONE64)
6653 udelay(25); /* 25 us */
6655 checksum = (uint8_t) checksum + inb(ha->io_addr + IPS_REG_FLDP);
6658 if (checksum != 0)
6659 /* failure */
6660 return (1);
6661 else
6662 /* success */
6663 return (0);
6666 /****************************************************************************/
6667 /* */
6668 /* Routine Name: ips_verify_bios_memio */
6669 /* */
6670 /* Routine Description: */
6671 /* Verify the BIOS on the adapter */
6672 /* */
6673 /****************************************************************************/
6674 static int
6675 ips_verify_bios_memio(ips_ha_t * ha, char *buffer, uint32_t buffersize,
6676 uint32_t offset)
6678 uint8_t checksum;
6679 int i;
6681 METHOD_TRACE("ips_verify_bios_memio", 1);
6683 /* test 1st byte */
6684 writel(0, ha->mem_ptr + IPS_REG_FLAP);
6685 if (ha->revision_id == IPS_REVID_TROMBONE64)
6686 udelay(25); /* 25 us */
6688 if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0x55)
6689 return (1);
6691 writel(1, ha->mem_ptr + IPS_REG_FLAP);
6692 if (ha->revision_id == IPS_REVID_TROMBONE64)
6693 udelay(25); /* 25 us */
6694 if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0xAA)
6695 return (1);
6697 checksum = 0xff;
6698 for (i = 2; i < buffersize; i++) {
6700 writel(i + offset, ha->mem_ptr + IPS_REG_FLAP);
6701 if (ha->revision_id == IPS_REVID_TROMBONE64)
6702 udelay(25); /* 25 us */
6704 checksum =
6705 (uint8_t) checksum + readb(ha->mem_ptr + IPS_REG_FLDP);
6708 if (checksum != 0)
6709 /* failure */
6710 return (1);
6711 else
6712 /* success */
6713 return (0);
6716 /*---------------------------------------------------------------------------*/
6717 /* Routine Name: ips_version_check */
6718 /* */
6719 /* Dependencies: */
6720 /* Assumes that ips_read_adapter_status() is called first filling in */
6721 /* the data for SubSystem Parameters. */
6722 /* Called from ips_write_driver_status() so it also assumes NVRAM Page 5 */
6723 /* Data is available. */
6724 /* */
6725 /*---------------------------------------------------------------------------*/
6726 static void
6727 ips_version_check(ips_ha_t * ha, int intr)
6729 IPS_VERSION_DATA *VersionInfo;
6730 uint8_t FirmwareVersion[IPS_COMPAT_ID_LENGTH + 1];
6731 uint8_t BiosVersion[IPS_COMPAT_ID_LENGTH + 1];
6732 int MatchError;
6733 int rc;
6734 char BiosString[10];
6735 char FirmwareString[10];
6737 METHOD_TRACE("ips_version_check", 1);
6739 VersionInfo = ( IPS_VERSION_DATA * ) ha->ioctl_data;
6741 memset(FirmwareVersion, 0, IPS_COMPAT_ID_LENGTH + 1);
6742 memset(BiosVersion, 0, IPS_COMPAT_ID_LENGTH + 1);
6744 /* Get the Compatible BIOS Version from NVRAM Page 5 */
6745 memcpy(BiosVersion, ha->nvram->BiosCompatibilityID,
6746 IPS_COMPAT_ID_LENGTH);
6748 rc = IPS_FAILURE;
6749 if (ha->subsys->param[4] & IPS_GET_VERSION_SUPPORT) { /* If Versioning is Supported */
6750 /* Get the Version Info with a Get Version Command */
6751 memset( VersionInfo, 0, sizeof (IPS_VERSION_DATA));
6752 rc = ips_get_version_info(ha, ha->ioctl_busaddr, intr);
6753 if (rc == IPS_SUCCESS)
6754 memcpy(FirmwareVersion, VersionInfo->compatibilityId,
6755 IPS_COMPAT_ID_LENGTH);
6758 if (rc != IPS_SUCCESS) { /* If Data Not Obtainable from a GetVersion Command */
6759 /* Get the Firmware Version from Enquiry Data */
6760 memcpy(FirmwareVersion, ha->enq->CodeBlkVersion,
6761 IPS_COMPAT_ID_LENGTH);
6764 /* printk(KERN_WARNING "Adapter's BIOS Version = %s\n", BiosVersion); */
6765 /* printk(KERN_WARNING "BIOS Compatible Version = %s\n", IPS_COMPAT_BIOS); */
6766 /* printk(KERN_WARNING "Adapter's Firmware Version = %s\n", FirmwareVersion); */
6767 /* printk(KERN_WARNING "Firmware Compatible Version = %s \n", Compatable[ ha->nvram->adapter_type ]); */
6769 MatchError = 0;
6771 if (strncmp
6772 (FirmwareVersion, Compatable[ha->nvram->adapter_type],
6773 IPS_COMPAT_ID_LENGTH) != 0)
6774 MatchError = 1;
6776 if (strncmp(BiosVersion, IPS_COMPAT_BIOS, IPS_COMPAT_ID_LENGTH) != 0)
6777 MatchError = 1;
6779 ha->nvram->versioning = 1; /* Indicate the Driver Supports Versioning */
6781 if (MatchError) {
6782 ha->nvram->version_mismatch = 1;
6783 if (ips_cd_boot == 0) {
6784 strncpy(&BiosString[0], ha->nvram->bios_high, 4);
6785 strncpy(&BiosString[4], ha->nvram->bios_low, 4);
6786 BiosString[8] = 0;
6788 strncpy(&FirmwareString[0], ha->enq->CodeBlkVersion, 8);
6789 FirmwareString[8] = 0;
6791 IPS_PRINTK(KERN_WARNING, ha->pcidev,
6792 "Warning ! ! ! ServeRAID Version Mismatch\n");
6793 IPS_PRINTK(KERN_WARNING, ha->pcidev,
6794 "Bios = %s, Firmware = %s, Device Driver = %s%s\n",
6795 BiosString, FirmwareString, IPS_VERSION_HIGH,
6796 IPS_VERSION_LOW);
6797 IPS_PRINTK(KERN_WARNING, ha->pcidev,
6798 "These levels should match to avoid possible compatibility problems.\n");
6800 } else {
6801 ha->nvram->version_mismatch = 0;
6804 return;
6807 /*---------------------------------------------------------------------------*/
6808 /* Routine Name: ips_get_version_info */
6809 /* */
6810 /* Routine Description: */
6811 /* Issue an internal GETVERSION Command */
6812 /* */
6813 /* Return Value: */
6814 /* 0 if Successful, else non-zero */
6815 /*---------------------------------------------------------------------------*/
6816 static int
6817 ips_get_version_info(ips_ha_t * ha, dma_addr_t Buffer, int intr)
6819 ips_scb_t *scb;
6820 int rc;
6822 METHOD_TRACE("ips_get_version_info", 1);
6824 scb = &ha->scbs[ha->max_cmds - 1];
6826 ips_init_scb(ha, scb);
6828 scb->timeout = ips_cmd_timeout;
6829 scb->cdb[0] = IPS_CMD_GET_VERSION_INFO;
6830 scb->cmd.version_info.op_code = IPS_CMD_GET_VERSION_INFO;
6831 scb->cmd.version_info.command_id = IPS_COMMAND_ID(ha, scb);
6832 scb->cmd.version_info.reserved = 0;
6833 scb->cmd.version_info.count = sizeof (IPS_VERSION_DATA);
6834 scb->cmd.version_info.reserved2 = 0;
6835 scb->data_len = sizeof (IPS_VERSION_DATA);
6836 scb->data_busaddr = Buffer;
6837 scb->cmd.version_info.buffer_addr = Buffer;
6838 scb->flags = 0;
6840 /* issue command */
6841 rc = ips_send_wait(ha, scb, ips_cmd_timeout, intr);
6842 return (rc);
6845 /****************************************************************************/
6846 /* */
6847 /* Routine Name: ips_abort_init */
6848 /* */
6849 /* Routine Description: */
6850 /* cleanup routine for a failed adapter initialization */
6851 /****************************************************************************/
6852 static int
6853 ips_abort_init(ips_ha_t * ha, int index)
6855 ha->active = 0;
6856 ips_free(ha);
6857 ips_ha[index] = NULL;
6858 ips_sh[index] = NULL;
6859 return -1;
6862 /****************************************************************************/
6863 /* */
6864 /* Routine Name: ips_shift_controllers */
6865 /* */
6866 /* Routine Description: */
6867 /* helper function for ordering adapters */
6868 /****************************************************************************/
6869 static void
6870 ips_shift_controllers(int lowindex, int highindex)
6872 ips_ha_t *ha_sav = ips_ha[highindex];
6873 struct Scsi_Host *sh_sav = ips_sh[highindex];
6874 int i;
6876 for (i = highindex; i > lowindex; i--) {
6877 ips_ha[i] = ips_ha[i - 1];
6878 ips_sh[i] = ips_sh[i - 1];
6879 ips_ha[i]->host_num = i;
6881 ha_sav->host_num = lowindex;
6882 ips_ha[lowindex] = ha_sav;
6883 ips_sh[lowindex] = sh_sav;
6886 /****************************************************************************/
6887 /* */
6888 /* Routine Name: ips_order_controllers */
6889 /* */
6890 /* Routine Description: */
6891 /* place controllers is the "proper" boot order */
6892 /****************************************************************************/
6893 static void
6894 ips_order_controllers(void)
6896 int i, j, tmp, position = 0;
6897 IPS_NVRAM_P5 *nvram;
6898 if (!ips_ha[0])
6899 return;
6900 nvram = ips_ha[0]->nvram;
6902 if (nvram->adapter_order[0]) {
6903 for (i = 1; i <= nvram->adapter_order[0]; i++) {
6904 for (j = position; j < ips_num_controllers; j++) {
6905 switch (ips_ha[j]->ad_type) {
6906 case IPS_ADTYPE_SERVERAID6M:
6907 case IPS_ADTYPE_SERVERAID7k:
6908 case IPS_ADTYPE_SERVERAID7M:
6909 if (nvram->adapter_order[i] == 'M') {
6910 ips_shift_controllers(position,
6912 position++;
6914 break;
6915 case IPS_ADTYPE_SERVERAID4L:
6916 case IPS_ADTYPE_SERVERAID4M:
6917 case IPS_ADTYPE_SERVERAID4MX:
6918 case IPS_ADTYPE_SERVERAID4LX:
6919 if (nvram->adapter_order[i] == 'N') {
6920 ips_shift_controllers(position,
6922 position++;
6924 break;
6925 case IPS_ADTYPE_SERVERAID6I:
6926 case IPS_ADTYPE_SERVERAID5I2:
6927 case IPS_ADTYPE_SERVERAID5I1:
6928 if (nvram->adapter_order[i] == 'S') {
6929 ips_shift_controllers(position,
6931 position++;
6933 break;
6934 case IPS_ADTYPE_SERVERAID:
6935 case IPS_ADTYPE_SERVERAID2:
6936 case IPS_ADTYPE_NAVAJO:
6937 case IPS_ADTYPE_KIOWA:
6938 case IPS_ADTYPE_SERVERAID3L:
6939 case IPS_ADTYPE_SERVERAID3:
6940 case IPS_ADTYPE_SERVERAID4H:
6941 if (nvram->adapter_order[i] == 'A') {
6942 ips_shift_controllers(position,
6944 position++;
6946 break;
6947 default:
6948 break;
6952 /* if adapter_order[0], then ordering is complete */
6953 return;
6955 /* old bios, use older ordering */
6956 tmp = 0;
6957 for (i = position; i < ips_num_controllers; i++) {
6958 if (ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID5I2 ||
6959 ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID5I1) {
6960 ips_shift_controllers(position, i);
6961 position++;
6962 tmp = 1;
6965 /* if there were no 5I cards, then don't do any extra ordering */
6966 if (!tmp)
6967 return;
6968 for (i = position; i < ips_num_controllers; i++) {
6969 if (ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID4L ||
6970 ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID4M ||
6971 ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID4LX ||
6972 ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID4MX) {
6973 ips_shift_controllers(position, i);
6974 position++;
6978 return;
6981 /****************************************************************************/
6982 /* */
6983 /* Routine Name: ips_register_scsi */
6984 /* */
6985 /* Routine Description: */
6986 /* perform any registration and setup with the scsi layer */
6987 /****************************************************************************/
6988 static int
6989 ips_register_scsi(int index)
6991 struct Scsi_Host *sh;
6992 ips_ha_t *ha, *oldha = ips_ha[index];
6993 sh = scsi_host_alloc(&ips_driver_template, sizeof (ips_ha_t));
6994 if (!sh) {
6995 IPS_PRINTK(KERN_WARNING, oldha->pcidev,
6996 "Unable to register controller with SCSI subsystem\n");
6997 return -1;
6999 ha = IPS_HA(sh);
7000 memcpy(ha, oldha, sizeof (ips_ha_t));
7001 free_irq(oldha->irq, oldha);
7002 /* Install the interrupt handler with the new ha */
7003 if (request_irq(ha->irq, do_ipsintr, SA_SHIRQ, ips_name, ha)) {
7004 IPS_PRINTK(KERN_WARNING, ha->pcidev,
7005 "Unable to install interrupt handler\n");
7006 scsi_host_put(sh);
7007 return -1;
7010 kfree(oldha);
7011 ips_sh[index] = sh;
7012 ips_ha[index] = ha;
7013 IPS_SCSI_SET_DEVICE(sh, ha);
7015 /* Store away needed values for later use */
7016 sh->io_port = ha->io_addr;
7017 sh->n_io_port = ha->io_addr ? 255 : 0;
7018 sh->unique_id = (ha->io_addr) ? ha->io_addr : ha->mem_addr;
7019 sh->irq = ha->irq;
7020 sh->sg_tablesize = sh->hostt->sg_tablesize;
7021 sh->can_queue = sh->hostt->can_queue;
7022 sh->cmd_per_lun = sh->hostt->cmd_per_lun;
7023 sh->unchecked_isa_dma = sh->hostt->unchecked_isa_dma;
7024 sh->use_clustering = sh->hostt->use_clustering;
7026 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7)
7027 sh->max_sectors = 128;
7028 #endif
7030 sh->max_id = ha->ntargets;
7031 sh->max_lun = ha->nlun;
7032 sh->max_channel = ha->nbus - 1;
7033 sh->can_queue = ha->max_cmds - 1;
7035 IPS_ADD_HOST(sh, NULL);
7036 return 0;
7039 /*---------------------------------------------------------------------------*/
7040 /* Routine Name: ips_remove_device */
7041 /* */
7042 /* Routine Description: */
7043 /* Remove one Adapter ( Hot Plugging ) */
7044 /*---------------------------------------------------------------------------*/
7045 static void __devexit
7046 ips_remove_device(struct pci_dev *pci_dev)
7048 int i;
7049 struct Scsi_Host *sh;
7050 ips_ha_t *ha;
7052 for (i = 0; i < IPS_MAX_ADAPTERS; i++) {
7053 ha = ips_ha[i];
7054 if (ha) {
7055 if ((pci_dev->bus->number == ha->pcidev->bus->number) &&
7056 (pci_dev->devfn == ha->pcidev->devfn)) {
7057 sh = ips_sh[i];
7058 ips_release(sh);
7064 /****************************************************************************/
7065 /* */
7066 /* Routine Name: ips_module_init */
7067 /* */
7068 /* Routine Description: */
7069 /* function called on module load */
7070 /****************************************************************************/
7071 static int __init
7072 ips_module_init(void)
7074 if (pci_module_init(&ips_pci_driver) < 0)
7075 return -ENODEV;
7076 ips_driver_template.module = THIS_MODULE;
7077 ips_order_controllers();
7078 if (IPS_REGISTER_HOSTS(&ips_driver_template)) {
7079 pci_unregister_driver(&ips_pci_driver);
7080 return -ENODEV;
7082 register_reboot_notifier(&ips_notifier);
7083 return 0;
7086 /****************************************************************************/
7087 /* */
7088 /* Routine Name: ips_module_exit */
7089 /* */
7090 /* Routine Description: */
7091 /* function called on module unload */
7092 /****************************************************************************/
7093 static void __exit
7094 ips_module_exit(void)
7096 IPS_UNREGISTER_HOSTS(&ips_driver_template);
7097 pci_unregister_driver(&ips_pci_driver);
7098 unregister_reboot_notifier(&ips_notifier);
7101 module_init(ips_module_init);
7102 module_exit(ips_module_exit);
7104 /*---------------------------------------------------------------------------*/
7105 /* Routine Name: ips_insert_device */
7106 /* */
7107 /* Routine Description: */
7108 /* Add One Adapter ( Hot Plug ) */
7109 /* */
7110 /* Return Value: */
7111 /* 0 if Successful, else non-zero */
7112 /*---------------------------------------------------------------------------*/
7113 static int __devinit
7114 ips_insert_device(struct pci_dev *pci_dev, const struct pci_device_id *ent)
7116 int index;
7117 int rc;
7119 METHOD_TRACE("ips_insert_device", 1);
7120 if (pci_enable_device(pci_dev))
7121 return -1;
7123 rc = ips_init_phase1(pci_dev, &index);
7124 if (rc == SUCCESS)
7125 rc = ips_init_phase2(index);
7127 if (ips_hotplug)
7128 if (ips_register_scsi(index)) {
7129 ips_free(ips_ha[index]);
7130 rc = -1;
7133 if (rc == SUCCESS)
7134 ips_num_controllers++;
7136 ips_next_controller = ips_num_controllers;
7137 return rc;
7140 /*---------------------------------------------------------------------------*/
7141 /* Routine Name: ips_init_phase1 */
7142 /* */
7143 /* Routine Description: */
7144 /* Adapter Initialization */
7145 /* */
7146 /* Return Value: */
7147 /* 0 if Successful, else non-zero */
7148 /*---------------------------------------------------------------------------*/
7149 static int
7150 ips_init_phase1(struct pci_dev *pci_dev, int *indexPtr)
7152 ips_ha_t *ha;
7153 uint32_t io_addr;
7154 uint32_t mem_addr;
7155 uint32_t io_len;
7156 uint32_t mem_len;
7157 uint8_t revision_id;
7158 uint8_t bus;
7159 uint8_t func;
7160 uint8_t irq;
7161 uint16_t subdevice_id;
7162 int j;
7163 int index;
7164 dma_addr_t dma_address;
7165 char *ioremap_ptr;
7166 char *mem_ptr;
7167 uint32_t IsDead;
7169 METHOD_TRACE("ips_init_phase1", 1);
7170 index = IPS_MAX_ADAPTERS;
7171 for (j = 0; j < IPS_MAX_ADAPTERS; j++) {
7172 if (ips_ha[j] == 0) {
7173 index = j;
7174 break;
7178 if (index >= IPS_MAX_ADAPTERS)
7179 return -1;
7181 /* stuff that we get in dev */
7182 irq = pci_dev->irq;
7183 bus = pci_dev->bus->number;
7184 func = pci_dev->devfn;
7186 /* Init MEM/IO addresses to 0 */
7187 mem_addr = 0;
7188 io_addr = 0;
7189 mem_len = 0;
7190 io_len = 0;
7192 for (j = 0; j < 2; j++) {
7193 if (!pci_resource_start(pci_dev, j))
7194 break;
7196 if (pci_resource_flags(pci_dev, j) & IORESOURCE_IO) {
7197 io_addr = pci_resource_start(pci_dev, j);
7198 io_len = pci_resource_len(pci_dev, j);
7199 } else {
7200 mem_addr = pci_resource_start(pci_dev, j);
7201 mem_len = pci_resource_len(pci_dev, j);
7205 /* setup memory mapped area (if applicable) */
7206 if (mem_addr) {
7207 uint32_t base;
7208 uint32_t offs;
7210 if (!request_mem_region(mem_addr, mem_len, "ips")) {
7211 IPS_PRINTK(KERN_WARNING, pci_dev,
7212 "Couldn't allocate IO Memory space %x len %d.\n",
7213 mem_addr, mem_len);
7214 return -1;
7217 base = mem_addr & PAGE_MASK;
7218 offs = mem_addr - base;
7219 ioremap_ptr = ioremap(base, PAGE_SIZE);
7220 mem_ptr = ioremap_ptr + offs;
7221 } else {
7222 ioremap_ptr = NULL;
7223 mem_ptr = NULL;
7226 /* setup I/O mapped area (if applicable) */
7227 if (io_addr) {
7228 if (!request_region(io_addr, io_len, "ips")) {
7229 IPS_PRINTK(KERN_WARNING, pci_dev,
7230 "Couldn't allocate IO space %x len %d.\n",
7231 io_addr, io_len);
7232 return -1;
7236 /* get the revision ID */
7237 if (pci_read_config_byte(pci_dev, PCI_REVISION_ID, &revision_id)) {
7238 IPS_PRINTK(KERN_WARNING, pci_dev, "Can't get revision id.\n");
7239 return -1;
7242 subdevice_id = pci_dev->subsystem_device;
7244 /* found a controller */
7245 ha = kmalloc(sizeof (ips_ha_t), GFP_KERNEL);
7246 if (ha == NULL) {
7247 IPS_PRINTK(KERN_WARNING, pci_dev,
7248 "Unable to allocate temporary ha struct\n");
7249 return -1;
7252 memset(ha, 0, sizeof (ips_ha_t));
7254 ips_sh[index] = NULL;
7255 ips_ha[index] = ha;
7256 ha->active = 1;
7258 /* Store info in HA structure */
7259 ha->irq = irq;
7260 ha->io_addr = io_addr;
7261 ha->io_len = io_len;
7262 ha->mem_addr = mem_addr;
7263 ha->mem_len = mem_len;
7264 ha->mem_ptr = mem_ptr;
7265 ha->ioremap_ptr = ioremap_ptr;
7266 ha->host_num = (uint32_t) index;
7267 ha->revision_id = revision_id;
7268 ha->slot_num = PCI_SLOT(pci_dev->devfn);
7269 ha->device_id = pci_dev->device;
7270 ha->subdevice_id = subdevice_id;
7271 ha->pcidev = pci_dev;
7274 * Set the pci_dev's dma_mask. Not all adapters support 64bit
7275 * addressing so don't enable it if the adapter can't support
7276 * it! Also, don't use 64bit addressing if dma addresses
7277 * are guaranteed to be < 4G.
7279 if (IPS_ENABLE_DMA64 && IPS_HAS_ENH_SGLIST(ha) &&
7280 !pci_set_dma_mask(ha->pcidev, 0xffffffffffffffffULL)) {
7281 (ha)->flags |= IPS_HA_ENH_SG;
7282 } else {
7283 if (pci_set_dma_mask(ha->pcidev, 0xffffffffULL) != 0) {
7284 printk(KERN_WARNING "Unable to set DMA Mask\n");
7285 return ips_abort_init(ha, index);
7288 if(ips_cd_boot && !ips_FlashData){
7289 ips_FlashData = pci_alloc_consistent(pci_dev, PAGE_SIZE << 7,
7290 &ips_flashbusaddr);
7293 ha->enq = pci_alloc_consistent(pci_dev, sizeof (IPS_ENQ),
7294 &ha->enq_busaddr);
7295 if (!ha->enq) {
7296 IPS_PRINTK(KERN_WARNING, pci_dev,
7297 "Unable to allocate host inquiry structure\n");
7298 return ips_abort_init(ha, index);
7301 ha->adapt = pci_alloc_consistent(pci_dev, sizeof (IPS_ADAPTER) +
7302 sizeof (IPS_IO_CMD), &dma_address);
7303 if (!ha->adapt) {
7304 IPS_PRINTK(KERN_WARNING, pci_dev,
7305 "Unable to allocate host adapt & dummy structures\n");
7306 return ips_abort_init(ha, index);
7308 ha->adapt->hw_status_start = dma_address;
7309 ha->dummy = (void *) (ha->adapt + 1);
7313 ha->logical_drive_info = pci_alloc_consistent(pci_dev, sizeof (IPS_LD_INFO), &dma_address);
7314 if (!ha->logical_drive_info) {
7315 IPS_PRINTK(KERN_WARNING, pci_dev,
7316 "Unable to allocate logical drive info structure\n");
7317 return ips_abort_init(ha, index);
7319 ha->logical_drive_info_dma_addr = dma_address;
7322 ha->conf = kmalloc(sizeof (IPS_CONF), GFP_KERNEL);
7324 if (!ha->conf) {
7325 IPS_PRINTK(KERN_WARNING, pci_dev,
7326 "Unable to allocate host conf structure\n");
7327 return ips_abort_init(ha, index);
7330 ha->nvram = kmalloc(sizeof (IPS_NVRAM_P5), GFP_KERNEL);
7332 if (!ha->nvram) {
7333 IPS_PRINTK(KERN_WARNING, pci_dev,
7334 "Unable to allocate host NVRAM structure\n");
7335 return ips_abort_init(ha, index);
7338 ha->subsys = kmalloc(sizeof (IPS_SUBSYS), GFP_KERNEL);
7340 if (!ha->subsys) {
7341 IPS_PRINTK(KERN_WARNING, pci_dev,
7342 "Unable to allocate host subsystem structure\n");
7343 return ips_abort_init(ha, index);
7346 /* the ioctl buffer is now used during adapter initialization, so its
7347 * successful allocation is now required */
7348 if (ips_ioctlsize < PAGE_SIZE)
7349 ips_ioctlsize = PAGE_SIZE;
7351 ha->ioctl_data = pci_alloc_consistent(pci_dev, ips_ioctlsize,
7352 &ha->ioctl_busaddr);
7353 ha->ioctl_len = ips_ioctlsize;
7354 if (!ha->ioctl_data) {
7355 IPS_PRINTK(KERN_WARNING, pci_dev,
7356 "Unable to allocate IOCTL data\n");
7357 return ips_abort_init(ha, index);
7361 * Setup Functions
7363 ips_setup_funclist(ha);
7365 if ((IPS_IS_MORPHEUS(ha)) || (IPS_IS_MARCO(ha))) {
7366 /* If Morpheus appears dead, reset it */
7367 IsDead = readl(ha->mem_ptr + IPS_REG_I960_MSG1);
7368 if (IsDead == 0xDEADBEEF) {
7369 ips_reset_morpheus(ha);
7374 * Initialize the card if it isn't already
7377 if (!(*ha->func.isinit) (ha)) {
7378 if (!(*ha->func.init) (ha)) {
7380 * Initialization failed
7382 IPS_PRINTK(KERN_WARNING, pci_dev,
7383 "Unable to initialize controller\n");
7384 return ips_abort_init(ha, index);
7388 *indexPtr = index;
7389 return SUCCESS;
7392 /*---------------------------------------------------------------------------*/
7393 /* Routine Name: ips_init_phase2 */
7394 /* */
7395 /* Routine Description: */
7396 /* Adapter Initialization Phase 2 */
7397 /* */
7398 /* Return Value: */
7399 /* 0 if Successful, else non-zero */
7400 /*---------------------------------------------------------------------------*/
7401 static int
7402 ips_init_phase2(int index)
7404 ips_ha_t *ha;
7406 ha = ips_ha[index];
7408 METHOD_TRACE("ips_init_phase2", 1);
7409 if (!ha->active) {
7410 ips_ha[index] = NULL;
7411 return -1;
7414 /* Install the interrupt handler */
7415 if (request_irq(ha->irq, do_ipsintr, SA_SHIRQ, ips_name, ha)) {
7416 IPS_PRINTK(KERN_WARNING, ha->pcidev,
7417 "Unable to install interrupt handler\n");
7418 return ips_abort_init(ha, index);
7422 * Allocate a temporary SCB for initialization
7424 ha->max_cmds = 1;
7425 if (!ips_allocatescbs(ha)) {
7426 IPS_PRINTK(KERN_WARNING, ha->pcidev,
7427 "Unable to allocate a CCB\n");
7428 free_irq(ha->irq, ha);
7429 return ips_abort_init(ha, index);
7432 if (!ips_hainit(ha)) {
7433 IPS_PRINTK(KERN_WARNING, ha->pcidev,
7434 "Unable to initialize controller\n");
7435 free_irq(ha->irq, ha);
7436 return ips_abort_init(ha, index);
7438 /* Free the temporary SCB */
7439 ips_deallocatescbs(ha, 1);
7441 /* allocate CCBs */
7442 if (!ips_allocatescbs(ha)) {
7443 IPS_PRINTK(KERN_WARNING, ha->pcidev,
7444 "Unable to allocate CCBs\n");
7445 free_irq(ha->irq, ha);
7446 return ips_abort_init(ha, index);
7449 return SUCCESS;
7452 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,9)
7453 MODULE_LICENSE("GPL");
7454 #endif
7457 * Overrides for Emacs so that we almost follow Linus's tabbing style.
7458 * Emacs will notice this stuff at the end of the file and automatically
7459 * adjust the settings for this buffer only. This must remain at the end
7460 * of the file.
7461 * ---------------------------------------------------------------------------
7462 * Local variables:
7463 * c-indent-level: 2
7464 * c-brace-imaginary-offset: 0
7465 * c-brace-offset: -2
7466 * c-argdecl-indent: 2
7467 * c-label-offset: -2
7468 * c-continued-statement-offset: 2
7469 * c-continued-brace-offset: 0
7470 * indent-tabs-mode: nil
7471 * tab-width: 8
7472 * End: