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