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