[SCSI] sem2mutex 3w-[x9]xxx
[linux-2.6/linux-loongson.git] / drivers / scsi / 3w-xxxx.c
blob25f678d0780b2e1bb2dcf12a767b8607739db150
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<(sizeof(tw_sense_table)/sizeof(tw_sense_table[0]));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 = sizeof(tw_aen_string)/sizeof(char *);
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 = sizeof(tw_aen_string)/sizeof(char *);
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->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;
1512 if (cmd->use_sg) {
1513 struct scatterlist *sg =
1514 (struct scatterlist *)cmd->request_buffer;
1515 buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
1516 transfer_len = min(sg->length, len);
1517 } else {
1518 buf = cmd->request_buffer;
1519 transfer_len = min(cmd->request_bufflen, len);
1522 memcpy(buf, data, transfer_len);
1524 if (cmd->use_sg) {
1525 struct scatterlist *sg;
1527 sg = (struct scatterlist *)cmd->request_buffer;
1528 kunmap_atomic(buf - sg->offset, KM_IRQ0);
1532 /* This function is called by the isr to complete an inquiry command */
1533 static int tw_scsiop_inquiry_complete(TW_Device_Extension *tw_dev, int request_id)
1535 unsigned char *is_unit_present;
1536 unsigned char request_buffer[36];
1537 TW_Param *param;
1539 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry_complete()\n");
1541 memset(request_buffer, 0, sizeof(request_buffer));
1542 request_buffer[0] = TYPE_DISK; /* Peripheral device type */
1543 request_buffer[1] = 0; /* Device type modifier */
1544 request_buffer[2] = 0; /* No ansi/iso compliance */
1545 request_buffer[4] = 31; /* Additional length */
1546 memcpy(&request_buffer[8], "3ware ", 8); /* Vendor ID */
1547 sprintf(&request_buffer[16], "Logical Disk %-2d ", tw_dev->srb[request_id]->device->id);
1548 memcpy(&request_buffer[32], TW_DRIVER_VERSION, 3);
1549 tw_transfer_internal(tw_dev, request_id, request_buffer,
1550 sizeof(request_buffer));
1552 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1553 if (param == NULL) {
1554 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry_complete(): Bad alignment virtual address.\n");
1555 return 1;
1557 is_unit_present = &(param->data[0]);
1559 if (is_unit_present[tw_dev->srb[request_id]->device->id] & TW_UNIT_ONLINE) {
1560 tw_dev->is_unit_present[tw_dev->srb[request_id]->device->id] = 1;
1561 } else {
1562 tw_dev->is_unit_present[tw_dev->srb[request_id]->device->id] = 0;
1563 tw_dev->srb[request_id]->result = (DID_BAD_TARGET << 16);
1564 return TW_ISR_DONT_RESULT;
1567 return 0;
1568 } /* End tw_scsiop_inquiry_complete() */
1570 /* This function handles scsi mode_sense commands */
1571 static int tw_scsiop_mode_sense(TW_Device_Extension *tw_dev, int request_id)
1573 TW_Param *param;
1574 TW_Command *command_packet;
1575 unsigned long command_que_value;
1576 unsigned long param_value;
1578 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_mode_sense()\n");
1580 /* Only page control = 0, page code = 0x8 (cache page) supported */
1581 if (tw_dev->srb[request_id]->cmnd[2] != 0x8) {
1582 tw_dev->state[request_id] = TW_S_COMPLETED;
1583 tw_state_request_finish(tw_dev, request_id);
1584 tw_dev->srb[request_id]->result = (DID_OK << 16);
1585 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1586 return 0;
1589 /* Now read firmware cache setting for this unit */
1590 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1591 if (command_packet == NULL) {
1592 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad command packet virtual address.\n");
1593 return 1;
1596 /* Setup the command packet */
1597 memset(command_packet, 0, sizeof(TW_Sector));
1598 command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
1599 command_packet->size = 4;
1600 command_packet->request_id = request_id;
1601 command_packet->status = 0;
1602 command_packet->flags = 0;
1603 command_packet->byte6.parameter_count = 1;
1605 /* Setup the param */
1606 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
1607 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad alignment virtual address.\n");
1608 return 1;
1611 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1612 memset(param, 0, sizeof(TW_Sector));
1613 param->table_id = TW_UNIT_INFORMATION_TABLE_BASE + tw_dev->srb[request_id]->device->id;
1614 param->parameter_id = 7; /* unit flags */
1615 param->parameter_size_bytes = 1;
1616 param_value = tw_dev->alignment_physical_address[request_id];
1617 if (param_value == 0) {
1618 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad alignment physical address.\n");
1619 return 1;
1622 command_packet->byte8.param.sgl[0].address = param_value;
1623 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
1624 command_que_value = tw_dev->command_packet_physical_address[request_id];
1625 if (command_que_value == 0) {
1626 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad command packet physical address.\n");
1627 return 1;
1630 /* Now try to post the command packet */
1631 tw_post_command_packet(tw_dev, request_id);
1633 return 0;
1634 } /* End tw_scsiop_mode_sense() */
1636 /* This function is called by the isr to complete a mode sense command */
1637 static int tw_scsiop_mode_sense_complete(TW_Device_Extension *tw_dev, int request_id)
1639 TW_Param *param;
1640 unsigned char *flags;
1641 unsigned char request_buffer[8];
1643 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_mode_sense_complete()\n");
1645 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1646 if (param == NULL) {
1647 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense_complete(): Bad alignment virtual address.\n");
1648 return 1;
1650 flags = (char *)&(param->data[0]);
1651 memset(request_buffer, 0, sizeof(request_buffer));
1653 request_buffer[0] = 0xf; /* mode data length */
1654 request_buffer[1] = 0; /* default medium type */
1655 request_buffer[2] = 0x10; /* dpo/fua support on */
1656 request_buffer[3] = 0; /* no block descriptors */
1657 request_buffer[4] = 0x8; /* caching page */
1658 request_buffer[5] = 0xa; /* page length */
1659 if (*flags & 0x1)
1660 request_buffer[6] = 0x4; /* WCE on */
1661 else
1662 request_buffer[6] = 0x0; /* WCE off */
1663 tw_transfer_internal(tw_dev, request_id, request_buffer,
1664 sizeof(request_buffer));
1666 return 0;
1667 } /* End tw_scsiop_mode_sense_complete() */
1669 /* This function handles scsi read_capacity commands */
1670 static int tw_scsiop_read_capacity(TW_Device_Extension *tw_dev, int request_id)
1672 TW_Param *param;
1673 TW_Command *command_packet;
1674 unsigned long command_que_value;
1675 unsigned long param_value;
1677 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity()\n");
1679 /* Initialize command packet */
1680 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1682 if (command_packet == NULL) {
1683 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad command packet virtual address.\n");
1684 return 1;
1686 memset(command_packet, 0, sizeof(TW_Sector));
1687 command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
1688 command_packet->size = 4;
1689 command_packet->request_id = request_id;
1690 command_packet->unit__hostid = TW_UNITHOST_IN(0, tw_dev->srb[request_id]->device->id);
1691 command_packet->status = 0;
1692 command_packet->flags = 0;
1693 command_packet->byte6.block_count = 1;
1695 /* Now setup the param */
1696 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
1697 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad alignment virtual address.\n");
1698 return 1;
1700 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1701 memset(param, 0, sizeof(TW_Sector));
1702 param->table_id = TW_UNIT_INFORMATION_TABLE_BASE +
1703 tw_dev->srb[request_id]->device->id;
1704 param->parameter_id = 4; /* unitcapacity parameter */
1705 param->parameter_size_bytes = 4;
1706 param_value = tw_dev->alignment_physical_address[request_id];
1707 if (param_value == 0) {
1708 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad alignment physical address.\n");
1709 return 1;
1712 command_packet->byte8.param.sgl[0].address = param_value;
1713 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
1714 command_que_value = tw_dev->command_packet_physical_address[request_id];
1715 if (command_que_value == 0) {
1716 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad command packet physical address.\n");
1717 return 1;
1720 /* Now try to post the command to the board */
1721 tw_post_command_packet(tw_dev, request_id);
1723 return 0;
1724 } /* End tw_scsiop_read_capacity() */
1726 /* This function is called by the isr to complete a readcapacity command */
1727 static int tw_scsiop_read_capacity_complete(TW_Device_Extension *tw_dev, int request_id)
1729 unsigned char *param_data;
1730 u32 capacity;
1731 char buff[8];
1732 TW_Param *param;
1734 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity_complete()\n");
1736 memset(buff, 0, sizeof(buff));
1737 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1738 if (param == NULL) {
1739 printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_capacity_complete(): Bad alignment virtual address.\n");
1740 return 1;
1742 param_data = &(param->data[0]);
1744 capacity = (param_data[3] << 24) | (param_data[2] << 16) |
1745 (param_data[1] << 8) | param_data[0];
1747 /* Subtract one sector to fix get last sector ioctl */
1748 capacity -= 1;
1750 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity_complete(): Capacity = 0x%x.\n", capacity);
1752 /* Number of LBA's */
1753 buff[0] = (capacity >> 24);
1754 buff[1] = (capacity >> 16) & 0xff;
1755 buff[2] = (capacity >> 8) & 0xff;
1756 buff[3] = capacity & 0xff;
1758 /* Block size in bytes (512) */
1759 buff[4] = (TW_BLOCK_SIZE >> 24);
1760 buff[5] = (TW_BLOCK_SIZE >> 16) & 0xff;
1761 buff[6] = (TW_BLOCK_SIZE >> 8) & 0xff;
1762 buff[7] = TW_BLOCK_SIZE & 0xff;
1764 tw_transfer_internal(tw_dev, request_id, buff, sizeof(buff));
1766 return 0;
1767 } /* End tw_scsiop_read_capacity_complete() */
1769 /* This function handles scsi read or write commands */
1770 static int tw_scsiop_read_write(TW_Device_Extension *tw_dev, int request_id)
1772 TW_Command *command_packet;
1773 unsigned long command_que_value;
1774 u32 lba = 0x0, num_sectors = 0x0, buffaddr = 0x0;
1775 int i, use_sg;
1776 struct scsi_cmnd *srb;
1777 struct scatterlist *sglist;
1779 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write()\n");
1781 if (tw_dev->srb[request_id]->request_buffer == NULL) {
1782 printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_write(): Request buffer NULL.\n");
1783 return 1;
1785 sglist = (struct scatterlist *)tw_dev->srb[request_id]->request_buffer;
1786 srb = tw_dev->srb[request_id];
1788 /* Initialize command packet */
1789 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1790 if (command_packet == NULL) {
1791 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): Bad command packet virtual address.\n");
1792 return 1;
1795 if (srb->cmnd[0] == READ_6 || srb->cmnd[0] == READ_10) {
1796 command_packet->opcode__sgloffset = TW_OPSGL_IN(3, TW_OP_READ);
1797 } else {
1798 command_packet->opcode__sgloffset = TW_OPSGL_IN(3, TW_OP_WRITE);
1801 command_packet->size = 3;
1802 command_packet->request_id = request_id;
1803 command_packet->unit__hostid = TW_UNITHOST_IN(0, srb->device->id);
1804 command_packet->status = 0;
1805 command_packet->flags = 0;
1807 if (srb->cmnd[0] == WRITE_10) {
1808 if ((srb->cmnd[1] & 0x8) || (srb->cmnd[1] & 0x10))
1809 command_packet->flags = 1;
1812 if (srb->cmnd[0] == READ_6 || srb->cmnd[0] == WRITE_6) {
1813 lba = ((u32)srb->cmnd[1] << 16) | ((u32)srb->cmnd[2] << 8) | (u32)srb->cmnd[3];
1814 num_sectors = (u32)srb->cmnd[4];
1815 } else {
1816 lba = ((u32)srb->cmnd[2] << 24) | ((u32)srb->cmnd[3] << 16) | ((u32)srb->cmnd[4] << 8) | (u32)srb->cmnd[5];
1817 num_sectors = (u32)srb->cmnd[8] | ((u32)srb->cmnd[7] << 8);
1820 /* Update sector statistic */
1821 tw_dev->sector_count = num_sectors;
1822 if (tw_dev->sector_count > tw_dev->max_sector_count)
1823 tw_dev->max_sector_count = tw_dev->sector_count;
1825 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): lba = 0x%x num_sectors = 0x%x\n", lba, num_sectors);
1826 command_packet->byte8.io.lba = lba;
1827 command_packet->byte6.block_count = num_sectors;
1829 /* Do this if there are no sg list entries */
1830 if (tw_dev->srb[request_id]->use_sg == 0) {
1831 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): SG = 0\n");
1832 buffaddr = tw_map_scsi_single_data(tw_dev->tw_pci_dev, tw_dev->srb[request_id]);
1833 if (buffaddr == 0)
1834 return 1;
1836 command_packet->byte8.io.sgl[0].address = buffaddr;
1837 command_packet->byte8.io.sgl[0].length = tw_dev->srb[request_id]->request_bufflen;
1838 command_packet->size+=2;
1841 /* Do this if we have multiple sg list entries */
1842 if (tw_dev->srb[request_id]->use_sg > 0) {
1843 use_sg = tw_map_scsi_sg_data(tw_dev->tw_pci_dev, tw_dev->srb[request_id]);
1844 if (use_sg == 0)
1845 return 1;
1847 for (i=0;i<use_sg; i++) {
1848 command_packet->byte8.io.sgl[i].address = sg_dma_address(&sglist[i]);
1849 command_packet->byte8.io.sgl[i].length = sg_dma_len(&sglist[i]);
1850 command_packet->size+=2;
1854 /* Update SG statistics */
1855 tw_dev->sgl_entries = tw_dev->srb[request_id]->use_sg;
1856 if (tw_dev->sgl_entries > tw_dev->max_sgl_entries)
1857 tw_dev->max_sgl_entries = tw_dev->sgl_entries;
1859 command_que_value = tw_dev->command_packet_physical_address[request_id];
1860 if (command_que_value == 0) {
1861 dprintk(KERN_WARNING "3w-xxxx: tw_scsiop_read_write(): Bad command packet physical address.\n");
1862 return 1;
1865 /* Now try to post the command to the board */
1866 tw_post_command_packet(tw_dev, request_id);
1868 return 0;
1869 } /* End tw_scsiop_read_write() */
1871 /* This function will handle the request sense scsi command */
1872 static int tw_scsiop_request_sense(TW_Device_Extension *tw_dev, int request_id)
1874 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_request_sense()\n");
1876 /* For now we just zero the request buffer */
1877 memset(tw_dev->srb[request_id]->request_buffer, 0, tw_dev->srb[request_id]->request_bufflen);
1878 tw_dev->state[request_id] = TW_S_COMPLETED;
1879 tw_state_request_finish(tw_dev, request_id);
1881 /* If we got a request_sense, we probably want a reset, return error */
1882 tw_dev->srb[request_id]->result = (DID_ERROR << 16);
1883 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1885 return 0;
1886 } /* End tw_scsiop_request_sense() */
1888 /* This function will handle synchronize cache scsi command */
1889 static int tw_scsiop_synchronize_cache(TW_Device_Extension *tw_dev, int request_id)
1891 TW_Command *command_packet;
1892 unsigned long command_que_value;
1894 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_synchronize_cache()\n");
1896 /* Send firmware flush command for this unit */
1897 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1898 if (command_packet == NULL) {
1899 printk(KERN_WARNING "3w-xxxx: tw_scsiop_synchronize_cache(): Bad command packet virtual address.\n");
1900 return 1;
1903 /* Setup the command packet */
1904 memset(command_packet, 0, sizeof(TW_Sector));
1905 command_packet->opcode__sgloffset = TW_OPSGL_IN(0, TW_OP_FLUSH_CACHE);
1906 command_packet->size = 2;
1907 command_packet->request_id = request_id;
1908 command_packet->unit__hostid = TW_UNITHOST_IN(0, tw_dev->srb[request_id]->device->id);
1909 command_packet->status = 0;
1910 command_packet->flags = 0;
1911 command_packet->byte6.parameter_count = 1;
1912 command_que_value = tw_dev->command_packet_physical_address[request_id];
1913 if (command_que_value == 0) {
1914 printk(KERN_WARNING "3w-xxxx: tw_scsiop_synchronize_cache(): Bad command packet physical address.\n");
1915 return 1;
1918 /* Now try to post the command packet */
1919 tw_post_command_packet(tw_dev, request_id);
1921 return 0;
1922 } /* End tw_scsiop_synchronize_cache() */
1924 /* This function will handle test unit ready scsi command */
1925 static int tw_scsiop_test_unit_ready(TW_Device_Extension *tw_dev, int request_id)
1927 TW_Param *param;
1928 TW_Command *command_packet;
1929 unsigned long command_que_value;
1930 unsigned long param_value;
1932 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_test_unit_ready()\n");
1934 /* Initialize command packet */
1935 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1936 if (command_packet == NULL) {
1937 printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready(): Bad command packet virtual address.\n");
1938 return 1;
1940 memset(command_packet, 0, sizeof(TW_Sector));
1941 command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
1942 command_packet->size = 4;
1943 command_packet->request_id = request_id;
1944 command_packet->status = 0;
1945 command_packet->flags = 0;
1946 command_packet->byte6.parameter_count = 1;
1948 /* Now setup the param */
1949 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
1950 printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready(): Bad alignment virtual address.\n");
1951 return 1;
1953 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1954 memset(param, 0, sizeof(TW_Sector));
1955 param->table_id = 3; /* unit summary table */
1956 param->parameter_id = 3; /* unitsstatus parameter */
1957 param->parameter_size_bytes = TW_MAX_UNITS;
1958 param_value = tw_dev->alignment_physical_address[request_id];
1959 if (param_value == 0) {
1960 printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready(): Bad alignment physical address.\n");
1961 return 1;
1964 command_packet->byte8.param.sgl[0].address = param_value;
1965 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
1966 command_que_value = tw_dev->command_packet_physical_address[request_id];
1967 if (command_que_value == 0) {
1968 printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready(): Bad command packet physical address.\n");
1969 return 1;
1972 /* Now try to post the command packet */
1973 tw_post_command_packet(tw_dev, request_id);
1975 return 0;
1976 } /* End tw_scsiop_test_unit_ready() */
1978 /* This function is called by the isr to complete a testunitready command */
1979 static int tw_scsiop_test_unit_ready_complete(TW_Device_Extension *tw_dev, int request_id)
1981 unsigned char *is_unit_present;
1982 TW_Param *param;
1984 dprintk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready_complete()\n");
1986 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1987 if (param == NULL) {
1988 printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready_complete(): Bad alignment virtual address.\n");
1989 return 1;
1991 is_unit_present = &(param->data[0]);
1993 if (is_unit_present[tw_dev->srb[request_id]->device->id] & TW_UNIT_ONLINE) {
1994 tw_dev->is_unit_present[tw_dev->srb[request_id]->device->id] = 1;
1995 } else {
1996 tw_dev->is_unit_present[tw_dev->srb[request_id]->device->id] = 0;
1997 tw_dev->srb[request_id]->result = (DID_BAD_TARGET << 16);
1998 return TW_ISR_DONT_RESULT;
2001 return 0;
2002 } /* End tw_scsiop_test_unit_ready_complete() */
2004 /* This is the main scsi queue function to handle scsi opcodes */
2005 static int tw_scsi_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
2007 unsigned char *command = SCpnt->cmnd;
2008 int request_id = 0;
2009 int retval = 1;
2010 TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
2012 /* Save done function into Scsi_Cmnd struct */
2013 SCpnt->scsi_done = done;
2015 /* Queue the command and get a request id */
2016 tw_state_request_start(tw_dev, &request_id);
2018 /* Save the scsi command for use by the ISR */
2019 tw_dev->srb[request_id] = SCpnt;
2021 /* Initialize phase to zero */
2022 SCpnt->SCp.phase = TW_PHASE_INITIAL;
2024 switch (*command) {
2025 case READ_10:
2026 case READ_6:
2027 case WRITE_10:
2028 case WRITE_6:
2029 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught READ/WRITE.\n");
2030 retval = tw_scsiop_read_write(tw_dev, request_id);
2031 break;
2032 case TEST_UNIT_READY:
2033 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught TEST_UNIT_READY.\n");
2034 retval = tw_scsiop_test_unit_ready(tw_dev, request_id);
2035 break;
2036 case INQUIRY:
2037 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught INQUIRY.\n");
2038 retval = tw_scsiop_inquiry(tw_dev, request_id);
2039 break;
2040 case READ_CAPACITY:
2041 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught READ_CAPACITY.\n");
2042 retval = tw_scsiop_read_capacity(tw_dev, request_id);
2043 break;
2044 case REQUEST_SENSE:
2045 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught REQUEST_SENSE.\n");
2046 retval = tw_scsiop_request_sense(tw_dev, request_id);
2047 break;
2048 case MODE_SENSE:
2049 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught MODE_SENSE.\n");
2050 retval = tw_scsiop_mode_sense(tw_dev, request_id);
2051 break;
2052 case SYNCHRONIZE_CACHE:
2053 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught SYNCHRONIZE_CACHE.\n");
2054 retval = tw_scsiop_synchronize_cache(tw_dev, request_id);
2055 break;
2056 case TW_IOCTL:
2057 printk(KERN_WARNING "3w-xxxx: SCSI_IOCTL_SEND_COMMAND deprecated, please update your 3ware tools.\n");
2058 break;
2059 default:
2060 printk(KERN_NOTICE "3w-xxxx: scsi%d: Unknown scsi opcode: 0x%x\n", tw_dev->host->host_no, *command);
2061 tw_dev->state[request_id] = TW_S_COMPLETED;
2062 tw_state_request_finish(tw_dev, request_id);
2063 SCpnt->result = (DID_BAD_TARGET << 16);
2064 done(SCpnt);
2065 retval = 0;
2067 if (retval) {
2068 tw_dev->state[request_id] = TW_S_COMPLETED;
2069 tw_state_request_finish(tw_dev, request_id);
2070 SCpnt->result = (DID_ERROR << 16);
2071 done(SCpnt);
2072 retval = 0;
2074 return retval;
2075 } /* End tw_scsi_queue() */
2077 /* This function is the interrupt service routine */
2078 static irqreturn_t tw_interrupt(int irq, void *dev_instance,
2079 struct pt_regs *regs)
2081 int request_id;
2082 u32 status_reg_value;
2083 TW_Device_Extension *tw_dev = (TW_Device_Extension *)dev_instance;
2084 TW_Response_Queue response_que;
2085 int error = 0, retval = 0;
2086 TW_Command *command_packet;
2087 int handled = 0;
2089 /* Get the host lock for io completions */
2090 spin_lock(tw_dev->host->host_lock);
2092 /* Read the registers */
2093 status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
2095 /* Check if this is our interrupt, otherwise bail */
2096 if (!(status_reg_value & TW_STATUS_VALID_INTERRUPT))
2097 goto tw_interrupt_bail;
2099 handled = 1;
2101 /* Check controller for errors */
2102 if (tw_check_bits(status_reg_value)) {
2103 dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n");
2104 if (tw_decode_bits(tw_dev, status_reg_value, 1)) {
2105 TW_CLEAR_ALL_INTERRUPTS(tw_dev);
2106 goto tw_interrupt_bail;
2110 /* Handle host interrupt */
2111 if (status_reg_value & TW_STATUS_HOST_INTERRUPT) {
2112 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Received host interrupt.\n");
2113 TW_CLEAR_HOST_INTERRUPT(tw_dev);
2116 /* Handle attention interrupt */
2117 if (status_reg_value & TW_STATUS_ATTENTION_INTERRUPT) {
2118 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Received attention interrupt.\n");
2119 TW_CLEAR_ATTENTION_INTERRUPT(tw_dev);
2120 tw_state_request_start(tw_dev, &request_id);
2121 error = tw_aen_read_queue(tw_dev, request_id);
2122 if (error) {
2123 printk(KERN_WARNING "3w-xxxx: scsi%d: Error reading aen queue.\n", tw_dev->host->host_no);
2124 tw_dev->state[request_id] = TW_S_COMPLETED;
2125 tw_state_request_finish(tw_dev, request_id);
2129 /* Handle command interrupt */
2130 if (status_reg_value & TW_STATUS_COMMAND_INTERRUPT) {
2131 /* Drain as many pending commands as we can */
2132 while (tw_dev->pending_request_count > 0) {
2133 request_id = tw_dev->pending_queue[tw_dev->pending_head];
2134 if (tw_dev->state[request_id] != TW_S_PENDING) {
2135 printk(KERN_WARNING "3w-xxxx: scsi%d: Found request id that wasn't pending.\n", tw_dev->host->host_no);
2136 break;
2138 if (tw_post_command_packet(tw_dev, request_id)==0) {
2139 if (tw_dev->pending_head == TW_Q_LENGTH-1) {
2140 tw_dev->pending_head = TW_Q_START;
2141 } else {
2142 tw_dev->pending_head = tw_dev->pending_head + 1;
2144 tw_dev->pending_request_count--;
2145 } else {
2146 /* If we get here, we will continue re-posting on the next command interrupt */
2147 break;
2150 /* If there are no more pending requests, we mask command interrupt */
2151 if (tw_dev->pending_request_count == 0)
2152 TW_MASK_COMMAND_INTERRUPT(tw_dev);
2155 /* Handle response interrupt */
2156 if (status_reg_value & TW_STATUS_RESPONSE_INTERRUPT) {
2157 /* Drain the response queue from the board */
2158 while ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
2159 /* Read response queue register */
2160 response_que.value = inl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
2161 request_id = TW_RESID_OUT(response_que.response_id);
2162 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
2163 error = 0;
2165 /* Check for bad response */
2166 if (command_packet->status != 0) {
2167 /* If internal command, don't error, don't fill sense */
2168 if (tw_dev->srb[request_id] == NULL) {
2169 tw_decode_sense(tw_dev, request_id, 0);
2170 } else {
2171 error = tw_decode_sense(tw_dev, request_id, 1);
2175 /* Check for correct state */
2176 if (tw_dev->state[request_id] != TW_S_POSTED) {
2177 if (tw_dev->srb[request_id] != NULL) {
2178 printk(KERN_WARNING "3w-xxxx: scsi%d: Received a request id that wasn't posted.\n", tw_dev->host->host_no);
2179 error = 1;
2183 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Response queue request id: %d.\n", request_id);
2185 /* Check for internal command completion */
2186 if (tw_dev->srb[request_id] == NULL) {
2187 dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Found internally posted command.\n");
2188 /* Check for chrdev ioctl completion */
2189 if (request_id != tw_dev->chrdev_request_id) {
2190 retval = tw_aen_complete(tw_dev, request_id);
2191 if (retval) {
2192 printk(KERN_WARNING "3w-xxxx: scsi%d: Error completing aen.\n", tw_dev->host->host_no);
2194 } else {
2195 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
2196 wake_up(&tw_dev->ioctl_wqueue);
2198 } else {
2199 switch (tw_dev->srb[request_id]->cmnd[0]) {
2200 case READ_10:
2201 case READ_6:
2202 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught READ_10/READ_6\n");
2203 break;
2204 case WRITE_10:
2205 case WRITE_6:
2206 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught WRITE_10/WRITE_6\n");
2207 break;
2208 case TEST_UNIT_READY:
2209 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught TEST_UNIT_READY\n");
2210 error = tw_scsiop_test_unit_ready_complete(tw_dev, request_id);
2211 break;
2212 case INQUIRY:
2213 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught INQUIRY\n");
2214 error = tw_scsiop_inquiry_complete(tw_dev, request_id);
2215 break;
2216 case READ_CAPACITY:
2217 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught READ_CAPACITY\n");
2218 error = tw_scsiop_read_capacity_complete(tw_dev, request_id);
2219 break;
2220 case MODE_SENSE:
2221 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught MODE_SENSE\n");
2222 error = tw_scsiop_mode_sense_complete(tw_dev, request_id);
2223 break;
2224 case SYNCHRONIZE_CACHE:
2225 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught SYNCHRONIZE_CACHE\n");
2226 break;
2227 default:
2228 printk(KERN_WARNING "3w-xxxx: case slip in tw_interrupt()\n");
2229 error = 1;
2232 /* If no error command was a success */
2233 if (error == 0) {
2234 tw_dev->srb[request_id]->result = (DID_OK << 16);
2237 /* If error, command failed */
2238 if (error == 1) {
2239 /* Ask for a host reset */
2240 tw_dev->srb[request_id]->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
2243 /* Now complete the io */
2244 if ((error != TW_ISR_DONT_COMPLETE)) {
2245 tw_dev->state[request_id] = TW_S_COMPLETED;
2246 tw_state_request_finish(tw_dev, request_id);
2247 tw_dev->posted_request_count--;
2248 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
2250 tw_unmap_scsi_data(tw_dev->tw_pci_dev, tw_dev->srb[request_id]);
2254 /* Check for valid status after each drain */
2255 status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
2256 if (tw_check_bits(status_reg_value)) {
2257 dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n");
2258 if (tw_decode_bits(tw_dev, status_reg_value, 1)) {
2259 TW_CLEAR_ALL_INTERRUPTS(tw_dev);
2260 goto tw_interrupt_bail;
2266 tw_interrupt_bail:
2267 spin_unlock(tw_dev->host->host_lock);
2268 return IRQ_RETVAL(handled);
2269 } /* End tw_interrupt() */
2271 /* This function tells the controller to shut down */
2272 static void __tw_shutdown(TW_Device_Extension *tw_dev)
2274 /* Disable interrupts */
2275 TW_DISABLE_INTERRUPTS(tw_dev);
2277 printk(KERN_WARNING "3w-xxxx: Shutting down host %d.\n", tw_dev->host->host_no);
2279 /* Tell the card we are shutting down */
2280 if (tw_initconnection(tw_dev, 1)) {
2281 printk(KERN_WARNING "3w-xxxx: Connection shutdown failed.\n");
2282 } else {
2283 printk(KERN_WARNING "3w-xxxx: Shutdown complete.\n");
2286 /* Clear all interrupts just before exit */
2287 TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
2288 } /* End __tw_shutdown() */
2290 /* Wrapper for __tw_shutdown */
2291 static void tw_shutdown(struct pci_dev *pdev)
2293 struct Scsi_Host *host = pci_get_drvdata(pdev);
2294 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
2296 __tw_shutdown(tw_dev);
2297 } /* End tw_shutdown() */
2299 static struct scsi_host_template driver_template = {
2300 .module = THIS_MODULE,
2301 .name = "3ware Storage Controller",
2302 .queuecommand = tw_scsi_queue,
2303 .eh_host_reset_handler = tw_scsi_eh_reset,
2304 .bios_param = tw_scsi_biosparam,
2305 .change_queue_depth = tw_change_queue_depth,
2306 .can_queue = TW_Q_LENGTH-2,
2307 .this_id = -1,
2308 .sg_tablesize = TW_MAX_SGL_LENGTH,
2309 .max_sectors = TW_MAX_SECTORS,
2310 .cmd_per_lun = TW_MAX_CMDS_PER_LUN,
2311 .use_clustering = ENABLE_CLUSTERING,
2312 .shost_attrs = tw_host_attrs,
2313 .emulated = 1
2316 /* This function will probe and initialize a card */
2317 static int __devinit tw_probe(struct pci_dev *pdev, const struct pci_device_id *dev_id)
2319 struct Scsi_Host *host = NULL;
2320 TW_Device_Extension *tw_dev;
2321 int retval = -ENODEV;
2323 retval = pci_enable_device(pdev);
2324 if (retval) {
2325 printk(KERN_WARNING "3w-xxxx: Failed to enable pci device.");
2326 goto out_disable_device;
2329 pci_set_master(pdev);
2331 retval = pci_set_dma_mask(pdev, TW_DMA_MASK);
2332 if (retval) {
2333 printk(KERN_WARNING "3w-xxxx: Failed to set dma mask.");
2334 goto out_disable_device;
2337 host = scsi_host_alloc(&driver_template, sizeof(TW_Device_Extension));
2338 if (!host) {
2339 printk(KERN_WARNING "3w-xxxx: Failed to allocate memory for device extension.");
2340 retval = -ENOMEM;
2341 goto out_disable_device;
2343 tw_dev = (TW_Device_Extension *)host->hostdata;
2345 memset(tw_dev, 0, sizeof(TW_Device_Extension));
2347 /* Save values to device extension */
2348 tw_dev->host = host;
2349 tw_dev->tw_pci_dev = pdev;
2351 if (tw_initialize_device_extension(tw_dev)) {
2352 printk(KERN_WARNING "3w-xxxx: Failed to initialize device extension.");
2353 goto out_free_device_extension;
2356 /* Request IO regions */
2357 retval = pci_request_regions(pdev, "3w-xxxx");
2358 if (retval) {
2359 printk(KERN_WARNING "3w-xxxx: Failed to get mem region.");
2360 goto out_free_device_extension;
2363 /* Save base address */
2364 tw_dev->base_addr = pci_resource_start(pdev, 0);
2365 if (!tw_dev->base_addr) {
2366 printk(KERN_WARNING "3w-xxxx: Failed to get io address.");
2367 goto out_release_mem_region;
2370 /* Disable interrupts on the card */
2371 TW_DISABLE_INTERRUPTS(tw_dev);
2373 /* Initialize the card */
2374 if (tw_reset_sequence(tw_dev))
2375 goto out_release_mem_region;
2377 /* Set host specific parameters */
2378 host->max_id = TW_MAX_UNITS;
2379 host->max_cmd_len = TW_MAX_CDB_LEN;
2381 /* Luns and channels aren't supported by adapter */
2382 host->max_lun = 0;
2383 host->max_channel = 0;
2385 /* Register the card with the kernel SCSI layer */
2386 retval = scsi_add_host(host, &pdev->dev);
2387 if (retval) {
2388 printk(KERN_WARNING "3w-xxxx: scsi add host failed");
2389 goto out_release_mem_region;
2392 pci_set_drvdata(pdev, host);
2394 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);
2396 /* Now setup the interrupt handler */
2397 retval = request_irq(pdev->irq, tw_interrupt, SA_SHIRQ, "3w-xxxx", tw_dev);
2398 if (retval) {
2399 printk(KERN_WARNING "3w-xxxx: Error requesting IRQ.");
2400 goto out_remove_host;
2403 tw_device_extension_list[tw_device_extension_count] = tw_dev;
2404 tw_device_extension_count++;
2406 /* Re-enable interrupts on the card */
2407 TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
2409 /* Finally, scan the host */
2410 scsi_scan_host(host);
2412 if (twe_major == -1) {
2413 if ((twe_major = register_chrdev (0, "twe", &tw_fops)) < 0)
2414 printk(KERN_WARNING "3w-xxxx: Failed to register character device.");
2416 return 0;
2418 out_remove_host:
2419 scsi_remove_host(host);
2420 out_release_mem_region:
2421 pci_release_regions(pdev);
2422 out_free_device_extension:
2423 tw_free_device_extension(tw_dev);
2424 scsi_host_put(host);
2425 out_disable_device:
2426 pci_disable_device(pdev);
2428 return retval;
2429 } /* End tw_probe() */
2431 /* This function is called to remove a device */
2432 static void tw_remove(struct pci_dev *pdev)
2434 struct Scsi_Host *host = pci_get_drvdata(pdev);
2435 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
2437 scsi_remove_host(tw_dev->host);
2439 /* Unregister character device */
2440 if (twe_major >= 0) {
2441 unregister_chrdev(twe_major, "twe");
2442 twe_major = -1;
2445 /* Free up the IRQ */
2446 free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
2448 /* Shutdown the card */
2449 __tw_shutdown(tw_dev);
2451 /* Free up the mem region */
2452 pci_release_regions(pdev);
2454 /* Free up device extension resources */
2455 tw_free_device_extension(tw_dev);
2457 scsi_host_put(tw_dev->host);
2458 pci_disable_device(pdev);
2459 tw_device_extension_count--;
2460 } /* End tw_remove() */
2462 /* PCI Devices supported by this driver */
2463 static struct pci_device_id tw_pci_tbl[] __devinitdata = {
2464 { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_1000,
2465 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2466 { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_7000,
2467 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2470 MODULE_DEVICE_TABLE(pci, tw_pci_tbl);
2472 /* pci_driver initializer */
2473 static struct pci_driver tw_driver = {
2474 .name = "3w-xxxx",
2475 .id_table = tw_pci_tbl,
2476 .probe = tw_probe,
2477 .remove = tw_remove,
2478 .shutdown = tw_shutdown,
2481 /* This function is called on driver initialization */
2482 static int __init tw_init(void)
2484 printk(KERN_WARNING "3ware Storage Controller device driver for Linux v%s.\n", TW_DRIVER_VERSION);
2486 return pci_module_init(&tw_driver);
2487 } /* End tw_init() */
2489 /* This function is called on driver exit */
2490 static void __exit tw_exit(void)
2492 pci_unregister_driver(&tw_driver);
2493 } /* End tw_exit() */
2495 module_init(tw_init);
2496 module_exit(tw_exit);