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