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