Version:  2.0.40 2.2.26 2.4.37 3.13 3.14 3.15 3.16 3.17 3.18 3.19 4.0 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 4.10

Linux/drivers/scsi/3w-xxxx.c

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

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us