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