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