[SCSI] aic79xx: Print out signalling
[linux-2.6] / 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-2005 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    1.26.02.000 - Convert driver to pci_driver format.
188    1.26.02.001 - Increase max ioctl buffer size to 512 sectors.
189                  Make tw_scsi_queue() return 0 for 'Unknown scsi opcode'.
190                  Fix tw_remove() to free irq handler/unregister_chrdev()
191                  before shutting down card.
192                  Change to new 'change_queue_depth' api.
193                  Fix 'handled=1' ISR usage, remove bogus IRQ check.
194 */
195
196 #include <linux/module.h>
197 #include <linux/reboot.h>
198 #include <linux/spinlock.h>
199 #include <linux/interrupt.h>
200 #include <linux/moduleparam.h>
201 #include <linux/errno.h>
202 #include <linux/types.h>
203 #include <linux/delay.h>
204 #include <linux/pci.h>
205 #include <linux/time.h>
206 #include <linux/mutex.h>
207 #include <asm/io.h>
208 #include <asm/irq.h>
209 #include <asm/uaccess.h>
210 #include <scsi/scsi.h>
211 #include <scsi/scsi_host.h>
212 #include <scsi/scsi_tcq.h>
213 #include <scsi/scsi_cmnd.h>
214 #include "3w-xxxx.h"
215
216 /* Globals */
217 #define TW_DRIVER_VERSION "1.26.02.001"
218 static TW_Device_Extension *tw_device_extension_list[TW_MAX_SLOT];
219 static int tw_device_extension_count = 0;
220 static int twe_major = -1;
221
222 /* Module parameters */
223 MODULE_AUTHOR("AMCC");
224 MODULE_DESCRIPTION("3ware Storage Controller Linux Driver");
225 MODULE_LICENSE("GPL");
226 MODULE_VERSION(TW_DRIVER_VERSION);
227
228 /* Function prototypes */
229 static int tw_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_reset);
230
231 /* Functions */
232
233 /* This function will check the status register for unexpected bits */
234 static int tw_check_bits(u32 status_reg_value)
235 {
236         if ((status_reg_value & TW_STATUS_EXPECTED_BITS) != TW_STATUS_EXPECTED_BITS) {  
237                 dprintk(KERN_WARNING "3w-xxxx: tw_check_bits(): No expected bits (0x%x).\n", status_reg_value);
238                 return 1;
239         }
240         if ((status_reg_value & TW_STATUS_UNEXPECTED_BITS) != 0) {
241                 dprintk(KERN_WARNING "3w-xxxx: tw_check_bits(): Found unexpected bits (0x%x).\n", status_reg_value);
242                 return 1;
243         }
244
245         return 0;
246 } /* End tw_check_bits() */
247
248 /* This function will print readable messages from status register errors */
249 static int tw_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value, int print_host)
250 {
251         char host[16];
252
253         dprintk(KERN_WARNING "3w-xxxx: tw_decode_bits()\n");
254
255         if (print_host)
256                 sprintf(host, " scsi%d:", tw_dev->host->host_no);
257         else
258                 host[0] = '\0';
259
260         if (status_reg_value & TW_STATUS_PCI_PARITY_ERROR) {
261                 printk(KERN_WARNING "3w-xxxx:%s PCI Parity Error: clearing.\n", host);
262                 outl(TW_CONTROL_CLEAR_PARITY_ERROR, TW_CONTROL_REG_ADDR(tw_dev));
263         }
264
265         if (status_reg_value & TW_STATUS_PCI_ABORT) {
266                 printk(KERN_WARNING "3w-xxxx:%s PCI Abort: clearing.\n", host);
267                 outl(TW_CONTROL_CLEAR_PCI_ABORT, TW_CONTROL_REG_ADDR(tw_dev));
268                 pci_write_config_word(tw_dev->tw_pci_dev, PCI_STATUS, TW_PCI_CLEAR_PCI_ABORT);
269         }
270
271         if (status_reg_value & TW_STATUS_QUEUE_ERROR) {
272                 printk(KERN_WARNING "3w-xxxx:%s Controller Queue Error: clearing.\n", host);
273                 outl(TW_CONTROL_CLEAR_QUEUE_ERROR, TW_CONTROL_REG_ADDR(tw_dev));
274         }
275
276         if (status_reg_value & TW_STATUS_SBUF_WRITE_ERROR) {
277                 printk(KERN_WARNING "3w-xxxx:%s SBUF Write Error: clearing.\n", host);
278                 outl(TW_CONTROL_CLEAR_SBUF_WRITE_ERROR, TW_CONTROL_REG_ADDR(tw_dev));
279         }
280
281         if (status_reg_value & TW_STATUS_MICROCONTROLLER_ERROR) {
282                 if (tw_dev->reset_print == 0) {
283                         printk(KERN_WARNING "3w-xxxx:%s Microcontroller Error: clearing.\n", host);
284                         tw_dev->reset_print = 1;
285                 }
286                 return 1;
287         }
288         
289         return 0;
290 } /* End tw_decode_bits() */
291
292 /* This function will poll the status register for a flag */
293 static int tw_poll_status(TW_Device_Extension *tw_dev, u32 flag, int seconds)
294 {
295         u32 status_reg_value;
296         unsigned long before;
297         int retval = 1;
298
299         status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
300         before = jiffies;
301
302         if (tw_check_bits(status_reg_value))
303                 tw_decode_bits(tw_dev, status_reg_value, 0);
304
305         while ((status_reg_value & flag) != flag) {
306                 status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
307
308                 if (tw_check_bits(status_reg_value))
309                         tw_decode_bits(tw_dev, status_reg_value, 0);
310
311                 if (time_after(jiffies, before + HZ * seconds))
312                         goto out;
313
314                 msleep(50);
315         }
316         retval = 0;
317 out:
318         return retval;
319 } /* End tw_poll_status() */
320
321 /* This function will poll the status register for disappearance of a flag */
322 static int tw_poll_status_gone(TW_Device_Extension *tw_dev, u32 flag, int seconds)
323 {
324         u32 status_reg_value;
325         unsigned long before;
326         int retval = 1;
327
328         status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
329         before = jiffies;
330
331         if (tw_check_bits(status_reg_value))
332                 tw_decode_bits(tw_dev, status_reg_value, 0);
333
334         while ((status_reg_value & flag) != 0) {
335                 status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
336
337                 if (tw_check_bits(status_reg_value))
338                         tw_decode_bits(tw_dev, status_reg_value, 0);
339
340                 if (time_after(jiffies, before + HZ * seconds))
341                         goto out;
342
343                 msleep(50);
344         }
345         retval = 0;
346 out:
347         return retval;
348 } /* End tw_poll_status_gone() */
349
350 /* This function will attempt to post a command packet to the board */
351 static int tw_post_command_packet(TW_Device_Extension *tw_dev, int request_id)
352 {
353         u32 status_reg_value;
354         unsigned long command_que_value;
355
356         dprintk(KERN_NOTICE "3w-xxxx: tw_post_command_packet()\n");
357         command_que_value = tw_dev->command_packet_physical_address[request_id];
358         status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
359
360         if (tw_check_bits(status_reg_value)) {
361                 dprintk(KERN_WARNING "3w-xxxx: tw_post_command_packet(): Unexpected bits.\n");
362                 tw_decode_bits(tw_dev, status_reg_value, 1);
363         }
364
365         if ((status_reg_value & TW_STATUS_COMMAND_QUEUE_FULL) == 0) {
366                 /* We successfully posted the command packet */
367                 outl(command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
368                 tw_dev->state[request_id] = TW_S_POSTED;
369                 tw_dev->posted_request_count++;
370                 if (tw_dev->posted_request_count > tw_dev->max_posted_request_count) {
371                         tw_dev->max_posted_request_count = tw_dev->posted_request_count;
372                 }
373         } else {
374                 /* Couldn't post the command packet, so we do it in the isr */
375                 if (tw_dev->state[request_id] != TW_S_PENDING) {
376                         tw_dev->state[request_id] = TW_S_PENDING;
377                         tw_dev->pending_request_count++;
378                         if (tw_dev->pending_request_count > tw_dev->max_pending_request_count) {
379                                 tw_dev->max_pending_request_count = tw_dev->pending_request_count;
380                         }
381                         tw_dev->pending_queue[tw_dev->pending_tail] = request_id;
382                         if (tw_dev->pending_tail == TW_Q_LENGTH-1) {
383                                 tw_dev->pending_tail = TW_Q_START;
384                         } else {
385                                 tw_dev->pending_tail = tw_dev->pending_tail + 1;
386                         }
387                 } 
388                 TW_UNMASK_COMMAND_INTERRUPT(tw_dev);
389                 return 1;
390         }
391         return 0;
392 } /* End tw_post_command_packet() */
393
394 /* This function will return valid sense buffer information for failed cmds */
395 static int tw_decode_sense(TW_Device_Extension *tw_dev, int request_id, int fill_sense)
396 {
397         int i;
398         TW_Command *command;
399
400         dprintk(KERN_WARNING "3w-xxxx: tw_decode_sense()\n");
401         command = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
402
403         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, TW_UNIT_OUT(command->unit__hostid));
404
405         /* Attempt to return intelligent sense information */
406         if (fill_sense) {
407                 if ((command->status == 0xc7) || (command->status == 0xcb)) {
408                         for (i = 0; i < ARRAY_SIZE(tw_sense_table); i++) {
409                                 if (command->flags == tw_sense_table[i][0]) {
410
411                                         /* Valid bit and 'current errors' */
412                                         tw_dev->srb[request_id]->sense_buffer[0] = (0x1 << 7 | 0x70);
413
414                                         /* Sense key */
415                                         tw_dev->srb[request_id]->sense_buffer[2] = tw_sense_table[i][1];
416
417                                         /* Additional sense length */
418                                         tw_dev->srb[request_id]->sense_buffer[7] = 0xa; /* 10 bytes */
419
420                                         /* Additional sense code */
421                                         tw_dev->srb[request_id]->sense_buffer[12] = tw_sense_table[i][2];
422
423                                         /* Additional sense code qualifier */
424                                         tw_dev->srb[request_id]->sense_buffer[13] = tw_sense_table[i][3];
425
426                                         tw_dev->srb[request_id]->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
427                                         return TW_ISR_DONT_RESULT; /* Special case for isr to not over-write result */
428                                 }
429                         }
430                 }
431
432                 /* If no table match, error so we get a reset */
433                 return 1;
434         }
435
436         return 0;
437 } /* End tw_decode_sense() */
438
439 /* This function will report controller error status */
440 static int tw_check_errors(TW_Device_Extension *tw_dev) 
441 {
442         u32 status_reg_value;
443   
444         status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
445
446         if (TW_STATUS_ERRORS(status_reg_value) || tw_check_bits(status_reg_value)) {
447                 tw_decode_bits(tw_dev, status_reg_value, 0);
448                 return 1;
449         }
450
451         return 0;
452 } /* End tw_check_errors() */
453
454 /* This function will empty the response que */
455 static void tw_empty_response_que(TW_Device_Extension *tw_dev) 
456 {
457         u32 status_reg_value, response_que_value;
458
459         status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
460
461         while ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
462                 response_que_value = inl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
463                 status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
464         }
465 } /* End tw_empty_response_que() */
466
467 /* This function will free a request_id */
468 static void tw_state_request_finish(TW_Device_Extension *tw_dev, int request_id)
469 {
470         tw_dev->free_queue[tw_dev->free_tail] = request_id;
471         tw_dev->state[request_id] = TW_S_FINISHED;
472         tw_dev->free_tail = (tw_dev->free_tail + 1) % TW_Q_LENGTH;
473 } /* End tw_state_request_finish() */
474
475 /* This function will assign an available request_id */
476 static void tw_state_request_start(TW_Device_Extension *tw_dev, int *request_id)
477 {
478         *request_id = tw_dev->free_queue[tw_dev->free_head];
479         tw_dev->free_head = (tw_dev->free_head + 1) % TW_Q_LENGTH;
480         tw_dev->state[*request_id] = TW_S_STARTED;
481 } /* End tw_state_request_start() */
482
483 /* Show some statistics about the card */
484 static ssize_t tw_show_stats(struct class_device *class_dev, char *buf)
485 {
486         struct Scsi_Host *host = class_to_shost(class_dev);
487         TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
488         unsigned long flags = 0;
489         ssize_t len;
490
491         spin_lock_irqsave(tw_dev->host->host_lock, flags);
492         len = snprintf(buf, PAGE_SIZE, "3w-xxxx Driver version: %s\n"
493                        "Current commands posted:   %4d\n"
494                        "Max commands posted:       %4d\n"
495                        "Current pending commands:  %4d\n"
496                        "Max pending commands:      %4d\n"
497                        "Last sgl length:           %4d\n"
498                        "Max sgl length:            %4d\n"
499                        "Last sector count:         %4d\n"
500                        "Max sector count:          %4d\n"
501                        "SCSI Host Resets:          %4d\n"
502                        "AEN's:                     %4d\n", 
503                        TW_DRIVER_VERSION,
504                        tw_dev->posted_request_count,
505                        tw_dev->max_posted_request_count,
506                        tw_dev->pending_request_count,
507                        tw_dev->max_pending_request_count,
508                        tw_dev->sgl_entries,
509                        tw_dev->max_sgl_entries,
510                        tw_dev->sector_count,
511                        tw_dev->max_sector_count,
512                        tw_dev->num_resets,
513                        tw_dev->aen_count);
514         spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
515         return len;
516 } /* End tw_show_stats() */
517
518 /* This function will set a devices queue depth */
519 static int tw_change_queue_depth(struct scsi_device *sdev, int queue_depth)
520 {
521         if (queue_depth > TW_Q_LENGTH-2)
522                 queue_depth = TW_Q_LENGTH-2;
523         scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, queue_depth);
524         return queue_depth;
525 } /* End tw_change_queue_depth() */
526
527 /* Create sysfs 'stats' entry */
528 static struct class_device_attribute tw_host_stats_attr = {
529         .attr = {
530                 .name =         "stats",
531                 .mode =         S_IRUGO,
532         },
533         .show = tw_show_stats
534 };
535
536 /* Host attributes initializer */
537 static struct class_device_attribute *tw_host_attrs[] = {
538         &tw_host_stats_attr,
539         NULL,
540 };
541
542 /* This function will read the aen queue from the isr */
543 static int tw_aen_read_queue(TW_Device_Extension *tw_dev, int request_id) 
544 {
545         TW_Command *command_packet;
546         TW_Param *param;
547         unsigned long command_que_value;
548         u32 status_reg_value;
549         unsigned long param_value = 0;
550
551         dprintk(KERN_NOTICE "3w-xxxx: tw_aen_read_queue()\n");
552
553         status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
554         if (tw_check_bits(status_reg_value)) {
555                 dprintk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Unexpected bits.\n");
556                 tw_decode_bits(tw_dev, status_reg_value, 1);
557                 return 1;
558         }
559         if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
560                 printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad command packet virtual address.\n");
561                 return 1;
562         }
563         command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
564         memset(command_packet, 0, sizeof(TW_Sector));
565         command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
566         command_packet->size = 4;
567         command_packet->request_id = request_id;
568         command_packet->status = 0;
569         command_packet->flags = 0;
570         command_packet->byte6.parameter_count = 1;
571         command_que_value = tw_dev->command_packet_physical_address[request_id];
572         if (command_que_value == 0) {
573                 printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad command packet physical address.\n");
574                 return 1;
575         }
576         /* Now setup the param */
577         if (tw_dev->alignment_virtual_address[request_id] == NULL) {
578                 printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad alignment virtual address.\n");
579                 return 1;
580         }
581         param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
582         memset(param, 0, sizeof(TW_Sector));
583         param->table_id = 0x401; /* AEN table */
584         param->parameter_id = 2; /* Unit code */
585         param->parameter_size_bytes = 2;
586         param_value = tw_dev->alignment_physical_address[request_id];
587         if (param_value == 0) {
588                 printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad alignment physical address.\n");
589                 return 1;
590         }
591         command_packet->byte8.param.sgl[0].address = param_value;
592         command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
593
594         /* Now post the command packet */
595         if ((status_reg_value & TW_STATUS_COMMAND_QUEUE_FULL) == 0) {
596                 dprintk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Post succeeded.\n");
597                 tw_dev->srb[request_id] = NULL; /* Flag internal command */
598                 tw_dev->state[request_id] = TW_S_POSTED;
599                 outl(command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
600         } else {
601                 printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Post failed, will retry.\n");
602                 return 1;
603         }
604
605         return 0;
606 } /* End tw_aen_read_queue() */
607
608 /* This function will complete an aen request from the isr */
609 static int tw_aen_complete(TW_Device_Extension *tw_dev, int request_id) 
610 {
611         TW_Param *param;
612         unsigned short aen;
613         int error = 0, table_max = 0;
614
615         dprintk(KERN_WARNING "3w-xxxx: tw_aen_complete()\n");
616         if (tw_dev->alignment_virtual_address[request_id] == NULL) {
617                 printk(KERN_WARNING "3w-xxxx: tw_aen_complete(): Bad alignment virtual address.\n");
618                 return 1;
619         }
620         param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
621         aen = *(unsigned short *)(param->data);
622         dprintk(KERN_NOTICE "3w-xxxx: tw_aen_complete(): Queue'd code 0x%x\n", aen);
623
624         /* Print some useful info when certain aen codes come out */
625         if (aen == 0x0ff) {
626                 printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: INFO: AEN queue overflow.\n", tw_dev->host->host_no);
627         } else {
628                 table_max = ARRAY_SIZE(tw_aen_string);
629                 if ((aen & 0x0ff) < table_max) {
630                         if ((tw_aen_string[aen & 0xff][strlen(tw_aen_string[aen & 0xff])-1]) == '#') {
631                                 printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: %s%d.\n", tw_dev->host->host_no, tw_aen_string[aen & 0xff], aen >> 8);
632                         } else {
633                                 if (aen != 0x0) 
634                                         printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: %s.\n", tw_dev->host->host_no, tw_aen_string[aen & 0xff]);
635                         }
636                 } else {
637                         printk(KERN_WARNING "3w-xxxx: scsi%d: Received AEN %d.\n", tw_dev->host->host_no, aen);
638                 }
639         }
640         if (aen != TW_AEN_QUEUE_EMPTY) {
641                 tw_dev->aen_count++;
642
643                 /* Now queue the code */
644                 tw_dev->aen_queue[tw_dev->aen_tail] = aen;
645                 if (tw_dev->aen_tail == TW_Q_LENGTH - 1) {
646                         tw_dev->aen_tail = TW_Q_START;
647                 } else {
648                         tw_dev->aen_tail = tw_dev->aen_tail + 1;
649                 }
650                 if (tw_dev->aen_head == tw_dev->aen_tail) {
651                         if (tw_dev->aen_head == TW_Q_LENGTH - 1) {
652                                 tw_dev->aen_head = TW_Q_START;
653                         } else {
654                                 tw_dev->aen_head = tw_dev->aen_head + 1;
655                         }
656                 }
657
658                 error = tw_aen_read_queue(tw_dev, request_id);
659                 if (error) {
660                         printk(KERN_WARNING "3w-xxxx: scsi%d: Error completing AEN.\n", tw_dev->host->host_no);
661                         tw_dev->state[request_id] = TW_S_COMPLETED;
662                         tw_state_request_finish(tw_dev, request_id);
663                 }
664         } else {
665                 tw_dev->state[request_id] = TW_S_COMPLETED;
666                 tw_state_request_finish(tw_dev, request_id);
667         }
668
669         return 0;
670 } /* End tw_aen_complete() */
671
672 /* This function will drain the aen queue after a soft reset */
673 static int tw_aen_drain_queue(TW_Device_Extension *tw_dev)
674 {
675         TW_Command *command_packet;
676         TW_Param *param;
677         int request_id = 0;
678         unsigned long command_que_value;
679         unsigned long param_value;
680         TW_Response_Queue response_queue;
681         unsigned short aen;
682         unsigned short aen_code;
683         int finished = 0;
684         int first_reset = 0;
685         int queue = 0;
686         int found = 0, table_max = 0;
687
688         dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue()\n");
689
690         if (tw_poll_status(tw_dev, TW_STATUS_ATTENTION_INTERRUPT | TW_STATUS_MICROCONTROLLER_READY, 30)) {
691                 dprintk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): No attention interrupt for card %d.\n", tw_device_extension_count);
692                 return 1;
693         }
694         TW_CLEAR_ATTENTION_INTERRUPT(tw_dev);
695
696         /* Empty response queue */
697         tw_empty_response_que(tw_dev);
698
699         /* Initialize command packet */
700         if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
701                 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad command packet virtual address.\n");
702                 return 1;
703         }
704         command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
705         memset(command_packet, 0, sizeof(TW_Sector));
706         command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
707         command_packet->size = 4;
708         command_packet->request_id = request_id;
709         command_packet->status = 0;
710         command_packet->flags = 0;
711         command_packet->byte6.parameter_count = 1;
712         command_que_value = tw_dev->command_packet_physical_address[request_id];
713         if (command_que_value == 0) {
714                 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad command packet physical address.\n");
715                 return 1;
716         }
717
718         /* Now setup the param */
719         if (tw_dev->alignment_virtual_address[request_id] == NULL) {
720                 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad alignment virtual address.\n");
721                 return 1;
722         }
723         param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
724         memset(param, 0, sizeof(TW_Sector));
725         param->table_id = 0x401; /* AEN table */
726         param->parameter_id = 2; /* Unit code */
727         param->parameter_size_bytes = 2;
728         param_value = tw_dev->alignment_physical_address[request_id];
729         if (param_value == 0) {
730                 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad alignment physical address.\n");
731                 return 1;
732         }
733         command_packet->byte8.param.sgl[0].address = param_value;
734         command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
735
736         /* Now drain the controller's aen queue */
737         do {
738                 /* Post command packet */
739                 outl(command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
740
741                 /* Now poll for completion */
742                 if (tw_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, 30) == 0) {
743                         response_queue.value = inl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
744                         request_id = TW_RESID_OUT(response_queue.response_id);
745
746                         if (request_id != 0) {
747                                 /* Unexpected request id */
748                                 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Unexpected request id.\n");
749                                 return 1;
750                         }
751                         
752                         if (command_packet->status != 0) {
753                                 if (command_packet->flags != TW_AEN_TABLE_UNDEFINED) {
754                                         /* Bad response */
755                                         tw_decode_sense(tw_dev, request_id, 0);
756                                         return 1;
757                                 } else {
758                                         /* We know this is a 3w-1x00, and doesn't support aen's */
759                                         return 0;
760                                 }
761                         }
762
763                         /* Now check the aen */
764                         aen = *(unsigned short *)(param->data);
765                         aen_code = (aen & 0x0ff);
766                         queue = 0;
767                         switch (aen_code) {
768                                 case TW_AEN_QUEUE_EMPTY:
769                                         dprintk(KERN_WARNING "3w-xxxx: AEN: %s.\n", tw_aen_string[aen & 0xff]);
770                                         if (first_reset != 1) {
771                                                 return 1;
772                                         } else {
773                                                 finished = 1;
774                                         }
775                                         break;
776                                 case TW_AEN_SOFT_RESET:
777                                         if (first_reset == 0) {
778                                                 first_reset = 1;
779                                         } else {
780                                                 printk(KERN_WARNING "3w-xxxx: AEN: %s.\n", tw_aen_string[aen & 0xff]);
781                                                 tw_dev->aen_count++;
782                                                 queue = 1;
783                                         }
784                                         break;
785                                 default:
786                                         if (aen == 0x0ff) {
787                                                 printk(KERN_WARNING "3w-xxxx: AEN: INFO: AEN queue overflow.\n");
788                                         } else {
789                                                 table_max = ARRAY_SIZE(tw_aen_string);
790                                                 if ((aen & 0x0ff) < table_max) {
791                                                         if ((tw_aen_string[aen & 0xff][strlen(tw_aen_string[aen & 0xff])-1]) == '#') {
792                                                                 printk(KERN_WARNING "3w-xxxx: AEN: %s%d.\n", tw_aen_string[aen & 0xff], aen >> 8);
793                                                         } else {
794                                                                 printk(KERN_WARNING "3w-xxxx: AEN: %s.\n", tw_aen_string[aen & 0xff]);
795                                                         }
796                                                 } else
797                                                         printk(KERN_WARNING "3w-xxxx: Received AEN %d.\n", aen);
798                                         }
799                                         tw_dev->aen_count++;
800                                         queue = 1;
801                         }
802
803                         /* Now put the aen on the aen_queue */
804                         if (queue == 1) {
805                                 tw_dev->aen_queue[tw_dev->aen_tail] = aen;
806                                 if (tw_dev->aen_tail == TW_Q_LENGTH - 1) {
807                                         tw_dev->aen_tail = TW_Q_START;
808                                 } else {
809                                         tw_dev->aen_tail = tw_dev->aen_tail + 1;
810                                 }
811                                 if (tw_dev->aen_head == tw_dev->aen_tail) {
812                                         if (tw_dev->aen_head == TW_Q_LENGTH - 1) {
813                                                 tw_dev->aen_head = TW_Q_START;
814                                         } else {
815                                                 tw_dev->aen_head = tw_dev->aen_head + 1;
816                                         }
817                                 }
818                         }
819                         found = 1;
820                 }
821                 if (found == 0) {
822                         printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Response never received.\n");
823                         return 1;
824                 }
825         } while (finished == 0);
826
827         return 0;
828 } /* End tw_aen_drain_queue() */
829
830 /* This function will allocate memory */
831 static int tw_allocate_memory(TW_Device_Extension *tw_dev, int size, int which)
832 {
833         int i;
834         dma_addr_t dma_handle;
835         unsigned long *cpu_addr = NULL;
836
837         dprintk(KERN_NOTICE "3w-xxxx: tw_allocate_memory()\n");
838
839         cpu_addr = pci_alloc_consistent(tw_dev->tw_pci_dev, size*TW_Q_LENGTH, &dma_handle);
840         if (cpu_addr == NULL) {
841                 printk(KERN_WARNING "3w-xxxx: pci_alloc_consistent() failed.\n");
842                 return 1;
843         }
844
845         if ((unsigned long)cpu_addr % (tw_dev->tw_pci_dev->device == TW_DEVICE_ID ? TW_ALIGNMENT_6000 : TW_ALIGNMENT_7000)) {
846                 printk(KERN_WARNING "3w-xxxx: Couldn't allocate correctly aligned memory.\n");
847                 pci_free_consistent(tw_dev->tw_pci_dev, size*TW_Q_LENGTH, cpu_addr, dma_handle);
848                 return 1;
849         }
850
851         memset(cpu_addr, 0, size*TW_Q_LENGTH);
852
853         for (i=0;i<TW_Q_LENGTH;i++) {
854                 switch(which) {
855                 case 0:
856                         tw_dev->command_packet_physical_address[i] = dma_handle+(i*size);
857                         tw_dev->command_packet_virtual_address[i] = (unsigned long *)((unsigned char *)cpu_addr + (i*size));
858                         break;
859                 case 1:
860                         tw_dev->alignment_physical_address[i] = dma_handle+(i*size);
861                         tw_dev->alignment_virtual_address[i] = (unsigned long *)((unsigned char *)cpu_addr + (i*size));
862                         break;
863                 default:
864                         printk(KERN_WARNING "3w-xxxx: tw_allocate_memory(): case slip in tw_allocate_memory()\n");
865                         return 1;
866                 }
867         }
868
869         return 0;
870 } /* End tw_allocate_memory() */
871
872 /* This function handles ioctl for the character device */
873 static int tw_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
874 {
875         int request_id;
876         dma_addr_t dma_handle;
877         unsigned short tw_aen_code;
878         unsigned long flags;
879         unsigned int data_buffer_length = 0;
880         unsigned long data_buffer_length_adjusted = 0;
881         unsigned long *cpu_addr;
882         long timeout;
883         TW_New_Ioctl *tw_ioctl;
884         TW_Passthru *passthru;
885         TW_Device_Extension *tw_dev = tw_device_extension_list[iminor(inode)];
886         int retval = -EFAULT;
887         void __user *argp = (void __user *)arg;
888
889         dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl()\n");
890
891         /* Only let one of these through at a time */
892         if (mutex_lock_interruptible(&tw_dev->ioctl_lock))
893                 return -EINTR;
894
895         /* First copy down the buffer length */
896         if (copy_from_user(&data_buffer_length, argp, sizeof(unsigned int)))
897                 goto out;
898
899         /* Check size */
900         if (data_buffer_length > TW_MAX_IOCTL_SECTORS * 512) {
901                 retval = -EINVAL;
902                 goto out;
903         }
904
905         /* Hardware can only do multiple of 512 byte transfers */
906         data_buffer_length_adjusted = (data_buffer_length + 511) & ~511;
907         
908         /* Now allocate ioctl buf memory */
909         cpu_addr = dma_alloc_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_New_Ioctl) - 1, &dma_handle, GFP_KERNEL);
910         if (cpu_addr == NULL) {
911                 retval = -ENOMEM;
912                 goto out;
913         }
914
915         tw_ioctl = (TW_New_Ioctl *)cpu_addr;
916
917         /* Now copy down the entire ioctl */
918         if (copy_from_user(tw_ioctl, argp, data_buffer_length + sizeof(TW_New_Ioctl) - 1))
919                 goto out2;
920
921         passthru = (TW_Passthru *)&tw_ioctl->firmware_command;
922
923         /* See which ioctl we are doing */
924         switch (cmd) {
925                 case TW_OP_NOP:
926                         dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl(): caught TW_OP_NOP.\n");
927                         break;
928                 case TW_OP_AEN_LISTEN:
929                         dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl(): caught TW_AEN_LISTEN.\n");
930                         memset(tw_ioctl->data_buffer, 0, data_buffer_length);
931
932                         spin_lock_irqsave(tw_dev->host->host_lock, flags);
933                         if (tw_dev->aen_head == tw_dev->aen_tail) {
934                                 tw_aen_code = TW_AEN_QUEUE_EMPTY;
935                         } else {
936                                 tw_aen_code = tw_dev->aen_queue[tw_dev->aen_head];
937                                 if (tw_dev->aen_head == TW_Q_LENGTH - 1) {
938                                         tw_dev->aen_head = TW_Q_START;
939                                 } else {
940                                         tw_dev->aen_head = tw_dev->aen_head + 1;
941                                 }
942                         }
943                         spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
944                         memcpy(tw_ioctl->data_buffer, &tw_aen_code, sizeof(tw_aen_code));
945                         break;
946                 case TW_CMD_PACKET_WITH_DATA:
947                         dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl(): caught TW_CMD_PACKET_WITH_DATA.\n");
948                         spin_lock_irqsave(tw_dev->host->host_lock, flags);
949
950                         tw_state_request_start(tw_dev, &request_id);
951
952                         /* Flag internal command */
953                         tw_dev->srb[request_id] = NULL;
954
955                         /* Flag chrdev ioctl */
956                         tw_dev->chrdev_request_id = request_id;
957
958                         tw_ioctl->firmware_command.request_id = request_id;
959
960                         /* Load the sg list */
961                         switch (TW_SGL_OUT(tw_ioctl->firmware_command.opcode__sgloffset)) {
962                         case 2:
963                                 tw_ioctl->firmware_command.byte8.param.sgl[0].address = dma_handle + sizeof(TW_New_Ioctl) - 1;
964                                 tw_ioctl->firmware_command.byte8.param.sgl[0].length = data_buffer_length_adjusted;
965                                 break;
966                         case 3:
967                                 tw_ioctl->firmware_command.byte8.io.sgl[0].address = dma_handle + sizeof(TW_New_Ioctl) - 1;
968                                 tw_ioctl->firmware_command.byte8.io.sgl[0].length = data_buffer_length_adjusted;
969                                 break;
970                         case 5:
971                                 passthru->sg_list[0].address = dma_handle + sizeof(TW_New_Ioctl) - 1;
972                                 passthru->sg_list[0].length = data_buffer_length_adjusted;
973                                 break;
974                         }
975
976                         memcpy(tw_dev->command_packet_virtual_address[request_id], &(tw_ioctl->firmware_command), sizeof(TW_Command));
977
978                         /* Now post the command packet to the controller */
979                         tw_post_command_packet(tw_dev, request_id);
980                         spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
981
982                         timeout = TW_IOCTL_CHRDEV_TIMEOUT*HZ;
983
984                         /* Now wait for the command to complete */
985                         timeout = wait_event_timeout(tw_dev->ioctl_wqueue, tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE, timeout);
986
987                         /* See if we reset while waiting for the ioctl to complete */
988                         if (test_bit(TW_IN_RESET, &tw_dev->flags)) {
989                                 clear_bit(TW_IN_RESET, &tw_dev->flags);
990                                 retval = -ERESTARTSYS;
991                                 goto out2;
992                         }
993
994                         /* We timed out, and didn't get an interrupt */
995                         if (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE) {
996                                 /* Now we need to reset the board */
997                                 printk(KERN_WARNING "3w-xxxx: scsi%d: Character ioctl (0x%x) timed out, resetting card.\n", tw_dev->host->host_no, cmd);
998                                 retval = -EIO;
999                                 spin_lock_irqsave(tw_dev->host->host_lock, flags);
1000                                 tw_dev->state[request_id] = TW_S_COMPLETED;
1001                                 tw_state_request_finish(tw_dev, request_id);
1002                                 tw_dev->posted_request_count--;
1003                                 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
1004                                 if (tw_reset_device_extension(tw_dev, 1)) {
1005                                         printk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl(): Reset failed for card %d.\n", tw_dev->host->host_no);
1006                                 }
1007                                 goto out2;
1008                         }
1009
1010                         /* Now copy in the command packet response */
1011                         memcpy(&(tw_ioctl->firmware_command), tw_dev->command_packet_virtual_address[request_id], sizeof(TW_Command));
1012
1013                         /* Now complete the io */
1014                         spin_lock_irqsave(tw_dev->host->host_lock, flags);
1015                         tw_dev->posted_request_count--;
1016                         tw_dev->state[request_id] = TW_S_COMPLETED;
1017                         tw_state_request_finish(tw_dev, request_id);
1018                         spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
1019                         break;
1020                 default:
1021                         retval = -ENOTTY;
1022                         goto out2;
1023         }
1024
1025         /* Now copy the response to userspace */
1026         if (copy_to_user(argp, tw_ioctl, sizeof(TW_New_Ioctl) + data_buffer_length - 1))
1027                 goto out2;
1028         retval = 0;
1029 out2:
1030         /* Now free ioctl buf memory */
1031         dma_free_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_New_Ioctl) - 1, cpu_addr, dma_handle);
1032 out:
1033         mutex_unlock(&tw_dev->ioctl_lock);
1034         return retval;
1035 } /* End tw_chrdev_ioctl() */
1036
1037 /* This function handles open for the character device */
1038 static int tw_chrdev_open(struct inode *inode, struct file *file)
1039 {
1040         unsigned int minor_number;
1041
1042         dprintk(KERN_WARNING "3w-xxxx: tw_ioctl_open()\n");
1043
1044         minor_number = iminor(inode);
1045         if (minor_number >= tw_device_extension_count)
1046                 return -ENODEV;
1047
1048         return 0;
1049 } /* End tw_chrdev_open() */
1050
1051 /* File operations struct for character device */
1052 static struct file_operations tw_fops = {
1053         .owner          = THIS_MODULE,
1054         .ioctl          = tw_chrdev_ioctl,
1055         .open           = tw_chrdev_open,
1056         .release        = NULL
1057 };
1058
1059 /* This function will free up device extension resources */
1060 static void tw_free_device_extension(TW_Device_Extension *tw_dev)
1061 {
1062         dprintk(KERN_NOTICE "3w-xxxx: tw_free_device_extension()\n");
1063
1064         /* Free command packet and generic buffer memory */
1065         if (tw_dev->command_packet_virtual_address[0])
1066                 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]);
1067
1068         if (tw_dev->alignment_virtual_address[0])
1069                 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]);
1070 } /* End tw_free_device_extension() */
1071
1072 /* This function will send an initconnection command to controller */
1073 static int tw_initconnection(TW_Device_Extension *tw_dev, int message_credits) 
1074 {
1075         unsigned long command_que_value;
1076         TW_Command  *command_packet;
1077         TW_Response_Queue response_queue;
1078         int request_id = 0;
1079
1080         dprintk(KERN_NOTICE "3w-xxxx: tw_initconnection()\n");
1081
1082         /* Initialize InitConnection command packet */
1083         if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
1084                 printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad command packet virtual address.\n");
1085                 return 1;
1086         }
1087
1088         command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1089         memset(command_packet, 0, sizeof(TW_Sector));
1090         command_packet->opcode__sgloffset = TW_OPSGL_IN(0, TW_OP_INIT_CONNECTION);
1091         command_packet->size = TW_INIT_COMMAND_PACKET_SIZE;
1092         command_packet->request_id = request_id;
1093         command_packet->status = 0x0;
1094         command_packet->flags = 0x0;
1095         command_packet->byte6.message_credits = message_credits; 
1096         command_packet->byte8.init_connection.response_queue_pointer = 0x0;
1097         command_que_value = tw_dev->command_packet_physical_address[request_id];
1098
1099         if (command_que_value == 0) {
1100                 printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad command packet physical address.\n");
1101                 return 1;
1102         }
1103   
1104         /* Send command packet to the board */
1105         outl(command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
1106     
1107         /* Poll for completion */
1108         if (tw_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, 30) == 0) {
1109                 response_queue.value = inl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
1110                 request_id = TW_RESID_OUT(response_queue.response_id);
1111
1112                 if (request_id != 0) {
1113                         /* unexpected request id */
1114                         printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Unexpected request id.\n");
1115                         return 1;
1116                 }
1117                 if (command_packet->status != 0) {
1118                         /* bad response */
1119                         tw_decode_sense(tw_dev, request_id, 0);
1120                         return 1;
1121                 }
1122         }
1123         return 0;
1124 } /* End tw_initconnection() */
1125
1126 /* Set a value in the features table */
1127 static int tw_setfeature(TW_Device_Extension *tw_dev, int parm, int param_size,
1128                   unsigned char *val)
1129 {
1130         TW_Param *param;
1131         TW_Command  *command_packet;
1132         TW_Response_Queue response_queue;
1133         int request_id = 0;
1134         unsigned long command_que_value;
1135         unsigned long param_value;
1136
1137         /* Initialize SetParam command packet */
1138         if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
1139                 printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad command packet virtual address.\n");
1140                 return 1;
1141         }
1142         command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1143         memset(command_packet, 0, sizeof(TW_Sector));
1144         param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1145
1146         command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_SET_PARAM);
1147         param->table_id = 0x404;  /* Features table */
1148         param->parameter_id = parm;
1149         param->parameter_size_bytes = param_size;
1150         memcpy(param->data, val, param_size);
1151
1152         param_value = tw_dev->alignment_physical_address[request_id];
1153         if (param_value == 0) {
1154                 printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad alignment physical address.\n");
1155                 tw_dev->state[request_id] = TW_S_COMPLETED;
1156                 tw_state_request_finish(tw_dev, request_id);
1157                 tw_dev->srb[request_id]->result = (DID_OK << 16);
1158                 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1159         }
1160         command_packet->byte8.param.sgl[0].address = param_value;
1161         command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
1162
1163         command_packet->size = 4;
1164         command_packet->request_id = request_id;
1165         command_packet->byte6.parameter_count = 1;
1166
1167         command_que_value = tw_dev->command_packet_physical_address[request_id];
1168         if (command_que_value == 0) {
1169                 printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad command packet physical address.\n");
1170         return 1;
1171         }
1172
1173         /* Send command packet to the board */
1174         outl(command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
1175
1176         /* Poll for completion */
1177         if (tw_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, 30) == 0) {
1178                 response_queue.value = inl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
1179                 request_id = TW_RESID_OUT(response_queue.response_id);
1180
1181                 if (request_id != 0) {
1182                         /* unexpected request id */
1183                         printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Unexpected request id.\n");
1184                         return 1;
1185                 }
1186                 if (command_packet->status != 0) {
1187                         /* bad response */
1188                         tw_decode_sense(tw_dev, request_id, 0);
1189                         return 1;
1190                 }
1191         }
1192
1193         return 0;
1194 } /* End tw_setfeature() */
1195
1196 /* This function will reset a controller */
1197 static int tw_reset_sequence(TW_Device_Extension *tw_dev) 
1198 {
1199         int error = 0;
1200         int tries = 0;
1201         unsigned char c = 1;
1202
1203         /* Reset the board */
1204         while (tries < TW_MAX_RESET_TRIES) {
1205                 TW_SOFT_RESET(tw_dev);
1206
1207                 error = tw_aen_drain_queue(tw_dev);
1208                 if (error) {
1209                         printk(KERN_WARNING "3w-xxxx: scsi%d: AEN drain failed, retrying.\n", tw_dev->host->host_no);
1210                         tries++;
1211                         continue;
1212                 }
1213
1214                 /* Check for controller errors */
1215                 if (tw_check_errors(tw_dev)) {
1216                         printk(KERN_WARNING "3w-xxxx: scsi%d: Controller errors found, retrying.\n", tw_dev->host->host_no);
1217                         tries++;
1218                         continue;
1219                 }
1220
1221                 /* Now the controller is in a good state */
1222                 break;
1223         }
1224
1225         if (tries >= TW_MAX_RESET_TRIES) {
1226                 printk(KERN_WARNING "3w-xxxx: scsi%d: Controller errors, card not responding, check all cabling.\n", tw_dev->host->host_no);
1227                 return 1;
1228         }
1229
1230         error = tw_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS);
1231         if (error) {
1232                 printk(KERN_WARNING "3w-xxxx: scsi%d: Connection initialization failed.\n", tw_dev->host->host_no);
1233                 return 1;
1234         }
1235
1236         error = tw_setfeature(tw_dev, 2, 1, &c);
1237         if (error) {
1238                 printk(KERN_WARNING "3w-xxxx: Unable to set features for card, probable old firmware or card.\n");
1239         }
1240
1241         return 0;
1242 } /* End tw_reset_sequence() */
1243
1244 /* This function will initialize the fields of a device extension */
1245 static int tw_initialize_device_extension(TW_Device_Extension *tw_dev)
1246 {
1247         int i, error=0;
1248
1249         dprintk(KERN_NOTICE "3w-xxxx: tw_initialize_device_extension()\n");
1250
1251         /* Initialize command packet buffers */
1252         error = tw_allocate_memory(tw_dev, sizeof(TW_Command), 0);
1253         if (error) {
1254                 printk(KERN_WARNING "3w-xxxx: Command packet memory allocation failed.\n");
1255                 return 1;
1256         }
1257
1258         /* Initialize generic buffer */
1259         error = tw_allocate_memory(tw_dev, sizeof(TW_Sector), 1);
1260         if (error) {
1261                 printk(KERN_WARNING "3w-xxxx: Generic memory allocation failed.\n");
1262                 return 1;
1263         }
1264
1265         for (i=0;i<TW_Q_LENGTH;i++) {
1266                 tw_dev->free_queue[i] = i;
1267                 tw_dev->state[i] = TW_S_INITIAL;
1268         }
1269
1270         tw_dev->pending_head = TW_Q_START;
1271         tw_dev->pending_tail = TW_Q_START;
1272         tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1273
1274         mutex_init(&tw_dev->ioctl_lock);
1275         init_waitqueue_head(&tw_dev->ioctl_wqueue);
1276
1277         return 0;
1278 } /* End tw_initialize_device_extension() */
1279
1280 static int tw_map_scsi_sg_data(struct pci_dev *pdev, struct scsi_cmnd *cmd)
1281 {
1282         int use_sg;
1283
1284         dprintk(KERN_WARNING "3w-xxxx: tw_map_scsi_sg_data()\n");
1285         
1286         if (cmd->use_sg == 0)
1287                 return 0;
1288
1289         use_sg = pci_map_sg(pdev, cmd->request_buffer, cmd->use_sg, DMA_BIDIRECTIONAL);
1290         
1291         if (use_sg == 0) {
1292                 printk(KERN_WARNING "3w-xxxx: tw_map_scsi_sg_data(): pci_map_sg() failed.\n");
1293                 return 0;
1294         }
1295
1296         cmd->SCp.phase = TW_PHASE_SGLIST;
1297         cmd->SCp.have_data_in = use_sg;
1298         
1299         return use_sg;
1300 } /* End tw_map_scsi_sg_data() */
1301
1302 static u32 tw_map_scsi_single_data(struct pci_dev *pdev, struct scsi_cmnd *cmd)
1303 {
1304         dma_addr_t mapping;
1305
1306         dprintk(KERN_WARNING "3w-xxxx: tw_map_scsi_single_data()\n");
1307
1308         if (cmd->request_bufflen == 0)
1309                 return 0;
1310
1311         mapping = pci_map_page(pdev, virt_to_page(cmd->request_buffer), offset_in_page(cmd->request_buffer), cmd->request_bufflen, DMA_BIDIRECTIONAL);
1312
1313         if (mapping == 0) {
1314                 printk(KERN_WARNING "3w-xxxx: tw_map_scsi_single_data(): pci_map_page() failed.\n");
1315                 return 0;
1316         }
1317
1318         cmd->SCp.phase = TW_PHASE_SINGLE;
1319         cmd->SCp.have_data_in = mapping;
1320
1321         return mapping;
1322 } /* End tw_map_scsi_single_data() */
1323
1324 static void tw_unmap_scsi_data(struct pci_dev *pdev, struct scsi_cmnd *cmd)
1325 {
1326         dprintk(KERN_WARNING "3w-xxxx: tw_unmap_scsi_data()\n");
1327
1328         switch(cmd->SCp.phase) {
1329                 case TW_PHASE_SINGLE:
1330                         pci_unmap_page(pdev, cmd->SCp.have_data_in, cmd->request_bufflen, DMA_BIDIRECTIONAL);
1331                         break;
1332                 case TW_PHASE_SGLIST:
1333                         pci_unmap_sg(pdev, cmd->request_buffer, cmd->use_sg, DMA_BIDIRECTIONAL);
1334                         break;
1335         }
1336 } /* End tw_unmap_scsi_data() */
1337
1338 /* This function will reset a device extension */
1339 static int tw_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_reset) 
1340 {
1341         int i = 0;
1342         struct scsi_cmnd *srb;
1343         unsigned long flags = 0;
1344
1345         dprintk(KERN_NOTICE "3w-xxxx: tw_reset_device_extension()\n");
1346
1347         set_bit(TW_IN_RESET, &tw_dev->flags);
1348         TW_DISABLE_INTERRUPTS(tw_dev);
1349         TW_MASK_COMMAND_INTERRUPT(tw_dev);
1350         spin_lock_irqsave(tw_dev->host->host_lock, flags);
1351
1352         /* Abort all requests that are in progress */
1353         for (i=0;i<TW_Q_LENGTH;i++) {
1354                 if ((tw_dev->state[i] != TW_S_FINISHED) && 
1355                     (tw_dev->state[i] != TW_S_INITIAL) &&
1356                     (tw_dev->state[i] != TW_S_COMPLETED)) {
1357                         srb = tw_dev->srb[i];
1358                         if (srb != NULL) {
1359                                 srb->result = (DID_RESET << 16);
1360                                 tw_dev->srb[i]->scsi_done(tw_dev->srb[i]);
1361                                 tw_unmap_scsi_data(tw_dev->tw_pci_dev, tw_dev->srb[i]);
1362                         }
1363                 }
1364         }
1365
1366         /* Reset queues and counts */
1367         for (i=0;i<TW_Q_LENGTH;i++) {
1368                 tw_dev->free_queue[i] = i;
1369                 tw_dev->state[i] = TW_S_INITIAL;
1370         }
1371         tw_dev->free_head = TW_Q_START;
1372         tw_dev->free_tail = TW_Q_START;
1373         tw_dev->posted_request_count = 0;
1374         tw_dev->pending_request_count = 0;
1375         tw_dev->pending_head = TW_Q_START;
1376         tw_dev->pending_tail = TW_Q_START;
1377         tw_dev->reset_print = 0;
1378
1379         spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
1380
1381         if (tw_reset_sequence(tw_dev)) {
1382                 printk(KERN_WARNING "3w-xxxx: scsi%d: Reset sequence failed.\n", tw_dev->host->host_no);
1383                 return 1;
1384         }
1385         TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
1386
1387         /* Wake up any ioctl that was pending before the reset */
1388         if ((tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE) || (ioctl_reset)) {
1389                 clear_bit(TW_IN_RESET, &tw_dev->flags);
1390         } else {
1391                 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1392                 wake_up(&tw_dev->ioctl_wqueue);
1393         }
1394
1395         return 0;
1396 } /* End tw_reset_device_extension() */
1397
1398 /* This funciton returns unit geometry in cylinders/heads/sectors */
1399 static int tw_scsi_biosparam(struct scsi_device *sdev, struct block_device *bdev,
1400                 sector_t capacity, int geom[]) 
1401 {
1402         int heads, sectors, cylinders;
1403         TW_Device_Extension *tw_dev;
1404         
1405         dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_biosparam()\n");
1406         tw_dev = (TW_Device_Extension *)sdev->host->hostdata;
1407
1408         heads = 64;
1409         sectors = 32;
1410         cylinders = sector_div(capacity, heads * sectors);
1411
1412         if (capacity >= 0x200000) {
1413                 heads = 255;
1414                 sectors = 63;
1415                 cylinders = sector_div(capacity, heads * sectors);
1416         }
1417
1418         dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_biosparam(): heads = %d, sectors = %d, cylinders = %d\n", heads, sectors, cylinders);
1419         geom[0] = heads;                         
1420         geom[1] = sectors;
1421         geom[2] = cylinders;
1422
1423         return 0;
1424 } /* End tw_scsi_biosparam() */
1425
1426 /* This is the new scsi eh reset function */
1427 static int tw_scsi_eh_reset(struct scsi_cmnd *SCpnt) 
1428 {
1429         TW_Device_Extension *tw_dev=NULL;
1430         int retval = FAILED;
1431
1432         tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
1433
1434         tw_dev->num_resets++;
1435
1436         sdev_printk(KERN_WARNING, SCpnt->device,
1437                 "WARNING: Command (0x%x) timed out, resetting card.\n",
1438                 SCpnt->cmnd[0]);
1439
1440         /* Now reset the card and some of the device extension data */
1441         if (tw_reset_device_extension(tw_dev, 0)) {
1442                 printk(KERN_WARNING "3w-xxxx: scsi%d: Reset failed.\n", tw_dev->host->host_no);
1443                 goto out;
1444         }
1445
1446         retval = SUCCESS;
1447 out:
1448         return retval;
1449 } /* End tw_scsi_eh_reset() */
1450
1451 /* This function handles scsi inquiry commands */
1452 static int tw_scsiop_inquiry(TW_Device_Extension *tw_dev, int request_id)
1453 {
1454         TW_Param *param;
1455         TW_Command *command_packet;
1456         unsigned long command_que_value;
1457         unsigned long param_value;
1458
1459         dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry()\n");
1460
1461         /* Initialize command packet */
1462         command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1463         if (command_packet == NULL) {
1464                 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad command packet virtual address.\n");
1465                 return 1;
1466         }
1467         memset(command_packet, 0, sizeof(TW_Sector));
1468         command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
1469         command_packet->size = 4;
1470         command_packet->request_id = request_id;
1471         command_packet->status = 0;
1472         command_packet->flags = 0;
1473         command_packet->byte6.parameter_count = 1;
1474
1475         /* Now setup the param */
1476         if (tw_dev->alignment_virtual_address[request_id] == NULL) {
1477                 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad alignment virtual address.\n");
1478                 return 1;
1479         }
1480         param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1481         memset(param, 0, sizeof(TW_Sector));
1482         param->table_id = 3;     /* unit summary table */
1483         param->parameter_id = 3; /* unitsstatus parameter */
1484         param->parameter_size_bytes = TW_MAX_UNITS;
1485         param_value = tw_dev->alignment_physical_address[request_id];
1486         if (param_value == 0) {
1487                 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad alignment physical address.\n");
1488                 return 1;
1489         }
1490
1491         command_packet->byte8.param.sgl[0].address = param_value;
1492         command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
1493         command_que_value = tw_dev->command_packet_physical_address[request_id];
1494         if (command_que_value == 0) {
1495                 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad command packet physical address.\n");
1496                 return 1;
1497         }
1498
1499         /* Now try to post the command packet */
1500         tw_post_command_packet(tw_dev, request_id);
1501
1502         return 0;
1503 } /* End tw_scsiop_inquiry() */
1504
1505 static void tw_transfer_internal(TW_Device_Extension *tw_dev, int request_id,
1506                                  void *data, unsigned int len)
1507 {
1508         struct scsi_cmnd *cmd = tw_dev->srb[request_id];
1509         void *buf;
1510         unsigned int transfer_len;
1511         unsigned long flags = 0;
1512
1513         if (cmd->use_sg) {
1514                 struct scatterlist *sg =
1515                         (struct scatterlist *)cmd->request_buffer;
1516                 local_irq_save(flags);
1517                 buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
1518                 transfer_len = min(sg->length, len);
1519         } else {
1520                 buf = cmd->request_buffer;
1521                 transfer_len = min(cmd->request_bufflen, len);
1522         }
1523
1524         memcpy(buf, data, transfer_len);
1525         
1526         if (cmd->use_sg) {
1527                 struct scatterlist *sg;
1528
1529                 sg = (struct scatterlist *)cmd->request_buffer;
1530                 kunmap_atomic(buf - sg->offset, KM_IRQ0);
1531                 local_irq_restore(flags);
1532         }
1533 }
1534
1535 /* This function is called by the isr to complete an inquiry command */
1536 static int tw_scsiop_inquiry_complete(TW_Device_Extension *tw_dev, int request_id)
1537 {
1538         unsigned char *is_unit_present;
1539         unsigned char request_buffer[36];
1540         TW_Param *param;
1541
1542         dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry_complete()\n");
1543
1544         memset(request_buffer, 0, sizeof(request_buffer));
1545         request_buffer[0] = TYPE_DISK; /* Peripheral device type */
1546         request_buffer[1] = 0;         /* Device type modifier */
1547         request_buffer[2] = 0;         /* No ansi/iso compliance */
1548         request_buffer[4] = 31;        /* Additional length */
1549         memcpy(&request_buffer[8], "3ware   ", 8);       /* Vendor ID */
1550         sprintf(&request_buffer[16], "Logical Disk %-2d ", tw_dev->srb[request_id]->device->id);
1551         memcpy(&request_buffer[32], TW_DRIVER_VERSION, 3);
1552         tw_transfer_internal(tw_dev, request_id, request_buffer,
1553                              sizeof(request_buffer));
1554
1555         param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1556         if (param == NULL) {
1557                 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry_complete(): Bad alignment virtual address.\n");
1558                 return 1;
1559         }
1560         is_unit_present = &(param->data[0]);
1561
1562         if (is_unit_present[tw_dev->srb[request_id]->device->id] & TW_UNIT_ONLINE) {
1563                 tw_dev->is_unit_present[tw_dev->srb[request_id]->device->id] = 1;
1564         } else {
1565                 tw_dev->is_unit_present[tw_dev->srb[request_id]->device->id] = 0;
1566                 tw_dev->srb[request_id]->result = (DID_BAD_TARGET << 16);
1567                 return TW_ISR_DONT_RESULT;
1568         }
1569
1570         return 0;
1571 } /* End tw_scsiop_inquiry_complete() */
1572
1573 /* This function handles scsi mode_sense commands */
1574 static int tw_scsiop_mode_sense(TW_Device_Extension *tw_dev, int request_id)
1575 {
1576         TW_Param *param;
1577         TW_Command *command_packet;
1578         unsigned long command_que_value;
1579         unsigned long param_value;
1580
1581         dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_mode_sense()\n");
1582
1583         /* Only page control = 0, page code = 0x8 (cache page) supported */
1584         if (tw_dev->srb[request_id]->cmnd[2] != 0x8) {
1585                 tw_dev->state[request_id] = TW_S_COMPLETED;
1586                 tw_state_request_finish(tw_dev, request_id);
1587                 tw_dev->srb[request_id]->result = (DID_OK << 16);
1588                 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1589                 return 0;
1590         }
1591
1592         /* Now read firmware cache setting for this unit */
1593         command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1594         if (command_packet == NULL) {
1595                 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad command packet virtual address.\n");
1596                 return 1;
1597         }
1598
1599         /* Setup the command packet */
1600         memset(command_packet, 0, sizeof(TW_Sector));
1601         command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
1602         command_packet->size = 4;
1603         command_packet->request_id = request_id;
1604         command_packet->status = 0;
1605         command_packet->flags = 0;
1606         command_packet->byte6.parameter_count = 1;
1607
1608         /* Setup the param */
1609         if (tw_dev->alignment_virtual_address[request_id] == NULL) {
1610                 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad alignment virtual address.\n");
1611                 return 1;
1612         }
1613
1614         param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1615         memset(param, 0, sizeof(TW_Sector));
1616         param->table_id = TW_UNIT_INFORMATION_TABLE_BASE + tw_dev->srb[request_id]->device->id;
1617         param->parameter_id = 7; /* unit flags */
1618         param->parameter_size_bytes = 1;
1619         param_value = tw_dev->alignment_physical_address[request_id];
1620         if (param_value == 0) {
1621                 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad alignment physical address.\n");
1622                 return 1;
1623         }
1624
1625         command_packet->byte8.param.sgl[0].address = param_value;
1626         command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
1627         command_que_value = tw_dev->command_packet_physical_address[request_id];
1628         if (command_que_value == 0) {
1629                 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad command packet physical address.\n");
1630                 return 1;
1631         }
1632
1633         /* Now try to post the command packet */
1634         tw_post_command_packet(tw_dev, request_id);
1635         
1636         return 0;
1637 } /* End tw_scsiop_mode_sense() */
1638
1639 /* This function is called by the isr to complete a mode sense command */
1640 static int tw_scsiop_mode_sense_complete(TW_Device_Extension *tw_dev, int request_id)
1641 {
1642         TW_Param *param;
1643         unsigned char *flags;
1644         unsigned char request_buffer[8];
1645
1646         dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_mode_sense_complete()\n");
1647
1648         param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1649         if (param == NULL) {
1650                 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense_complete(): Bad alignment virtual address.\n");
1651                 return 1;
1652         }
1653         flags = (char *)&(param->data[0]);
1654         memset(request_buffer, 0, sizeof(request_buffer));
1655
1656         request_buffer[0] = 0xf;        /* mode data length */
1657         request_buffer[1] = 0;          /* default medium type */
1658         request_buffer[2] = 0x10;       /* dpo/fua support on */
1659         request_buffer[3] = 0;          /* no block descriptors */
1660         request_buffer[4] = 0x8;        /* caching page */
1661         request_buffer[5] = 0xa;        /* page length */
1662         if (*flags & 0x1)
1663                 request_buffer[6] = 0x4;        /* WCE on */
1664         else
1665                 request_buffer[6] = 0x0;        /* WCE off */
1666         tw_transfer_internal(tw_dev, request_id, request_buffer,
1667                              sizeof(request_buffer));
1668
1669         return 0;
1670 } /* End tw_scsiop_mode_sense_complete() */
1671
1672 /* This function handles scsi read_capacity commands */
1673 static int tw_scsiop_read_capacity(TW_Device_Extension *tw_dev, int request_id) 
1674 {
1675         TW_Param *param;
1676         TW_Command *command_packet;
1677         unsigned long command_que_value;
1678         unsigned long param_value;
1679
1680         dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity()\n");
1681
1682         /* Initialize command packet */
1683         command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1684
1685         if (command_packet == NULL) {
1686                 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad command packet virtual address.\n");
1687                 return 1;
1688         }
1689         memset(command_packet, 0, sizeof(TW_Sector));
1690         command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
1691         command_packet->size = 4;
1692         command_packet->request_id = request_id;
1693         command_packet->unit__hostid = TW_UNITHOST_IN(0, tw_dev->srb[request_id]->device->id);
1694         command_packet->status = 0;
1695         command_packet->flags = 0;
1696         command_packet->byte6.block_count = 1;
1697
1698         /* Now setup the param */
1699         if (tw_dev->alignment_virtual_address[request_id] == NULL) {
1700                 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad alignment virtual address.\n");
1701                 return 1;
1702         }
1703         param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1704         memset(param, 0, sizeof(TW_Sector));
1705         param->table_id = TW_UNIT_INFORMATION_TABLE_BASE + 
1706         tw_dev->srb[request_id]->device->id;
1707         param->parameter_id = 4;        /* unitcapacity parameter */
1708         param->parameter_size_bytes = 4;
1709         param_value = tw_dev->alignment_physical_address[request_id];
1710         if (param_value == 0) {
1711                 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad alignment physical address.\n");
1712                 return 1;
1713         }
1714   
1715         command_packet->byte8.param.sgl[0].address = param_value;
1716         command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
1717         command_que_value = tw_dev->command_packet_physical_address[request_id];
1718         if (command_que_value == 0) {
1719                 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad command packet physical address.\n");
1720                 return 1;
1721         }
1722
1723         /* Now try to post the command to the board */
1724         tw_post_command_packet(tw_dev, request_id);
1725   
1726         return 0;
1727 } /* End tw_scsiop_read_capacity() */
1728
1729 /* This function is called by the isr to complete a readcapacity command */
1730 static int tw_scsiop_read_capacity_complete(TW_Device_Extension *tw_dev, int request_id)
1731 {
1732         unsigned char *param_data;
1733         u32 capacity;
1734         char buff[8];
1735         TW_Param *param;
1736
1737         dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity_complete()\n");
1738
1739         memset(buff, 0, sizeof(buff));
1740         param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1741         if (param == NULL) {
1742                 printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_capacity_complete(): Bad alignment virtual address.\n");
1743                 return 1;
1744         }
1745         param_data = &(param->data[0]);
1746
1747         capacity = (param_data[3] << 24) | (param_data[2] << 16) | 
1748                    (param_data[1] << 8) | param_data[0];
1749
1750         /* Subtract one sector to fix get last sector ioctl */
1751         capacity -= 1;
1752
1753         dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity_complete(): Capacity = 0x%x.\n", capacity);
1754
1755         /* Number of LBA's */
1756         buff[0] = (capacity >> 24);
1757         buff[1] = (capacity >> 16) & 0xff;
1758         buff[2] = (capacity >> 8) & 0xff;
1759         buff[3] = capacity & 0xff;
1760
1761         /* Block size in bytes (512) */
1762         buff[4] = (TW_BLOCK_SIZE >> 24);
1763         buff[5] = (TW_BLOCK_SIZE >> 16) & 0xff;
1764         buff[6] = (TW_BLOCK_SIZE >> 8) & 0xff;
1765         buff[7] = TW_BLOCK_SIZE & 0xff;
1766
1767         tw_transfer_internal(tw_dev, request_id, buff, sizeof(buff));
1768
1769         return 0;
1770 } /* End tw_scsiop_read_capacity_complete() */
1771
1772 /* This function handles scsi read or write commands */
1773 static int tw_scsiop_read_write(TW_Device_Extension *tw_dev, int request_id) 
1774 {
1775         TW_Command *command_packet;
1776         unsigned long command_que_value;
1777         u32 lba = 0x0, num_sectors = 0x0, buffaddr = 0x0;
1778         int i, use_sg;
1779         struct scsi_cmnd *srb;
1780         struct scatterlist *sglist;
1781
1782         dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write()\n");
1783
1784         if (tw_dev->srb[request_id]->request_buffer == NULL) {
1785                 printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_write(): Request buffer NULL.\n");
1786                 return 1;
1787         }
1788         sglist = (struct scatterlist *)tw_dev->srb[request_id]->request_buffer;
1789         srb = tw_dev->srb[request_id];
1790
1791         /* Initialize command packet */
1792         command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1793         if (command_packet == NULL) {
1794                 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): Bad command packet virtual address.\n");
1795                 return 1;
1796         }
1797
1798         if (srb->cmnd[0] == READ_6 || srb->cmnd[0] == READ_10) {
1799                 command_packet->opcode__sgloffset = TW_OPSGL_IN(3, TW_OP_READ);
1800         } else {
1801                 command_packet->opcode__sgloffset = TW_OPSGL_IN(3, TW_OP_WRITE);
1802         }
1803
1804         command_packet->size = 3;
1805         command_packet->request_id = request_id;
1806         command_packet->unit__hostid = TW_UNITHOST_IN(0, srb->device->id);
1807         command_packet->status = 0;
1808         command_packet->flags = 0;
1809
1810         if (srb->cmnd[0] == WRITE_10) {
1811                 if ((srb->cmnd[1] & 0x8) || (srb->cmnd[1] & 0x10))
1812                         command_packet->flags = 1;
1813         }
1814
1815         if (srb->cmnd[0] == READ_6 || srb->cmnd[0] == WRITE_6) {
1816                 lba = ((u32)srb->cmnd[1] << 16) | ((u32)srb->cmnd[2] << 8) | (u32)srb->cmnd[3];
1817                 num_sectors = (u32)srb->cmnd[4];
1818         } else {
1819                 lba = ((u32)srb->cmnd[2] << 24) | ((u32)srb->cmnd[3] << 16) | ((u32)srb->cmnd[4] << 8) | (u32)srb->cmnd[5];
1820                 num_sectors = (u32)srb->cmnd[8] | ((u32)srb->cmnd[7] << 8);
1821         }
1822   
1823         /* Update sector statistic */
1824         tw_dev->sector_count = num_sectors;
1825         if (tw_dev->sector_count > tw_dev->max_sector_count)
1826                 tw_dev->max_sector_count = tw_dev->sector_count;
1827   
1828         dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): lba = 0x%x num_sectors = 0x%x\n", lba, num_sectors);
1829         command_packet->byte8.io.lba = lba;
1830         command_packet->byte6.block_count = num_sectors;
1831
1832         /* Do this if there are no sg list entries */
1833         if (tw_dev->srb[request_id]->use_sg == 0) {    
1834                 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): SG = 0\n");
1835                 buffaddr = tw_map_scsi_single_data(tw_dev->tw_pci_dev, tw_dev->srb[request_id]);
1836                 if (buffaddr == 0)
1837                         return 1;
1838
1839                 command_packet->byte8.io.sgl[0].address = buffaddr;
1840                 command_packet->byte8.io.sgl[0].length = tw_dev->srb[request_id]->request_bufflen;
1841                 command_packet->size+=2;
1842         }
1843
1844         /* Do this if we have multiple sg list entries */
1845         if (tw_dev->srb[request_id]->use_sg > 0) {
1846                 use_sg = tw_map_scsi_sg_data(tw_dev->tw_pci_dev, tw_dev->srb[request_id]);
1847                 if (use_sg == 0)
1848                         return 1;
1849
1850                 for (i=0;i<use_sg; i++) {
1851                         command_packet->byte8.io.sgl[i].address = sg_dma_address(&sglist[i]);
1852                         command_packet->byte8.io.sgl[i].length = sg_dma_len(&sglist[i]);
1853                         command_packet->size+=2;
1854                 }
1855         }
1856
1857         /* Update SG statistics */
1858         tw_dev->sgl_entries = tw_dev->srb[request_id]->use_sg;
1859         if (tw_dev->sgl_entries > tw_dev->max_sgl_entries)
1860                 tw_dev->max_sgl_entries = tw_dev->sgl_entries;
1861
1862         command_que_value = tw_dev->command_packet_physical_address[request_id];
1863         if (command_que_value == 0) {
1864                 dprintk(KERN_WARNING "3w-xxxx: tw_scsiop_read_write(): Bad command packet physical address.\n");
1865                 return 1;
1866         }
1867       
1868         /* Now try to post the command to the board */
1869         tw_post_command_packet(tw_dev, request_id);
1870
1871         return 0;
1872 } /* End tw_scsiop_read_write() */
1873
1874 /* This function will handle the request sense scsi command */
1875 static int tw_scsiop_request_sense(TW_Device_Extension *tw_dev, int request_id)
1876 {
1877         dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_request_sense()\n");
1878
1879         /* For now we just zero the request buffer */
1880         memset(tw_dev->srb[request_id]->request_buffer, 0, tw_dev->srb[request_id]->request_bufflen);
1881         tw_dev->state[request_id] = TW_S_COMPLETED;
1882         tw_state_request_finish(tw_dev, request_id);
1883
1884         /* If we got a request_sense, we probably want a reset, return error */
1885         tw_dev->srb[request_id]->result = (DID_ERROR << 16);
1886         tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1887
1888         return 0;
1889 } /* End tw_scsiop_request_sense() */
1890
1891 /* This function will handle synchronize cache scsi command */
1892 static int tw_scsiop_synchronize_cache(TW_Device_Extension *tw_dev, int request_id)
1893 {
1894         TW_Command *command_packet;
1895         unsigned long command_que_value;
1896
1897         dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_synchronize_cache()\n");
1898
1899         /* Send firmware flush command for this unit */
1900         command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1901         if (command_packet == NULL) {
1902                 printk(KERN_WARNING "3w-xxxx: tw_scsiop_synchronize_cache(): Bad command packet virtual address.\n");
1903                 return 1;
1904         }
1905
1906         /* Setup the command packet */
1907         memset(command_packet, 0, sizeof(TW_Sector));
1908         command_packet->opcode__sgloffset = TW_OPSGL_IN(0, TW_OP_FLUSH_CACHE);
1909         command_packet->size = 2;
1910         command_packet->request_id = request_id;
1911         command_packet->unit__hostid = TW_UNITHOST_IN(0, tw_dev->srb[request_id]->device->id);
1912         command_packet->status = 0;
1913         command_packet->flags = 0;
1914         command_packet->byte6.parameter_count = 1;
1915         command_que_value = tw_dev->command_packet_physical_address[request_id];
1916         if (command_que_value == 0) {
1917                 printk(KERN_WARNING "3w-xxxx: tw_scsiop_synchronize_cache(): Bad command packet physical address.\n");
1918                 return 1;
1919         }
1920
1921         /* Now try to post the command packet */
1922         tw_post_command_packet(tw_dev, request_id);
1923
1924         return 0;
1925 } /* End tw_scsiop_synchronize_cache() */
1926
1927 /* This function will handle test unit ready scsi command */
1928 static int tw_scsiop_test_unit_ready(TW_Device_Extension *tw_dev, int request_id)
1929 {
1930         TW_Param *param;
1931         TW_Command *command_packet;
1932         unsigned long command_que_value;
1933         unsigned long param_value;
1934
1935         dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_test_unit_ready()\n");
1936
1937         /* Initialize command packet */
1938         command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1939         if (command_packet == NULL) {
1940                 printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready(): Bad command packet virtual address.\n");
1941                 return 1;
1942         }
1943         memset(command_packet, 0, sizeof(TW_Sector));
1944         command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
1945         command_packet->size = 4;
1946         command_packet->request_id = request_id;
1947         command_packet->status = 0;
1948         command_packet->flags = 0;
1949         command_packet->byte6.parameter_count = 1;
1950
1951         /* Now setup the param */
1952         if (tw_dev->alignment_virtual_address[request_id] == NULL) {
1953                 printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready(): Bad alignment virtual address.\n");
1954                 return 1;
1955         }
1956         param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1957         memset(param, 0, sizeof(TW_Sector));
1958         param->table_id = 3;     /* unit summary table */
1959         param->parameter_id = 3; /* unitsstatus parameter */
1960         param->parameter_size_bytes = TW_MAX_UNITS;
1961         param_value = tw_dev->alignment_physical_address[request_id];
1962         if (param_value == 0) {
1963                 printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready(): Bad alignment physical address.\n");
1964                 return 1;
1965         }
1966
1967         command_packet->byte8.param.sgl[0].address = param_value;
1968         command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
1969         command_que_value = tw_dev->command_packet_physical_address[request_id];
1970         if (command_que_value == 0) {
1971                 printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready(): Bad command packet physical address.\n");
1972                 return 1;
1973         }
1974
1975         /* Now try to post the command packet */
1976         tw_post_command_packet(tw_dev, request_id);
1977
1978         return 0;
1979 } /* End tw_scsiop_test_unit_ready() */
1980
1981 /* This function is called by the isr to complete a testunitready command */
1982 static int tw_scsiop_test_unit_ready_complete(TW_Device_Extension *tw_dev, int request_id)
1983 {
1984         unsigned char *is_unit_present;
1985         TW_Param *param;
1986
1987         dprintk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready_complete()\n");
1988
1989         param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1990         if (param == NULL) {
1991                 printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready_complete(): Bad alignment virtual address.\n");
1992                 return 1;
1993         }
1994         is_unit_present = &(param->data[0]);
1995
1996         if (is_unit_present[tw_dev->srb[request_id]->device->id] & TW_UNIT_ONLINE) {
1997                 tw_dev->is_unit_present[tw_dev->srb[request_id]->device->id] = 1;
1998         } else {
1999                 tw_dev->is_unit_present[tw_dev->srb[request_id]->device->id] = 0;
2000                 tw_dev->srb[request_id]->result = (DID_BAD_TARGET << 16);
2001                 return TW_ISR_DONT_RESULT;
2002         }
2003
2004         return 0;
2005 } /* End tw_scsiop_test_unit_ready_complete() */
2006
2007 /* This is the main scsi queue function to handle scsi opcodes */
2008 static int tw_scsi_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) 
2009 {
2010         unsigned char *command = SCpnt->cmnd;
2011         int request_id = 0;
2012         int retval = 1;
2013         TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
2014
2015         /* Save done function into Scsi_Cmnd struct */
2016         SCpnt->scsi_done = done;
2017                  
2018         /* Queue the command and get a request id */
2019         tw_state_request_start(tw_dev, &request_id);
2020
2021         /* Save the scsi command for use by the ISR */
2022         tw_dev->srb[request_id] = SCpnt;
2023
2024         /* Initialize phase to zero */
2025         SCpnt->SCp.phase = TW_PHASE_INITIAL;
2026
2027         switch (*command) {
2028                 case READ_10:
2029                 case READ_6:
2030                 case WRITE_10:
2031                 case WRITE_6:
2032                         dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught READ/WRITE.\n");
2033                         retval = tw_scsiop_read_write(tw_dev, request_id);
2034                         break;
2035                 case TEST_UNIT_READY:
2036                         dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught TEST_UNIT_READY.\n");
2037                         retval = tw_scsiop_test_unit_ready(tw_dev, request_id);
2038                         break;
2039                 case INQUIRY:
2040                         dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught INQUIRY.\n");
2041                         retval = tw_scsiop_inquiry(tw_dev, request_id);
2042                         break;
2043                 case READ_CAPACITY:
2044                         dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught READ_CAPACITY.\n");
2045                         retval = tw_scsiop_read_capacity(tw_dev, request_id);
2046                         break;
2047                 case REQUEST_SENSE:
2048                         dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught REQUEST_SENSE.\n");
2049                         retval = tw_scsiop_request_sense(tw_dev, request_id);
2050                         break;
2051                 case MODE_SENSE:
2052                         dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught MODE_SENSE.\n");
2053                         retval = tw_scsiop_mode_sense(tw_dev, request_id);
2054                         break;
2055                 case SYNCHRONIZE_CACHE:
2056                         dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught SYNCHRONIZE_CACHE.\n");
2057                         retval = tw_scsiop_synchronize_cache(tw_dev, request_id);
2058                         break;
2059                 case TW_IOCTL:
2060                         printk(KERN_WARNING "3w-xxxx: SCSI_IOCTL_SEND_COMMAND deprecated, please update your 3ware tools.\n");
2061                         break;
2062                 default:
2063                         printk(KERN_NOTICE "3w-xxxx: scsi%d: Unknown scsi opcode: 0x%x\n", tw_dev->host->host_no, *command);
2064                         tw_dev->state[request_id] = TW_S_COMPLETED;
2065                         tw_state_request_finish(tw_dev, request_id);
2066                         SCpnt->result = (DID_BAD_TARGET << 16);
2067                         done(SCpnt);
2068                         retval = 0;
2069         }
2070         if (retval) {
2071                 tw_dev->state[request_id] = TW_S_COMPLETED;
2072                 tw_state_request_finish(tw_dev, request_id);
2073                 SCpnt->result = (DID_ERROR << 16);
2074                 done(SCpnt);
2075                 retval = 0;
2076         }
2077         return retval;
2078 } /* End tw_scsi_queue() */
2079
2080 /* This function is the interrupt service routine */
2081 static irqreturn_t tw_interrupt(int irq, void *dev_instance) 
2082 {
2083         int request_id;
2084         u32 status_reg_value;
2085         TW_Device_Extension *tw_dev = (TW_Device_Extension *)dev_instance;
2086         TW_Response_Queue response_que;
2087         int error = 0, retval = 0;
2088         TW_Command *command_packet;
2089         int handled = 0;
2090
2091         /* Get the host lock for io completions */
2092         spin_lock(tw_dev->host->host_lock);
2093
2094         /* Read the registers */
2095         status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
2096
2097         /* Check if this is our interrupt, otherwise bail */
2098         if (!(status_reg_value & TW_STATUS_VALID_INTERRUPT))
2099                 goto tw_interrupt_bail;
2100
2101         handled = 1;
2102
2103         /* Check controller for errors */
2104         if (tw_check_bits(status_reg_value)) {
2105                 dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n");
2106                 if (tw_decode_bits(tw_dev, status_reg_value, 1)) {
2107                         TW_CLEAR_ALL_INTERRUPTS(tw_dev);
2108                         goto tw_interrupt_bail;
2109                 }
2110         }
2111
2112         /* Handle host interrupt */
2113         if (status_reg_value & TW_STATUS_HOST_INTERRUPT) {
2114                 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Received host interrupt.\n");
2115                 TW_CLEAR_HOST_INTERRUPT(tw_dev);
2116         }
2117
2118         /* Handle attention interrupt */
2119         if (status_reg_value & TW_STATUS_ATTENTION_INTERRUPT) {
2120                 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Received attention interrupt.\n");
2121                 TW_CLEAR_ATTENTION_INTERRUPT(tw_dev);
2122                 tw_state_request_start(tw_dev, &request_id);
2123                 error = tw_aen_read_queue(tw_dev, request_id);
2124                 if (error) {
2125                         printk(KERN_WARNING "3w-xxxx: scsi%d: Error reading aen queue.\n", tw_dev->host->host_no);
2126                         tw_dev->state[request_id] = TW_S_COMPLETED;
2127                         tw_state_request_finish(tw_dev, request_id);
2128                 }
2129         }
2130
2131         /* Handle command interrupt */
2132         if (status_reg_value & TW_STATUS_COMMAND_INTERRUPT) {
2133                 /* Drain as many pending commands as we can */
2134                 while (tw_dev->pending_request_count > 0) {
2135                         request_id = tw_dev->pending_queue[tw_dev->pending_head];
2136                         if (tw_dev->state[request_id] != TW_S_PENDING) {
2137                                 printk(KERN_WARNING "3w-xxxx: scsi%d: Found request id that wasn't pending.\n", tw_dev->host->host_no);
2138                                 break;
2139                         }
2140                         if (tw_post_command_packet(tw_dev, request_id)==0) {
2141                                 if (tw_dev->pending_head == TW_Q_LENGTH-1) {
2142                                         tw_dev->pending_head = TW_Q_START;
2143                                 } else {
2144                                         tw_dev->pending_head = tw_dev->pending_head + 1;
2145                                 }
2146                                 tw_dev->pending_request_count--;
2147                         } else {
2148                                 /* If we get here, we will continue re-posting on the next command interrupt */
2149                                 break;
2150                         }
2151                 }
2152                 /* If there are no more pending requests, we mask command interrupt */
2153                 if (tw_dev->pending_request_count == 0) 
2154                         TW_MASK_COMMAND_INTERRUPT(tw_dev);
2155         }
2156
2157         /* Handle response interrupt */
2158         if (status_reg_value & TW_STATUS_RESPONSE_INTERRUPT) {
2159                 /* Drain the response queue from the board */
2160                 while ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
2161                         /* Read response queue register */
2162                         response_que.value = inl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
2163                         request_id = TW_RESID_OUT(response_que.response_id);
2164                         command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
2165                         error = 0;
2166
2167                         /* Check for bad response */
2168                         if (command_packet->status != 0) {
2169                                 /* If internal command, don't error, don't fill sense */
2170                                 if (tw_dev->srb[request_id] == NULL) {
2171                                         tw_decode_sense(tw_dev, request_id, 0);
2172                                 } else {
2173                                         error = tw_decode_sense(tw_dev, request_id, 1);
2174                                 }
2175                         }
2176
2177                         /* Check for correct state */
2178                         if (tw_dev->state[request_id] != TW_S_POSTED) {
2179                                 if (tw_dev->srb[request_id] != NULL) {
2180                                         printk(KERN_WARNING "3w-xxxx: scsi%d: Received a request id that wasn't posted.\n", tw_dev->host->host_no);
2181                                         error = 1;
2182                                 }
2183                         }
2184
2185                         dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Response queue request id: %d.\n", request_id);
2186
2187                         /* Check for internal command completion */
2188                         if (tw_dev->srb[request_id] == NULL) {
2189                                 dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Found internally posted command.\n");
2190                                 /* Check for chrdev ioctl completion */
2191                                 if (request_id != tw_dev->chrdev_request_id) {
2192                                         retval = tw_aen_complete(tw_dev, request_id);
2193                                         if (retval) {
2194                                                 printk(KERN_WARNING "3w-xxxx: scsi%d: Error completing aen.\n", tw_dev->host->host_no);
2195                                         }
2196                                 } else {
2197                                         tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
2198                                         wake_up(&tw_dev->ioctl_wqueue);
2199                                 }
2200                         } else {
2201                                 switch (tw_dev->srb[request_id]->cmnd[0]) {
2202                                 case READ_10:
2203                                 case READ_6:
2204                                         dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught READ_10/READ_6\n");
2205                                         break;
2206                                 case WRITE_10:
2207                                 case WRITE_6:
2208                                         dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught WRITE_10/WRITE_6\n");
2209                                         break;
2210                                 case TEST_UNIT_READY:
2211                                         dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught TEST_UNIT_READY\n");
2212                                         error = tw_scsiop_test_unit_ready_complete(tw_dev, request_id);
2213                                         break;
2214                                 case INQUIRY:
2215                                         dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught INQUIRY\n");
2216                                         error = tw_scsiop_inquiry_complete(tw_dev, request_id);
2217                                         break;
2218                                 case READ_CAPACITY:
2219                                         dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught READ_CAPACITY\n");
2220                                         error = tw_scsiop_read_capacity_complete(tw_dev, request_id);
2221                                         break;
2222                                 case MODE_SENSE:
2223                                         dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught MODE_SENSE\n");
2224                                         error = tw_scsiop_mode_sense_complete(tw_dev, request_id);
2225                                         break;
2226                                 case SYNCHRONIZE_CACHE:
2227                                         dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught SYNCHRONIZE_CACHE\n");
2228                                         break;
2229                                 default:
2230                                         printk(KERN_WARNING "3w-xxxx: case slip in tw_interrupt()\n");
2231                                         error = 1;
2232                                 }
2233
2234                                 /* If no error command was a success */
2235                                 if (error == 0) {
2236                                         tw_dev->srb[request_id]->result = (DID_OK << 16);
2237                                 }
2238
2239                                 /* If error, command failed */
2240                                 if (error == 1) {
2241                                         /* Ask for a host reset */
2242                                         tw_dev->srb[request_id]->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
2243                                 }
2244
2245                                 /* Now complete the io */
2246                                 if ((error != TW_ISR_DONT_COMPLETE)) {
2247                                         tw_dev->state[request_id] = TW_S_COMPLETED;
2248                                         tw_state_request_finish(tw_dev, request_id);
2249                                         tw_dev->posted_request_count--;
2250                                         tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
2251                                         
2252                                         tw_unmap_scsi_data(tw_dev->tw_pci_dev, tw_dev->srb[request_id]);
2253                                 }
2254                         }
2255                                 
2256                         /* Check for valid status after each drain */
2257                         status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
2258                         if (tw_check_bits(status_reg_value)) {
2259                                 dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n");
2260                                 if (tw_decode_bits(tw_dev, status_reg_value, 1)) {
2261                                         TW_CLEAR_ALL_INTERRUPTS(tw_dev);
2262                                         goto tw_interrupt_bail;
2263                                 }
2264                         }
2265                 }
2266         }
2267
2268 tw_interrupt_bail:
2269         spin_unlock(tw_dev->host->host_lock);
2270         return IRQ_RETVAL(handled);
2271 } /* End tw_interrupt() */
2272
2273 /* This function tells the controller to shut down */
2274 static void __tw_shutdown(TW_Device_Extension *tw_dev)
2275 {
2276         /* Disable interrupts */
2277         TW_DISABLE_INTERRUPTS(tw_dev);
2278
2279         printk(KERN_WARNING "3w-xxxx: Shutting down host %d.\n", tw_dev->host->host_no);
2280
2281         /* Tell the card we are shutting down */
2282         if (tw_initconnection(tw_dev, 1)) {
2283                 printk(KERN_WARNING "3w-xxxx: Connection shutdown failed.\n");
2284         } else {
2285                 printk(KERN_WARNING "3w-xxxx: Shutdown complete.\n");
2286         }
2287
2288         /* Clear all interrupts just before exit */
2289         TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
2290 } /* End __tw_shutdown() */
2291
2292 /* Wrapper for __tw_shutdown */
2293 static void tw_shutdown(struct pci_dev *pdev)
2294 {
2295         struct Scsi_Host *host = pci_get_drvdata(pdev);
2296         TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
2297
2298         __tw_shutdown(tw_dev);
2299 } /* End tw_shutdown() */
2300
2301 static struct scsi_host_template driver_template = {
2302         .module                 = THIS_MODULE,
2303         .name                   = "3ware Storage Controller",
2304         .queuecommand           = tw_scsi_queue,
2305         .eh_host_reset_handler  = tw_scsi_eh_reset,
2306         .bios_param             = tw_scsi_biosparam,
2307         .change_queue_depth     = tw_change_queue_depth,
2308         .can_queue              = TW_Q_LENGTH-2,
2309         .this_id                = -1,
2310         .sg_tablesize           = TW_MAX_SGL_LENGTH,
2311         .max_sectors            = TW_MAX_SECTORS,
2312         .cmd_per_lun            = TW_MAX_CMDS_PER_LUN,  
2313         .use_clustering         = ENABLE_CLUSTERING,
2314         .shost_attrs            = tw_host_attrs,
2315         .emulated               = 1
2316 };
2317
2318 /* This function will probe and initialize a card */
2319 static int __devinit tw_probe(struct pci_dev *pdev, const struct pci_device_id *dev_id)
2320 {
2321         struct Scsi_Host *host = NULL;
2322         TW_Device_Extension *tw_dev;
2323         int retval = -ENODEV;
2324
2325         retval = pci_enable_device(pdev);
2326         if (retval) {
2327                 printk(KERN_WARNING "3w-xxxx: Failed to enable pci device.");
2328                 goto out_disable_device;
2329         }
2330
2331         pci_set_master(pdev);
2332
2333         retval = pci_set_dma_mask(pdev, TW_DMA_MASK);
2334         if (retval) {
2335                 printk(KERN_WARNING "3w-xxxx: Failed to set dma mask.");
2336                 goto out_disable_device;
2337         }
2338
2339         host = scsi_host_alloc(&driver_template, sizeof(TW_Device_Extension));
2340         if (!host) {
2341                 printk(KERN_WARNING "3w-xxxx: Failed to allocate memory for device extension.");
2342                 retval = -ENOMEM;
2343                 goto out_disable_device;
2344         }
2345         tw_dev = (TW_Device_Extension *)host->hostdata;
2346
2347         memset(tw_dev, 0, sizeof(TW_Device_Extension));
2348
2349         /* Save values to device extension */
2350         tw_dev->host = host;
2351         tw_dev->tw_pci_dev = pdev;
2352
2353         if (tw_initialize_device_extension(tw_dev)) {
2354                 printk(KERN_WARNING "3w-xxxx: Failed to initialize device extension.");
2355                 goto out_free_device_extension;
2356         }
2357
2358         /* Request IO regions */
2359         retval = pci_request_regions(pdev, "3w-xxxx");
2360         if (retval) {
2361                 printk(KERN_WARNING "3w-xxxx: Failed to get mem region.");
2362                 goto out_free_device_extension;
2363         }
2364
2365         /* Save base address */
2366         tw_dev->base_addr = pci_resource_start(pdev, 0);
2367         if (!tw_dev->base_addr) {
2368                 printk(KERN_WARNING "3w-xxxx: Failed to get io address.");
2369                 goto out_release_mem_region;
2370         }
2371
2372         /* Disable interrupts on the card */
2373         TW_DISABLE_INTERRUPTS(tw_dev);
2374
2375         /* Initialize the card */
2376         if (tw_reset_sequence(tw_dev))
2377                 goto out_release_mem_region;
2378
2379         /* Set host specific parameters */
2380         host->max_id = TW_MAX_UNITS;
2381         host->max_cmd_len = TW_MAX_CDB_LEN;
2382
2383         /* Luns and channels aren't supported by adapter */
2384         host->max_lun = 0;
2385         host->max_channel = 0;
2386
2387         /* Register the card with the kernel SCSI layer */
2388         retval = scsi_add_host(host, &pdev->dev);
2389         if (retval) {
2390                 printk(KERN_WARNING "3w-xxxx: scsi add host failed");
2391                 goto out_release_mem_region;
2392         }
2393
2394         pci_set_drvdata(pdev, host);
2395
2396         printk(KERN_WARNING "3w-xxxx: scsi%d: Found a 3ware Storage Controller at 0x%x, IRQ: %d.\n", host->host_no, tw_dev->base_addr, pdev->irq);
2397
2398         /* Now setup the interrupt handler */
2399         retval = request_irq(pdev->irq, tw_interrupt, IRQF_SHARED, "3w-xxxx", tw_dev);
2400         if (retval) {
2401                 printk(KERN_WARNING "3w-xxxx: Error requesting IRQ.");
2402                 goto out_remove_host;
2403         }
2404
2405         tw_device_extension_list[tw_device_extension_count] = tw_dev;
2406         tw_device_extension_count++;
2407
2408         /* Re-enable interrupts on the card */
2409         TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
2410
2411         /* Finally, scan the host */
2412         scsi_scan_host(host);
2413
2414         if (twe_major == -1) {
2415                 if ((twe_major = register_chrdev (0, "twe", &tw_fops)) < 0)
2416                         printk(KERN_WARNING "3w-xxxx: Failed to register character device.");
2417         }
2418         return 0;
2419
2420 out_remove_host:
2421         scsi_remove_host(host);
2422 out_release_mem_region:
2423         pci_release_regions(pdev);
2424 out_free_device_extension:
2425         tw_free_device_extension(tw_dev);
2426         scsi_host_put(host);
2427 out_disable_device:
2428         pci_disable_device(pdev);
2429
2430         return retval;
2431 } /* End tw_probe() */
2432
2433 /* This function is called to remove a device */
2434 static void tw_remove(struct pci_dev *pdev)
2435 {
2436         struct Scsi_Host *host = pci_get_drvdata(pdev);
2437         TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
2438
2439         scsi_remove_host(tw_dev->host);
2440
2441         /* Unregister character device */
2442         if (twe_major >= 0) {
2443                 unregister_chrdev(twe_major, "twe");
2444                 twe_major = -1;
2445         }
2446
2447         /* Free up the IRQ */
2448         free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
2449
2450         /* Shutdown the card */
2451         __tw_shutdown(tw_dev);
2452
2453         /* Free up the mem region */
2454         pci_release_regions(pdev);
2455
2456         /* Free up device extension resources */
2457         tw_free_device_extension(tw_dev);
2458
2459         scsi_host_put(tw_dev->host);
2460         pci_disable_device(pdev);
2461         tw_device_extension_count--;
2462 } /* End tw_remove() */
2463
2464 /* PCI Devices supported by this driver */
2465 static struct pci_device_id tw_pci_tbl[] __devinitdata = {
2466         { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_1000,
2467           PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2468         { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_7000,
2469           PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2470         { }
2471 };
2472 MODULE_DEVICE_TABLE(pci, tw_pci_tbl);
2473
2474 /* pci_driver initializer */
2475 static struct pci_driver tw_driver = {
2476         .name           = "3w-xxxx",
2477         .id_table       = tw_pci_tbl,
2478         .probe          = tw_probe,
2479         .remove         = tw_remove,
2480         .shutdown       = tw_shutdown,
2481 };
2482
2483 /* This function is called on driver initialization */
2484 static int __init tw_init(void)
2485 {
2486         printk(KERN_WARNING "3ware Storage Controller device driver for Linux v%s.\n", TW_DRIVER_VERSION);
2487
2488         return pci_register_driver(&tw_driver);
2489 } /* End tw_init() */
2490
2491 /* This function is called on driver exit */
2492 static void __exit tw_exit(void)
2493 {
2494         pci_unregister_driver(&tw_driver);
2495 } /* End tw_exit() */
2496
2497 module_init(tw_init);
2498 module_exit(tw_exit);
2499