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