File: /usr/src/linux/drivers/scsi/3w-xxxx.c

1     /* 
2        3w-xxxx.c -- 3ware Storage Controller device driver for Linux.
3     
4        Written By: Adam Radford <linux@3ware.com>
5        Modifications By: Joel Jacobson <linux@3ware.com>
6        		     Arnaldo Carvalho de Melo <acme@conectiva.com.br>
7     
8        Copyright (C) 1999-2001 3ware Inc.
9     
10        Kernel compatablity By: 	Andre Hedrick <andre@suse.com>
11        Non-Copyright (C) 2000	Andre Hedrick <andre@suse.com>
12        
13        Further tiny build fixes and trivial hoovering    Alan Cox
14     
15        This program is free software; you can redistribute it and/or modify
16        it under the terms of the GNU General Public License as published by
17        the Free Software Foundation; version 2 of the License.
18     
19        This program is distributed in the hope that it will be useful,           
20        but WITHOUT ANY WARRANTY; without even the implied warranty of            
21        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             
22        GNU General Public License for more details.                              
23     
24        NO WARRANTY                                                               
25        THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR        
26        CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT      
27        LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,      
28        MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is    
29        solely responsible for determining the appropriateness of using and       
30        distributing the Program and assumes all risks associated with its        
31        exercise of rights under this Agreement, including but not limited to     
32        the risks and costs of program errors, damage to or loss of data,         
33        programs or equipment, and unavailability or interruption of operations.  
34     
35        DISCLAIMER OF LIABILITY                                                   
36        NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY   
37        DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL        
38        DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND   
39        ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR     
40        TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE    
41        USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED  
42        HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES             
43     
44        You should have received a copy of the GNU General Public License         
45        along with this program; if not, write to the Free Software               
46        Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
47     
48        Bugs/Comments/Suggestions should be mailed to:                            
49        linux@3ware.com
50     
51        For more information, goto:
52        http://www.3ware.com
53     
54        History
55        -------
56        0.1.000 -     Initial release.
57        0.4.000 -     Added support for Asynchronous Event Notification through
58                      ioctls for 3DM.
59        1.0.000 -     Added DPO & FUA bit support for WRITE_10 & WRITE_6 cdb
60                      to disable drive write-cache before writes.
61        1.1.000 -     Fixed performance bug with DPO & FUA not existing for WRITE_6.
62        1.2.000 -     Added support for clean shutdown notification/feature table.
63        1.02.00.001 - Added support for full command packet posts through ioctls
64                      for 3DM.
65                      Bug fix so hot spare drives don't show up.
66        1.02.00.002 - Fix bug with tw_setfeature() call that caused oops on some
67                      systems.
68        08/21/00    - release previously allocated resources on failure at
69                      tw_allocate_memory (acme)
70        1.02.00.003 - Fix tw_interrupt() to report error to scsi layer when
71                      controller status is non-zero.
72                      Added handling of request_sense opcode.
73                      Fix possible null pointer dereference in 
74                      tw_reset_device_extension()
75        1.02.00.004 - Add support for device id of 3ware 7000 series controllers.
76                      Make tw_setfeature() call with interrupts disabled.
77                      Register interrupt handler before enabling interrupts.
78                      Clear attention interrupt before draining aen queue.
79        1.02.00.005 - Allocate bounce buffers and custom queue depth for raid5 for
80                      6000 and 5000 series controllers.
81                      Reduce polling mdelays causing problems on some systems.
82                      Fix use_sg = 1 calculation bug.
83                      Check for scsi_register returning NULL.
84                      Add aen count to /proc/scsi/3w-xxxx.
85                      Remove aen code unit masking in tw_aen_complete().
86        1.02.00.006 - Remove unit from printk in tw_scsi_eh_abort(), causing
87                      possible oops.
88                      Fix possible null pointer dereference in tw_scsi_queue()
89                      if done function pointer was invalid.
90        1.02.00.007 - Fix possible null pointer dereferences in tw_ioctl().
91                      Remove check for invalid done function pointer from
92                      tw_scsi_queue().
93        1.02.00.008 - Set max sectors per io to TW_MAX_SECTORS in tw_findcards().
94                      Add tw_decode_error() for printing readable error messages.
95                      Print some useful information on certain aen codes.
96                      Add tw_decode_bits() for interpreting status register output.
97                      Make scsi_set_pci_device() for kernels >= 2.4.4
98                      Fix bug where aen's could be lost before a reset.
99                      Re-add spinlocks in tw_scsi_detect().
100                      Fix possible null pointer dereference in tw_aen_drain_queue()
101                      during initialization.
102                      Clear pci parity errors during initialization and during io.
103     */
104     
105     #include <linux/module.h>
106     
107     MODULE_AUTHOR ("3ware Inc.");
108     MODULE_DESCRIPTION ("3ware Storage Controller Linux Driver");
109     
110     #include <linux/kernel.h>
111     #include <linux/pci.h>
112     #include <linux/time.h>
113     #include <linux/proc_fs.h>
114     #include <linux/sched.h>
115     #include <linux/ioport.h>
116     #include <linux/blk.h>
117     #include <linux/hdreg.h>
118     #include <linux/string.h>
119     #include <linux/delay.h>
120     #include <linux/smp.h>
121     #include <linux/reboot.h>
122     #include <linux/spinlock.h>
123     
124     #include <asm/errno.h>
125     #include <asm/io.h>
126     #include <asm/irq.h>
127     #include <asm/uaccess.h>
128     
129     #define __3W_C			/* let 3w-xxxx.h know it is use */
130     
131     #include "sd.h"
132     #include "scsi.h"
133     #include "hosts.h"
134     
135     #include "3w-xxxx.h"
136     
137     static int tw_copy_info(TW_Info *info, char *fmt, ...);
138     static void tw_copy_mem_info(TW_Info *info, char *data, int len);
139     static void tw_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
140     static int tw_halt(struct notifier_block *nb, ulong event, void *buf);
141     
142     /* Notifier block to get a notify on system shutdown/halt/reboot */
143     static struct notifier_block tw_notifier = {
144       tw_halt, NULL, 0
145     };
146     
147     /* Globals */
148     char *tw_driver_version="1.02.00.008";
149     TW_Device_Extension *tw_device_extension_list[TW_MAX_SLOT];
150     int tw_device_extension_count = 0;
151     
152     /* Functions */
153     
154     /* This function will complete an aen request from the isr */
155     int tw_aen_complete(TW_Device_Extension *tw_dev, int request_id) 
156     {
157     	TW_Param *param;
158     	unsigned short aen;
159     
160     	dprintk(KERN_WARNING "3w-xxxx: tw_aen_complete()\n");
161     	if (tw_dev->alignment_virtual_address[request_id] == NULL) {
162     		printk(KERN_WARNING "3w-xxxx: tw_aen_complete(): Bad alignment virtual address.\n");
163     		return 1;
164     	}
165     	param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
166     	aen = *(unsigned short *)(param->data);
167     	dprintk(KERN_NOTICE "3w-xxxx: tw_aen_complete(): Queue'd code 0x%x\n", aen);
168     
169     	/* Print some useful info when certain aen codes come out */
170     	switch (aen & 0x0ff) {
171     		case TW_AEN_APORT_TIMEOUT:
172     			printk(KERN_WARNING "3w-xxxx: scsi%d: Received drive timeout AEN on port %d, check drive and drive cables.\n", tw_dev->host->host_no,  aen >> 8);
173     			break;
174     		case TW_AEN_DRIVE_ERROR:
175     			printk(KERN_WARNING "3w-xxxx: scsi%d: Received drive error AEN on port %d, check/replace cabling, or possible bad drive.\n", tw_dev->host->host_no, aen >> 8);
176     			break;
177     		case TW_AEN_SMART_FAIL:
178     			printk(KERN_WARNING "3w-xxxx: scsi%d: Received S.M.A.R.T. threshold AEN on port %d, check drive/cooling, or possible bad drive.\n", tw_dev->host->host_no, aen >> 8);
179     			break;
180     		case TW_AEN_SBUF_FAIL:
181     			printk(KERN_WARNING "3w-xxxx: scsi%d: Received SBUF integrity check failure AEN, reseat card or bad card.\n", tw_dev->host->host_no);
182     			break;
183     		default:
184     			printk(KERN_WARNING "3w-xxxx: Received AEN 0x%x\n", aen);
185     	}
186     
187     	tw_dev->aen_count++;
188     
189     	/* Now queue the code */
190     	tw_dev->aen_queue[tw_dev->aen_tail] = aen;
191     	if (tw_dev->aen_tail == TW_Q_LENGTH - 1) {
192     		tw_dev->aen_tail = TW_Q_START;
193     	} else {
194     		tw_dev->aen_tail = tw_dev->aen_tail + 1;
195     	}
196     	if (tw_dev->aen_head == tw_dev->aen_tail) {
197     		if (tw_dev->aen_head == TW_Q_LENGTH - 1) {
198     			tw_dev->aen_head = TW_Q_START;
199     		} else {
200     			tw_dev->aen_head = tw_dev->aen_head + 1;
201     		}
202     	}
203     	tw_dev->state[request_id] = TW_S_COMPLETED;
204     	tw_state_request_finish(tw_dev, request_id);
205     
206     	return 0;
207     } /* End tw_aen_complete() */
208     
209     /* This function will drain the aen queue after a soft reset */
210     int tw_aen_drain_queue(TW_Device_Extension *tw_dev)
211     {
212     	TW_Command *command_packet;
213     	TW_Param *param;
214     	int tries = 0;
215     	int request_id = 0;
216     	u32 command_que_value = 0, command_que_addr;
217     	u32 status_reg_value = 0, status_reg_addr;
218     	u32 param_value;
219     	TW_Response_Queue response_queue;
220     	u32 response_que_addr;
221     	unsigned short aen;
222     	unsigned short aen_code;
223     	int finished = 0;
224     	int first_reset = 0;
225     	int queue = 0;
226     	int imax, i;
227     	int found = 0;
228     
229     	dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue()\n");
230     
231     	command_que_addr = tw_dev->registers.command_que_addr;
232     	status_reg_addr = tw_dev->registers.status_reg_addr;
233     	response_que_addr = tw_dev->registers.response_que_addr;
234     
235     	if (tw_poll_status(tw_dev, TW_STATUS_ATTENTION_INTERRUPT, 15)) {
236     		printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): No attention interrupt for card %d.\n", tw_device_extension_count);
237     		return 1;
238     	}
239     
240     	/* Initialize command packet */
241     	if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
242     		printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad command packet virtual address.\n");
243     		return 1;
244     	}
245     	command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
246     	memset(command_packet, 0, sizeof(TW_Sector));
247     	command_packet->byte0.opcode = TW_OP_GET_PARAM;
248     	command_packet->byte0.sgl_offset = 2;
249     	command_packet->size = 4;
250     	command_packet->request_id = request_id;
251     	command_packet->byte3.unit = 0;
252     	command_packet->byte3.host_id = 0;
253     	command_packet->status = 0;
254     	command_packet->flags = 0;
255     	command_packet->byte6.parameter_count = 1;
256     	command_que_value = tw_dev->command_packet_physical_address[request_id];
257     	if (command_que_value == 0) {
258     		printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad command packet physical address.\n");
259     		return 1;
260     	}
261     
262     	/* Now setup the param */
263     	if (tw_dev->alignment_virtual_address[request_id] == NULL) {
264     		printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad alignment virtual address.\n");
265     		return 1;
266     	}
267     	param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
268     	memset(param, 0, sizeof(TW_Sector));
269     	param->table_id = 0x401; /* AEN table */
270     	param->parameter_id = 2; /* Unit code */
271     	param->parameter_size_bytes = 2;
272     	param_value = tw_dev->alignment_physical_address[request_id];
273     	if (param_value == 0) {
274     		printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad alignment physical address.\n");
275     		return 1;
276     	}
277     	command_packet->byte8.param.sgl[0].address = param_value;
278     	command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
279     
280     	imax = TW_POLL_MAX_RETRIES;
281     
282     	/* Now drain the controller's aen queue */
283     	do {
284     		/* Post command packet */
285     		outl(command_que_value, command_que_addr);
286         
287     		/* Now poll for completion */
288     		for (i=0;i<imax;i++) {
289     			mdelay(5);
290     			status_reg_value = inl(status_reg_addr);
291     			if (tw_check_bits(status_reg_value)) {
292     				printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Unexpected bits.\n");
293     				tw_decode_bits(tw_dev, status_reg_value);
294     				return 1;
295     			}
296     			if ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
297     				response_queue.value = inl(response_que_addr);
298     				request_id = (unsigned char)response_queue.u.response_id;
299         
300     				if (request_id != 0) {
301     					/* Unexpected request id */
302     					printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Unexpected request id.\n");
303     					return 1;
304     				}
305     	
306     				if (command_packet->status != 0) {
307     					if (command_packet->flags != TW_AEN_TABLE_UNDEFINED) {
308     						/* Bad response */
309     						printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags);
310     						return 1;
311     					} else {
312     						/* We know this is a 3w-1x00, and doesn't support aen's */
313     						return 0;
314     					}
315     				}
316     
317     				/* Now check the aen */
318     				aen = *(unsigned short *)(param->data);
319     				aen_code = (aen & 0x0ff);
320     				queue = 0;
321     				switch (aen_code) {
322     					case TW_AEN_QUEUE_EMPTY:
323     						dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue(): Found TW_AEN_QUEUE_EMPTY.\n");
324     						if (first_reset != 1) {
325     							continue;
326     						} else {
327     							finished = 1;
328     						}
329     						break;
330     					case TW_AEN_SOFT_RESET:
331     						dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue(): Found TW_AEN_SOFT_RESET.\n");
332     						if (first_reset == 0) {
333     							first_reset = 1;
334     						} else {
335     							queue = 1;
336     						}
337     						break;
338     					case TW_AEN_DEGRADED_MIRROR:
339     						dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue(): Found TW_AEN_DEGRADED_MIRROR.\n");
340     						queue = 1;
341     						break;
342     					case TW_AEN_CONTROLLER_ERROR:
343     						dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue(): Found TW_AEN_CONTROLLER_ERROR.\n");
344     						queue = 1;
345     						break;
346     					case TW_AEN_REBUILD_FAIL:
347     						dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue(): Found TW_AEN_REBUILD_FAIL.\n");
348     						queue = 1;
349     						break;
350     					case TW_AEN_REBUILD_DONE:
351     						dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue(): Found TW_AEN_REBUILD_DONE.\n");
352     						queue = 1;
353     						break;
354     					case TW_AEN_QUEUE_FULL:
355     						dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue(): Found TW_AEN_QUEUE_FULL.\n");
356     						queue = 1;
357     						break;
358     					case TW_AEN_APORT_TIMEOUT:
359     						printk(KERN_WARNING "3w-xxxx: Received drive timeout AEN on port %d, check drive and drive cables.\n", aen >> 8);
360     						queue = 1;
361     						break;
362     					case TW_AEN_DRIVE_ERROR:
363     						printk(KERN_WARNING "3w-xxxx: Received drive error AEN on port %d, check/replace cabling, or possible bad drive.\n", aen >> 8);
364     						queue = 1;
365     						break;
366     					case TW_AEN_SMART_FAIL:
367     						printk(KERN_WARNING "3w-xxxx: Received S.M.A.R.T. threshold AEN on port %d, check drive/cooling, or possible bad drive.\n", aen >> 8);
368     						queue = 1;
369     						break;
370     					case TW_AEN_SBUF_FAIL:
371     						printk(KERN_WARNING "3w-xxxx: Received SBUF integrity check failure AEN, reseat card or bad card.\n");
372     						queue = 1;
373     						break;
374     					default:
375     						dprintk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Unknown AEN code 0x%x.\n", aen_code);
376     						queue = 1;
377     				}
378     
379     				/* Now put the aen on the aen_queue */
380     				if (queue == 1) {
381     					tw_dev->aen_queue[tw_dev->aen_tail] = aen_code;
382     					if (tw_dev->aen_tail == TW_Q_LENGTH - 1) {
383     						tw_dev->aen_tail = TW_Q_START;
384     					} else {
385     						tw_dev->aen_tail = tw_dev->aen_tail + 1;
386     					}
387     					if (tw_dev->aen_head == tw_dev->aen_tail) {
388     						if (tw_dev->aen_head == TW_Q_LENGTH - 1) {
389     							tw_dev->aen_head = TW_Q_START;
390     						} else {
391     							tw_dev->aen_head = tw_dev->aen_head + 1;
392     						}
393     					}
394     				}
395     				found = 1;
396     				break;
397     			}
398     		}
399     		if (found == 0) {
400     			printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Response never received.\n");
401     			return 1;
402     		}
403     		tries++;
404     	} while ((tries < TW_MAX_AEN_TRIES) && (finished == 0));
405     
406     	if (tries >=TW_MAX_AEN_TRIES) {
407     		printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Aen queue error.\n");
408     		return 1;
409     	}
410     
411     	return 0;
412     } /* End tw_aen_drain_queue() */
413     
414     /* This function will read the aen queue from the isr */
415     int tw_aen_read_queue(TW_Device_Extension *tw_dev, int request_id) 
416     {
417     	TW_Command *command_packet;
418     	TW_Param *param;
419     	u32 command_que_value = 0, command_que_addr;
420     	u32 status_reg_value = 0, status_reg_addr;
421     	u32 param_value = 0;
422     
423     	dprintk(KERN_NOTICE "3w-xxxx: tw_aen_read_queue()\n");
424     	command_que_addr = tw_dev->registers.command_que_addr;
425     	status_reg_addr = tw_dev->registers.status_reg_addr;
426     
427     	status_reg_value = inl(status_reg_addr);
428     	if (tw_check_bits(status_reg_value)) {
429     		printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Unexpected bits.\n");
430     		tw_decode_bits(tw_dev, status_reg_value);
431     		return 1;
432     	}
433     	if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
434     		printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad command packet virtual address.\n");
435     		return 1;
436     	}
437     	command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
438     	memset(command_packet, 0, sizeof(TW_Sector));
439     	command_packet->byte0.opcode = TW_OP_GET_PARAM;
440     	command_packet->byte0.sgl_offset = 2;
441     	command_packet->size = 4;
442     	command_packet->request_id = request_id;
443     	command_packet->byte3.unit = 0;
444     	command_packet->byte3.host_id = 0;
445     	command_packet->status = 0;
446     	command_packet->flags = 0;
447     	command_packet->byte6.parameter_count = 1;
448     	command_que_value = tw_dev->command_packet_physical_address[request_id];
449     	if (command_que_value == 0) {
450     		printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad command packet physical address.\n");
451     		return 1;
452     	}
453     	/* Now setup the param */
454     	if (tw_dev->alignment_virtual_address[request_id] == NULL) {
455     		printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad alignment virtual address.\n");
456     		return 1;
457     	}
458     	param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
459     	memset(param, 0, sizeof(TW_Sector));
460     	param->table_id = 0x401; /* AEN table */
461     	param->parameter_id = 2; /* Unit code */
462     	param->parameter_size_bytes = 2;
463     	param_value = tw_dev->alignment_physical_address[request_id];
464     	if (param_value == 0) {
465     		printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad alignment physical address.\n");
466     		return 1;
467     	}
468     	command_packet->byte8.param.sgl[0].address = param_value;
469     	command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
470     
471     	/* Now post the command packet */
472     	if ((status_reg_value & TW_STATUS_COMMAND_QUEUE_FULL) == 0) {
473     		dprintk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Post succeeded.\n");
474     		tw_dev->srb[request_id] = 0; /* Flag internal command */
475     		tw_dev->state[request_id] = TW_S_POSTED;
476     		outl(command_que_value, command_que_addr);
477     	} else {
478     		printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Post failed, will retry.\n");
479     		return 1;
480     	}
481     
482     	return 0;
483     } /* End tw_aen_read_queue() */
484     
485     /* This function will allocate memory and check if it is 16 d-word aligned */
486     int tw_allocate_memory(TW_Device_Extension *tw_dev, int request_id, int size, int which)
487     {
488     	u32 *virt_addr = kmalloc(size, GFP_ATOMIC);
489     
490     	dprintk(KERN_NOTICE "3w-xxxx: tw_allocate_memory()\n");
491     
492     	if (!virt_addr) {
493     		printk(KERN_WARNING "3w-xxxx: tw_allocate_memory(): kmalloc() failed.\n");
494     		return 1;
495     	}
496     
497     	if ((u32)virt_addr % TW_ALIGNMENT) {
498     		kfree(virt_addr);
499     		printk(KERN_WARNING "3w-xxxx: tw_allocate_memory(): Found unaligned address.\n");
500     		return 1;
501     	}
502     
503     	switch(which) {
504     	case 0:
505     		tw_dev->command_packet_virtual_address[request_id] = virt_addr;
506     		tw_dev->command_packet_physical_address[request_id] = virt_to_bus(virt_addr);
507     		break;
508     	case 1:
509     		tw_dev->alignment_virtual_address[request_id] = virt_addr;
510     		tw_dev->alignment_physical_address[request_id] = virt_to_bus(virt_addr);
511     		break;
512     	case 2:
513     		tw_dev->bounce_buffer[request_id] = virt_addr;
514     		break;
515     	default:
516     		printk(KERN_WARNING "3w-xxxx: tw_allocate_memory(): case slip in tw_allocate_memory()\n");
517     		return 1;
518     	}
519     	return 0;
520     } /* End tw_allocate_memory() */
521     
522     /* This function will check the status register for unexpected bits */
523     int tw_check_bits(u32 status_reg_value)
524     {
525     	if ((status_reg_value & TW_STATUS_EXPECTED_BITS) != TW_STATUS_EXPECTED_BITS) {  
526     		printk(KERN_WARNING "3w-xxxx: tw_check_bits(): No expected bits (0x%x).\n", status_reg_value);
527     		return 1;
528     	}
529     	if ((status_reg_value & TW_STATUS_UNEXPECTED_BITS) != 0) {
530     		printk(KERN_WARNING "3w-xxxx: tw_check_bits(): Found unexpected bits (0x%x).\n", status_reg_value);
531     		return 1;
532     	}
533     
534     	return 0;
535     } /* End tw_check_bits() */
536     
537     /* This function will report controller error status */
538     int tw_check_errors(TW_Device_Extension *tw_dev) 
539     {
540     	u32 status_reg_addr, status_reg_value;
541       
542     	status_reg_addr = tw_dev->registers.status_reg_addr;
543     	status_reg_value = inl(status_reg_addr);
544     
545     	if (TW_STATUS_ERRORS(status_reg_value) || tw_check_bits(status_reg_value))
546     		return 1;
547     
548     	return 0;
549     } /* End tw_check_errors() */
550     
551     /* This function will clear the attention interrupt */
552     void tw_clear_attention_interrupt(TW_Device_Extension *tw_dev)
553     {
554     	u32 control_reg_addr, control_reg_value;
555       
556     	control_reg_addr = tw_dev->registers.control_reg_addr;
557     	control_reg_value = TW_CONTROL_CLEAR_ATTENTION_INTERRUPT;
558     	outl(control_reg_value, control_reg_addr);
559     } /* End tw_clear_attention_interrupt() */
560     
561     /* This function will clear the host interrupt */
562     void tw_clear_host_interrupt(TW_Device_Extension *tw_dev)
563     {
564     	u32 control_reg_addr, control_reg_value;
565     
566     	control_reg_addr = tw_dev->registers.control_reg_addr;
567     	control_reg_value = TW_CONTROL_CLEAR_HOST_INTERRUPT;
568     	outl(control_reg_value, control_reg_addr);
569     } /* End tw_clear_host_interrupt() */
570     
571     /* This function is called by tw_scsi_proc_info */
572     static int tw_copy_info(TW_Info *info, char *fmt, ...) 
573     {
574     	va_list args;
575     	char buf[81];
576     	int len;
577       
578     	va_start(args, fmt);
579     	len = vsprintf(buf, fmt, args);
580     	va_end(args);
581     	tw_copy_mem_info(info, buf, len);
582     	return len;
583     } /* End tw_copy_info() */
584     
585     /* This function is called by tw_scsi_proc_info */
586     static void tw_copy_mem_info(TW_Info *info, char *data, int len)
587     {
588     	if (info->position + len > info->length)
589     		len = info->length - info->position;
590     
591     	if (info->position + len < info->offset) {
592     		info->position += len;
593     		return;
594     	}
595     	if (info->position < info->offset) {
596     		data += (info->offset - info->position);
597     		len  -= (info->offset - info->position);
598     	}
599     	if (len > 0) {
600     		memcpy(info->buffer + info->position, data, len);
601     		info->position += len;
602     	}
603     } /* End tw_copy_mem_info() */
604     
605     /* This function will print readable messages from statsu register errors */
606     void tw_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value)
607     {
608     	dprintk(KERN_WARNING "3w-xxxx: tw_decode_bits()\n");
609     	switch (status_reg_value & TW_STATUS_UNEXPECTED_BITS) {
610     	case TW_STATUS_PCI_PARITY_ERROR:
611     		printk(KERN_WARNING "3w-xxxx: PCI Parity Error: Reseat card, move card, or buggy device on the bus.\n");
612     		outl(TW_CONTROL_CLEAR_PARITY_ERROR, tw_dev->registers.control_reg_addr);
613     		pci_write_config_word(tw_dev->tw_pci_dev, PCI_STATUS, TW_PCI_CLEAR_PARITY_ERRORS);
614     		break;
615     	case TW_STATUS_MICROCONTROLLER_ERROR:
616     		printk(KERN_WARNING "3w-xxxx: Microcontroller Error.\n");
617     		break;
618       }
619     } /* End tw_decode_bits() */
620     
621     /* This function will print readable messages from flags and status values */
622     void tw_decode_error(TW_Device_Extension *tw_dev, unsigned char status, unsigned char flags, unsigned char unit)
623     {
624     	dprintk(KERN_WARNING "3w-xxxx: tw_decode_error()\n");
625     	switch (status) {
626     	case 0xc7:
627     		switch (flags) {
628     		case 0x1b: 
629     			printk(KERN_WARNING "3w-xxxx: scsi%d: Drive timeout on unit %d, check drive and drive cables.\n", tw_dev->host->host_no, unit);
630     			break;
631     		case 0x51:
632     			printk(KERN_WARNING "3w-xxxx: scsi%d: Unrecoverable drive error on unit %d, check/replace cabling, or possible bad drive.\n", tw_dev->host->host_no, unit);
633     			break;
634     		}
635     		break;
636     	}
637     } /* End tw_decode_error() */
638     
639     /* This function will disable interrupts on the controller */  
640     void tw_disable_interrupts(TW_Device_Extension *tw_dev) 
641     {
642     	u32 control_reg_value, control_reg_addr;
643     
644     	control_reg_addr = tw_dev->registers.control_reg_addr;
645     	control_reg_value = TW_CONTROL_DISABLE_INTERRUPTS;
646     	outl(control_reg_value, control_reg_addr);
647     } /* End tw_disable_interrupts() */
648     
649     /* This function will empty the response que */
650     int tw_empty_response_que(TW_Device_Extension *tw_dev) 
651     {
652     	u32 status_reg_addr, status_reg_value;
653     	u32 response_que_addr, response_que_value;
654     
655     	status_reg_addr = tw_dev->registers.status_reg_addr;
656     	response_que_addr = tw_dev->registers.response_que_addr;
657       
658     	status_reg_value = inl(status_reg_addr);
659     
660     	if (tw_check_bits(status_reg_value)) {
661     		printk(KERN_WARNING "3w-xxxx: tw_empty_response_queue(): Unexpected bits 1.\n");
662     		tw_decode_bits(tw_dev, status_reg_value);
663     		return 1;
664     	}
665       
666     	while ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
667     		response_que_value = inl(response_que_addr);
668     		status_reg_value = inl(status_reg_addr);
669     		if (tw_check_bits(status_reg_value)) {
670     			printk(KERN_WARNING "3w-xxxx: tw_empty_response_queue(): Unexpected bits 2.\n");
671     			tw_decode_bits(tw_dev, status_reg_value);
672     			return 1;
673     		}
674     	}
675     	return 0;
676     } /* End tw_empty_response_que() */
677     
678     /* This function will enable interrupts on the controller */
679     void tw_enable_interrupts(TW_Device_Extension *tw_dev)
680     {
681     	u32 control_reg_value, control_reg_addr;
682     
683     	control_reg_addr = tw_dev->registers.control_reg_addr;
684     	control_reg_value = (TW_CONTROL_CLEAR_ATTENTION_INTERRUPT |
685     			     TW_CONTROL_UNMASK_RESPONSE_INTERRUPT |
686     			     TW_CONTROL_ENABLE_INTERRUPTS);
687     	outl(control_reg_value, control_reg_addr);
688     } /* End tw_enable_interrupts() */
689     
690     /* This function will find and initialize all cards */
691     int tw_findcards(Scsi_Host_Template *tw_host) 
692     {
693     	int numcards = 0, tries = 0, error = 0;
694     	struct Scsi_Host *host;
695     	TW_Device_Extension *tw_dev;
696     	TW_Device_Extension *tw_dev2;
697     	struct pci_dev *tw_pci_dev = NULL;
698     	u32 status_reg_value;
699     	unsigned char c = 1;
700     	int i;
701     	u16 device[TW_NUMDEVICES] = { TW_DEVICE_ID, TW_DEVICE_ID2 };
702     
703     	dprintk(KERN_NOTICE "3w-xxxx: tw_findcards()\n");
704     
705     	for (i=0;i<TW_NUMDEVICES;i++) {
706     		while ((tw_pci_dev = pci_find_device(TW_VENDOR_ID, device[i], tw_pci_dev))) {
707     			if (pci_enable_device(tw_pci_dev))
708     				continue;
709     			/* Prepare temporary device extension */
710     			tw_dev=(TW_Device_Extension *)kmalloc(sizeof(TW_Device_Extension), GFP_ATOMIC);
711     			if (tw_dev == NULL) {
712     				printk(KERN_WARNING "3w-xxxx: tw_findcards(): kmalloc() failed for card %d.\n", numcards);
713     				continue;
714     			}
715     			memset(tw_dev, 0, sizeof(TW_Device_Extension));
716     
717     			error = tw_initialize_device_extension(tw_dev);
718     			if (error) {
719     				printk(KERN_WARNING "3w-xxxx: tw_findcards(): Couldn't initialize device extension for card %d.\n", numcards);
720     				tw_free_device_extension(tw_dev);
721     				kfree(tw_dev);
722     				continue;
723     			}
724     
725     			/* Calculate the cards register addresses */
726     			tw_dev->registers.base_addr = pci_resource_start(tw_pci_dev, 0);
727     			tw_dev->registers.control_reg_addr = pci_resource_start(tw_pci_dev, 0);
728     			tw_dev->registers.status_reg_addr = pci_resource_start(tw_pci_dev, 0) + 0x4;
729     			tw_dev->registers.command_que_addr = pci_resource_start(tw_pci_dev, 0) + 0x8;
730     			tw_dev->registers.response_que_addr = pci_resource_start(tw_pci_dev, 0) + 0xC;
731     			/* Save pci_dev struct to device extension */
732     			tw_dev->tw_pci_dev = tw_pci_dev;
733     
734     			/* Check for errors and clear them */
735     			status_reg_value = inl(tw_dev->registers.status_reg_addr);
736     			if (TW_STATUS_ERRORS(status_reg_value)) 
737     			  tw_decode_bits(tw_dev, status_reg_value);
738     			
739     			/* Poll status register for 60 secs for 'Controller Ready' flag */
740     			if (tw_poll_status(tw_dev, TW_STATUS_MICROCONTROLLER_READY, 60)) {
741     				printk(KERN_WARNING "3w-xxxx: tw_findcards(): Microcontroller not ready for card %d.\n", numcards);
742     				tw_free_device_extension(tw_dev);
743     				kfree(tw_dev);
744     				continue;
745     			}
746     
747     			/* Disable interrupts on the card */
748     			tw_disable_interrupts(tw_dev);
749     			
750     			while (tries < TW_MAX_RESET_TRIES) {
751     				/* Do soft reset */
752     				tw_soft_reset(tw_dev);
753     			  
754     				error = tw_aen_drain_queue(tw_dev);
755     				if (error) {
756     					printk(KERN_WARNING "3w-xxxx: tw_findcards(): No attention interrupt for card %d.\n", numcards);
757     					tries++;
758     					continue;
759     				}
760     
761     				/* Check for controller errors */
762     				if (tw_check_errors(tw_dev)) {
763     					printk(KERN_WARNING "3w-xxxx: tw_findcards(): Controller errors found, soft resetting card %d.\n", numcards);
764     					tries++;
765     					continue;
766     				}
767     
768     				/* Empty the response queue */
769     				error = tw_empty_response_que(tw_dev);
770     				if (error) {
771     					printk(KERN_WARNING "3w-xxxx: tw_findcards(): Couldn't empty response queue for card %d.\n", numcards);
772     					tries++;
773     					continue;
774     				}
775     
776     				/* Now the controller is in a good state */
777     				break;
778     			}
779     
780     			if (tries >= TW_MAX_RESET_TRIES) {
781     				printk(KERN_WARNING "3w-xxxx: tw_findcards(): Controller error or no attention interrupt: giving up for card %d.\n", numcards);
782     				tw_free_device_extension(tw_dev);
783     				kfree(tw_dev);
784     				continue;
785     			}
786     
787     			/* Make sure that io region isn't already taken */
788     			if (check_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE)) {
789     				printk(KERN_WARNING "3w-xxxx: tw_findcards(): Couldn't get io range 0x%lx-0x%lx for card %d.\n", 
790     				       (tw_dev->tw_pci_dev->resource[0].start), 
791     				       (tw_dev->tw_pci_dev->resource[0].start) + 
792     				       TW_IO_ADDRESS_RANGE, numcards);
793     				tw_free_device_extension(tw_dev);
794     				kfree(tw_dev);
795     				continue;
796     			}
797         
798     			/* Reserve the io address space */
799     			request_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE, TW_DEVICE_NAME);
800     			error = tw_initialize_units(tw_dev);
801     			if (error) {
802     				printk(KERN_WARNING "3w-xxxx: tw_findcards(): Couldn't initialize units for card %d.\n", numcards);
803     				release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
804     				tw_free_device_extension(tw_dev);
805     				kfree(tw_dev);
806     				continue;
807     			}
808     
809     			error = tw_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS);
810     			if (error) {
811     				printk(KERN_WARNING "3w-xxxx: tw_findcards(): Couldn't initconnection for card %d.\n", numcards);
812     				release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
813     				tw_free_device_extension(tw_dev);
814     				kfree(tw_dev);
815     				continue;
816     			}
817     
818     			/* Calculate max cmds per lun */
819     			if (tw_dev->num_units > 0)
820     				tw_host->cmd_per_lun = (TW_Q_LENGTH-2)/tw_dev->num_units;
821     
822     		/* Register the card with the kernel SCSI layer */
823     			host = scsi_register(tw_host, sizeof(TW_Device_Extension));
824     			if (host == NULL) {
825     				printk(KERN_WARNING "3w-xxxx: tw_findcards(): scsi_register() failed for card %d.\n", numcards-1);
826     				release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
827     				tw_free_device_extension(tw_dev);
828     				kfree(tw_dev);
829     				continue;
830     			}
831     
832     			/* Set max sectors per io */
833     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7)
834     			host->max_sectors = TW_MAX_SECTORS;
835     #endif
836     
837     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4)
838     			scsi_set_pci_device(host, tw_pci_dev);
839     #endif
840     
841     			status_reg_value = inl(tw_dev->registers.status_reg_addr);
842     
843     			printk(KERN_NOTICE "scsi%d : Found a 3ware Storage Controller at 0x%x, IRQ: %d, P-chip: %d.%d\n", host->host_no,
844     				(u32)(tw_pci_dev->resource[0].start), tw_pci_dev->irq, 
845     				(status_reg_value & TW_STATUS_MAJOR_VERSION_MASK) >> 28, 
846     				(status_reg_value & TW_STATUS_MINOR_VERSION_MASK) >> 24);
847     
848     			if (host->hostdata) {
849     				tw_dev2 = (TW_Device_Extension *)host->hostdata;
850     				memcpy(tw_dev2, tw_dev, sizeof(TW_Device_Extension));
851     				tw_device_extension_list[tw_device_extension_count] = tw_dev2;
852     				numcards++;
853     				tw_device_extension_count = numcards;
854     				tw_dev2->host = host;
855     			} else { 
856     				printk(KERN_WARNING "3w-xxxx: tw_findcards(): Bad scsi host data for card %d.\n", numcards-1);
857     				scsi_unregister(host);
858     				release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
859     				tw_free_device_extension(tw_dev);
860     				kfree(tw_dev);
861     				continue;
862     			}
863     
864     			/* Tell the firmware we support shutdown notification*/
865     			tw_setfeature(tw_dev2, 2, 1, &c);
866     
867     			/* Now setup the interrupt handler */
868     			error = tw_setup_irq(tw_dev2);
869     			if (error) {
870     				printk(KERN_WARNING "3w-xxxx: tw_findcards(): Error requesting irq for card %d.\n", numcards-1);
871     				scsi_unregister(host);
872     				release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
873     
874     				tw_free_device_extension(tw_dev);
875     				kfree(tw_dev);
876     				numcards--;
877     				continue;
878     			}
879     
880     			/* Re-enable interrupts on the card */
881     			tw_enable_interrupts(tw_dev2);
882     
883     			/* Free the temporary device extension */
884     			if (tw_dev)
885     				kfree(tw_dev);
886     		}
887     	}
888     
889     	if (numcards == 0) 
890     		printk(KERN_WARNING "3w-xxxx: tw_findcards(): No cards found.\n");
891     	else
892     	  register_reboot_notifier(&tw_notifier);
893     
894     	return numcards;
895     } /* End tw_findcards() */
896     
897     /* This function will free up device extension resources */
898     void tw_free_device_extension(TW_Device_Extension *tw_dev)
899     {
900     	int i, imax;
901     	imax = TW_Q_LENGTH;
902     
903     	dprintk(KERN_NOTICE "3w-xxxx: tw_free_device_extension()\n");
904     	/* Free command packet and generic buffer memory */
905     	for (i=0;i<imax;i++) {
906     		if (tw_dev->command_packet_virtual_address[i]) 
907     			kfree(tw_dev->command_packet_virtual_address[i]);
908     
909     		if (tw_dev->alignment_virtual_address[i])
910     			kfree(tw_dev->alignment_virtual_address[i]);
911     
912     		if (tw_dev->bounce_buffer[i])
913     			kfree(tw_dev->bounce_buffer[i]);
914     	}
915     } /* End tw_free_device_extension() */
916     
917     /* Clean shutdown routine */
918     static int tw_halt(struct notifier_block *nb, ulong event, void *buf)
919     {
920     	int i;
921     
922     	for (i=0;i<tw_device_extension_count;i++) {
923     		printk(KERN_NOTICE "3w-xxxx: Notifying card #%d\n", i);
924     		tw_shutdown_device(tw_device_extension_list[i]);
925     	}
926     	unregister_reboot_notifier(&tw_notifier);
927     
928     	return NOTIFY_OK;
929     } /* End tw_halt() */
930     
931     /* This function will send an initconnection command to controller */
932     int tw_initconnection(TW_Device_Extension *tw_dev, int message_credits) 
933     {
934     	u32 command_que_addr, command_que_value;
935     	u32 status_reg_addr, status_reg_value;
936     	u32 response_que_addr;
937     	TW_Command  *command_packet;
938     	TW_Response_Queue response_queue;
939     	int request_id = 0;
940     	int i = 0;
941     	int imax = 0;
942     
943     	dprintk(KERN_NOTICE "3w-xxxx: tw_initconnection()\n");
944     	command_que_addr = tw_dev->registers.command_que_addr;
945     	status_reg_addr = tw_dev->registers.status_reg_addr;
946     	response_que_addr = tw_dev->registers.response_que_addr;
947     
948     	/* Initialize InitConnection command packet */
949     	if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
950     		printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad command packet virtual address.\n");
951     		return 1;
952     	}
953     
954     	command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
955     	memset(command_packet, 0, sizeof(TW_Sector));
956     	command_packet->byte0.opcode = TW_OP_INIT_CONNECTION;
957     	command_packet->byte0.sgl_offset = 0x0;
958     	command_packet->size = TW_INIT_COMMAND_PACKET_SIZE;
959     	command_packet->request_id = request_id;
960     	command_packet->byte3.unit = 0x0;
961     	command_packet->byte3.host_id = 0x0;
962     	command_packet->status = 0x0;
963     	command_packet->flags = 0x0;
964     	command_packet->byte6.message_credits = message_credits; 
965     	command_packet->byte8.init_connection.response_queue_pointer = 0x0;
966     	command_que_value = tw_dev->command_packet_physical_address[request_id];
967     
968     	if (command_que_value == 0) {
969     		printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad command packet physical address.\n");
970     		return 1;
971     	}
972       
973     	/* Send command packet to the board */
974     	outl(command_que_value, command_que_addr);
975         
976     	/* Poll for completion */
977     	imax = TW_POLL_MAX_RETRIES;
978     	for (i=0;i<imax;i++) {
979     		mdelay(5);
980     		status_reg_value = inl(status_reg_addr);
981     		if (tw_check_bits(status_reg_value)) {
982     			printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Unexpected bits.\n");
983     			tw_decode_bits(tw_dev, status_reg_value);
984     			return 1;
985     		}
986     		if ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
987     			response_queue.value = inl(response_que_addr);
988     			request_id = (unsigned char)response_queue.u.response_id;
989     			if (request_id != 0) {
990     				/* unexpected request id */
991     				printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Unexpected request id.\n");
992     				return 1;
993     			}
994     			if (command_packet->status != 0) {
995     				/* bad response */
996     				printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags);
997     				return 1;
998     			}
999     			break;	/* Response was okay, so we exit */
1000     		}
1001     	}
1002     	return 0;
1003     } /* End tw_initconnection() */
1004     
1005     /* This function will initialize the fields of a device extension */
1006     int tw_initialize_device_extension(TW_Device_Extension *tw_dev)
1007     {
1008     	int i, imax;
1009     
1010     	dprintk(KERN_NOTICE "3w-xxxx: tw_initialize_device_extension()\n");
1011     	imax = TW_Q_LENGTH;
1012     
1013     	for (i=0; i<imax; i++) {
1014     		/* Initialize command packet buffers */
1015     		tw_allocate_memory(tw_dev, i, sizeof(TW_Sector), 0);
1016     		if (tw_dev->command_packet_virtual_address[i] == NULL) {
1017     			printk(KERN_WARNING "3w-xxxx: tw_initialize_device_extension(): Bad command packet virtual address.\n");
1018     			return 1;
1019     		}
1020     		memset(tw_dev->command_packet_virtual_address[i], 0, sizeof(TW_Sector));
1021         
1022     		/* Initialize generic buffer */
1023     		tw_allocate_memory(tw_dev, i, sizeof(TW_Sector), 1);
1024     		if (tw_dev->alignment_virtual_address[i] == NULL) {
1025     			printk(KERN_WARNING "3w-xxxx: tw_initialize_device_extension(): Bad alignment virtual address.\n");
1026     			return 1;
1027     		}
1028     		memset(tw_dev->alignment_virtual_address[i], 0, sizeof(TW_Sector));
1029     
1030     		tw_dev->free_queue[i] = i;
1031     		tw_dev->state[i] = TW_S_INITIAL;
1032     		tw_dev->ioctl_size[i] = 0;
1033     		tw_dev->aen_queue[i] = 0;
1034     	}
1035     
1036     	for (i=0;i<TW_MAX_UNITS;i++) {
1037     		tw_dev->is_unit_present[i] = 0;
1038     		tw_dev->is_raid_five[i] = 0;
1039     	}
1040     
1041     	tw_dev->num_units = 0;
1042     	tw_dev->num_aborts = 0;
1043     	tw_dev->num_resets = 0;
1044     	tw_dev->free_head = TW_Q_START;
1045     	tw_dev->free_tail = TW_Q_LENGTH - 1;
1046     	tw_dev->posted_request_count = 0;
1047     	tw_dev->max_posted_request_count = 0;
1048     	tw_dev->max_sgl_entries = 0;
1049     	tw_dev->sgl_entries = 0;
1050     	tw_dev->host = NULL;
1051     	tw_dev->pending_head = TW_Q_START;
1052     	tw_dev->pending_tail = TW_Q_START;
1053     	tw_dev->aen_head = 0;
1054     	tw_dev->aen_tail = 0;
1055     	tw_dev->sector_count = 0;
1056     	tw_dev->max_sector_count = 0;
1057     	tw_dev->aen_count = 0;
1058     	tw_dev->num_raid_five = 0;
1059     	spin_lock_init(&tw_dev->tw_lock);
1060     	tw_dev->flags = 0;
1061     	return 0;
1062     } /* End tw_initialize_device_extension() */
1063     
1064     /* This function will get unit info from the controller */
1065     int tw_initialize_units(TW_Device_Extension *tw_dev) 
1066     {
1067     	int found = 0;
1068     	unsigned char request_id = 0;
1069     	TW_Command *command_packet;
1070     	TW_Param *param;
1071     	int i, j, imax, num_units = 0, num_raid_five = 0;
1072     	u32 status_reg_addr, status_reg_value;
1073     	u32 command_que_addr, command_que_value;
1074     	u32 response_que_addr;
1075     	TW_Response_Queue response_queue;
1076     	u32 param_value;
1077     	unsigned char *is_unit_present;
1078     	unsigned char *raid_level;
1079     
1080     	dprintk(KERN_NOTICE "3w-xxxx: tw_initialize_units()\n");
1081     
1082     	status_reg_addr = tw_dev->registers.status_reg_addr;
1083     	command_que_addr = tw_dev->registers.command_que_addr;
1084     	response_que_addr = tw_dev->registers.response_que_addr;
1085       
1086     	/* Setup the command packet */
1087     	command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1088     	if (command_packet == NULL) {
1089     		printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad command packet virtual address.\n");
1090     		return 1;
1091     	}
1092     	memset(command_packet, 0, sizeof(TW_Sector));
1093     	command_packet->byte0.opcode      = TW_OP_GET_PARAM;
1094     	command_packet->byte0.sgl_offset  = 2;
1095     	command_packet->size              = 4;
1096     	command_packet->request_id        = request_id;
1097     	command_packet->byte3.unit        = 0;
1098     	command_packet->byte3.host_id     = 0;
1099     	command_packet->status            = 0;
1100     	command_packet->flags             = 0;
1101     	command_packet->byte6.block_count = 1;
1102     
1103     	/* Now setup the param */
1104     	if (tw_dev->alignment_virtual_address[request_id] == NULL) {
1105     		printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad alignment virtual address.\n");
1106     		return 1;
1107     	}
1108     	param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1109     	memset(param, 0, sizeof(TW_Sector));
1110     	param->table_id = 3;       /* unit summary table */
1111     	param->parameter_id = 3;   /* unitstatus parameter */
1112     	param->parameter_size_bytes = TW_MAX_UNITS;
1113     	param_value = tw_dev->alignment_physical_address[request_id];
1114     	if (param_value == 0) {
1115     		printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad alignment physical address.\n");
1116     		return 1;
1117     	}
1118     
1119     	command_packet->byte8.param.sgl[0].address = param_value;
1120     	command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
1121     
1122     	/* Post the command packet to the board */
1123     	command_que_value = tw_dev->command_packet_physical_address[request_id];
1124     	if (command_que_value == 0) {
1125     		printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad command packet physical address.\n");
1126     		return 1;
1127     	}
1128     	outl(command_que_value, command_que_addr);
1129     
1130     	/* Poll for completion */
1131     	imax = TW_POLL_MAX_RETRIES;
1132     	for(i=0; i<imax; i++) {
1133     		mdelay(5);
1134     		status_reg_value = inl(status_reg_addr);
1135     		if (tw_check_bits(status_reg_value)) {
1136     			printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Unexpected bits.\n");
1137     			tw_decode_bits(tw_dev, status_reg_value);
1138     			return 1;
1139     		}
1140     		if ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
1141     			response_queue.value = inl(response_que_addr);
1142     			request_id = (unsigned char)response_queue.u.response_id;
1143     			if (request_id != 0) {
1144     				/* unexpected request id */
1145     				printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Unexpected request id.\n");
1146     				return 1;
1147     			}
1148     			if (command_packet->status != 0) {
1149     				/* bad response */
1150     				printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags);
1151     				return 1;
1152     			}
1153     			found = 1;
1154     			break;
1155     		}
1156     	}
1157     	if (found == 0) {
1158     		/* response never received */
1159     		printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): No response.\n");
1160     		return 1;
1161     	}
1162     
1163     	param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1164     	is_unit_present = (unsigned char *)&(param->data[0]);
1165       
1166     	/* Show all units present */
1167     	imax = TW_MAX_UNITS;
1168     	for(i=0; i<imax; i++) {
1169     		if (is_unit_present[i] == 0) {
1170     			tw_dev->is_unit_present[i] = FALSE;
1171     		} else {
1172     		  if (is_unit_present[i] & TW_UNIT_ONLINE) {
1173     			dprintk(KERN_NOTICE "3w-xxxx: tw_initialize_units(): Unit %d found.\n", i);
1174     			tw_dev->is_unit_present[i] = TRUE;
1175     			num_units++;
1176     		  }
1177     		}
1178     	}
1179     	tw_dev->num_units = num_units;
1180     
1181     	if (num_units == 0) {
1182     		printk(KERN_NOTICE "3w-xxxx: tw_initialize_units(): No units found.\n");
1183     		return 1;
1184     	}
1185     
1186     	/* Find raid 5 arrays */
1187     	for (j=0;j<TW_MAX_UNITS;j++) {
1188     		if (tw_dev->is_unit_present[j] == 0)
1189     			continue;
1190     		command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1191     		if (command_packet == NULL) {
1192     			printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad command packet virtual address.\n");
1193     			return 1;
1194     		}
1195     		memset(command_packet, 0, sizeof(TW_Sector));
1196     		command_packet->byte0.opcode      = TW_OP_GET_PARAM;
1197     		command_packet->byte0.sgl_offset  = 2;
1198     		command_packet->size              = 4;
1199     		command_packet->request_id        = request_id;
1200     		command_packet->byte3.unit        = 0;
1201     		command_packet->byte3.host_id     = 0;
1202     		command_packet->status            = 0;
1203     		command_packet->flags             = 0;
1204     		command_packet->byte6.block_count = 1;
1205     
1206     		/* Now setup the param */
1207     		if (tw_dev->alignment_virtual_address[request_id] == NULL) {
1208     			printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad alignment virtual address.\n");
1209     			return 1;
1210     		}
1211     		param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1212     		memset(param, 0, sizeof(TW_Sector));
1213     		param->table_id = 0x300+j; /* unit summary table */
1214     		param->parameter_id = 0x6; /* unit descriptor */
1215     		param->parameter_size_bytes = 0xc;
1216     		param_value = tw_dev->alignment_physical_address[request_id];
1217     		if (param_value == 0) {
1218     			printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad alignment physical address.\n");
1219     			return 1;
1220     		}
1221     
1222     		command_packet->byte8.param.sgl[0].address = param_value;
1223     		command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
1224     
1225     		/* Post the command packet to the board */
1226     		command_que_value = tw_dev->command_packet_physical_address[request_id];
1227     		if (command_que_value == 0) {
1228     			printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad command packet physical address.\n");
1229     			return 1;
1230     		}
1231     		outl(command_que_value, command_que_addr);
1232     
1233     		/* Poll for completion */
1234     		imax = TW_POLL_MAX_RETRIES;
1235     		for(i=0; i<imax; i++) {
1236     			mdelay(5);
1237     			status_reg_value = inl(status_reg_addr);
1238     			if (tw_check_bits(status_reg_value)) {
1239     				printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Unexpected bits.\n");
1240     				tw_decode_bits(tw_dev, status_reg_value);
1241     				return 1;
1242     			}
1243     			if ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
1244     				response_queue.value = inl(response_que_addr);
1245     				request_id = (unsigned char)response_queue.u.response_id;
1246     				if (request_id != 0) {
1247     					/* unexpected request id */
1248     					printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Unexpected request id.\n");
1249     					return 1;
1250     				}
1251     				if (command_packet->status != 0) {
1252     					/* bad response */
1253     					printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags);
1254     					return 1;
1255     				}
1256     				found = 1;
1257     				break;
1258     			}
1259     		}
1260     		if (found == 0) {
1261     			/* response never received */
1262     			printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): No response.\n");
1263     			return 1;
1264     		}
1265     
1266     		param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1267     		raid_level = (unsigned char *)&(param->data[1]);
1268     		if (*raid_level == 5) {
1269     			dprintk(KERN_WARNING "3w-xxxx: Found unit %d to be a raid5 unit.\n", j);
1270     			tw_dev->is_raid_five[j] = 1;
1271     			num_raid_five++;
1272     		}
1273     	}
1274     	tw_dev->num_raid_five = num_raid_five;
1275     
1276     	/* Now allocate raid5 bounce buffers */
1277     	if ((num_raid_five != 0) && (tw_dev->tw_pci_dev->device == TW_DEVICE_ID)) {
1278     		for (i=0;i<TW_Q_LENGTH;i++) {
1279     			tw_allocate_memory(tw_dev, i, sizeof(TW_Sector)*TW_MAX_SECTORS, 2);
1280     			if (tw_dev->bounce_buffer[i] == NULL) {
1281     				printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bounce buffer allocation failed.\n");
1282     				return 1;
1283     			}
1284     			memset(tw_dev->bounce_buffer[i], 0, sizeof(TW_Sector)*TW_MAX_SECTORS);
1285     		}
1286     	}
1287       
1288     	return 0;
1289     } /* End tw_initialize_units() */
1290     
1291     /* This function is the interrupt service routine */
1292     static void tw_interrupt(int irq, void *dev_instance, struct pt_regs *regs) 
1293     {
1294     	int request_id;
1295     	u32 status_reg_addr, status_reg_value;
1296     	u32 response_que_addr;
1297     	TW_Device_Extension *tw_dev = (TW_Device_Extension *)dev_instance;
1298     	TW_Response_Queue response_que;
1299     	int error = 0;
1300     	int do_response_interrupt=0;
1301     	int do_attention_interrupt=0;
1302     	int do_host_interrupt=0;
1303     	int do_command_interrupt=0;
1304     	unsigned long flags = 0;
1305     	TW_Command *command_packet;
1306     	if (test_and_set_bit(TW_IN_INTR, &tw_dev->flags))
1307     		return;
1308     	spin_lock_irqsave(&io_request_lock, flags);
1309     
1310     	if (tw_dev->tw_pci_dev->irq == irq) {
1311     		spin_lock(&tw_dev->tw_lock);
1312     		dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt()\n");
1313     
1314     		/* Read the registers */
1315     		status_reg_addr = tw_dev->registers.status_reg_addr;
1316     		response_que_addr = tw_dev->registers.response_que_addr;
1317     		status_reg_value = inl(status_reg_addr);
1318     
1319     		/* Check which interrupt */
1320     		if (status_reg_value & TW_STATUS_HOST_INTERRUPT)
1321     			do_host_interrupt=1;
1322     		if (status_reg_value & TW_STATUS_ATTENTION_INTERRUPT)
1323     			do_attention_interrupt=1;
1324     		if (status_reg_value & TW_STATUS_COMMAND_INTERRUPT)
1325     			do_command_interrupt=1;
1326     		if (status_reg_value & TW_STATUS_RESPONSE_INTERRUPT)
1327     			do_response_interrupt=1;
1328     
1329     		/* Handle host interrupt */
1330     		if (do_host_interrupt) {
1331     			dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Received host interrupt.\n");
1332     			tw_clear_host_interrupt(tw_dev);
1333     		}
1334     
1335     		/* Handle attention interrupt */
1336     		if (do_attention_interrupt) {
1337     			dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Received attention interrupt.\n");
1338     			dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Clearing attention interrupt.\n");
1339     			tw_clear_attention_interrupt(tw_dev);
1340     			tw_state_request_start(tw_dev, &request_id);
1341     			error = tw_aen_read_queue(tw_dev, request_id);
1342     			if (error) {
1343     				printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Error reading aen queue.\n");
1344     				tw_dev->state[request_id] = TW_S_COMPLETED;
1345     				tw_state_request_finish(tw_dev, request_id);
1346     			}
1347     		}
1348     
1349     		/* Handle command interrupt */
1350     		if (do_command_interrupt) {
1351     			/* Drain as many pending commands as we can */
1352     			while (tw_dev->pending_request_count > 0) {
1353     				request_id = tw_dev->pending_queue[tw_dev->pending_head];
1354     				if (tw_dev->state[request_id] != TW_S_PENDING) {
1355     					printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Found request id that wasn't pending.\n");
1356     					break;
1357     				}
1358     				if (tw_post_command_packet(tw_dev, request_id)==0) {
1359     					if (tw_dev->pending_head == TW_Q_LENGTH-1) {
1360     						tw_dev->pending_head = TW_Q_START;
1361     					} else {
1362     						tw_dev->pending_head = tw_dev->pending_head + 1;
1363     					}
1364     					tw_dev->pending_request_count--;
1365     				} else {
1366     					break;
1367     				}
1368     			}
1369     			/* If there are no more pending requests, we mask command interrupt */
1370     			if (tw_dev->pending_request_count == 0) 
1371     				tw_mask_command_interrupt(tw_dev);
1372     		}
1373     
1374     		/* Handle response interrupt */
1375     		if (do_response_interrupt) {
1376     			/* Drain the response queue from the board */
1377     			while ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
1378     				response_que.value = inl(response_que_addr);
1379     				request_id = response_que.u.response_id;
1380     				command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1381     				error = 0;
1382     				if (command_packet->status != 0) {
1383     					printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Bad response, status = 0x%x, flags = 0x%x, unit = 0x%x.\n", command_packet->status, command_packet->flags, command_packet->byte3.unit);
1384     					tw_decode_error(tw_dev, command_packet->status, command_packet->flags, command_packet->byte3.unit);
1385     					error = 1;
1386     				}
1387     				if (tw_dev->state[request_id] != TW_S_POSTED) {
1388     					printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Received a request id (%d) (opcode = 0x%x) that wasn't posted.\n", request_id, command_packet->byte0.opcode);
1389     					error = 1;
1390     				}
1391     				if (TW_STATUS_ERRORS(status_reg_value)) {
1392     				  tw_decode_bits(tw_dev, status_reg_value);
1393     				  error = 1;
1394     				}
1395     				dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Response queue request id: %d.\n", request_id);
1396     				/* Check for internal command */
1397     				if (tw_dev->srb[request_id] == 0) {
1398     					dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Found internally posted command.\n");
1399     					error = tw_aen_complete(tw_dev, request_id);
1400     					if (error) {
1401     						printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Error completing aen.\n");
1402     					}
1403     					status_reg_value = inl(status_reg_addr);
1404     					if (tw_check_bits(status_reg_value)) {
1405     						printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n");
1406     						tw_decode_bits(tw_dev, status_reg_value);
1407     					}
1408     		} else {
1409     				switch (tw_dev->srb[request_id]->cmnd[0]) {
1410     					case READ_10:
1411     						dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught READ_10\n");
1412     					case READ_6:
1413     						dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught READ_6\n");
1414     						break;
1415     					case WRITE_10:
1416     						dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught WRITE_10\n");
1417     					case WRITE_6:
1418     						dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught WRITE_6\n");
1419     						break;
1420     					case INQUIRY:
1421     						dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught INQUIRY\n");
1422     						error = tw_scsiop_inquiry_complete(tw_dev, request_id);
1423     						break;
1424     					case READ_CAPACITY:
1425     						dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught READ_CAPACITY\n");
1426     						error = tw_scsiop_read_capacity_complete(tw_dev, request_id);
1427     						break;
1428     					case TW_IOCTL:
1429     						dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught TW_IOCTL\n");
1430     						error = tw_ioctl_complete(tw_dev, request_id);
1431     						break;
1432     					default:
1433     						printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unknown scsi opcode: 0x%x.\n", tw_dev->srb[request_id]->cmnd[0]);
1434     						tw_dev->srb[request_id]->result = (DID_BAD_TARGET << 16);
1435     						tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1436     					}
1437     					if (error) {
1438     						/* Tell scsi layer there was an error */
1439     						dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Scsi Error.\n");
1440     						tw_dev->srb[request_id]->result = (DID_RESET << 16);
1441     					} else {
1442     						/* Tell scsi layer command was a success */
1443     						tw_dev->srb[request_id]->result = (DID_OK << 16);
1444     					}
1445     					tw_dev->state[request_id] = TW_S_COMPLETED;
1446     					tw_state_request_finish(tw_dev, request_id);
1447     					tw_dev->posted_request_count--;
1448     					tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1449     					status_reg_value = inl(status_reg_addr);
1450     					if (tw_check_bits(status_reg_value)) {
1451     						printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n");
1452     						tw_decode_bits(tw_dev, status_reg_value);
1453     					}
1454     				}
1455     			}
1456     		}
1457     		spin_unlock(&tw_dev->tw_lock);
1458     	}
1459     	spin_unlock_irqrestore(&io_request_lock, flags);
1460     	clear_bit(TW_IN_INTR, &tw_dev->flags);
1461     }	/* End tw_interrupt() */
1462     
1463     /* This function handles ioctls from userspace to the driver */
1464     int tw_ioctl(TW_Device_Extension *tw_dev, int request_id)
1465     {
1466     	unsigned char opcode;
1467     	int bufflen;
1468     	TW_Param *param;
1469     	TW_Command *command_packet;
1470     	u32 param_value;
1471     	TW_Ioctl *ioctl = NULL;
1472     	int tw_aen_code;
1473     
1474     	ioctl = (TW_Ioctl *)tw_dev->srb[request_id]->request_buffer;
1475     	if (ioctl == NULL) {
1476     		printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Request buffer NULL.\n");
1477     		tw_dev->state[request_id] = TW_S_COMPLETED;
1478     		tw_state_request_finish(tw_dev, request_id);
1479     		tw_dev->srb[request_id]->result = (DID_OK << 16);
1480     		tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1481     		return 0;
1482     	}
1483     	bufflen = tw_dev->srb[request_id]->request_bufflen;
1484     
1485     	/* Initialize command packet */
1486     	command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1487     	if (command_packet == NULL) {
1488     		printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Bad command packet virtual address.\n");
1489     		tw_dev->state[request_id] = TW_S_COMPLETED;
1490     		tw_state_request_finish(tw_dev, request_id);
1491     		tw_dev->srb[request_id]->result = (DID_OK << 16);
1492     		tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1493     		return 0;
1494     	}
1495     	memset(command_packet, 0, sizeof(TW_Sector));
1496     
1497     	/* Initialize param */
1498     	if (tw_dev->alignment_virtual_address[request_id] == NULL) {
1499     		printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Bad alignment virtual address.\n");
1500     		tw_dev->state[request_id] = TW_S_COMPLETED;
1501     		tw_state_request_finish(tw_dev, request_id);
1502     		tw_dev->srb[request_id]->result = (DID_OK << 16);
1503     		tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1504     		return 0;
1505     	}
1506     	param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1507     	memset(param, 0, sizeof(TW_Sector));
1508     
1509     	dprintk(KERN_NOTICE "opcode = %d table_id = %d parameter_id = %d parameter_size_bytes = %d\n", ioctl->opcode, ioctl->table_id, ioctl->parameter_id, ioctl->parameter_size_bytes);
1510     	opcode = ioctl->opcode;
1511     
1512     	switch (opcode) {
1513     		case TW_OP_NOP:
1514     			dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): caught TW_OP_NOP.\n");
1515     			command_packet->byte0.opcode = TW_OP_NOP;
1516     			break;
1517     		case TW_OP_GET_PARAM:
1518     			dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): caught TW_OP_GET_PARAM.\n");
1519     			command_packet->byte0.opcode = TW_OP_GET_PARAM;
1520     			param->table_id = ioctl->table_id;
1521     			param->parameter_id = ioctl->parameter_id;
1522     			param->parameter_size_bytes = ioctl->parameter_size_bytes;
1523     			tw_dev->ioctl_size[request_id] = ioctl->parameter_size_bytes;
1524     			dprintk(KERN_NOTICE "table_id = %d parameter_id = %d parameter_size_bytes %d\n", param->table_id, param->parameter_id, param->parameter_size_bytes);
1525     			break;
1526     		case TW_OP_SET_PARAM:
1527     			dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): caught TW_OP_SET_PARAM: table_id = %d, parameter_id = %d, parameter_size_bytes = %d.\n",
1528     			ioctl->table_id, ioctl->parameter_id, ioctl->parameter_size_bytes);
1529     			if (ioctl->data != NULL) {
1530     				command_packet->byte0.opcode = TW_OP_SET_PARAM;
1531     				param->table_id = ioctl->table_id;
1532     				param->parameter_id = ioctl->parameter_id;
1533     				param->parameter_size_bytes = ioctl->parameter_size_bytes;
1534     				memcpy(param->data, ioctl->data, ioctl->parameter_size_bytes);
1535     				break;
1536     			} else {
1537     				printk(KERN_WARNING "3w-xxxx: tw_ioctl(): ioctl->data NULL.\n");
1538     				return 1;
1539     			}
1540     		case TW_OP_AEN_LISTEN:
1541     			dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): caught TW_OP_AEN_LISTEN.\n");
1542     			if (tw_dev->aen_head == tw_dev->aen_tail) {
1543     				/* aen queue empty */
1544     				dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): Aen queue empty.\n");
1545     				tw_aen_code = TW_AEN_QUEUE_EMPTY;
1546     				memcpy(tw_dev->srb[request_id]->request_buffer, &tw_aen_code, ioctl->parameter_size_bytes);
1547     			} else {
1548     				/* Copy aen queue entry to request buffer */
1549     				dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): Returning aen 0x%x\n", tw_dev->aen_queue[tw_dev->aen_head]);
1550     				tw_aen_code = tw_dev->aen_queue[tw_dev->aen_head];
1551     				memcpy(tw_dev->srb[request_id]->request_buffer, &tw_aen_code, ioctl->parameter_size_bytes);
1552     				if (tw_dev->aen_head == TW_Q_LENGTH - 1) {
1553     					tw_dev->aen_head = TW_Q_START;
1554     				} else {
1555     					tw_dev->aen_head = tw_dev->aen_head + 1;
1556     				}
1557     			}
1558     			tw_dev->state[request_id] = TW_S_COMPLETED;
1559     			tw_state_request_finish(tw_dev, request_id);
1560     			tw_dev->srb[request_id]->result = (DID_OK << 16);
1561     			tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1562     			return 0;
1563     	        case TW_CMD_PACKET:
1564     			if (ioctl->data != NULL) {
1565     				memcpy(command_packet, ioctl->data, sizeof(TW_Command));
1566     				command_packet->request_id = request_id;
1567     				tw_post_command_packet(tw_dev, request_id);
1568     				return 0;
1569     			} else {
1570     				printk(KERN_WARNING "3w-xxxx: tw_ioctl(): ioctl->data NULL.\n");
1571     				return 1;
1572     			}
1573     		default:
1574     			printk(KERN_WARNING "3w-xxxx: Unknown ioctl 0x%x.\n", opcode);
1575     			tw_dev->state[request_id] = TW_S_COMPLETED;
1576     			tw_state_request_finish(tw_dev, request_id);
1577     			tw_dev->srb[request_id]->result = (DID_OK << 16);
1578     			tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1579     			return 0;
1580     	}
1581     
1582     	param_value = tw_dev->alignment_physical_address[request_id];
1583     	if (param_value == 0) {
1584     		printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Bad alignment physical address.\n");
1585     		tw_dev->state[request_id] = TW_S_COMPLETED;
1586     		tw_state_request_finish(tw_dev, request_id);
1587     		tw_dev->srb[request_id]->result = (DID_OK << 16);
1588     		tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1589     	}
1590     
1591     	command_packet->byte8.param.sgl[0].address = param_value;
1592     	command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
1593     
1594     	command_packet->byte0.sgl_offset = 2;
1595     	command_packet->size = 4;
1596     	command_packet->request_id = request_id;
1597     	command_packet->byte3.unit = 0;
1598     	command_packet->byte3.host_id = 0;
1599     	command_packet->status = 0;
1600     	command_packet->flags = 0;
1601     	command_packet->byte6.parameter_count = 1;
1602     
1603     	/* Now try to post the command to the board */
1604     	tw_post_command_packet(tw_dev, request_id);
1605     
1606     	return 0;
1607     } /* End tw_ioctl() */
1608     
1609     /* This function is called by the isr to complete ioctl requests */
1610     int tw_ioctl_complete(TW_Device_Extension *tw_dev, int request_id)
1611     {
1612     	unsigned char *param_data;
1613     	unsigned char *buff;
1614     	TW_Param *param;
1615     
1616     	dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl_complete()\n");
1617     	buff = tw_dev->srb[request_id]->request_buffer;
1618     	if (buff == NULL) {
1619     		printk(KERN_WARNING "3w-xxxx: tw_ioctl_complete(): Request buffer NULL.\n");
1620     		return 1;
1621     	}
1622     	dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl_complete(): Request_bufflen = %d\n", tw_dev->srb[request_id]->request_bufflen);
1623     	memset(buff, 0, tw_dev->srb[request_id]->request_bufflen);
1624     	param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1625     	if (param == NULL) {
1626     		printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_capacity_complete(): Bad alignment virtual address.\n");
1627     		return 1;
1628     	}
1629     	param_data = &(param->data[0]);
1630     
1631     	memcpy(buff, param_data, tw_dev->ioctl_size[request_id]);
1632     
1633     	return 0;
1634     } /* End tw_ioctl_complete() */
1635     
1636     /* This function will mask the command interrupt */
1637     void tw_mask_command_interrupt(TW_Device_Extension *tw_dev)
1638     {
1639     	u32 control_reg_addr, control_reg_value;
1640     	
1641     	control_reg_addr = tw_dev->registers.control_reg_addr;
1642     	control_reg_value = TW_CONTROL_MASK_COMMAND_INTERRUPT;
1643     	outl(control_reg_value, control_reg_addr);
1644     } /* End tw_mask_command_interrupt() */
1645     
1646     /* This function will poll the status register for a flag */
1647     int tw_poll_status(TW_Device_Extension *tw_dev, u32 flag, int seconds)
1648     {
1649     	u32 status_reg_addr, status_reg_value;
1650     	struct timeval before, timeout;
1651     
1652     	status_reg_addr = tw_dev->registers.status_reg_addr;
1653     	do_gettimeofday(&before);
1654     	status_reg_value = inl(status_reg_addr);
1655     
1656     	while ((status_reg_value & flag) != flag) {
1657     		status_reg_value = inl(status_reg_addr);
1658     		do_gettimeofday(&timeout);
1659     		if (before.tv_sec + seconds < timeout.tv_sec) { 
1660     			printk(KERN_WARNING "3w-xxxx: tw_poll_status(): Flag 0x%x not found.\n", flag);
1661     			return 1;
1662     		}
1663     		mdelay(1);
1664     	}
1665     	return 0;
1666     } /* End tw_poll_status() */
1667     
1668     /* This function will attempt to post a command packet to the board */
1669     int tw_post_command_packet(TW_Device_Extension *tw_dev, int request_id)
1670     {
1671     	u32 status_reg_addr, status_reg_value;
1672     	u32 command_que_addr, command_que_value;
1673     
1674     	dprintk(KERN_NOTICE "3w-xxxx: tw_post_command_packet()\n");
1675     	command_que_addr = tw_dev->registers.command_que_addr;
1676     	command_que_value = tw_dev->command_packet_physical_address[request_id];
1677     	status_reg_addr = tw_dev->registers.status_reg_addr;
1678     	status_reg_value = inl(status_reg_addr);
1679     
1680     	if (tw_check_bits(status_reg_value)) {
1681     		printk(KERN_WARNING "3w-xxxx: tw_post_command_packet(): Unexpected bits.\n");
1682     		tw_decode_bits(tw_dev, status_reg_value);
1683     	}
1684     
1685     	if ((status_reg_value & TW_STATUS_COMMAND_QUEUE_FULL) == 0) {
1686     		/* We successfully posted the command packet */
1687     		outl(command_que_value, command_que_addr);
1688     		tw_dev->state[request_id] = TW_S_POSTED;
1689     		tw_dev->posted_request_count++;
1690     		if (tw_dev->posted_request_count > tw_dev->max_posted_request_count) {
1691     			tw_dev->max_posted_request_count = tw_dev->posted_request_count;
1692     		}
1693     	} else {
1694     		/* Couldn't post the command packet, so we do it in the isr */
1695     		if (tw_dev->state[request_id] != TW_S_PENDING) {
1696     			tw_dev->state[request_id] = TW_S_PENDING;
1697     			tw_dev->pending_request_count++;
1698     			if (tw_dev->pending_request_count > tw_dev->max_pending_request_count) {
1699     				tw_dev->max_pending_request_count = tw_dev->pending_request_count;
1700     			}
1701     			tw_dev->pending_queue[tw_dev->pending_tail] = request_id;
1702     			if (tw_dev->pending_tail == TW_Q_LENGTH-1) {
1703     				tw_dev->pending_tail = TW_Q_START;
1704     			} else {
1705     				tw_dev->pending_tail = tw_dev->pending_tail + 1;
1706     			}
1707     		} 
1708     		tw_unmask_command_interrupt(tw_dev);
1709     		return 1;
1710     	}
1711     	return 0;
1712     } /* End tw_post_command_packet() */
1713     
1714     /* This function will reset a device extension */
1715     int tw_reset_device_extension(TW_Device_Extension *tw_dev) 
1716     {
1717     	int imax = 0;
1718     	int i = 0;
1719     	Scsi_Cmnd *srb;
1720     
1721     	dprintk(KERN_NOTICE "3w-xxxx: tw_reset_device_extension()\n");
1722     	imax = TW_Q_LENGTH;
1723     
1724     	if (tw_reset_sequence(tw_dev)) {
1725     		printk(KERN_WARNING "3w-xxxx: tw_reset_device_extension(): Reset sequence failed for card %d.\n", tw_dev->host->host_no);
1726     		return 1;
1727     	}
1728     
1729     	/* Abort all requests that are in progress */
1730     	for (i=0;i<imax;i++) {
1731     		if ((tw_dev->state[i] != TW_S_FINISHED) && 
1732     		    (tw_dev->state[i] != TW_S_INITIAL) &&
1733     		    (tw_dev->state[i] != TW_S_COMPLETED)) {
1734     			srb = tw_dev->srb[i];
1735     			if (srb != NULL) {
1736     				srb = tw_dev->srb[i];
1737     				srb->result = (DID_RESET << 16);
1738     				tw_dev->srb[i]->scsi_done(tw_dev->srb[i]);
1739     			}
1740     		}
1741     	}
1742     
1743     	/* Reset queues and counts */
1744     	for (i=0;i<imax;i++) {
1745     		tw_dev->free_queue[i] = i;
1746     		tw_dev->state[i] = TW_S_INITIAL;
1747     	}
1748     	tw_dev->free_head = TW_Q_START;
1749     	tw_dev->free_tail = TW_Q_LENGTH - 1;
1750     	tw_dev->posted_request_count = 0;
1751     	tw_dev->pending_request_count = 0;
1752     	tw_dev->pending_head = TW_Q_START;
1753     	tw_dev->pending_tail = TW_Q_START;
1754     
1755     	return 0;
1756     } /* End tw_reset_device_extension() */
1757     
1758     /* This function will reset a controller */
1759     int tw_reset_sequence(TW_Device_Extension *tw_dev) 
1760     {
1761     	int error = 0;
1762     	int tries = 0;
1763     
1764     	/* Disable interrupts */
1765     	tw_disable_interrupts(tw_dev);
1766     
1767     	/* Reset the board */
1768     	while (tries < TW_MAX_RESET_TRIES) {
1769     		tw_soft_reset(tw_dev);
1770     
1771     		error = tw_aen_drain_queue(tw_dev);
1772     		if (error) {
1773     			printk(KERN_WARNING "3w-xxxx: tw_reset_sequence(): No attention interrupt for card %d.\n", tw_dev->host->host_no);
1774     			tries++;
1775     			continue;
1776     		}
1777     
1778     		/* Check for controller errors */
1779     		if (tw_check_errors(tw_dev)) {
1780     			printk(KERN_WARNING "3w-xxxx: tw_reset_sequence(): Controller errors found, soft resetting card %d.\n", tw_dev->host->host_no);
1781     			tries++;
1782     			continue;
1783     		}
1784     
1785     		/* Empty the response queue again */
1786     		error = tw_empty_response_que(tw_dev);
1787     		if (error) {
1788     			printk(KERN_WARNING "3w-xxxx: tw_reset_sequence(): Couldn't empty response queue for card %d.\n", tw_dev->host->host_no);
1789     			tries++;
1790     			continue;
1791     		}
1792     
1793     		/* Now the controller is in a good state */
1794     		break;
1795     	}
1796     
1797     	if (tries >= TW_MAX_RESET_TRIES) {
1798     		printk(KERN_WARNING "3w-xxxx: tw_reset_sequence(): Controller error or no attention interrupt: giving up for card %d.\n", tw_dev->host->host_no);
1799     		return 1;
1800     	}
1801     
1802     	error = tw_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS);
1803     	if (error) {
1804     		printk(KERN_WARNING "3w-xxxx: tw_reset_sequence(): Couldn't initconnection for card %d.\n", tw_dev->host->host_no);
1805     		return 1;
1806     	}
1807     
1808     	/* Re-enable interrupts */
1809     	tw_enable_interrupts(tw_dev);
1810     
1811     	return 0;
1812     } /* End tw_reset_sequence() */
1813     
1814     /* This funciton returns unit geometry in cylinders/heads/sectors */
1815     int tw_scsi_biosparam(Disk *disk, kdev_t dev, int geom[]) 
1816     {
1817     	int heads, sectors, cylinders;
1818     	TW_Device_Extension *tw_dev;
1819     	
1820     	dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_biosparam()\n");
1821     	tw_dev = (TW_Device_Extension *)disk->device->host->hostdata;
1822     
1823     	heads = 64;
1824     	sectors = 32;
1825     	cylinders = disk->capacity / (heads * sectors);
1826     
1827     	if (disk->capacity >= 0x200000) {
1828     		heads = 255;
1829     		sectors = 63;
1830     		cylinders = disk->capacity / (heads * sectors);
1831     	}
1832     
1833     	dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_biosparam(): heads = %d, sectors = %d, cylinders = %d\n", heads, sectors, cylinders);
1834     	geom[0] = heads;			 
1835     	geom[1] = sectors;
1836     	geom[2] = cylinders;
1837     
1838     	return 0;
1839     } /* End tw_scsi_biosparam() */
1840     
1841     /* This function will find and initialize any cards */
1842     int tw_scsi_detect(Scsi_Host_Template *tw_host)
1843     {
1844     	int ret;
1845     	
1846     	dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_detect()\n");
1847     
1848     	printk(KERN_WARNING "3ware Storage Controller device driver for Linux v%s.\n", tw_driver_version);
1849     
1850     	/* Check if the kernel has PCI interface compiled in */
1851     	if (!pci_present()) {
1852     		printk(KERN_WARNING "3w-xxxx: tw_scsi_detect(): No pci interface present.\n");
1853     		return 0;
1854     	}
1855     
1856     	spin_unlock_irq(&io_request_lock);
1857     	ret = tw_findcards(tw_host);
1858     	spin_lock_irq(&io_request_lock);
1859     
1860     	return ret;
1861     } /* End tw_scsi_detect() */
1862     
1863     /* This is the new scsi eh abort function */
1864     int tw_scsi_eh_abort(Scsi_Cmnd *SCpnt) 
1865     {
1866     	TW_Device_Extension *tw_dev=NULL;
1867     	int i = 0;
1868     
1869     	dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_eh_abort()\n");
1870     
1871     	if (!SCpnt) {
1872     		printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Invalid Scsi_Cmnd.\n");
1873     		return (FAILED);
1874     	}
1875     
1876     	tw_dev = (TW_Device_Extension *)SCpnt->host->hostdata;
1877     	if (tw_dev == NULL) {
1878     		printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Invalid device extension.\n");
1879     		return (FAILED);
1880     	}
1881     
1882     	/* We have to let AEN requests through before the reset */
1883     	spin_unlock_irq(&io_request_lock);
1884     	mdelay(TW_AEN_WAIT_TIME);
1885     	spin_lock_irq(&io_request_lock);
1886     
1887     	spin_lock(&tw_dev->tw_lock);
1888     	tw_dev->num_aborts++;
1889     
1890     	/* If the command hasn't been posted yet, we can do the abort */
1891     	for (i=0;i<TW_Q_LENGTH;i++) {
1892     		if (tw_dev->srb[i] == SCpnt) {
1893     			if (tw_dev->state[i] == TW_S_STARTED) {
1894     				printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Abort succeeded for started Scsi_Cmnd 0x%x\n", (u32)tw_dev->srb[i]);
1895     				tw_dev->state[i] = TW_S_COMPLETED;
1896     				tw_state_request_finish(tw_dev, i);
1897     				spin_unlock(&tw_dev->tw_lock);
1898     				return (SUCCESS);
1899     			}
1900     			if (tw_dev->state[i] == TW_S_PENDING) {
1901     				printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Abort succeeded for pending Scsi_Cmnd 0x%x\n", (u32)tw_dev->srb[i]);
1902     				if (tw_dev->pending_head == TW_Q_LENGTH-1) {
1903     					tw_dev->pending_head = TW_Q_START;
1904     				} else {
1905     					tw_dev->pending_head = tw_dev->pending_head + 1;
1906     				}
1907     				tw_dev->pending_request_count--;
1908     				tw_dev->state[i] = TW_S_COMPLETED;
1909     				tw_state_request_finish(tw_dev, i);
1910     				spin_unlock(&tw_dev->tw_lock);
1911     				return (SUCCESS);
1912     			}
1913     		}
1914     	}
1915     
1916     	/* If the command has already been posted, we have to reset the card */
1917     	printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Abort failed for unknown Scsi_Cmnd 0x%x, resetting card %d.\n", (u32)SCpnt, tw_dev->host->host_no);
1918     
1919     	if (tw_reset_device_extension(tw_dev)) {
1920     		printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Reset failed for card %d.\n", tw_dev->host->host_no);
1921     		spin_unlock(&tw_dev->tw_lock);
1922     		return (FAILED);
1923     	}
1924     	spin_unlock(&tw_dev->tw_lock);
1925     
1926     	return (SUCCESS);
1927     } /* End tw_scsi_eh_abort() */
1928     
1929     /* This is the new scsi eh reset function */
1930     int tw_scsi_eh_reset(Scsi_Cmnd *SCpnt) 
1931     {
1932     	TW_Device_Extension *tw_dev=NULL;
1933     
1934     	dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_eh_reset()\n");
1935     
1936     	if (!SCpnt) {
1937     		printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_reset(): Invalid Scsi_Cmnd.\n");
1938     		return (FAILED);
1939     	}
1940     
1941     	tw_dev = (TW_Device_Extension *)SCpnt->host->hostdata;
1942     	if (tw_dev == NULL) {
1943     		printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_reset(): Invalid device extension.\n");
1944     		return (FAILED);
1945     	}
1946     
1947     	/* We have to let AEN requests through before the reset */
1948     	spin_unlock_irq(&io_request_lock);
1949     	mdelay(TW_AEN_WAIT_TIME);
1950     	spin_lock_irq(&io_request_lock);
1951     
1952     	spin_lock(&tw_dev->tw_lock);
1953     	tw_dev->num_resets++;
1954     
1955     	/* Now reset the card and some of the device extension data */
1956     	if (tw_reset_device_extension(tw_dev)) {
1957     		printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_reset(): Reset failed for card %d.\n", tw_dev->host->host_no);
1958     		spin_unlock(&tw_dev->tw_lock);
1959     		return (FAILED);
1960     	}
1961     	printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_reset(): Reset succeeded for card %d.\n", tw_dev->host->host_no);
1962     	spin_unlock(&tw_dev->tw_lock);
1963     
1964     	return (SUCCESS);
1965     } /* End tw_scsi_eh_reset() */
1966     
1967     /* This function handles input and output from /proc/scsi/3w-xxxx/x */
1968     int tw_scsi_proc_info(char *buffer, char **start, off_t offset, int length, int hostno, int inout) 
1969     {
1970     	TW_Device_Extension *tw_dev = NULL;
1971     	TW_Info info;
1972     	int i;
1973     	int j;
1974     
1975     	dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_proc_info()\n");
1976     
1977     	/* Find the correct device extension */
1978     	for (i=0;i<tw_device_extension_count;i++) 
1979     		if (tw_device_extension_list[i]->host->host_no == hostno) 
1980     			tw_dev = tw_device_extension_list[i];
1981     	if (tw_dev == NULL) {
1982     		printk(KERN_WARNING "3w-xxxx: tw_scsi_proc_info(): Couldn't locate device extension.\n");
1983     		return (-EINVAL);
1984     	}
1985     
1986     	info.buffer = buffer;
1987     	info.length = length;
1988     	info.offset = offset;
1989     	info.position = 0;
1990     	
1991     	if (inout) {
1992     		/* Write */
1993     		if (strncmp(buffer, "debug", 5) == 0) {
1994     			printk(KERN_INFO "3w-xxxx: Posted commands:\n");
1995     			for (j=0;j<TW_Q_LENGTH;j++) {
1996     				if (tw_dev->state[j] == TW_S_POSTED) {
1997     					TW_Command *command = (TW_Command *)tw_dev->command_packet_virtual_address[j];
1998     					printk(KERN_INFO "3w-xxxx: Request_id: %d\n", j);
1999     					printk(KERN_INFO "Opcode: 0x%x\n", command->byte0.opcode);
2000     					printk(KERN_INFO "Block_count: 0x%x\n", command->byte6.block_count);
2001     					printk(KERN_INFO "LBA: 0x%x\n", (u32)command->byte8.io.lba);
2002     					printk(KERN_INFO "Physical command packet addr: 0x%x\n", tw_dev->command_packet_physical_address[j]);
2003     					printk(KERN_INFO "Scsi_Cmnd: 0x%x\n", (u32)tw_dev->srb[j]);
2004     				}
2005     			}
2006     			printk(KERN_INFO "3w-xxxx: Free_head: %3d\n", tw_dev->free_head);
2007     			printk(KERN_INFO "3w-xxxx: Free_tail: %3d\n", tw_dev->free_tail);
2008     		} 
2009     		return length;
2010     	} else {
2011     		/* Read */
2012     		if (start) {
2013     			*start = buffer;
2014     		}
2015     		tw_copy_info(&info, "scsi%d: 3ware Storage Controller\n", hostno);
2016     		tw_copy_info(&info, "Driver version: %s\n", tw_driver_version);
2017     		tw_copy_info(&info, "Current commands posted:       %3d\n", tw_dev->posted_request_count);
2018     		tw_copy_info(&info, "Max commands posted:           %3d\n", tw_dev->max_posted_request_count);
2019     		tw_copy_info(&info, "Current pending commands:      %3d\n", tw_dev->pending_request_count);
2020     		tw_copy_info(&info, "Max pending commands:          %3d\n", tw_dev->max_pending_request_count);
2021     		tw_copy_info(&info, "Last sgl length:               %3d\n", tw_dev->sgl_entries);
2022     		tw_copy_info(&info, "Max sgl length:                %3d\n", tw_dev->max_sgl_entries);
2023     		tw_copy_info(&info, "Last sector count:             %3d\n", tw_dev->sector_count);
2024     		tw_copy_info(&info, "Max sector count:              %3d\n", tw_dev->max_sector_count);
2025     		tw_copy_info(&info, "Resets:                        %3d\n", tw_dev->num_resets);
2026     		tw_copy_info(&info, "Aborts:                        %3d\n", tw_dev->num_aborts);
2027     		tw_copy_info(&info, "AEN's:                         %3d\n", tw_dev->aen_count);
2028     	}
2029     	if (info.position > info.offset) {
2030     		return (info.position - info.offset);
2031     	} else { 
2032     		return 0;
2033     	}
2034     } /* End tw_scsi_proc_info() */
2035     
2036     /* This is the main scsi queue function to handle scsi opcodes */
2037     int tw_scsi_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) 
2038     {
2039     	unsigned char *command = SCpnt->cmnd;
2040     	int request_id = 0;
2041     	int error = 0;
2042     	unsigned long flags = 0;
2043     	TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->host->hostdata;
2044     
2045     	if (tw_dev == NULL) {
2046     		printk(KERN_WARNING "3w-xxxx: tw_scsi_queue(): Invalid device extension.\n");
2047     		SCpnt->result = (DID_ERROR << 16);
2048     		done(SCpnt);
2049     		return 0;
2050     	}
2051     
2052     	spin_lock_irqsave(&tw_dev->tw_lock, flags);
2053     	dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue()\n");
2054     
2055     	/* Skip scsi command if it isn't for us */
2056     	if ((tw_dev->is_unit_present[SCpnt->target] == FALSE) || (SCpnt->lun != 0)) {
2057     		SCpnt->result = (DID_BAD_TARGET << 16);
2058     		done(SCpnt);
2059     		spin_unlock_irqrestore(&tw_dev->tw_lock, flags);
2060     		return 0;
2061     	}
2062     	
2063     	/* Save done function into Scsi_Cmnd struct */
2064     	SCpnt->scsi_done = done;
2065     		 
2066     	/* Queue the command and get a request id */
2067     	tw_state_request_start(tw_dev, &request_id);
2068     
2069     	/* Save the scsi command for use by the ISR */
2070     	tw_dev->srb[request_id] = SCpnt;
2071     
2072     	switch (*command) {
2073     		case READ_10:
2074     			dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught READ_10.\n");
2075     		case READ_6:
2076     			dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught READ_6.\n");
2077     		case WRITE_10:
2078     			dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught WRITE_10.\n");
2079     		case WRITE_6:
2080     			dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught WRITE_6.\n");
2081     			error = tw_scsiop_read_write(tw_dev, request_id);
2082     			break;
2083     		case TEST_UNIT_READY:
2084     			dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught TEST_UNIT_READY.\n");
2085     			error = tw_scsiop_test_unit_ready(tw_dev, request_id);
2086     			break;
2087     		case INQUIRY:
2088     			dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught INQUIRY.\n");
2089     			error = tw_scsiop_inquiry(tw_dev, request_id);
2090     			break;
2091     		case READ_CAPACITY:
2092     			dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught READ_CAPACITY.\n");
2093     			error = tw_scsiop_read_capacity(tw_dev, request_id);
2094     			break;
2095     	        case REQUEST_SENSE:
2096     		        dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught REQUEST_SENSE.\n");
2097     		        error = tw_scsiop_request_sense(tw_dev, request_id);
2098     		        break;
2099     		case TW_IOCTL:
2100     			dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught TW_SCSI_IOCTL.\n");
2101     			error = tw_ioctl(tw_dev, request_id);
2102     			break;
2103     		default:
2104     			printk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): Unknown scsi opcode: 0x%x\n", *command);
2105     			tw_dev->state[request_id] = TW_S_COMPLETED;
2106     			tw_state_request_finish(tw_dev, request_id);
2107     			SCpnt->result = (DID_BAD_TARGET << 16);
2108     			done(SCpnt);
2109     	}
2110     	if (error) {
2111     		tw_dev->state[request_id] = TW_S_COMPLETED;
2112     		tw_state_request_finish(tw_dev, request_id);
2113     		SCpnt->result = (DID_ERROR << 16);
2114     		done(SCpnt);
2115     	}
2116     	spin_unlock_irqrestore(&tw_dev->tw_lock, flags);
2117     
2118     	return 0;
2119     } /* End tw_scsi_queue() */
2120     
2121     /* This function will release the resources on an rmmod call */
2122     int tw_scsi_release(struct Scsi_Host *tw_host) 
2123     {
2124     	TW_Device_Extension *tw_dev;
2125     	tw_dev = (TW_Device_Extension *)tw_host->hostdata;
2126     
2127     	dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_release()\n");
2128     
2129     	/* Free up the IO region */
2130     	release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
2131     
2132     	/* Free up the IRQ */
2133     	free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
2134     
2135     	/* Free up device extension resources */
2136     	tw_free_device_extension(tw_dev);
2137     
2138     	/* Tell kernel scsi-layer we are gone */
2139     	scsi_unregister(tw_host);
2140     	
2141     	/* Fake like we just shut down, so notify the card that
2142     	 * we "shut down cleanly".
2143     	 */
2144     	tw_halt(0, 0, 0);  // parameters aren't actually used
2145     
2146     	return 0;
2147     } /* End tw_scsi_release() */
2148     
2149     /* This function handles scsi inquiry commands */
2150     int tw_scsiop_inquiry(TW_Device_Extension *tw_dev, int request_id)
2151     {
2152     	TW_Param *param;
2153     	TW_Command *command_packet;
2154     	u32 command_que_value, command_que_addr;
2155     	u32 param_value;
2156     
2157     	dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry()\n");
2158     
2159     	/* Initialize command packet */
2160     	command_que_addr = tw_dev->registers.command_que_addr;
2161     	command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
2162     	if (command_packet == NULL) {
2163     		printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad command packet virtual address.\n");
2164     		return 1;
2165     	}
2166     	memset(command_packet, 0, sizeof(TW_Sector));
2167     	command_packet->byte0.opcode = TW_OP_GET_PARAM;
2168     	command_packet->byte0.sgl_offset = 2;
2169     	command_packet->size = 4;
2170     	command_packet->request_id = request_id;
2171     	command_packet->byte3.unit = 0;
2172     	command_packet->byte3.host_id = 0;
2173     	command_packet->status = 0;
2174     	command_packet->flags = 0;
2175     	command_packet->byte6.parameter_count = 1;
2176     
2177     	/* Now setup the param */
2178     	if (tw_dev->alignment_virtual_address[request_id] == NULL) {
2179     		printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad alignment virtual address.\n");
2180     		return 1;
2181     	}
2182     	param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
2183     	memset(param, 0, sizeof(TW_Sector));
2184     	param->table_id = 3;	 /* unit summary table */
2185     	param->parameter_id = 3; /* unitsstatus parameter */
2186     	param->parameter_size_bytes = TW_MAX_UNITS;
2187     	param_value = tw_dev->alignment_physical_address[request_id];
2188     	if (param_value == 0) {
2189     		printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad alignment physical address.\n");
2190     		return 1;
2191     	}
2192     
2193     	command_packet->byte8.param.sgl[0].address = param_value;
2194     	command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
2195     	command_que_value = tw_dev->command_packet_physical_address[request_id];
2196     	if (command_que_value == 0) {
2197     		printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad command packet physical address.\n");
2198     		return 1;
2199     	}
2200     
2201     	/* Now try to post the command packet */
2202     	tw_post_command_packet(tw_dev, request_id);
2203     
2204     	return 0;
2205     } /* End tw_scsiop_inquiry() */
2206     
2207     /* This function is called by the isr to complete an inquiry command */
2208     int tw_scsiop_inquiry_complete(TW_Device_Extension *tw_dev, int request_id)
2209     {
2210     	unsigned char *is_unit_present;
2211     	unsigned char *request_buffer;
2212     	int i;
2213     	TW_Param *param;
2214     
2215     	dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry_complete()\n");
2216     
2217     	/* Fill request buffer */
2218     	if (tw_dev->srb[request_id]->request_buffer == NULL) {
2219     		printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry_complete(): Request buffer NULL.\n");
2220     		return 1;
2221     	}
2222     	request_buffer = tw_dev->srb[request_id]->request_buffer;
2223     	memset(request_buffer, 0, tw_dev->srb[request_id]->request_bufflen);
2224     	request_buffer[0] = TYPE_DISK;									 /* Peripheral device type */
2225     	request_buffer[1] = 0;													 /* Device type modifier */
2226     	request_buffer[2] = 0;													 /* No ansi/iso compliance */
2227     	request_buffer[4] = 31;													/* Additional length */
2228     	memcpy(&request_buffer[8], "3ware   ", 8);	 /* Vendor ID */
2229     	memcpy(&request_buffer[16], "3w-xxxx         ", 16); /* Product ID */
2230     	memcpy(&request_buffer[32], tw_driver_version, 3);
2231     
2232     	param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
2233     	if (param == NULL) {
2234     		printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry_complete(): Bad alignment virtual address.\n");
2235     		return 1;
2236     	}
2237     	is_unit_present = &(param->data[0]);
2238     
2239     	for (i=0 ; i<TW_MAX_UNITS; i++) {
2240     		if (is_unit_present[i] == 0) {
2241     			tw_dev->is_unit_present[i] = FALSE;
2242     		} else {
2243     		  if (is_unit_present[i] & TW_UNIT_ONLINE) {
2244     			tw_dev->is_unit_present[i] = TRUE;
2245     			dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry_complete: Unit %d found.\n", i);
2246     		  }
2247     		}
2248     	}
2249     
2250     	return 0;
2251     } /* End tw_scsiop_inquiry_complete() */
2252     
2253     /* This function handles scsi read_capacity commands */
2254     int tw_scsiop_read_capacity(TW_Device_Extension *tw_dev, int request_id) 
2255     {
2256     	TW_Param *param;
2257     	TW_Command *command_packet;
2258     	u32 command_que_addr, command_que_value;
2259     	u32 param_value;
2260     
2261     	dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity()\n");
2262     
2263     	/* Initialize command packet */
2264     	command_que_addr = tw_dev->registers.command_que_addr;
2265     	command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
2266     
2267     	if (command_packet == NULL) {
2268     		dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad command packet virtual address.\n");
2269     		return 1;
2270     	}
2271     	memset(command_packet, 0, sizeof(TW_Sector));
2272     	command_packet->byte0.opcode = TW_OP_GET_PARAM;
2273     	command_packet->byte0.sgl_offset = 2;
2274     	command_packet->size = 4;
2275     	command_packet->request_id = request_id;
2276     	command_packet->byte3.unit = tw_dev->srb[request_id]->target;
2277     	command_packet->byte3.host_id = 0;
2278     	command_packet->status = 0;
2279     	command_packet->flags = 0;
2280     	command_packet->byte6.block_count = 1;
2281     
2282     	/* Now setup the param */
2283     	if (tw_dev->alignment_virtual_address[request_id] == NULL) {
2284     		dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad alignment virtual address.\n");
2285     		return 1;
2286     	}
2287     	param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
2288     	memset(param, 0, sizeof(TW_Sector));
2289     	param->table_id = TW_UNIT_INFORMATION_TABLE_BASE + 
2290     	tw_dev->srb[request_id]->target;
2291     	param->parameter_id = 4;	/* unitcapacity parameter */
2292     	param->parameter_size_bytes = 4;
2293     	param_value = tw_dev->alignment_physical_address[request_id];
2294     	if (param_value == 0) {
2295     		dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad alignment physical address.\n");
2296     		return 1;
2297     	}
2298       
2299     	command_packet->byte8.param.sgl[0].address = param_value;
2300     	command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
2301     	command_que_value = tw_dev->command_packet_physical_address[request_id];
2302     	if (command_que_value == 0) {
2303     		dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad command packet physical address.\n");
2304     		return 1;
2305     	}
2306     
2307     	/* Now try to post the command to the board */
2308     	tw_post_command_packet(tw_dev, request_id);
2309       
2310     	return 0;
2311     } /* End tw_scsiop_read_capacity() */
2312     
2313     /* This function is called by the isr to complete a readcapacity command */
2314     int tw_scsiop_read_capacity_complete(TW_Device_Extension *tw_dev, int request_id)
2315     {
2316     	unsigned char *param_data;
2317     	u32 capacity;
2318     	char *buff;
2319     	TW_Param *param;
2320     
2321     	dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity_complete()\n");
2322     
2323     	buff = tw_dev->srb[request_id]->request_buffer;
2324     	if (buff == NULL) {
2325     		printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_capacity_complete(): Request buffer NULL.\n");
2326     		return 1;
2327     	}
2328     	memset(buff, 0, tw_dev->srb[request_id]->request_bufflen);
2329     	param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
2330     	if (param == NULL) {
2331     		printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_capacity_complete(): Bad alignment virtual address.\n");
2332     		return 1;
2333     	}
2334     	param_data = &(param->data[0]);
2335     
2336     	capacity = (param_data[3] << 24) | (param_data[2] << 16) | 
2337     		   (param_data[1] << 8) | param_data[0];
2338     
2339     	dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity_complete(): Capacity = 0x%x.\n", capacity);
2340     
2341     	/* Number of LBA's */
2342     	buff[0] = (capacity >> 24);
2343     	buff[1] = (capacity >> 16) & 0xff;
2344     	buff[2] = (capacity >> 8) & 0xff;
2345     	buff[3] = capacity & 0xff;
2346     
2347     	/* Block size in bytes (512) */
2348     	buff[4] = (TW_BLOCK_SIZE >> 24);
2349     	buff[5] = (TW_BLOCK_SIZE >> 16) & 0xff;
2350     	buff[6] = (TW_BLOCK_SIZE >> 8) & 0xff;
2351     	buff[7] = TW_BLOCK_SIZE & 0xff;
2352     
2353     	return 0;
2354     } /* End tw_scsiop_read_capacity_complete() */
2355     
2356     /* This function handles scsi read or write commands */
2357     int tw_scsiop_read_write(TW_Device_Extension *tw_dev, int request_id) 
2358     {
2359     	TW_Command *command_packet;
2360     	u32 command_que_addr, command_que_value = 0;
2361     	u32 lba = 0x0, num_sectors = 0x0;
2362     	int i, count = 0;
2363     	Scsi_Cmnd *srb;
2364     	struct scatterlist *sglist;
2365     
2366     	dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write()\n");
2367     
2368     	if (tw_dev->srb[request_id]->request_buffer == NULL) {
2369     		printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_write(): Request buffer NULL.\n");
2370     		return 1;
2371     	}
2372     	sglist = (struct scatterlist *)tw_dev->srb[request_id]->request_buffer;
2373     	srb = tw_dev->srb[request_id];
2374     
2375     	/* Initialize command packet */
2376     	command_que_addr = tw_dev->registers.command_que_addr;
2377     	command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
2378     	if (command_packet == NULL) {
2379     		dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): Bad command packet virtual address.\n");
2380     		return 1;
2381     	}
2382     
2383     	if (srb->cmnd[0] == READ_6 || srb->cmnd[0] == READ_10) {
2384     		command_packet->byte0.opcode = TW_OP_READ;
2385     	} else {
2386     		command_packet->byte0.opcode = TW_OP_WRITE;
2387     	}
2388     
2389     	command_packet->byte0.sgl_offset = 3;
2390     	command_packet->size = 5;
2391     	command_packet->request_id = request_id;
2392     	command_packet->byte3.unit = srb->target;
2393     	command_packet->byte3.host_id = 0;
2394     	command_packet->status = 0;
2395     	command_packet->flags = 0;
2396     
2397     	if (srb->cmnd[0] == WRITE_10) {
2398     		if ((srb->cmnd[1] & 0x8) || (srb->cmnd[1] & 0x10))
2399     			command_packet->flags = 1;
2400     	}
2401     
2402     	if (srb->cmnd[0] == READ_6 || srb->cmnd[0] == WRITE_6) {
2403     		lba = ((u32)srb->cmnd[1] << 16) | ((u32)srb->cmnd[2] << 8) | (u32)srb->cmnd[3];
2404     		num_sectors = (u32)srb->cmnd[4];
2405     	} else {
2406     		lba = ((u32)srb->cmnd[2] << 24) | ((u32)srb->cmnd[3] << 16) | ((u32)srb->cmnd[4] << 8) | (u32)srb->cmnd[5];
2407     		num_sectors = (u32)srb->cmnd[8] | ((u32)srb->cmnd[7] << 8);
2408     	}
2409       
2410     	/* Update sector statistic */
2411     	tw_dev->sector_count = num_sectors;
2412     	if (tw_dev->sector_count > tw_dev->max_sector_count)
2413     		tw_dev->max_sector_count = tw_dev->sector_count;
2414       
2415     	dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): lba = 0x%x num_sectors = 0x%x\n", lba, num_sectors);
2416     	command_packet->byte8.io.lba = lba;
2417     	command_packet->byte6.block_count = num_sectors;
2418     
2419     	if ((tw_dev->is_raid_five[tw_dev->srb[request_id]->target] == 0) || (srb->cmnd[0] == READ_6) || (srb->cmnd[0] == READ_10) || (tw_dev->tw_pci_dev->device == TW_DEVICE_ID2)) {
2420     		/* Do this if there are no sg list entries */
2421     		if (tw_dev->srb[request_id]->use_sg == 0) {    
2422     			dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): SG = 0\n");
2423     			command_packet->byte8.io.sgl[0].address = virt_to_bus(tw_dev->srb[request_id]->request_buffer);
2424     			command_packet->byte8.io.sgl[0].length = tw_dev->srb[request_id]->request_bufflen;
2425     		}
2426     
2427     		/* Do this if we have multiple sg list entries */
2428     		if (tw_dev->srb[request_id]->use_sg > 0) {
2429     			for (i=0;i<tw_dev->srb[request_id]->use_sg; i++) {
2430     				command_packet->byte8.io.sgl[i].address = virt_to_bus(sglist[i].address);
2431     				command_packet->byte8.io.sgl[i].length = sglist[i].length;
2432     				command_packet->size+=2;
2433     			}
2434     			if (tw_dev->srb[request_id]->use_sg >= 1)
2435     				command_packet->size-=2;
2436     		}
2437     	} else {
2438                     /* Do this if there are no sg list entries for raid 5 */
2439                     if (tw_dev->srb[request_id]->use_sg == 0) {
2440     			dprintk(KERN_WARNING "doing raid 5 write use_sg = 0, bounce_buffer[%d] = 0x%p\n", request_id, tw_dev->bounce_buffer[request_id]);
2441     			memcpy(tw_dev->bounce_buffer[request_id], tw_dev->srb[request_id]->request_buffer, tw_dev->srb[request_id]->request_bufflen);
2442     			command_packet->byte8.io.sgl[0].address = virt_to_bus(tw_dev->bounce_buffer[request_id]);
2443     			command_packet->byte8.io.sgl[0].length = tw_dev->srb[request_id]->request_bufflen;
2444                     }
2445     
2446                     /* Do this if we have multiple sg list entries for raid 5 */
2447                     if (tw_dev->srb[request_id]->use_sg > 0) {
2448                             dprintk(KERN_WARNING "doing raid 5 write use_sg = %d, sglist[0].length = %d\n", tw_dev->srb[request_id]->use_sg, sglist[0].length);
2449                             for (i=0;i<tw_dev->srb[request_id]->use_sg; i++) {
2450                                     memcpy((char *)(tw_dev->bounce_buffer[request_id])+count, sglist[i].address, sglist[i].length);
2451     				count+=sglist[i].length;
2452                             }
2453                             command_packet->byte8.io.sgl[0].address = virt_to_bus(tw_dev->bounce_buffer[request_id]);
2454                             command_packet->byte8.io.sgl[0].length = count;
2455                             command_packet->size = 5; /* single sgl */
2456                     }
2457             }
2458     
2459     	/* Update SG statistics */
2460     	tw_dev->sgl_entries = tw_dev->srb[request_id]->use_sg;
2461     	if (tw_dev->sgl_entries > tw_dev->max_sgl_entries)
2462     		tw_dev->max_sgl_entries = tw_dev->sgl_entries;
2463     
2464     	command_que_value = tw_dev->command_packet_physical_address[request_id];
2465     	if (command_que_value == 0) {
2466     		dprintk(KERN_WARNING "3w-xxxx: tw_scsiop_read_write(): Bad command packet physical address.\n");
2467     		return 1;
2468     	}
2469           
2470     	/* Now try to post the command to the board */
2471     	tw_post_command_packet(tw_dev, request_id);
2472     
2473     	return 0;
2474     } /* End tw_scsiop_read_write() */
2475     
2476     /* This function will handle the request sense scsi command */
2477     int tw_scsiop_request_sense(TW_Device_Extension *tw_dev, int request_id)
2478     {
2479            dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_request_sense()\n");
2480       
2481            /* For now we just zero the sense buffer */
2482            memset(tw_dev->srb[request_id]->request_buffer, 0, tw_dev->srb[request_id]->request_bufflen);
2483            tw_dev->state[request_id] = TW_S_COMPLETED;
2484            tw_state_request_finish(tw_dev, request_id);
2485       
2486            /* If we got a request_sense, we probably want a reset, return error */
2487            tw_dev->srb[request_id]->result = (DID_ERROR << 16);
2488            tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
2489       
2490            return 0;
2491     } /* End tw_scsiop_request_sense() */
2492     
2493     /* This function will handle test unit ready scsi command */
2494     int tw_scsiop_test_unit_ready(TW_Device_Extension *tw_dev, int request_id)
2495     {
2496     	dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_test_unit_ready()\n");
2497     
2498     	/* Tell the scsi layer were done */
2499     	tw_dev->state[request_id] = TW_S_COMPLETED;
2500     	tw_state_request_finish(tw_dev, request_id);
2501     	tw_dev->srb[request_id]->result = (DID_OK << 16);
2502     	tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
2503     
2504     	return 0;
2505     } /* End tw_scsiop_test_unit_ready() */
2506     
2507     /* Set a value in the features table */
2508     int tw_setfeature(TW_Device_Extension *tw_dev, int parm, int param_size,
2509                       unsigned char *val)
2510     {
2511     	TW_Param *param;
2512     	TW_Command  *command_packet;
2513     	TW_Response_Queue response_queue;
2514     	int request_id = 0;
2515     	u32 command_que_value, command_que_addr;
2516     	u32 status_reg_addr, status_reg_value;
2517     	u32 response_que_addr;
2518     	u32 param_value;
2519     	int imax, i;
2520     
2521       	/* Initialize SetParam command packet */
2522     	if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
2523     		printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad command packet virtual address.\n");
2524     		return 1;
2525     	}
2526     	command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
2527     	memset(command_packet, 0, sizeof(TW_Sector));
2528     	param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
2529     
2530     	command_packet->byte0.opcode = TW_OP_SET_PARAM;
2531     	command_packet->byte0.sgl_offset  = 2;
2532     	param->table_id = 0x404;  /* Features table */
2533     	param->parameter_id = parm;
2534     	param->parameter_size_bytes = param_size;
2535     	memcpy(param->data, val, param_size);
2536     
2537     	param_value = tw_dev->alignment_physical_address[request_id];
2538     	if (param_value == 0) {
2539     		printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Bad alignment physical address.\n");
2540     		tw_dev->state[request_id] = TW_S_COMPLETED;
2541     		tw_state_request_finish(tw_dev, request_id);
2542     		tw_dev->srb[request_id]->result = (DID_OK << 16);
2543     		tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
2544     	}
2545     	command_packet->byte8.param.sgl[0].address = param_value;
2546     	command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
2547     
2548     	command_packet->size = 4;
2549     	command_packet->request_id = request_id;
2550     	command_packet->byte6.parameter_count = 1;
2551     
2552       	command_que_value = tw_dev->command_packet_physical_address[request_id];
2553     	if (command_que_value == 0) {
2554     		printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad command packet physical address.\n");
2555     	return 1;
2556     	}
2557     	command_que_addr = tw_dev->registers.command_que_addr;
2558     	status_reg_addr = tw_dev->registers.status_reg_addr;
2559     	response_que_addr = tw_dev->registers.response_que_addr;
2560     
2561     	/* Send command packet to the board */
2562     	outl(command_que_value, command_que_addr);
2563     
2564     	/* Poll for completion */
2565     	imax = TW_POLL_MAX_RETRIES;
2566     	for (i=0;i<imax;i++) {
2567     		mdelay(5);
2568     		status_reg_value = inl(status_reg_addr);
2569     		if (tw_check_bits(status_reg_value)) {
2570     			printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Unexpected bits.\n");
2571     			tw_decode_bits(tw_dev, status_reg_value);
2572     			return 1;
2573     		}
2574     		if ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
2575     			response_queue.value = inl(response_que_addr);
2576     			request_id = (unsigned char)response_queue.u.response_id;
2577     			if (request_id != 0) {
2578     				/* unexpected request id */
2579     				printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Unexpected request id.\n");
2580     				return 1;
2581     			}
2582     			if (command_packet->status != 0) {
2583     				/* bad response */
2584     				printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags);
2585     				return 1;
2586     			}
2587     			break; /* Response was okay, so we exit */
2588     		}
2589     	}
2590     
2591       return 0;
2592     } /* End tw_setfeature() */
2593     
2594     /* This function will setup the interrupt handler */
2595     int tw_setup_irq(TW_Device_Extension *tw_dev)
2596     {
2597     	char *device = TW_DEVICE_NAME;
2598     	int error;
2599     
2600     	dprintk(KERN_NOTICE "3w-xxxx: tw_setup_irq()\n");
2601     	error = request_irq(tw_dev->tw_pci_dev->irq, tw_interrupt, SA_SHIRQ, device, tw_dev);
2602     
2603     	if (error < 0) {
2604     		printk(KERN_WARNING "3w-xxxx: tw_setup_irq(): Error requesting IRQ: %d for card %d.\n", tw_dev->tw_pci_dev->irq, tw_dev->host->host_no);
2605     		return 1;
2606     	}
2607     	return 0;
2608     } /* End tw_setup_irq() */
2609     
2610     /* This function will tell the controller we're shutting down by sending
2611        initconnection with a 1 */
2612     int tw_shutdown_device(TW_Device_Extension *tw_dev)
2613     {
2614     	int error;
2615     
2616     	/* Disable interrupts */
2617     	tw_disable_interrupts(tw_dev);
2618     
2619     	/* poke the board */
2620     	error = tw_initconnection(tw_dev, 1);
2621     	if (error) {
2622     		printk(KERN_WARNING "3w-xxxx: tw_shutdown_device(): Couldn't initconnection for card %d.\n", tw_dev->host->host_no);
2623     	} else {
2624     		printk(KERN_NOTICE "3w-xxxx shutdown succeeded\n");
2625     	}
2626     
2627     	/* Re-enable interrupts */
2628     	tw_enable_interrupts(tw_dev);
2629     
2630     	return 0;
2631     } /* End tw_shutdown_device() */
2632     
2633     /* This function will soft reset the controller */
2634     void tw_soft_reset(TW_Device_Extension *tw_dev) 
2635     {
2636     	u32 control_reg_addr, control_reg_value;
2637     
2638     	control_reg_addr = tw_dev->registers.control_reg_addr;
2639     	control_reg_value = (	TW_CONTROL_ISSUE_SOFT_RESET |
2640     				TW_CONTROL_CLEAR_HOST_INTERRUPT |
2641     				TW_CONTROL_CLEAR_ATTENTION_INTERRUPT |
2642     				TW_CONTROL_MASK_COMMAND_INTERRUPT |
2643     				TW_CONTROL_MASK_RESPONSE_INTERRUPT |
2644     				TW_CONTROL_CLEAR_ERROR_STATUS | 
2645     				TW_CONTROL_DISABLE_INTERRUPTS);
2646     	outl(control_reg_value, control_reg_addr);
2647     } /* End tw_soft_reset() */
2648     
2649     /* This function will free a request_id */
2650     int tw_state_request_finish(TW_Device_Extension *tw_dev, int request_id)
2651     {
2652     	dprintk(KERN_NOTICE "3w-xxxx: tw_state_request_finish()\n");
2653       
2654     	do {    
2655     		if (tw_dev->free_tail == TW_Q_LENGTH-1) {
2656     			tw_dev->free_tail = TW_Q_START;
2657     		} else {
2658     			tw_dev->free_tail = tw_dev->free_tail + 1;
2659     		}
2660     	} while ((tw_dev->state[tw_dev->free_queue[tw_dev->free_tail]] != TW_S_COMPLETED));
2661     
2662     	tw_dev->free_queue[tw_dev->free_tail] = request_id;
2663     
2664     	tw_dev->state[request_id] = TW_S_FINISHED;
2665     	dprintk(KERN_NOTICE "3w-xxxx: tw_state_request_finish(): Freeing request_id %d\n", request_id);
2666     
2667     	return 0;
2668     } /* End tw_state_request_finish() */
2669     
2670     /* This function will assign an available request_id */
2671     int tw_state_request_start(TW_Device_Extension *tw_dev, int *request_id)
2672     {
2673     	int id = 0;
2674     
2675     	dprintk(KERN_NOTICE "3w-xxxx: tw_state_request_start()\n");
2676     
2677     	/* Obtain next free request_id */
2678     	do {
2679     		if (tw_dev->free_head == TW_Q_LENGTH - 1) {
2680     			tw_dev->free_head = TW_Q_START;
2681     		} else {
2682     			tw_dev->free_head = tw_dev->free_head + 1;
2683     		}
2684     	} while ((tw_dev->state[tw_dev->free_queue[tw_dev->free_head]] == TW_S_STARTED) ||
2685     		 (tw_dev->state[tw_dev->free_queue[tw_dev->free_head]] == TW_S_POSTED) ||
2686     		 (tw_dev->state[tw_dev->free_queue[tw_dev->free_head]] == TW_S_PENDING) ||
2687     		 (tw_dev->state[tw_dev->free_queue[tw_dev->free_head]] == TW_S_COMPLETED));
2688     
2689     	id = tw_dev->free_queue[tw_dev->free_head];
2690     
2691     	if (tw_dev->free_head == TW_Q_LENGTH - 1) {
2692     		tw_dev->free_head = TW_Q_START;
2693     	} else {
2694     		tw_dev->free_head = tw_dev->free_head + 1;
2695     	}
2696     
2697     	dprintk(KERN_NOTICE "3w-xxxx: tw_state_request_start(): id = %d.\n", id);
2698     	*request_id = id;
2699     	tw_dev->state[id] = TW_S_STARTED;
2700     
2701     	return 0;
2702     } /* End tw_state_request_start() */
2703     
2704     /* This function will unmask the command interrupt on the controller */
2705     void tw_unmask_command_interrupt(TW_Device_Extension *tw_dev)
2706     {
2707     	u32 control_reg_addr, control_reg_value;
2708     
2709     	control_reg_addr = tw_dev->registers.control_reg_addr;
2710     	control_reg_value = TW_CONTROL_UNMASK_COMMAND_INTERRUPT;
2711     	outl(control_reg_value, control_reg_addr);
2712     } /* End tw_unmask_command_interrupt() */
2713     
2714     /* Now get things going */
2715     
2716     static Scsi_Host_Template driver_template = TWXXXX;
2717     #include "scsi_module.c"
2718     
2719