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