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