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