2 3w-xxxx.c -- 3ware Storage Controller device driver for Linux.
4 Written By: Adam Radford <linux@3ware.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-2002 3ware Inc.
11 Kernel compatablity 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.
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:
52 For more information, goto:
57 0.1.000 - Initial release.
58 0.4.000 - Added support for Asynchronous Event Notification through
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
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
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
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
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
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 1.02.00.016 - Set max_cmd_len for 3dm.
123 Set max sectors to 256 for non raid5 & 6XXX.
124 1.02.00.017 - Modified pci parity error handling/clearing from config space
125 during initialization.
126 1.02.00.018 - Better handling of request sense opcode and sense information
127 for failed commands. Add tw_decode_sense().
128 Replace all mdelay()'s with scsi_sleep().
129 1.02.00.019 - Revert mdelay's and scsi_sleep's, this caused problems on
131 1.02.00.020 - Bump cmd_per_lun in SHT to 255 for better jbod performance.
132 Make module license ifdef'd for backward compatibility.
133 Improve handling of errors in tw_interrupt().
134 Add handling/clearing of controller queue error.
135 Better alignment checking in tw_allocate_memory().
136 Cleanup tw_initialize_device_extension().
137 Empty stale responses before draining aen queue.
138 Fix tw_scsi_eh_abort() to not reset on every io abort.
139 Set can_queue in SHT to 255 to prevent hang from AEN.
140 1.02.00.021 - Fix possible null pointer dereference in tw_scsi_release().
141 1.02.00.022 - Fix bug in tw_aen_drain_queue() where unit # was always zero.
142 1.02.00.023 - Add severity levels to AEN strings.
143 1.02.00.024 - Fix command interrupt spurious error messages.
144 Fix bug in raw command post with data ioctl method.
145 Fix bug where rollcall sometimes failed with cable errors.
146 1.02.00.025 - Print unit # on all command timeouts.
147 1.02.00.026 - Fix possible infinite retry bug with power glitch induced
149 Cleanup some AEN severity levels.
150 1.02.00.027 - Add drive not supported AEN code for SATA controllers.
151 Remove spurious unknown ioctl error message.
152 1.02.00.028 - Fix bug where multiple controllers with no units were the
154 Fix bug where cards were being shut down more than once.
155 1.02.00.029 - Add new pci dma mapping for kernel 2.4 for highmem support.
156 Replace pci_map_single() with pci_map_page() for highmem.
157 Check for tw_setfeature() failure.
158 1.02.00.030 - Make driver 64-bit clean.
159 1.02.00.031 - Cleanup polling timeouts/routines in several places.
160 Add support for mode sense opcode.
161 Add support for cache mode page.
162 Add support for synchronize cache opcode.
165 #include <linux/module.h>
167 MODULE_AUTHOR ("3ware Inc.");
169 MODULE_DESCRIPTION ("3ware Storage Controller Linux Driver (SMP)");
171 MODULE_DESCRIPTION ("3ware Storage Controller Linux Driver");
174 #include <linux/kernel.h>
175 #include <linux/pci.h>
176 #include <linux/time.h>
177 #include <linux/proc_fs.h>
178 #include <linux/sched.h>
179 #include <linux/ioport.h>
180 #include <linux/blk.h>
181 #include <linux/hdreg.h>
182 #include <linux/string.h>
183 #include <linux/delay.h>
184 #include <linux/smp.h>
185 #include <linux/reboot.h>
186 #include <linux/spinlock.h>
188 #include <asm/errno.h>
191 #include <asm/uaccess.h>
193 #define __3W_C /* let 3w-xxxx.h know it is use */
201 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,10)
202 MODULE_LICENSE("GPL");
205 static int tw_copy_info(TW_Info *info, char *fmt, ...);
206 static void tw_copy_mem_info(TW_Info *info, char *data, int len);
207 static void tw_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
208 static int tw_halt(struct notifier_block *nb, ulong event, void *buf);
209 static int tw_map_scsi_sg_data(struct pci_dev *pdev, Scsi_Cmnd *cmd);
210 static u32 tw_map_scsi_single_data(struct pci_dev *pdev, Scsi_Cmnd *cmd);
211 static void tw_unmap_scsi_data(struct pci_dev *pdev, Scsi_Cmnd *cmd);
213 /* Notifier block to get a notify on system shutdown/halt/reboot */
214 static struct notifier_block tw_notifier = {
219 char *tw_driver_version="1.02.00.031";
220 TW_Device_Extension *tw_device_extension_list[TW_MAX_SLOT];
221 int tw_device_extension_count = 0;
225 /* This function will complete an aen request from the isr */
226 int tw_aen_complete(TW_Device_Extension *tw_dev, int request_id)
230 int error = 0, table_max = 0;
232 dprintk(KERN_WARNING "3w-xxxx: tw_aen_complete()\n");
233 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
234 printk(KERN_WARNING "3w-xxxx: tw_aen_complete(): Bad alignment virtual address.\n");
237 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
238 aen = *(unsigned short *)(param->data);
239 dprintk(KERN_NOTICE "3w-xxxx: tw_aen_complete(): Queue'd code 0x%x\n", aen);
241 /* Print some useful info when certain aen codes come out */
243 printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: INFO: AEN queue overflow.\n", tw_dev->host->host_no);
245 table_max = sizeof(tw_aen_string)/sizeof(char *);
246 if ((aen & 0x0ff) < table_max) {
247 if ((tw_aen_string[aen & 0xff][strlen(tw_aen_string[aen & 0xff])-1]) == '#') {
248 printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: %s%d.\n", tw_dev->host->host_no, tw_aen_string[aen & 0xff], aen >> 8);
251 printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: %s.\n", tw_dev->host->host_no, tw_aen_string[aen & 0xff]);
254 printk(KERN_WARNING "3w-xxxx: scsi%d: Received AEN %d.\n", tw_dev->host->host_no, aen);
260 /* Now queue the code */
261 tw_dev->aen_queue[tw_dev->aen_tail] = aen;
262 if (tw_dev->aen_tail == TW_Q_LENGTH - 1) {
263 tw_dev->aen_tail = TW_Q_START;
265 tw_dev->aen_tail = tw_dev->aen_tail + 1;
267 if (tw_dev->aen_head == tw_dev->aen_tail) {
268 if (tw_dev->aen_head == TW_Q_LENGTH - 1) {
269 tw_dev->aen_head = TW_Q_START;
271 tw_dev->aen_head = tw_dev->aen_head + 1;
275 if (aen != TW_AEN_QUEUE_EMPTY) {
276 error = tw_aen_read_queue(tw_dev, request_id);
278 printk(KERN_WARNING "3w-xxxx: scsi%d: Error completing AEN.\n", tw_dev->host->host_no);
279 tw_dev->state[request_id] = TW_S_COMPLETED;
280 tw_state_request_finish(tw_dev, request_id);
283 tw_dev->state[request_id] = TW_S_COMPLETED;
284 tw_state_request_finish(tw_dev, request_id);
288 } /* End tw_aen_complete() */
290 /* This function will drain the aen queue after a soft reset */
291 int tw_aen_drain_queue(TW_Device_Extension *tw_dev)
293 TW_Command *command_packet;
296 u32 command_que_addr;
297 unsigned long command_que_value;
298 unsigned long param_value;
299 TW_Response_Queue response_queue;
300 u32 response_que_addr;
302 unsigned short aen_code;
306 int found = 0, table_max = 0;
308 dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue()\n");
310 command_que_addr = tw_dev->registers.command_que_addr;
311 response_que_addr = tw_dev->registers.response_que_addr;
313 if (tw_poll_status(tw_dev, TW_STATUS_ATTENTION_INTERRUPT | TW_STATUS_MICROCONTROLLER_READY, 30)) {
314 dprintk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): No attention interrupt for card %d.\n", tw_device_extension_count);
317 tw_clear_attention_interrupt(tw_dev);
319 /* Empty response queue */
320 tw_empty_response_que(tw_dev);
322 /* Initialize command packet */
323 if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
324 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad command packet virtual address.\n");
327 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
328 memset(command_packet, 0, sizeof(TW_Sector));
329 command_packet->byte0.opcode = TW_OP_GET_PARAM;
330 command_packet->byte0.sgl_offset = 2;
331 command_packet->size = 4;
332 command_packet->request_id = request_id;
333 command_packet->byte3.unit = 0;
334 command_packet->byte3.host_id = 0;
335 command_packet->status = 0;
336 command_packet->flags = 0;
337 command_packet->byte6.parameter_count = 1;
338 command_que_value = tw_dev->command_packet_physical_address[request_id];
339 if (command_que_value == 0) {
340 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad command packet physical address.\n");
344 /* Now setup the param */
345 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
346 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad alignment virtual address.\n");
349 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
350 memset(param, 0, sizeof(TW_Sector));
351 param->table_id = 0x401; /* AEN table */
352 param->parameter_id = 2; /* Unit code */
353 param->parameter_size_bytes = 2;
354 param_value = tw_dev->alignment_physical_address[request_id];
355 if (param_value == 0) {
356 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad alignment physical address.\n");
359 command_packet->byte8.param.sgl[0].address = param_value;
360 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
362 /* Now drain the controller's aen queue */
364 /* Post command packet */
365 outl(command_que_value, command_que_addr);
367 /* Now poll for completion */
368 if (tw_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, 30) == 0) {
369 response_queue.value = inl(response_que_addr);
370 request_id = (unsigned char)response_queue.u.response_id;
371 if (request_id != 0) {
372 /* Unexpected request id */
373 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Unexpected request id.\n");
377 if (command_packet->status != 0) {
378 if (command_packet->flags != TW_AEN_TABLE_UNDEFINED) {
380 tw_decode_sense(tw_dev, request_id, 0);
383 /* We know this is a 3w-1x00, and doesn't support aen's */
388 /* Now check the aen */
389 aen = *(unsigned short *)(param->data);
390 aen_code = (aen & 0x0ff);
393 case TW_AEN_QUEUE_EMPTY:
394 dprintk(KERN_WARNING "3w-xxxx: AEN: %s.\n", tw_aen_string[aen & 0xff]);
395 if (first_reset != 1) {
401 case TW_AEN_SOFT_RESET:
402 if (first_reset == 0) {
405 printk(KERN_WARNING "3w-xxxx: AEN: %s.\n", tw_aen_string[aen & 0xff]);
412 printk(KERN_WARNING "3w-xxxx: AEN: INFO: AEN queue overflow.\n");
414 table_max = sizeof(tw_aen_string)/sizeof(char *);
415 if ((aen & 0x0ff) < table_max) {
416 if ((tw_aen_string[aen & 0xff][strlen(tw_aen_string[aen & 0xff])-1]) == '#') {
417 printk(KERN_WARNING "3w-xxxx: AEN: %s%d.\n", tw_aen_string[aen & 0xff], aen >> 8);
419 printk(KERN_WARNING "3w-xxxx: AEN: %s.\n", tw_aen_string[aen & 0xff]);
422 printk(KERN_WARNING "3w-xxxx: Received AEN %d.\n", aen);
428 /* Now put the aen on the aen_queue */
430 tw_dev->aen_queue[tw_dev->aen_tail] = aen;
431 if (tw_dev->aen_tail == TW_Q_LENGTH - 1) {
432 tw_dev->aen_tail = TW_Q_START;
434 tw_dev->aen_tail = tw_dev->aen_tail + 1;
436 if (tw_dev->aen_head == tw_dev->aen_tail) {
437 if (tw_dev->aen_head == TW_Q_LENGTH - 1) {
438 tw_dev->aen_head = TW_Q_START;
440 tw_dev->aen_head = tw_dev->aen_head + 1;
447 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Response never received.\n");
450 } while (finished == 0);
453 } /* End tw_aen_drain_queue() */
455 /* This function will read the aen queue from the isr */
456 int tw_aen_read_queue(TW_Device_Extension *tw_dev, int request_id)
458 TW_Command *command_packet;
460 u32 command_que_addr;
461 unsigned long command_que_value;
462 u32 status_reg_value = 0, status_reg_addr;
463 unsigned long param_value = 0;
465 dprintk(KERN_NOTICE "3w-xxxx: tw_aen_read_queue()\n");
466 command_que_addr = tw_dev->registers.command_que_addr;
467 status_reg_addr = tw_dev->registers.status_reg_addr;
469 status_reg_value = inl(status_reg_addr);
470 if (tw_check_bits(status_reg_value)) {
471 dprintk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Unexpected bits.\n");
472 tw_decode_bits(tw_dev, status_reg_value, 1);
475 if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
476 printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad command packet virtual address.\n");
479 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
480 memset(command_packet, 0, sizeof(TW_Sector));
481 command_packet->byte0.opcode = TW_OP_GET_PARAM;
482 command_packet->byte0.sgl_offset = 2;
483 command_packet->size = 4;
484 command_packet->request_id = request_id;
485 command_packet->byte3.unit = 0;
486 command_packet->byte3.host_id = 0;
487 command_packet->status = 0;
488 command_packet->flags = 0;
489 command_packet->byte6.parameter_count = 1;
490 command_que_value = tw_dev->command_packet_physical_address[request_id];
491 if (command_que_value == 0) {
492 printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad command packet physical address.\n");
495 /* Now setup the param */
496 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
497 printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad alignment virtual address.\n");
500 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
501 memset(param, 0, sizeof(TW_Sector));
502 param->table_id = 0x401; /* AEN table */
503 param->parameter_id = 2; /* Unit code */
504 param->parameter_size_bytes = 2;
505 param_value = tw_dev->alignment_physical_address[request_id];
506 if (param_value == 0) {
507 printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad alignment physical address.\n");
510 command_packet->byte8.param.sgl[0].address = param_value;
511 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
513 /* Now post the command packet */
514 if ((status_reg_value & TW_STATUS_COMMAND_QUEUE_FULL) == 0) {
515 dprintk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Post succeeded.\n");
516 tw_dev->srb[request_id] = 0; /* Flag internal command */
517 tw_dev->state[request_id] = TW_S_POSTED;
518 outl(command_que_value, command_que_addr);
520 printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Post failed, will retry.\n");
525 } /* End tw_aen_read_queue() */
527 /* This function will allocate memory and check if it is 16 d-word aligned */
528 int tw_allocate_memory(TW_Device_Extension *tw_dev, int size, int which)
531 dma_addr_t dma_handle;
532 unsigned long *cpu_addr = NULL;
534 dprintk(KERN_NOTICE "3w-xxxx: tw_allocate_memory()\n");
538 imax = TW_MAX_BOUNCEBUF;
542 for (i=0;i<imax;i++) {
543 cpu_addr = pci_alloc_consistent(tw_dev->tw_pci_dev, size, &dma_handle);
544 if (cpu_addr == NULL) {
545 printk(KERN_WARNING "3w-xxxx: pci_alloc_consistent() failed.\n");
549 if ((unsigned long)cpu_addr % (tw_dev->tw_pci_dev->device == TW_DEVICE_ID ? TW_ALIGNMENT_6000 : TW_ALIGNMENT_7000)) {
550 printk(KERN_WARNING "3w-xxxx: Couldn't allocate correctly aligned memory.\n");
551 pci_free_consistent(tw_dev->tw_pci_dev, size, cpu_addr, dma_handle);
557 tw_dev->command_packet_virtual_address[i] = cpu_addr;
558 tw_dev->command_packet_physical_address[i] = dma_handle;
559 memset(tw_dev->command_packet_virtual_address[i], 0, size);
562 tw_dev->alignment_virtual_address[i] = cpu_addr;
563 tw_dev->alignment_physical_address[i] = dma_handle;
564 memset(tw_dev->alignment_virtual_address[i], 0, size);
567 tw_dev->bounce_buffer[i] = cpu_addr;
568 tw_dev->bounce_buffer_phys[i] = dma_handle;
569 memset(tw_dev->bounce_buffer[i], 0, size);
572 printk(KERN_WARNING "3w-xxxx: tw_allocate_memory(): case slip in tw_allocate_memory()\n");
578 } /* End tw_allocate_memory() */
580 /* This function will check the status register for unexpected bits */
581 int tw_check_bits(u32 status_reg_value)
583 if ((status_reg_value & TW_STATUS_EXPECTED_BITS) != TW_STATUS_EXPECTED_BITS) {
584 dprintk(KERN_WARNING "3w-xxxx: tw_check_bits(): No expected bits (0x%x).\n", status_reg_value);
587 if ((status_reg_value & TW_STATUS_UNEXPECTED_BITS) != 0) {
588 dprintk(KERN_WARNING "3w-xxxx: tw_check_bits(): Found unexpected bits (0x%x).\n", status_reg_value);
593 } /* End tw_check_bits() */
595 /* This function will report controller error status */
596 int tw_check_errors(TW_Device_Extension *tw_dev)
598 u32 status_reg_addr, status_reg_value;
600 status_reg_addr = tw_dev->registers.status_reg_addr;
601 status_reg_value = inl(status_reg_addr);
603 if (TW_STATUS_ERRORS(status_reg_value) || tw_check_bits(status_reg_value)) {
604 tw_decode_bits(tw_dev, status_reg_value, 0);
609 } /* End tw_check_errors() */
611 /* This function will clear all interrupts on the controller */
612 void tw_clear_all_interrupts(TW_Device_Extension *tw_dev)
614 u32 control_reg_addr, control_reg_value;
616 control_reg_addr = tw_dev->registers.control_reg_addr;
617 control_reg_value = TW_STATUS_VALID_INTERRUPT;
618 outl(control_reg_value, control_reg_addr);
619 } /* End tw_clear_all_interrupts() */
621 /* This function will clear the attention interrupt */
622 void tw_clear_attention_interrupt(TW_Device_Extension *tw_dev)
624 u32 control_reg_addr, control_reg_value;
626 control_reg_addr = tw_dev->registers.control_reg_addr;
627 control_reg_value = TW_CONTROL_CLEAR_ATTENTION_INTERRUPT;
628 outl(control_reg_value, control_reg_addr);
629 } /* End tw_clear_attention_interrupt() */
631 /* This function will clear the host interrupt */
632 void tw_clear_host_interrupt(TW_Device_Extension *tw_dev)
634 u32 control_reg_addr, control_reg_value;
636 control_reg_addr = tw_dev->registers.control_reg_addr;
637 control_reg_value = TW_CONTROL_CLEAR_HOST_INTERRUPT;
638 outl(control_reg_value, control_reg_addr);
639 } /* End tw_clear_host_interrupt() */
641 /* This function is called by tw_scsi_proc_info */
642 static int tw_copy_info(TW_Info *info, char *fmt, ...)
649 len = vsprintf(buf, fmt, args);
651 tw_copy_mem_info(info, buf, len);
653 } /* End tw_copy_info() */
655 /* This function is called by tw_scsi_proc_info */
656 static void tw_copy_mem_info(TW_Info *info, char *data, int len)
658 if (info->position + len > info->length)
659 len = info->length - info->position;
661 if (info->position + len < info->offset) {
662 info->position += len;
665 if (info->position < info->offset) {
666 data += (info->offset - info->position);
667 len -= (info->offset - info->position);
670 memcpy(info->buffer + info->position, data, len);
671 info->position += len;
673 } /* End tw_copy_mem_info() */
675 /* This function will print readable messages from status register errors */
676 int tw_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value, int print_host)
680 dprintk(KERN_WARNING "3w-xxxx: tw_decode_bits()\n");
683 sprintf(host, " scsi%d:", tw_dev->host->host_no);
687 switch (status_reg_value & TW_STATUS_UNEXPECTED_BITS) {
688 case TW_STATUS_PCI_PARITY_ERROR:
689 printk(KERN_WARNING "3w-xxxx:%s PCI Parity Error: clearing.\n", host);
690 outl(TW_CONTROL_CLEAR_PARITY_ERROR, tw_dev->registers.control_reg_addr);
692 case TW_STATUS_MICROCONTROLLER_ERROR:
693 if (tw_dev->reset_print == 0) {
694 printk(KERN_WARNING "3w-xxxx:%s Microcontroller Error: clearing.\n", host);
695 tw_dev->reset_print = 1;
698 case TW_STATUS_PCI_ABORT:
699 printk(KERN_WARNING "3w-xxxx:%s PCI Abort: clearing.\n", host);
700 outl(TW_CONTROL_CLEAR_PCI_ABORT, tw_dev->registers.control_reg_addr);
701 pci_write_config_word(tw_dev->tw_pci_dev, PCI_STATUS, TW_PCI_CLEAR_PCI_ABORT);
703 case TW_STATUS_QUEUE_ERROR:
704 printk(KERN_WARNING "3w-xxxx:%s Controller Queue Error: clearing.\n", host);
705 outl(TW_CONTROL_CLEAR_QUEUE_ERROR, tw_dev->registers.control_reg_addr);
707 case TW_STATUS_SBUF_WRITE_ERROR:
708 printk(KERN_WARNING "3w-xxxx:%s SBUF Write Error: clearing.\n", host);
709 outl(TW_CONTROL_CLEAR_SBUF_WRITE_ERROR, tw_dev->registers.control_reg_addr);
714 } /* End tw_decode_bits() */
716 /* This function will return valid sense buffer information for failed cmds */
717 int tw_decode_sense(TW_Device_Extension *tw_dev, int request_id, int fill_sense)
722 dprintk(KERN_WARNING "3w-xxxx: tw_decode_sense()\n");
723 command = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
725 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, command->byte3.unit);
727 /* Attempt to return intelligent sense information */
729 if ((command->status == 0xc7) || (command->status == 0xcb)) {
730 for (i=0;i<(sizeof(tw_sense_table)/sizeof(tw_sense_table[0]));i++) {
731 if (command->flags == tw_sense_table[i][0]) {
733 /* Valid bit and 'current errors' */
734 tw_dev->srb[request_id]->sense_buffer[0] = (0x1 << 7 | 0x70);
737 tw_dev->srb[request_id]->sense_buffer[2] = tw_sense_table[i][1];
739 /* Additional sense length */
740 tw_dev->srb[request_id]->sense_buffer[7] = 0xa; /* 10 bytes */
742 /* Additional sense code */
743 tw_dev->srb[request_id]->sense_buffer[12] = tw_sense_table[i][2];
745 /* Additional sense code qualifier */
746 tw_dev->srb[request_id]->sense_buffer[13] = tw_sense_table[i][3];
748 tw_dev->srb[request_id]->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
749 return TW_ISR_DONT_RESULT; /* Special case for isr to not over-write result */
754 /* If no table match, error so we get a reset */
759 } /* End tw_decode_sense() */
761 /* This function will disable interrupts on the controller */
762 void tw_disable_interrupts(TW_Device_Extension *tw_dev)
764 u32 control_reg_value, control_reg_addr;
766 control_reg_addr = tw_dev->registers.control_reg_addr;
767 control_reg_value = TW_CONTROL_DISABLE_INTERRUPTS;
768 outl(control_reg_value, control_reg_addr);
769 } /* End tw_disable_interrupts() */
771 /* This function will empty the response que */
772 void tw_empty_response_que(TW_Device_Extension *tw_dev)
774 u32 status_reg_addr, status_reg_value;
775 u32 response_que_addr, response_que_value;
777 status_reg_addr = tw_dev->registers.status_reg_addr;
778 response_que_addr = tw_dev->registers.response_que_addr;
780 status_reg_value = inl(status_reg_addr);
782 while ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
783 response_que_value = inl(response_que_addr);
784 status_reg_value = inl(status_reg_addr);
786 } /* End tw_empty_response_que() */
788 /* This function will enable interrupts on the controller */
789 void tw_enable_interrupts(TW_Device_Extension *tw_dev)
791 u32 control_reg_value, control_reg_addr;
793 control_reg_addr = tw_dev->registers.control_reg_addr;
794 control_reg_value = (TW_CONTROL_ENABLE_INTERRUPTS |
795 TW_CONTROL_UNMASK_RESPONSE_INTERRUPT);
796 outl(control_reg_value, control_reg_addr);
797 } /* End tw_enable_interrupts() */
799 /* This function will enable interrupts on the controller */
800 void tw_enable_and_clear_interrupts(TW_Device_Extension *tw_dev)
802 u32 control_reg_value, control_reg_addr;
804 control_reg_addr = tw_dev->registers.control_reg_addr;
805 control_reg_value = (TW_CONTROL_CLEAR_ATTENTION_INTERRUPT |
806 TW_CONTROL_UNMASK_RESPONSE_INTERRUPT |
807 TW_CONTROL_ENABLE_INTERRUPTS);
808 outl(control_reg_value, control_reg_addr);
809 } /* End tw_enable_and_clear_interrupts() */
811 /* This function will find and initialize all cards */
812 int tw_findcards(Scsi_Host_Template *tw_host)
814 int numcards = 0, tries = 0, error = 0;
815 struct Scsi_Host *host;
816 TW_Device_Extension *tw_dev;
817 TW_Device_Extension *tw_dev2;
818 struct pci_dev *tw_pci_dev = NULL;
819 u32 status_reg_value;
822 u16 device[TW_NUMDEVICES] = { TW_DEVICE_ID, TW_DEVICE_ID2 };
824 dprintk(KERN_NOTICE "3w-xxxx: tw_findcards()\n");
826 for (i=0;i<TW_NUMDEVICES;i++) {
827 while ((tw_pci_dev = pci_find_device(TW_VENDOR_ID, device[i], tw_pci_dev))) {
829 if (pci_enable_device(tw_pci_dev))
832 /* We only need 32-bit addressing for 5,6,7xxx cards */
833 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4)
834 if (pci_set_dma_mask(tw_pci_dev, 0xffffffff)) {
835 printk(KERN_WARNING "3w-xxxx: No suitable DMA available.\n");
840 /* Prepare temporary device extension */
841 tw_dev=(TW_Device_Extension *)kmalloc(sizeof(TW_Device_Extension), GFP_ATOMIC);
842 if (tw_dev == NULL) {
843 printk(KERN_WARNING "3w-xxxx: tw_findcards(): kmalloc() failed for card %d.\n", j);
846 memset(tw_dev, 0, sizeof(TW_Device_Extension));
848 /* Save pci_dev struct to device extension */
849 tw_dev->tw_pci_dev = tw_pci_dev;
851 error = tw_initialize_device_extension(tw_dev);
853 printk(KERN_WARNING "3w-xxxx: tw_findcards(): Couldn't initialize device extension for card %d.\n", j);
854 tw_free_device_extension(tw_dev);
859 /* Calculate the cards register addresses */
860 tw_dev->registers.base_addr = pci_resource_start(tw_pci_dev, 0);
861 tw_dev->registers.control_reg_addr = pci_resource_start(tw_pci_dev, 0);
862 tw_dev->registers.status_reg_addr = pci_resource_start(tw_pci_dev, 0) + 0x4;
863 tw_dev->registers.command_que_addr = pci_resource_start(tw_pci_dev, 0) + 0x8;
864 tw_dev->registers.response_que_addr = pci_resource_start(tw_pci_dev, 0) + 0xC;
866 /* Check for errors and clear them */
867 status_reg_value = inl(tw_dev->registers.status_reg_addr);
868 if (TW_STATUS_ERRORS(status_reg_value))
869 tw_decode_bits(tw_dev, status_reg_value, 0);
871 /* Poll status register for 60 secs for 'Controller Ready' flag */
872 if (tw_poll_status(tw_dev, TW_STATUS_MICROCONTROLLER_READY, 60)) {
873 printk(KERN_WARNING "3w-xxxx: tw_findcards(): Microcontroller not ready for card %d.\n", j);
874 tw_free_device_extension(tw_dev);
879 /* Disable interrupts on the card */
880 tw_disable_interrupts(tw_dev);
882 while (tries < TW_MAX_RESET_TRIES) {
884 tw_soft_reset(tw_dev);
886 error = tw_aen_drain_queue(tw_dev);
888 printk(KERN_WARNING "3w-xxxx: AEN drain failed for card %d.\n", j);
893 /* Check for controller errors */
894 if (tw_check_errors(tw_dev)) {
895 printk(KERN_WARNING "3w-xxxx: Controller errors found, retrying for card %d.\n", j);
900 /* Now the controller is in a good state */
904 if (tries >= TW_MAX_RESET_TRIES) {
905 printk(KERN_WARNING "3w-xxxx: Controller errors, card not responding, check all cabling for card %d.\n", j);
906 tw_free_device_extension(tw_dev);
911 /* Make sure that io region isn't already taken */
912 if (check_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE)) {
913 printk(KERN_WARNING "3w-xxxx: tw_findcards(): Couldn't get io range 0x%lx-0x%lx for card %d.\n",
914 (tw_dev->tw_pci_dev->resource[0].start),
915 (tw_dev->tw_pci_dev->resource[0].start) +
916 TW_IO_ADDRESS_RANGE, j);
917 tw_free_device_extension(tw_dev);
922 /* Reserve the io address space */
923 request_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE, TW_DEVICE_NAME);
924 error = tw_initialize_units(tw_dev);
926 printk(KERN_WARNING "3w-xxxx: No valid units for card %d.\n", j);
927 release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
928 tw_free_device_extension(tw_dev);
933 error = tw_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS);
935 printk(KERN_WARNING "3w-xxxx: Connection initialization failed for card %d.\n", j);
936 release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
937 tw_free_device_extension(tw_dev);
942 /* Set card status as online */
945 /* Calculate max cmds per lun, and setup queues */
946 if (tw_dev->num_units > 0) {
947 if ((tw_dev->num_raid_five > 0) && (tw_dev->tw_pci_dev->device == TW_DEVICE_ID)) {
948 tw_host->cmd_per_lun = (TW_MAX_BOUNCEBUF-1)/tw_dev->num_units;
949 tw_dev->free_head = TW_Q_START;
950 tw_dev->free_tail = TW_MAX_BOUNCEBUF - 1;
951 tw_dev->free_wrap = TW_MAX_BOUNCEBUF - 1;
953 /* Use SHT cmd_per_lun here */
954 tw_dev->free_head = TW_Q_START;
955 tw_dev->free_tail = TW_Q_LENGTH - 1;
956 tw_dev->free_wrap = TW_Q_LENGTH - 1;
960 /* Register the card with the kernel SCSI layer */
961 host = scsi_register(tw_host, sizeof(TW_Device_Extension));
963 printk(KERN_WARNING "3w-xxxx: tw_findcards(): scsi_register() failed for card %d.\n", j);
964 release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
965 tw_free_device_extension(tw_dev);
970 /* Set max target id's */
971 host->max_id = TW_MAX_UNITS;
973 /* Set max cdb size in bytes */
974 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,15)
975 host->max_cmd_len = TW_MAX_CDB_LEN;
978 /* Set max sectors per io */
979 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7)
980 if ((tw_dev->num_raid_five > 0) && (tw_dev->tw_pci_dev->device == TW_DEVICE_ID))
981 host->max_sectors = TW_MAX_BOUNCE_SECTORS;
983 host->max_sectors = TW_MAX_SECTORS;
986 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4)
987 scsi_set_pci_device(host, tw_pci_dev);
990 status_reg_value = inl(tw_dev->registers.status_reg_addr);
992 printk(KERN_NOTICE "scsi%d : Found a 3ware Storage Controller at 0x%x, IRQ: %d, P-chip: %d.%d\n", host->host_no,
993 (u32)(tw_pci_dev->resource[0].start), tw_pci_dev->irq,
994 (status_reg_value & TW_STATUS_MAJOR_VERSION_MASK) >> 28,
995 (status_reg_value & TW_STATUS_MINOR_VERSION_MASK) >> 24);
997 if (host->hostdata) {
998 tw_dev2 = (TW_Device_Extension *)host->hostdata;
999 memcpy(tw_dev2, tw_dev, sizeof(TW_Device_Extension));
1000 tw_device_extension_list[tw_device_extension_count] = tw_dev2;
1002 tw_device_extension_count = numcards;
1003 tw_dev2->host = host;
1005 printk(KERN_WARNING "3w-xxxx: tw_findcards(): Bad scsi host data for card %d.\n", j);
1006 scsi_unregister(host);
1007 release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
1008 tw_free_device_extension(tw_dev);
1013 /* Tell the firmware we support shutdown notification*/
1014 error = tw_setfeature(tw_dev2, 2, 1, &c);
1016 printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Error setting features for card %d.\n", j);
1017 scsi_unregister(host);
1018 release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
1019 tw_free_device_extension(tw_dev);
1025 /* Now setup the interrupt handler */
1026 error = tw_setup_irq(tw_dev2);
1028 printk(KERN_WARNING "3w-xxxx: tw_findcards(): Error requesting irq for card %d.\n", j);
1029 scsi_unregister(host);
1030 release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
1032 tw_free_device_extension(tw_dev);
1038 /* Re-enable interrupts on the card */
1039 tw_enable_interrupts(tw_dev2);
1041 /* Free the temporary device extension */
1048 printk(KERN_WARNING "3w-xxxx: No cards with valid units found.\n");
1050 register_reboot_notifier(&tw_notifier);
1053 } /* End tw_findcards() */
1055 /* This function will free up device extension resources */
1056 void tw_free_device_extension(TW_Device_Extension *tw_dev)
1060 dprintk(KERN_NOTICE "3w-xxxx: tw_free_device_extension()\n");
1061 /* Free command packet and generic buffer memory */
1062 for (i=0;i<TW_Q_LENGTH;i++) {
1063 if (tw_dev->command_packet_virtual_address[i])
1064 pci_free_consistent(tw_dev->tw_pci_dev, sizeof(TW_Sector), tw_dev->command_packet_virtual_address[i], tw_dev->command_packet_physical_address[i]);
1066 if (tw_dev->alignment_virtual_address[i])
1067 pci_free_consistent(tw_dev->tw_pci_dev, sizeof(TW_Sector), tw_dev->alignment_virtual_address[i], tw_dev->alignment_physical_address[i]);
1070 for (i=0;i<TW_MAX_BOUNCEBUF;i++) {
1071 if (tw_dev->bounce_buffer[i])
1072 pci_free_consistent(tw_dev->tw_pci_dev, sizeof(TW_Sector)*TW_MAX_BOUNCE_SECTORS, tw_dev->bounce_buffer[i], tw_dev->bounce_buffer_phys[i]);
1074 } /* End tw_free_device_extension() */
1076 /* Clean shutdown routine */
1077 static int tw_halt(struct notifier_block *nb, ulong event, void *buf)
1081 for (i=0;i<tw_device_extension_count;i++) {
1082 if (tw_device_extension_list[i]->online == 1) {
1083 printk(KERN_NOTICE "3w-xxxx: Shutting down card %d.\n", i);
1084 tw_shutdown_device(tw_device_extension_list[i]);
1085 tw_device_extension_list[i]->online = 0;
1088 unregister_reboot_notifier(&tw_notifier);
1091 } /* End tw_halt() */
1093 /* This function will send an initconnection command to controller */
1094 int tw_initconnection(TW_Device_Extension *tw_dev, int message_credits)
1096 unsigned long command_que_value;
1097 u32 command_que_addr;
1098 u32 response_que_addr;
1099 TW_Command *command_packet;
1100 TW_Response_Queue response_queue;
1103 dprintk(KERN_NOTICE "3w-xxxx: tw_initconnection()\n");
1104 command_que_addr = tw_dev->registers.command_que_addr;
1105 response_que_addr = tw_dev->registers.response_que_addr;
1107 /* Initialize InitConnection command packet */
1108 if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
1109 printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad command packet virtual address.\n");
1113 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1114 memset(command_packet, 0, sizeof(TW_Sector));
1115 command_packet->byte0.opcode = TW_OP_INIT_CONNECTION;
1116 command_packet->byte0.sgl_offset = 0x0;
1117 command_packet->size = TW_INIT_COMMAND_PACKET_SIZE;
1118 command_packet->request_id = request_id;
1119 command_packet->byte3.unit = 0x0;
1120 command_packet->byte3.host_id = 0x0;
1121 command_packet->status = 0x0;
1122 command_packet->flags = 0x0;
1123 command_packet->byte6.message_credits = message_credits;
1124 command_packet->byte8.init_connection.response_queue_pointer = 0x0;
1125 command_que_value = tw_dev->command_packet_physical_address[request_id];
1127 if (command_que_value == 0) {
1128 printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad command packet physical address.\n");
1132 /* Send command packet to the board */
1133 outl(command_que_value, command_que_addr);
1135 /* Poll for completion */
1136 if (tw_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, 30) == 0) {
1137 response_queue.value = inl(response_que_addr);
1138 request_id = (unsigned char)response_queue.u.response_id;
1139 if (request_id != 0) {
1140 /* unexpected request id */
1141 printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Unexpected request id.\n");
1144 if (command_packet->status != 0) {
1146 tw_decode_sense(tw_dev, request_id, 0);
1151 } /* End tw_initconnection() */
1153 /* This function will initialize the fields of a device extension */
1154 int tw_initialize_device_extension(TW_Device_Extension *tw_dev)
1158 dprintk(KERN_NOTICE "3w-xxxx: tw_initialize_device_extension()\n");
1160 /* Initialize command packet buffers */
1161 error = tw_allocate_memory(tw_dev, sizeof(TW_Command), 0);
1163 printk(KERN_WARNING "3w-xxxx: Command packet memory allocation failed.\n");
1167 /* Initialize generic buffer */
1168 error = tw_allocate_memory(tw_dev, sizeof(TW_Sector), 1);
1170 printk(KERN_WARNING "3w-xxxx: Generic memory allocation failed.\n");
1174 for (i=0;i<TW_Q_LENGTH;i++) {
1175 tw_dev->free_queue[i] = i;
1176 tw_dev->state[i] = TW_S_INITIAL;
1179 tw_dev->pending_head = TW_Q_START;
1180 tw_dev->pending_tail = TW_Q_START;
1181 spin_lock_init(&tw_dev->tw_lock);
1184 } /* End tw_initialize_device_extension() */
1186 /* This function will get unit info from the controller */
1187 int tw_initialize_units(TW_Device_Extension *tw_dev)
1189 int found = 0, error = 0;
1190 unsigned char request_id = 0;
1191 TW_Command *command_packet;
1193 int i, j, imax, num_units = 0, num_raid_five = 0;
1194 unsigned long command_que_value;
1195 u32 command_que_addr;
1196 u32 response_que_addr;
1197 TW_Response_Queue response_queue;
1198 unsigned long param_value;
1199 unsigned char *is_unit_present;
1200 unsigned char *raid_level;
1202 dprintk(KERN_NOTICE "3w-xxxx: tw_initialize_units()\n");
1204 command_que_addr = tw_dev->registers.command_que_addr;
1205 response_que_addr = tw_dev->registers.response_que_addr;
1207 /* Setup the command packet */
1208 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1209 if (command_packet == NULL) {
1210 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad command packet virtual address.\n");
1213 memset(command_packet, 0, sizeof(TW_Sector));
1214 command_packet->byte0.opcode = TW_OP_GET_PARAM;
1215 command_packet->byte0.sgl_offset = 2;
1216 command_packet->size = 4;
1217 command_packet->request_id = request_id;
1218 command_packet->byte3.unit = 0;
1219 command_packet->byte3.host_id = 0;
1220 command_packet->status = 0;
1221 command_packet->flags = 0;
1222 command_packet->byte6.block_count = 1;
1224 /* Now setup the param */
1225 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
1226 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad alignment virtual address.\n");
1229 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1230 memset(param, 0, sizeof(TW_Sector));
1231 param->table_id = 3; /* unit summary table */
1232 param->parameter_id = 3; /* unitstatus parameter */
1233 param->parameter_size_bytes = TW_MAX_UNITS;
1234 param_value = tw_dev->alignment_physical_address[request_id];
1235 if (param_value == 0) {
1236 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad alignment physical address.\n");
1240 command_packet->byte8.param.sgl[0].address = param_value;
1241 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
1243 /* Post the command packet to the board */
1244 command_que_value = tw_dev->command_packet_physical_address[request_id];
1245 if (command_que_value == 0) {
1246 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad command packet physical address.\n");
1249 outl(command_que_value, command_que_addr);
1251 /* Poll for completion */
1252 if (tw_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, 30) == 0) {
1253 response_queue.value = inl(response_que_addr);
1254 request_id = (unsigned char)response_queue.u.response_id;
1255 if (request_id != 0) {
1256 /* unexpected request id */
1257 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Unexpected request id.\n");
1260 if (command_packet->status != 0) {
1262 tw_decode_sense(tw_dev, request_id, 0);
1268 /* response never received */
1269 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): No response.\n");
1273 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1274 is_unit_present = (unsigned char *)&(param->data[0]);
1276 /* Show all units present */
1277 imax = TW_MAX_UNITS;
1278 for(i=0; i<imax; i++) {
1279 if (is_unit_present[i] == 0) {
1280 tw_dev->is_unit_present[i] = FALSE;
1282 if (is_unit_present[i] & TW_UNIT_ONLINE) {
1283 dprintk(KERN_NOTICE "3w-xxxx: tw_initialize_units(): Unit %d found.\n", i);
1284 tw_dev->is_unit_present[i] = TRUE;
1289 tw_dev->num_units = num_units;
1291 if (num_units == 0) {
1292 dprintk(KERN_NOTICE "3w-xxxx: tw_initialize_units(): No units found.\n");
1296 /* Find raid 5 arrays */
1297 for (j=0;j<TW_MAX_UNITS;j++) {
1298 if (tw_dev->is_unit_present[j] == 0)
1300 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1301 if (command_packet == NULL) {
1302 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad command packet virtual address.\n");
1305 memset(command_packet, 0, sizeof(TW_Sector));
1306 command_packet->byte0.opcode = TW_OP_GET_PARAM;
1307 command_packet->byte0.sgl_offset = 2;
1308 command_packet->size = 4;
1309 command_packet->request_id = request_id;
1310 command_packet->byte3.unit = 0;
1311 command_packet->byte3.host_id = 0;
1312 command_packet->status = 0;
1313 command_packet->flags = 0;
1314 command_packet->byte6.block_count = 1;
1316 /* Now setup the param */
1317 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
1318 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad alignment virtual address.\n");
1321 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1322 memset(param, 0, sizeof(TW_Sector));
1323 param->table_id = 0x300+j; /* unit summary table */
1324 param->parameter_id = 0x6; /* unit descriptor */
1325 param->parameter_size_bytes = 0xc;
1326 param_value = tw_dev->alignment_physical_address[request_id];
1327 if (param_value == 0) {
1328 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad alignment physical address.\n");
1332 command_packet->byte8.param.sgl[0].address = param_value;
1333 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
1335 /* Post the command packet to the board */
1336 command_que_value = tw_dev->command_packet_physical_address[request_id];
1337 if (command_que_value == 0) {
1338 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad command packet physical address.\n");
1341 outl(command_que_value, command_que_addr);
1343 /* Poll for completion */
1344 if (tw_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, 30) == 0) {
1345 response_queue.value = inl(response_que_addr);
1346 request_id = (unsigned char)response_queue.u.response_id;
1347 if (request_id != 0) {
1348 /* unexpected request id */
1349 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Unexpected request id.\n");
1352 if (command_packet->status != 0) {
1354 tw_decode_sense(tw_dev, request_id, 0);
1360 /* response never received */
1361 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): No response.\n");
1365 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1366 raid_level = (unsigned char *)&(param->data[1]);
1367 if (*raid_level == 5) {
1368 dprintk(KERN_WARNING "3w-xxxx: Found unit %d to be a raid5 unit.\n", j);
1369 tw_dev->is_raid_five[j] = 1;
1373 tw_dev->num_raid_five = num_raid_five;
1375 /* Now allocate raid5 bounce buffers */
1376 if ((num_raid_five != 0) && (tw_dev->tw_pci_dev->device == TW_DEVICE_ID)) {
1377 error = tw_allocate_memory(tw_dev, sizeof(TW_Sector)*TW_MAX_BOUNCE_SECTORS, 2);
1379 printk(KERN_WARNING "3w-xxxx: Bounce buffer allocation failed.\n");
1385 } /* End tw_initialize_units() */
1387 /* This function is the interrupt service routine */
1388 static void tw_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
1391 u32 status_reg_addr, status_reg_value;
1392 u32 response_que_addr;
1393 TW_Device_Extension *tw_dev = (TW_Device_Extension *)dev_instance;
1394 TW_Response_Queue response_que;
1395 int error = 0, retval = 0;
1396 unsigned long flags = 0;
1397 TW_Command *command_packet;
1399 dprintk(KERN_WARNING "3w-xxxx: tw_interrupt()\n");
1401 /* See if we are already running on another processor */
1402 if (test_and_set_bit(TW_IN_INTR, &tw_dev->flags))
1405 /* Get the block layer lock for io completions */
1406 spin_lock_irqsave(&io_request_lock, flags);
1408 /* See if the interrupt matches this instance */
1409 if (tw_dev->tw_pci_dev->irq == irq) {
1411 /* Make sure io isn't queueing */
1412 spin_lock(&tw_dev->tw_lock);
1414 /* Read the registers */
1415 status_reg_addr = tw_dev->registers.status_reg_addr;
1416 response_que_addr = tw_dev->registers.response_que_addr;
1417 status_reg_value = inl(status_reg_addr);
1419 /* Check if this is our interrupt, otherwise bail */
1420 if (!(status_reg_value & TW_STATUS_VALID_INTERRUPT))
1421 goto tw_interrupt_bail;
1423 /* Check controller for errors */
1424 if (tw_check_bits(status_reg_value)) {
1425 dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n");
1426 if (tw_decode_bits(tw_dev, status_reg_value, 1)) {
1427 tw_clear_all_interrupts(tw_dev);
1428 goto tw_interrupt_bail;
1432 /* Handle host interrupt */
1433 if (status_reg_value & TW_STATUS_HOST_INTERRUPT) {
1434 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Received host interrupt.\n");
1435 tw_clear_host_interrupt(tw_dev);
1438 /* Handle attention interrupt */
1439 if (status_reg_value & TW_STATUS_ATTENTION_INTERRUPT) {
1440 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Received attention interrupt.\n");
1441 tw_clear_attention_interrupt(tw_dev);
1442 tw_state_request_start(tw_dev, &request_id);
1443 error = tw_aen_read_queue(tw_dev, request_id);
1445 printk(KERN_WARNING "3w-xxxx: scsi%d: Error reading aen queue.\n", tw_dev->host->host_no);
1446 tw_dev->state[request_id] = TW_S_COMPLETED;
1447 tw_state_request_finish(tw_dev, request_id);
1451 /* Handle command interrupt */
1452 if (status_reg_value & TW_STATUS_COMMAND_INTERRUPT) {
1453 /* Drain as many pending commands as we can */
1454 while (tw_dev->pending_request_count > 0) {
1455 request_id = tw_dev->pending_queue[tw_dev->pending_head];
1456 if (tw_dev->state[request_id] != TW_S_PENDING) {
1457 printk(KERN_WARNING "3w-xxxx: scsi%d: Found request id that wasn't pending.\n", tw_dev->host->host_no);
1460 if (tw_post_command_packet(tw_dev, request_id)==0) {
1461 if (tw_dev->pending_head == TW_Q_LENGTH-1) {
1462 tw_dev->pending_head = TW_Q_START;
1464 tw_dev->pending_head = tw_dev->pending_head + 1;
1466 tw_dev->pending_request_count--;
1468 /* If we get here, we will continue re-posting on the next command interrupt */
1472 /* If there are no more pending requests, we mask command interrupt */
1473 if (tw_dev->pending_request_count == 0)
1474 tw_mask_command_interrupt(tw_dev);
1477 /* Handle response interrupt */
1478 if (status_reg_value & TW_STATUS_RESPONSE_INTERRUPT) {
1479 /* Drain the response queue from the board */
1480 while ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
1481 /* Read response queue register */
1482 response_que.value = inl(response_que_addr);
1483 request_id = response_que.u.response_id;
1484 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1487 /* Check for bad response */
1488 if (command_packet->status != 0) {
1489 /* If internal command, don't error, don't fill sense */
1490 if (tw_dev->srb[request_id] == 0) {
1491 tw_decode_sense(tw_dev, request_id, 0);
1493 error = tw_decode_sense(tw_dev, request_id, 1);
1497 /* Check for correct state */
1498 if (tw_dev->state[request_id] != TW_S_POSTED) {
1499 /* Handle timed out ioctl's */
1500 if (tw_dev->srb[request_id] != 0) {
1501 if (tw_dev->srb[request_id]->cmnd[0] != TW_IOCTL) {
1502 printk(KERN_WARNING "3w-xxxx: scsi%d: Received a request id (%d) (opcode = 0x%x) that wasn't posted.\n", tw_dev->host->host_no, request_id, command_packet->byte0.opcode);
1508 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Response queue request id: %d.\n", request_id);
1510 /* Check for internal command completion */
1511 if (tw_dev->srb[request_id] == 0) {
1512 dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Found internally posted command.\n");
1513 retval = tw_aen_complete(tw_dev, request_id);
1515 printk(KERN_WARNING "3w-xxxx: scsi%d: Error completing aen.\n", tw_dev->host->host_no);
1518 switch (tw_dev->srb[request_id]->cmnd[0]) {
1521 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught READ_10/READ_6\n");
1525 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught WRITE_10/WRITE_6\n");
1528 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught INQUIRY\n");
1529 error = tw_scsiop_inquiry_complete(tw_dev, request_id);
1532 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught READ_CAPACITY\n");
1533 error = tw_scsiop_read_capacity_complete(tw_dev, request_id);
1536 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught MODE_SENSE\n");
1537 error = tw_scsiop_mode_sense_complete(tw_dev, request_id);
1539 case SYNCHRONIZE_CACHE:
1540 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught SYNCHRONIZE_CACHE\n");
1543 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught TW_IOCTL\n");
1544 error = tw_ioctl_complete(tw_dev, request_id);
1547 printk(KERN_WARNING "3w-xxxx: case slip in tw_interrupt()\n");
1551 /* If no error command was a success */
1553 tw_dev->srb[request_id]->result = (DID_OK << 16);
1556 /* If error, command failed */
1558 /* Ask for a host reset */
1559 tw_dev->srb[request_id]->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
1562 /* Now complete the io */
1563 if ((error != TW_ISR_DONT_COMPLETE)) {
1564 tw_dev->state[request_id] = TW_S_COMPLETED;
1565 tw_state_request_finish(tw_dev, request_id);
1566 tw_dev->posted_request_count--;
1567 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1568 tw_unmap_scsi_data(tw_dev->tw_pci_dev, tw_dev->srb[request_id]);
1572 /* Check for valid status after each drain */
1573 status_reg_value = inl(status_reg_addr);
1574 if (tw_check_bits(status_reg_value)) {
1575 dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n");
1576 if (tw_decode_bits(tw_dev, status_reg_value, 1)) {
1577 tw_clear_all_interrupts(tw_dev);
1578 goto tw_interrupt_bail;
1584 spin_unlock(&tw_dev->tw_lock);
1586 dprintk(KERN_WARNING "3w-xxxx: tw_interrupt() called for wrong instance.\n");
1588 spin_unlock_irqrestore(&io_request_lock, flags);
1589 clear_bit(TW_IN_INTR, &tw_dev->flags);
1590 } /* End tw_interrupt() */
1592 /* This function handles ioctls from userspace to the driver */
1593 int tw_ioctl(TW_Device_Extension *tw_dev, int request_id)
1595 unsigned char opcode;
1596 int bufflen, error = 0;
1598 TW_Command *command_packet, *command_save;
1599 unsigned long param_value;
1600 TW_Ioctl *ioctl = NULL;
1601 TW_Passthru *passthru = NULL;
1602 int tw_aen_code, i, use_sg;
1603 unsigned long *data_ptr;
1604 int total_bytes = 0, posted = 0;
1605 dma_addr_t dma_handle;
1606 struct timeval before, timeout;
1608 ioctl = (TW_Ioctl *)tw_dev->srb[request_id]->request_buffer;
1609 if (ioctl == NULL) {
1610 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Request buffer NULL.\n");
1611 tw_dev->state[request_id] = TW_S_COMPLETED;
1612 tw_state_request_finish(tw_dev, request_id);
1613 tw_dev->srb[request_id]->result = (DID_OK << 16);
1614 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1617 bufflen = tw_dev->srb[request_id]->request_bufflen;
1619 /* Initialize command packet */
1620 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1621 if (command_packet == NULL) {
1622 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Bad command packet virtual address.\n");
1623 tw_dev->state[request_id] = TW_S_COMPLETED;
1624 tw_state_request_finish(tw_dev, request_id);
1625 tw_dev->srb[request_id]->result = (DID_OK << 16);
1626 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1629 memset(command_packet, 0, sizeof(TW_Sector));
1631 /* Initialize param */
1632 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
1633 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Bad alignment virtual address.\n");
1634 tw_dev->state[request_id] = TW_S_COMPLETED;
1635 tw_state_request_finish(tw_dev, request_id);
1636 tw_dev->srb[request_id]->result = (DID_OK << 16);
1637 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1640 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1641 memset(param, 0, sizeof(TW_Sector));
1643 dprintk(KERN_NOTICE "opcode = %d table_id = %d parameter_id = %d parameter_size_bytes = %d\n", ioctl->opcode, ioctl->table_id, ioctl->parameter_id, ioctl->parameter_size_bytes);
1644 opcode = ioctl->opcode;
1648 dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): caught TW_OP_NOP.\n");
1649 command_packet->byte0.opcode = TW_OP_NOP;
1651 case TW_OP_GET_PARAM:
1652 dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): caught TW_OP_GET_PARAM.\n");
1653 command_packet->byte0.opcode = TW_OP_GET_PARAM;
1654 command_packet->byte3.unit = ioctl->unit_index;
1655 param->table_id = ioctl->table_id;
1656 param->parameter_id = ioctl->parameter_id;
1657 param->parameter_size_bytes = ioctl->parameter_size_bytes;
1658 tw_dev->ioctl_size[request_id] = ioctl->parameter_size_bytes;
1659 dprintk(KERN_NOTICE "table_id = %d parameter_id = %d parameter_size_bytes %d\n", param->table_id, param->parameter_id, param->parameter_size_bytes);
1661 case TW_OP_SET_PARAM:
1662 dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): caught TW_OP_SET_PARAM: table_id = %d, parameter_id = %d, parameter_size_bytes = %d.\n",
1663 ioctl->table_id, ioctl->parameter_id, ioctl->parameter_size_bytes);
1664 if (ioctl->data != NULL) {
1665 command_packet->byte0.opcode = TW_OP_SET_PARAM;
1666 param->table_id = ioctl->table_id;
1667 param->parameter_id = ioctl->parameter_id;
1668 param->parameter_size_bytes = ioctl->parameter_size_bytes;
1669 memcpy(param->data, ioctl->data, ioctl->parameter_size_bytes);
1672 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): ioctl->data NULL.\n");
1675 case TW_OP_AEN_LISTEN:
1676 dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): caught TW_OP_AEN_LISTEN.\n");
1677 if (tw_dev->aen_head == tw_dev->aen_tail) {
1678 /* aen queue empty */
1679 dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): Aen queue empty.\n");
1680 tw_aen_code = TW_AEN_QUEUE_EMPTY;
1681 memcpy(tw_dev->srb[request_id]->request_buffer, &tw_aen_code, ioctl->parameter_size_bytes);
1683 /* Copy aen queue entry to request buffer */
1684 dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): Returning aen 0x%x\n", tw_dev->aen_queue[tw_dev->aen_head]);
1685 tw_aen_code = tw_dev->aen_queue[tw_dev->aen_head];
1686 memcpy(tw_dev->srb[request_id]->request_buffer, &tw_aen_code, ioctl->parameter_size_bytes);
1687 if (tw_dev->aen_head == TW_Q_LENGTH - 1) {
1688 tw_dev->aen_head = TW_Q_START;
1690 tw_dev->aen_head = tw_dev->aen_head + 1;
1693 tw_dev->state[request_id] = TW_S_COMPLETED;
1694 tw_state_request_finish(tw_dev, request_id);
1695 tw_dev->srb[request_id]->result = (DID_OK << 16);
1696 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1698 case TW_ATA_PASSTHRU:
1699 if (ioctl->data != NULL) {
1700 memcpy(command_packet, ioctl->data, sizeof(TW_Command));
1701 command_packet->request_id = request_id;
1703 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): ioctl->data NULL.\n");
1707 passthru = (TW_Passthru *)tw_dev->command_packet_virtual_address[request_id];
1708 passthru->sg_list[0].length = passthru->sector_count*512;
1709 if (passthru->sg_list[0].length > TW_MAX_PASSTHRU_BYTES) {
1710 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Passthru size (%d) too big.\n", passthru->sg_list[0].length);
1713 passthru->sg_list[0].address = tw_dev->alignment_physical_address[request_id];
1714 tw_post_command_packet(tw_dev, request_id);
1717 dprintk(KERN_WARNING "3w-xxxx: tw_ioctl(): caught TW_CMD_PACKET.\n");
1718 if (ioctl->data != NULL) {
1719 memcpy(command_packet, ioctl->data, sizeof(TW_Command));
1720 command_packet->request_id = request_id;
1721 tw_post_command_packet(tw_dev, request_id);
1724 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): ioctl->data NULL.\n");
1727 case TW_CMD_PACKET_WITH_DATA:
1728 dprintk(KERN_WARNING "3w-xxxx: tw_ioctl(): caught TW_CMD_PACKET_WITH_DATA.\n");
1729 command_save = (TW_Command *)tw_dev->alignment_virtual_address[request_id];
1730 if (command_save == NULL) {
1731 printk(KERN_WARNING "3w-xxxx: scsi%d: tw_ioctl(): Bad alignment virtual address.\n", tw_dev->host->host_no);
1734 if (ioctl->data != NULL) {
1735 /* Copy down the command packet */
1736 memcpy(command_packet, ioctl->data, sizeof(TW_Command));
1737 memcpy(command_save, ioctl->data, sizeof(TW_Command));
1738 command_packet->request_id = request_id;
1740 /* Now deal with the two possible sglists */
1741 if (command_packet->byte0.sgl_offset == 2) {
1742 use_sg = command_packet->size - 3;
1743 for (i=0;i<use_sg;i++)
1744 total_bytes+=command_packet->byte8.param.sgl[i].length;
1745 tw_dev->ioctl_data[request_id] = pci_alloc_consistent(tw_dev->tw_pci_dev, total_bytes, &dma_handle);
1747 if (!tw_dev->ioctl_data[request_id]) {
1748 printk(KERN_WARNING "3w-xxxx: scsi%d: tw_ioctl(): pci_alloc_consistent() failed for request_id %d.\n", tw_dev->host->host_no, request_id);
1752 /* Copy param sglist into the kernel */
1753 data_ptr = tw_dev->ioctl_data[request_id];
1754 for (i=0;i<use_sg;i++) {
1755 if (command_packet->byte8.param.sgl[i].address != 0) {
1756 error = copy_from_user(data_ptr, (void *)(unsigned long)command_packet->byte8.param.sgl[i].address, command_packet->byte8.param.sgl[i].length);
1758 dprintk(KERN_WARNING "3w-xxxx: scsi%d: Error copying param sglist from userspace.\n", tw_dev->host->host_no);
1762 printk(KERN_WARNING "3w-xxxx: scsi%d: tw_ioctl(): Bad param sgl address.\n", tw_dev->host->host_no);
1763 tw_dev->srb[request_id]->result = (DID_RESET << 16);
1766 data_ptr+=command_packet->byte8.param.sgl[i].length;
1768 command_packet->size = 4;
1769 command_packet->byte8.param.sgl[0].address = dma_handle;
1770 command_packet->byte8.param.sgl[0].length = total_bytes;
1772 if (command_packet->byte0.sgl_offset == 3) {
1773 use_sg = command_packet->size - 4;
1774 for (i=0;i<use_sg;i++)
1775 total_bytes+=command_packet->byte8.io.sgl[i].length;
1776 tw_dev->ioctl_data[request_id] = pci_alloc_consistent(tw_dev->tw_pci_dev, total_bytes, &dma_handle);
1778 if (!tw_dev->ioctl_data[request_id]) {
1779 printk(KERN_WARNING "3w-xxxx: scsi%d: tw_ioctl(): pci_alloc_consistent() failed for request_id %d.\n", tw_dev->host->host_no, request_id);
1782 if (command_packet->byte0.opcode == TW_OP_WRITE) {
1783 /* Copy io sglist into the kernel */
1784 data_ptr = tw_dev->ioctl_data[request_id];
1785 for (i=0;i<use_sg;i++) {
1786 if (command_packet->byte8.io.sgl[i].address != 0) {
1787 error = copy_from_user(data_ptr, (void *)(unsigned long)command_packet->byte8.io.sgl[i].address, command_packet->byte8.io.sgl[i].length);
1789 dprintk(KERN_WARNING "3w-xxxx: scsi%d: Error copying io sglist from userspace.\n", tw_dev->host->host_no);
1793 printk(KERN_WARNING "3w-xxxx: scsi%d: tw_ioctl(): Bad io sgl address.\n", tw_dev->host->host_no);
1794 tw_dev->srb[request_id]->result = (DID_RESET << 16);
1797 data_ptr+=command_packet->byte8.io.sgl[i].length;
1800 command_packet->size = 5;
1801 command_packet->byte8.io.sgl[0].address = dma_handle;
1802 command_packet->byte8.io.sgl[0].length = total_bytes;
1805 spin_unlock(&tw_dev->tw_lock);
1806 spin_unlock_irq(&io_request_lock);
1808 set_bit(TW_IN_IOCTL, &tw_dev->flags);
1810 /* Finally post the command packet */
1811 tw_post_command_packet(tw_dev, request_id);
1813 do_gettimeofday(&before);
1816 mdelay(TW_IOCTL_WAIT_TIME);
1817 if (test_bit(TW_IN_IOCTL, &tw_dev->flags)) {
1818 do_gettimeofday(&timeout);
1819 if (before.tv_sec + TW_IOCTL_TIMEOUT < timeout.tv_sec) {
1820 spin_lock_irq(&io_request_lock);
1821 spin_lock(&tw_dev->tw_lock);
1824 goto tw_ioctl_retry;
1828 spin_lock_irq(&io_request_lock);
1829 spin_lock(&tw_dev->tw_lock);
1831 if (signal_pending(current)) {
1832 dprintk(KERN_WARNING "3w-xxxx: scsi%d: tw_ioctl(): Signal pending, aborting ioctl().\n", tw_dev->host->host_no);
1833 tw_dev->srb[request_id]->result = (DID_OK << 16);
1837 tw_dev->srb[request_id]->result = (DID_OK << 16);
1838 /* Now copy up the param or io sglist to userspace */
1839 if (command_packet->byte0.sgl_offset == 2) {
1840 use_sg = command_save->size - 3;
1841 data_ptr = tw_dev->ioctl_data[request_id];
1842 for (i=0;i<use_sg;i++) {
1843 if (command_save->byte8.param.sgl[i].address != 0) {
1844 error = copy_to_user((void *)(unsigned long)command_save->byte8.param.sgl[i].address, data_ptr, command_save->byte8.param.sgl[i].length);
1846 dprintk(KERN_WARNING "3w-xxxx: scsi%d: Error copying param sglist to userspace.\n", tw_dev->host->host_no);
1849 dprintk(KERN_WARNING "3w-xxxx: scsi%d: Copied %ld bytes to pid %d.\n", tw_dev->host->host_no, command_save->byte8.param.sgl[i].length, current->pid);
1850 data_ptr+=command_save->byte8.param.sgl[i].length;
1852 printk(KERN_WARNING "3w-xxxx: scsi%d: tw_ioctl(): Bad param sgl address.\n", tw_dev->host->host_no);
1853 tw_dev->srb[request_id]->result = (DID_RESET << 16);
1858 if (command_packet->byte0.sgl_offset == 3) {
1859 use_sg = command_save->size - 4;
1860 if (command_packet->byte0.opcode == TW_OP_READ) {
1861 data_ptr = tw_dev->ioctl_data[request_id];
1862 for(i=0;i<use_sg;i++) {
1863 if (command_save->byte8.io.sgl[i].address != 0) {
1864 error = copy_to_user((void *)(unsigned long)command_save->byte8.io.sgl[i].address, data_ptr, command_save->byte8.io.sgl[i].length);
1866 dprintk(KERN_WARNING "3w-xxxx: scsi%d: Error copying io sglist to userspace.\n", tw_dev->host->host_no);
1869 dprintk(KERN_WARNING "3w-xxxx: scsi%d: Copied %ld bytes to pid %d.\n", tw_dev->host->host_no, command_save->byte8.io.sgl[i].length, current->pid);
1870 data_ptr+=command_save->byte8.io.sgl[i].length;
1872 printk(KERN_WARNING "3w-xxxx: scsi%d: tw_ioctl(): Bad io sgl address.\n", tw_dev->host->host_no);
1873 tw_dev->srb[request_id]->result = (DID_RESET << 16);
1882 /* Free up sglist memory */
1883 if (tw_dev->ioctl_data[request_id])
1884 pci_free_consistent(tw_dev->tw_pci_dev, total_bytes, tw_dev->ioctl_data[request_id], dma_handle);
1886 printk(KERN_WARNING "3w-xxxx: scsi%d: tw_ioctl(): Error freeing ioctl data.\n", tw_dev->host->host_no);
1888 /* Now complete the io */
1889 tw_dev->state[request_id] = TW_S_COMPLETED;
1890 tw_state_request_finish(tw_dev, request_id);
1892 tw_dev->posted_request_count--;
1893 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1896 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): ioctl->data NULL.\n");
1900 dprintk(KERN_WARNING "3w-xxxx: Unknown ioctl 0x%x.\n", opcode);
1901 tw_dev->state[request_id] = TW_S_COMPLETED;
1902 tw_state_request_finish(tw_dev, request_id);
1903 tw_dev->srb[request_id]->result = (DID_OK << 16);
1904 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1908 param_value = tw_dev->alignment_physical_address[request_id];
1909 if (param_value == 0) {
1910 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Bad alignment physical address.\n");
1911 tw_dev->state[request_id] = TW_S_COMPLETED;
1912 tw_state_request_finish(tw_dev, request_id);
1913 tw_dev->srb[request_id]->result = (DID_OK << 16);
1914 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1917 command_packet->byte8.param.sgl[0].address = param_value;
1918 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
1920 command_packet->byte0.sgl_offset = 2;
1921 command_packet->size = 4;
1922 command_packet->request_id = request_id;
1923 command_packet->byte3.host_id = 0;
1924 command_packet->status = 0;
1925 command_packet->flags = 0;
1926 command_packet->byte6.parameter_count = 1;
1928 /* Now try to post the command to the board */
1929 tw_post_command_packet(tw_dev, request_id);
1932 } /* End tw_ioctl() */
1934 /* This function is called by the isr to complete ioctl requests */
1935 int tw_ioctl_complete(TW_Device_Extension *tw_dev, int request_id)
1937 unsigned char *param_data;
1938 unsigned char *buff;
1940 TW_Ioctl *ioctl = NULL;
1941 TW_Passthru *passthru = NULL;
1942 TW_Command *command_packet;
1944 ioctl = (TW_Ioctl *)tw_dev->srb[request_id]->request_buffer;
1945 dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl_complete()\n");
1946 buff = tw_dev->srb[request_id]->request_buffer;
1948 printk(KERN_WARNING "3w-xxxx: tw_ioctl_complete(): Request buffer NULL.\n");
1952 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1953 if (command_packet == NULL) {
1954 printk(KERN_WARNING "3w-xxxx: scsi%d: tw_ioctl_complete(): Bad command packet virtual address.\n", tw_dev->host->host_no);
1958 dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl_complete(): Request_bufflen = %d\n", tw_dev->srb[request_id]->request_bufflen);
1960 ioctl = (TW_Ioctl *)buff;
1961 switch (ioctl->opcode) {
1962 case TW_ATA_PASSTHRU:
1963 passthru = (TW_Passthru *)ioctl->data;
1964 memcpy(buff, tw_dev->alignment_virtual_address[request_id], passthru->sector_count * 512);
1966 case TW_CMD_PACKET_WITH_DATA:
1967 dprintk(KERN_WARNING "3w-xxxx: tw_ioctl_complete(): caught TW_CMD_PACKET_WITH_DATA.\n");
1968 clear_bit(TW_IN_IOCTL, &tw_dev->flags);
1969 return TW_ISR_DONT_COMPLETE; /* Special case for isr to not complete io */
1971 memset(buff, 0, tw_dev->srb[request_id]->request_bufflen);
1972 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1973 if (param == NULL) {
1974 printk(KERN_WARNING "3w-xxxx: tw_ioctl_complete(): Bad alignment virtual address.\n");
1977 param_data = &(param->data[0]);
1978 memcpy(buff, param_data, tw_dev->ioctl_size[request_id]);
1981 } /* End tw_ioctl_complete() */
1983 static int tw_map_scsi_sg_data(struct pci_dev *pdev, Scsi_Cmnd *cmd)
1986 int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
1988 dprintk(KERN_WARNING "3w-xxxx: tw_map_scsi_sg_data()\n");
1990 if (cmd->use_sg == 0)
1993 use_sg = pci_map_sg(pdev, cmd->buffer, cmd->use_sg, dma_dir);
1996 printk(KERN_WARNING "3w-xxxx: tw_map_scsi_sg_data(): pci_map_sg() failed.\n");
2001 cmd->SCp.have_data_in = use_sg;
2004 } /* End tw_map_scsi_sg_data() */
2006 static u32 tw_map_scsi_single_data(struct pci_dev *pdev, Scsi_Cmnd *cmd)
2009 int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
2011 dprintk(KERN_WARNING "3w-xxxx: tw_map_scsi_single_data()\n");
2013 if (cmd->request_bufflen == 0)
2015 #ifdef BLK_BOUNCE_HIGH
2016 mapping = pci_map_page(pdev, virt_to_page(cmd->request_buffer), ((unsigned long)cmd->request_buffer & ~PAGE_MASK), cmd->request_bufflen, dma_dir);
2018 mapping = pci_map_single(pdev, cmd->request_buffer, cmd->request_bufflen, dma_dir);
2022 printk(KERN_WARNING "3w-xxxx: tw_map_scsi_single_data(): pci_map_page() failed.\n");
2027 cmd->SCp.have_data_in = mapping;
2030 } /* End tw_map_scsi_single_data() */
2032 /* This function will mask the command interrupt */
2033 void tw_mask_command_interrupt(TW_Device_Extension *tw_dev)
2035 u32 control_reg_addr, control_reg_value;
2037 control_reg_addr = tw_dev->registers.control_reg_addr;
2038 control_reg_value = TW_CONTROL_MASK_COMMAND_INTERRUPT;
2039 outl(control_reg_value, control_reg_addr);
2040 } /* End tw_mask_command_interrupt() */
2042 /* This function will poll the status register for a flag */
2043 int tw_poll_status(TW_Device_Extension *tw_dev, u32 flag, int seconds)
2045 u32 status_reg_addr, status_reg_value;
2046 struct timeval before, timeout;
2048 status_reg_addr = tw_dev->registers.status_reg_addr;
2049 do_gettimeofday(&before);
2050 status_reg_value = inl(status_reg_addr);
2052 if (tw_check_bits(status_reg_value)) {
2053 dprintk(KERN_WARNING "3w-xxxx: tw_poll_status(): Unexpected bits.\n");
2054 tw_decode_bits(tw_dev, status_reg_value, 0);
2057 while ((status_reg_value & flag) != flag) {
2058 status_reg_value = inl(status_reg_addr);
2060 if (tw_check_bits(status_reg_value)) {
2061 dprintk(KERN_WARNING "3w-xxxx: tw_poll_status(): Unexpected bits.\n");
2062 tw_decode_bits(tw_dev, status_reg_value, 0);
2065 do_gettimeofday(&timeout);
2066 if (before.tv_sec + seconds < timeout.tv_sec) {
2067 dprintk(KERN_WARNING "3w-xxxx: tw_poll_status(): Flag 0x%x not found.\n", flag);
2073 } /* End tw_poll_status() */
2075 /* This function will poll the status register for disappearance of a flag */
2076 int tw_poll_status_gone(TW_Device_Extension *tw_dev, u32 flag, int seconds)
2078 u32 status_reg_addr, status_reg_value;
2079 struct timeval before, timeout;
2081 status_reg_addr = tw_dev->registers.status_reg_addr;
2082 do_gettimeofday(&before);
2083 status_reg_value = inl(status_reg_addr);
2085 if (tw_check_bits(status_reg_value)) {
2086 dprintk(KERN_WARNING "3w-xxxx: tw_poll_status_gone(): Unexpected bits.\n");
2087 tw_decode_bits(tw_dev, status_reg_value, 0);
2090 while ((status_reg_value & flag) != 0) {
2091 status_reg_value = inl(status_reg_addr);
2093 if (tw_check_bits(status_reg_value)) {
2094 dprintk(KERN_WARNING "3w-xxxx: tw_poll_status_gone(): Unexpected bits.\n");
2095 tw_decode_bits(tw_dev, status_reg_value, 0);
2098 do_gettimeofday(&timeout);
2099 if (before.tv_sec + seconds < timeout.tv_sec) {
2100 dprintk(KERN_WARNING "3w-xxxx: tw_poll_status_gone(): Flag 0x%x never disappeared.\n", flag);
2106 } /* End tw_poll_status_gone() */
2108 /* This function will attempt to post a command packet to the board */
2109 int tw_post_command_packet(TW_Device_Extension *tw_dev, int request_id)
2111 u32 status_reg_addr, status_reg_value;
2112 unsigned long command_que_value;
2113 u32 command_que_addr;
2115 dprintk(KERN_NOTICE "3w-xxxx: tw_post_command_packet()\n");
2116 command_que_addr = tw_dev->registers.command_que_addr;
2117 command_que_value = tw_dev->command_packet_physical_address[request_id];
2118 status_reg_addr = tw_dev->registers.status_reg_addr;
2119 status_reg_value = inl(status_reg_addr);
2121 if (tw_check_bits(status_reg_value)) {
2122 dprintk(KERN_WARNING "3w-xxxx: tw_post_command_packet(): Unexpected bits.\n");
2123 tw_decode_bits(tw_dev, status_reg_value, 1);
2126 if ((status_reg_value & TW_STATUS_COMMAND_QUEUE_FULL) == 0) {
2127 /* We successfully posted the command packet */
2128 outl(command_que_value, command_que_addr);
2129 tw_dev->state[request_id] = TW_S_POSTED;
2130 tw_dev->posted_request_count++;
2131 if (tw_dev->posted_request_count > tw_dev->max_posted_request_count) {
2132 tw_dev->max_posted_request_count = tw_dev->posted_request_count;
2135 /* Couldn't post the command packet, so we do it in the isr */
2136 if (tw_dev->state[request_id] != TW_S_PENDING) {
2137 tw_dev->state[request_id] = TW_S_PENDING;
2138 tw_dev->pending_request_count++;
2139 if (tw_dev->pending_request_count > tw_dev->max_pending_request_count) {
2140 tw_dev->max_pending_request_count = tw_dev->pending_request_count;
2142 tw_dev->pending_queue[tw_dev->pending_tail] = request_id;
2143 if (tw_dev->pending_tail == TW_Q_LENGTH-1) {
2144 tw_dev->pending_tail = TW_Q_START;
2146 tw_dev->pending_tail = tw_dev->pending_tail + 1;
2149 tw_unmask_command_interrupt(tw_dev);
2153 } /* End tw_post_command_packet() */
2155 /* This function will reset a device extension */
2156 int tw_reset_device_extension(TW_Device_Extension *tw_dev)
2162 dprintk(KERN_NOTICE "3w-xxxx: tw_reset_device_extension()\n");
2165 if (tw_reset_sequence(tw_dev)) {
2166 printk(KERN_WARNING "3w-xxxx: scsi%d: Reset sequence failed.\n", tw_dev->host->host_no);
2170 /* Abort all requests that are in progress */
2171 for (i=0;i<imax;i++) {
2172 if ((tw_dev->state[i] != TW_S_FINISHED) &&
2173 (tw_dev->state[i] != TW_S_INITIAL) &&
2174 (tw_dev->state[i] != TW_S_COMPLETED)) {
2175 srb = tw_dev->srb[i];
2177 srb->result = (DID_RESET << 16);
2178 tw_dev->srb[i]->scsi_done(tw_dev->srb[i]);
2179 tw_unmap_scsi_data(tw_dev->tw_pci_dev, tw_dev->srb[i]);
2184 /* Reset queues and counts */
2185 for (i=0;i<imax;i++) {
2186 tw_dev->free_queue[i] = i;
2187 tw_dev->state[i] = TW_S_INITIAL;
2189 tw_dev->free_head = TW_Q_START;
2190 tw_dev->free_tail = TW_Q_LENGTH - 1;
2191 tw_dev->posted_request_count = 0;
2192 tw_dev->pending_request_count = 0;
2193 tw_dev->pending_head = TW_Q_START;
2194 tw_dev->pending_tail = TW_Q_START;
2195 tw_dev->reset_print = 0;
2198 } /* End tw_reset_device_extension() */
2200 /* This function will reset a controller */
2201 int tw_reset_sequence(TW_Device_Extension *tw_dev)
2206 /* Disable interrupts */
2207 tw_disable_interrupts(tw_dev);
2209 /* Reset the board */
2210 while (tries < TW_MAX_RESET_TRIES) {
2211 tw_soft_reset(tw_dev);
2213 error = tw_aen_drain_queue(tw_dev);
2215 printk(KERN_WARNING "3w-xxxx: scsi%d: AEN drain failed, retrying.\n", tw_dev->host->host_no);
2220 /* Check for controller errors */
2221 if (tw_check_errors(tw_dev)) {
2222 printk(KERN_WARNING "3w-xxxx: scsi%d: Controller errors found, retrying.\n", tw_dev->host->host_no);
2227 /* Now the controller is in a good state */
2231 if (tries >= TW_MAX_RESET_TRIES) {
2232 printk(KERN_WARNING "3w-xxxx: scsi%d: Controller errors, card not responding, check all cabling.\n", tw_dev->host->host_no);
2236 error = tw_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS);
2238 printk(KERN_WARNING "3w-xxxx: scsi%d: Connection initialization failed.\n", tw_dev->host->host_no);
2242 /* Re-enable interrupts */
2243 tw_enable_and_clear_interrupts(tw_dev);
2246 } /* End tw_reset_sequence() */
2248 /* This funciton returns unit geometry in cylinders/heads/sectors */
2249 int tw_scsi_biosparam(Disk *disk, kdev_t dev, int geom[])
2251 int heads, sectors, cylinders;
2252 TW_Device_Extension *tw_dev;
2254 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_biosparam()\n");
2255 tw_dev = (TW_Device_Extension *)disk->device->host->hostdata;
2259 cylinders = disk->capacity / (heads * sectors);
2261 if (disk->capacity >= 0x200000) {
2264 cylinders = disk->capacity / (heads * sectors);
2267 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_biosparam(): heads = %d, sectors = %d, cylinders = %d\n", heads, sectors, cylinders);
2270 geom[2] = cylinders;
2273 } /* End tw_scsi_biosparam() */
2275 /* This function will find and initialize any cards */
2276 int tw_scsi_detect(Scsi_Host_Template *tw_host)
2280 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_detect()\n");
2282 printk(KERN_WARNING "3ware Storage Controller device driver for Linux v%s.\n", tw_driver_version);
2284 /* Check if the kernel has PCI interface compiled in */
2285 if (!pci_present()) {
2286 printk(KERN_WARNING "3w-xxxx: tw_scsi_detect(): No pci interface present.\n");
2290 spin_unlock_irq(&io_request_lock);
2291 ret = tw_findcards(tw_host);
2292 spin_lock_irq(&io_request_lock);
2295 } /* End tw_scsi_detect() */
2297 /* This is the new scsi eh abort function */
2298 int tw_scsi_eh_abort(Scsi_Cmnd *SCpnt)
2300 TW_Device_Extension *tw_dev=NULL;
2303 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_eh_abort()\n");
2306 printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Invalid Scsi_Cmnd.\n");
2310 tw_dev = (TW_Device_Extension *)SCpnt->host->hostdata;
2311 if (tw_dev == NULL) {
2312 printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Invalid device extension.\n");
2316 spin_lock(&tw_dev->tw_lock);
2317 tw_dev->num_aborts++;
2319 /* If the command hasn't been posted yet, we can do the abort */
2320 for (i=0;i<TW_Q_LENGTH;i++) {
2321 if (tw_dev->srb[i] == SCpnt) {
2322 if (tw_dev->state[i] == TW_S_STARTED) {
2323 printk(KERN_WARNING "3w-xxxx: scsi%d: Unit #%d: Command (%p) timed out.\n", tw_dev->host->host_no, tw_dev->srb[i]==0 ? 0 : tw_dev->srb[i]->target, SCpnt);
2324 tw_dev->state[i] = TW_S_COMPLETED;
2325 tw_state_request_finish(tw_dev, i);
2326 spin_unlock(&tw_dev->tw_lock);
2329 if (tw_dev->state[i] == TW_S_PENDING) {
2330 printk(KERN_WARNING "3w-xxxx: scsi%d: Unit #%d: Command (%p) timed out.\n", tw_dev->host->host_no, tw_dev->srb[i]==0 ? 0 : tw_dev->srb[i]->target, SCpnt);
2331 if (tw_dev->pending_head == TW_Q_LENGTH-1) {
2332 tw_dev->pending_head = TW_Q_START;
2334 tw_dev->pending_head = tw_dev->pending_head + 1;
2336 tw_dev->pending_request_count--;
2337 tw_dev->state[i] = TW_S_COMPLETED;
2338 tw_state_request_finish(tw_dev, i);
2339 spin_unlock(&tw_dev->tw_lock);
2342 if (tw_dev->state[i] == TW_S_POSTED) {
2343 /* If the command has already been posted, we have to reset the card */
2344 printk(KERN_WARNING "3w-xxxx: scsi%d: Unit #%d: Command (%p) timed out, resetting card.\n", tw_dev->host->host_no, tw_dev->srb[i]==0 ? 0 : tw_dev->srb[i]->target, SCpnt);
2345 /* We have to let AEN requests through before the reset */
2346 spin_unlock(&tw_dev->tw_lock);
2347 spin_unlock_irq(&io_request_lock);
2348 mdelay(TW_AEN_WAIT_TIME);
2349 spin_lock_irq(&io_request_lock);
2350 spin_lock(&tw_dev->tw_lock);
2352 if (tw_reset_device_extension(tw_dev)) {
2353 dprintk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Reset failed for card %d.\n", tw_dev->host->host_no);
2354 spin_unlock(&tw_dev->tw_lock);
2361 spin_unlock(&tw_dev->tw_lock);
2363 } /* End tw_scsi_eh_abort() */
2365 /* This is the new scsi eh reset function */
2366 int tw_scsi_eh_reset(Scsi_Cmnd *SCpnt)
2368 TW_Device_Extension *tw_dev=NULL;
2370 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_eh_reset()\n");
2373 printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_reset(): Invalid Scsi_Cmnd.\n");
2377 tw_dev = (TW_Device_Extension *)SCpnt->host->hostdata;
2378 if (tw_dev == NULL) {
2379 printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_reset(): Invalid device extension.\n");
2383 /* We have to let AEN requests through before the reset */
2384 spin_unlock_irq(&io_request_lock);
2385 mdelay(TW_AEN_WAIT_TIME);
2386 spin_lock_irq(&io_request_lock);
2388 spin_lock(&tw_dev->tw_lock);
2389 tw_dev->num_resets++;
2391 /* Now reset the card and some of the device extension data */
2392 if (tw_reset_device_extension(tw_dev)) {
2393 printk(KERN_WARNING "3w-xxxx: scsi%d: Reset failed.\n", tw_dev->host->host_no);
2394 spin_unlock(&tw_dev->tw_lock);
2397 printk(KERN_WARNING "3w-xxxx: scsi%d: Reset succeeded.\n", tw_dev->host->host_no);
2398 spin_unlock(&tw_dev->tw_lock);
2401 } /* End tw_scsi_eh_reset() */
2403 /* This function handles input and output from /proc/scsi/3w-xxxx/x */
2404 int tw_scsi_proc_info(char *buffer, char **start, off_t offset, int length, int hostno, int inout)
2406 TW_Device_Extension *tw_dev = NULL;
2411 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_proc_info()\n");
2413 /* Find the correct device extension */
2414 for (i=0;i<tw_device_extension_count;i++)
2415 if (tw_device_extension_list[i]->host->host_no == hostno)
2416 tw_dev = tw_device_extension_list[i];
2417 if (tw_dev == NULL) {
2418 printk(KERN_WARNING "3w-xxxx: tw_scsi_proc_info(): Couldn't locate device extension.\n");
2422 info.buffer = buffer;
2423 info.length = length;
2424 info.offset = offset;
2429 if (strncmp(buffer, "debug", 5) == 0) {
2430 printk(KERN_INFO "3w-xxxx: Posted commands:\n");
2431 for (j=0;j<TW_Q_LENGTH;j++) {
2432 if (tw_dev->state[j] == TW_S_POSTED) {
2433 TW_Command *command = (TW_Command *)tw_dev->command_packet_virtual_address[j];
2434 printk(KERN_INFO "3w-xxxx: Request_id: %d\n", j);
2435 printk(KERN_INFO "Opcode: 0x%x\n", command->byte0.opcode);
2436 printk(KERN_INFO "Block_count: 0x%x\n", command->byte6.block_count);
2437 printk(KERN_INFO "LBA: 0x%x\n", command->byte8.io.lba);
2438 printk(KERN_INFO "Physical command packet addr: 0x%lx\n", tw_dev->command_packet_physical_address[j]);
2439 printk(KERN_INFO "Scsi_Cmnd: %p\n", tw_dev->srb[j]);
2442 printk(KERN_INFO "3w-xxxx: Free_head: %3d\n", tw_dev->free_head);
2443 printk(KERN_INFO "3w-xxxx: Free_tail: %3d\n", tw_dev->free_tail);
2451 tw_copy_info(&info, "scsi%d: 3ware Storage Controller\n", hostno);
2452 tw_copy_info(&info, "Driver version: %s\n", tw_driver_version);
2453 tw_copy_info(&info, "Current commands posted: %3d\n", tw_dev->posted_request_count);
2454 tw_copy_info(&info, "Max commands posted: %3d\n", tw_dev->max_posted_request_count);
2455 tw_copy_info(&info, "Current pending commands: %3d\n", tw_dev->pending_request_count);
2456 tw_copy_info(&info, "Max pending commands: %3d\n", tw_dev->max_pending_request_count);
2457 tw_copy_info(&info, "Last sgl length: %3d\n", tw_dev->sgl_entries);
2458 tw_copy_info(&info, "Max sgl length: %3d\n", tw_dev->max_sgl_entries);
2459 tw_copy_info(&info, "Last sector count: %3d\n", tw_dev->sector_count);
2460 tw_copy_info(&info, "Max sector count: %3d\n", tw_dev->max_sector_count);
2461 tw_copy_info(&info, "Resets: %3d\n", tw_dev->num_resets);
2462 tw_copy_info(&info, "Aborts: %3d\n", tw_dev->num_aborts);
2463 tw_copy_info(&info, "AEN's: %3d\n", tw_dev->aen_count);
2465 if (info.position > info.offset) {
2466 return (info.position - info.offset);
2470 } /* End tw_scsi_proc_info() */
2472 /* This is the main scsi queue function to handle scsi opcodes */
2473 int tw_scsi_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
2475 unsigned char *command = SCpnt->cmnd;
2478 unsigned long flags = 0;
2479 TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->host->hostdata;
2481 if (tw_dev == NULL) {
2482 printk(KERN_WARNING "3w-xxxx: tw_scsi_queue(): Invalid device extension.\n");
2483 SCpnt->result = (DID_ERROR << 16);
2488 spin_lock_irqsave(&tw_dev->tw_lock, flags);
2489 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue()\n");
2491 /* Skip scsi command if it isn't for us */
2492 if ((tw_dev->is_unit_present[SCpnt->target] == FALSE) || (SCpnt->lun != 0)) {
2493 SCpnt->result = (DID_BAD_TARGET << 16);
2495 spin_unlock_irqrestore(&tw_dev->tw_lock, flags);
2499 /* Save done function into Scsi_Cmnd struct */
2500 SCpnt->scsi_done = done;
2502 /* Queue the command and get a request id */
2503 tw_state_request_start(tw_dev, &request_id);
2505 /* Save the scsi command for use by the ISR */
2506 tw_dev->srb[request_id] = SCpnt;
2513 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught READ/WRITE.\n");
2514 error = tw_scsiop_read_write(tw_dev, request_id);
2516 case TEST_UNIT_READY:
2517 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught TEST_UNIT_READY.\n");
2518 error = tw_scsiop_test_unit_ready(tw_dev, request_id);
2521 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught INQUIRY.\n");
2522 error = tw_scsiop_inquiry(tw_dev, request_id);
2525 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught READ_CAPACITY.\n");
2526 error = tw_scsiop_read_capacity(tw_dev, request_id);
2529 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught REQUEST_SENSE.\n");
2530 error = tw_scsiop_request_sense(tw_dev, request_id);
2533 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught MODE_SENSE.\n");
2534 error = tw_scsiop_mode_sense(tw_dev, request_id);
2536 case SYNCHRONIZE_CACHE:
2537 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught SYNCHRONIZE_CACHE.\n");
2538 error = tw_scsiop_synchronize_cache(tw_dev, request_id);
2541 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught TW_SCSI_IOCTL.\n");
2542 error = tw_ioctl(tw_dev, request_id);
2545 printk(KERN_NOTICE "3w-xxxx: scsi%d: Unknown scsi opcode: 0x%x\n", tw_dev->host->host_no, *command);
2546 tw_dev->state[request_id] = TW_S_COMPLETED;
2547 tw_state_request_finish(tw_dev, request_id);
2548 SCpnt->result = (DID_BAD_TARGET << 16);
2552 tw_dev->state[request_id] = TW_S_COMPLETED;
2553 tw_state_request_finish(tw_dev, request_id);
2554 SCpnt->result = (DID_ERROR << 16);
2557 spin_unlock_irqrestore(&tw_dev->tw_lock, flags);
2560 } /* End tw_scsi_queue() */
2562 /* This function will release the resources on an rmmod call */
2563 int tw_scsi_release(struct Scsi_Host *tw_host)
2565 TW_Device_Extension *tw_dev;
2566 tw_dev = (TW_Device_Extension *)tw_host->hostdata;
2568 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_release()\n");
2570 /* Fake like we just shut down, so notify the card that
2571 * we "shut down cleanly".
2573 tw_halt(0, 0, 0); // parameters aren't actually used
2575 /* Free up the IO region */
2576 release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
2578 /* Free up the IRQ */
2579 free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
2581 /* Free up device extension resources */
2582 tw_free_device_extension(tw_dev);
2584 /* Tell kernel scsi-layer we are gone */
2585 scsi_unregister(tw_host);
2588 } /* End tw_scsi_release() */
2590 /* This function handles scsi inquiry commands */
2591 int tw_scsiop_inquiry(TW_Device_Extension *tw_dev, int request_id)
2594 TW_Command *command_packet;
2595 unsigned long command_que_value;
2596 u32 command_que_addr;
2597 unsigned long param_value;
2599 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry()\n");
2601 /* Initialize command packet */
2602 command_que_addr = tw_dev->registers.command_que_addr;
2603 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
2604 if (command_packet == NULL) {
2605 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad command packet virtual address.\n");
2608 memset(command_packet, 0, sizeof(TW_Sector));
2609 command_packet->byte0.opcode = TW_OP_GET_PARAM;
2610 command_packet->byte0.sgl_offset = 2;
2611 command_packet->size = 4;
2612 command_packet->request_id = request_id;
2613 command_packet->byte3.unit = 0;
2614 command_packet->byte3.host_id = 0;
2615 command_packet->status = 0;
2616 command_packet->flags = 0;
2617 command_packet->byte6.parameter_count = 1;
2619 /* Now setup the param */
2620 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
2621 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad alignment virtual address.\n");
2624 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
2625 memset(param, 0, sizeof(TW_Sector));
2626 param->table_id = 3; /* unit summary table */
2627 param->parameter_id = 3; /* unitsstatus parameter */
2628 param->parameter_size_bytes = TW_MAX_UNITS;
2629 param_value = tw_dev->alignment_physical_address[request_id];
2630 if (param_value == 0) {
2631 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad alignment physical address.\n");
2635 command_packet->byte8.param.sgl[0].address = param_value;
2636 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
2637 command_que_value = tw_dev->command_packet_physical_address[request_id];
2638 if (command_que_value == 0) {
2639 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad command packet physical address.\n");
2643 /* Now try to post the command packet */
2644 tw_post_command_packet(tw_dev, request_id);
2647 } /* End tw_scsiop_inquiry() */
2649 /* This function is called by the isr to complete an inquiry command */
2650 int tw_scsiop_inquiry_complete(TW_Device_Extension *tw_dev, int request_id)
2652 unsigned char *is_unit_present;
2653 unsigned char *request_buffer;
2657 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry_complete()\n");
2659 /* Fill request buffer */
2660 if (tw_dev->srb[request_id]->request_buffer == NULL) {
2661 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry_complete(): Request buffer NULL.\n");
2664 request_buffer = tw_dev->srb[request_id]->request_buffer;
2665 memset(request_buffer, 0, tw_dev->srb[request_id]->request_bufflen);
2666 request_buffer[0] = TYPE_DISK; /* Peripheral device type */
2667 request_buffer[1] = 0; /* Device type modifier */
2668 request_buffer[2] = 0; /* No ansi/iso compliance */
2669 request_buffer[4] = 31; /* Additional length */
2670 memcpy(&request_buffer[8], "3ware ", 8); /* Vendor ID */
2671 memcpy(&request_buffer[16], "3w-xxxx ", 16); /* Product ID */
2672 memcpy(&request_buffer[32], tw_driver_version, 3);
2674 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
2675 if (param == NULL) {
2676 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry_complete(): Bad alignment virtual address.\n");
2679 is_unit_present = &(param->data[0]);
2681 for (i=0 ; i<TW_MAX_UNITS; i++) {
2682 if (is_unit_present[i] == 0) {
2683 tw_dev->is_unit_present[i] = FALSE;
2685 if (is_unit_present[i] & TW_UNIT_ONLINE) {
2686 tw_dev->is_unit_present[i] = TRUE;
2687 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry_complete: Unit %d found.\n", i);
2693 } /* End tw_scsiop_inquiry_complete() */
2695 /* This function handles scsi mode_sense commands */
2696 int tw_scsiop_mode_sense(TW_Device_Extension *tw_dev, int request_id)
2699 TW_Command *command_packet;
2700 unsigned long command_que_value;
2701 unsigned long param_value;
2703 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_mode_sense()\n");
2705 /* Only page control = 0, page code = 0x8 (cache page) supported */
2706 if (tw_dev->srb[request_id]->cmnd[2] != 0x8) {
2707 tw_dev->state[request_id] = TW_S_COMPLETED;
2708 tw_state_request_finish(tw_dev, request_id);
2709 tw_dev->srb[request_id]->result = (DID_OK << 16);
2710 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
2714 /* Now read firmware cache setting for this unit */
2715 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
2716 if (command_packet == NULL) {
2717 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad command packet virtual address.\n");
2721 /* Setup the command packet */
2722 memset(command_packet, 0, sizeof(TW_Sector));
2723 command_packet->byte0.opcode = TW_OP_GET_PARAM;
2724 command_packet->byte0.sgl_offset = 2;
2725 command_packet->size = 4;
2726 command_packet->request_id = request_id;
2727 command_packet->byte3.unit = 0;
2728 command_packet->byte3.host_id = 0;
2729 command_packet->status = 0;
2730 command_packet->flags = 0;
2731 command_packet->byte6.parameter_count = 1;
2733 /* Setup the param */
2734 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
2735 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad alignment virtual address.\n");
2739 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
2740 memset(param, 0, sizeof(TW_Sector));
2741 param->table_id = TW_UNIT_INFORMATION_TABLE_BASE + tw_dev->srb[request_id]->target;
2742 param->parameter_id = 7; /* unit flags */
2743 param->parameter_size_bytes = 1;
2744 param_value = tw_dev->alignment_physical_address[request_id];
2745 if (param_value == 0) {
2746 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad alignment physical address.\n");
2750 command_packet->byte8.param.sgl[0].address = param_value;
2751 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
2752 command_que_value = tw_dev->command_packet_physical_address[request_id];
2753 if (command_que_value == 0) {
2754 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad command packet physical address.\n");
2758 /* Now try to post the command packet */
2759 tw_post_command_packet(tw_dev, request_id);
2762 } /* End tw_scsiop_mode_sense() */
2764 /* This function is called by the isr to complete a mode sense command */
2765 int tw_scsiop_mode_sense_complete(TW_Device_Extension *tw_dev, int request_id)
2768 unsigned char *flags;
2769 unsigned char *request_buffer;
2771 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_mode_sense_complete()\n");
2773 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
2774 if (param == NULL) {
2775 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense_complete(): Bad alignment virtual address.\n");
2778 flags = (char *)&(param->data[0]);
2779 request_buffer = tw_dev->srb[request_id]->buffer;
2780 memset(request_buffer, 0, tw_dev->srb[request_id]->request_bufflen);
2782 request_buffer[0] = 0xf; /* mode data length */
2783 request_buffer[1] = 0; /* default medium type */
2784 request_buffer[2] = 0x10; /* dpo/fua support on */
2785 request_buffer[3] = 0; /* no block descriptors */
2786 request_buffer[4] = 0x8; /* caching page */
2787 request_buffer[5] = 0xa; /* page length */
2789 request_buffer[6] = 0x4; /* WCE on */
2791 request_buffer[6] = 0x0; /* WCE off */
2794 } /* End tw_scsiop_mode_sense_complete() */
2796 /* This function handles scsi read_capacity commands */
2797 int tw_scsiop_read_capacity(TW_Device_Extension *tw_dev, int request_id)
2800 TW_Command *command_packet;
2801 unsigned long command_que_value;
2802 u32 command_que_addr;
2803 unsigned long param_value;
2805 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity()\n");
2807 /* Initialize command packet */
2808 command_que_addr = tw_dev->registers.command_que_addr;
2809 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
2811 if (command_packet == NULL) {
2812 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad command packet virtual address.\n");
2815 memset(command_packet, 0, sizeof(TW_Sector));
2816 command_packet->byte0.opcode = TW_OP_GET_PARAM;
2817 command_packet->byte0.sgl_offset = 2;
2818 command_packet->size = 4;
2819 command_packet->request_id = request_id;
2820 command_packet->byte3.unit = tw_dev->srb[request_id]->target;
2821 command_packet->byte3.host_id = 0;
2822 command_packet->status = 0;
2823 command_packet->flags = 0;
2824 command_packet->byte6.block_count = 1;
2826 /* Now setup the param */
2827 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
2828 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad alignment virtual address.\n");
2831 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
2832 memset(param, 0, sizeof(TW_Sector));
2833 param->table_id = TW_UNIT_INFORMATION_TABLE_BASE +
2834 tw_dev->srb[request_id]->target;
2835 param->parameter_id = 4; /* unitcapacity parameter */
2836 param->parameter_size_bytes = 4;
2837 param_value = tw_dev->alignment_physical_address[request_id];
2838 if (param_value == 0) {
2839 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad alignment physical address.\n");
2843 command_packet->byte8.param.sgl[0].address = param_value;
2844 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
2845 command_que_value = tw_dev->command_packet_physical_address[request_id];
2846 if (command_que_value == 0) {
2847 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad command packet physical address.\n");
2851 /* Now try to post the command to the board */
2852 tw_post_command_packet(tw_dev, request_id);
2855 } /* End tw_scsiop_read_capacity() */
2857 /* This function is called by the isr to complete a readcapacity command */
2858 int tw_scsiop_read_capacity_complete(TW_Device_Extension *tw_dev, int request_id)
2860 unsigned char *param_data;
2865 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity_complete()\n");
2867 buff = tw_dev->srb[request_id]->request_buffer;
2869 printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_capacity_complete(): Request buffer NULL.\n");
2872 memset(buff, 0, tw_dev->srb[request_id]->request_bufflen);
2873 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
2874 if (param == NULL) {
2875 printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_capacity_complete(): Bad alignment virtual address.\n");
2878 param_data = &(param->data[0]);
2880 capacity = (param_data[3] << 24) | (param_data[2] << 16) |
2881 (param_data[1] << 8) | param_data[0];
2883 /* Subtract one sector to fix get last sector ioctl */
2886 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity_complete(): Capacity = 0x%x.\n", capacity);
2888 /* Number of LBA's */
2889 buff[0] = (capacity >> 24);
2890 buff[1] = (capacity >> 16) & 0xff;
2891 buff[2] = (capacity >> 8) & 0xff;
2892 buff[3] = capacity & 0xff;
2894 /* Block size in bytes (512) */
2895 buff[4] = (TW_BLOCK_SIZE >> 24);
2896 buff[5] = (TW_BLOCK_SIZE >> 16) & 0xff;
2897 buff[6] = (TW_BLOCK_SIZE >> 8) & 0xff;
2898 buff[7] = TW_BLOCK_SIZE & 0xff;
2901 } /* End tw_scsiop_read_capacity_complete() */
2903 /* This function handles scsi read or write commands */
2904 int tw_scsiop_read_write(TW_Device_Extension *tw_dev, int request_id)
2906 TW_Command *command_packet;
2907 unsigned long command_que_value;
2908 u32 command_que_addr = 0x0;
2909 u32 lba = 0x0, num_sectors = 0x0, buffaddr = 0x0;
2910 int i, use_sg, count = 0;
2912 struct scatterlist *sglist;
2914 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write()\n");
2916 if (tw_dev->srb[request_id]->request_buffer == NULL) {
2917 printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_write(): Request buffer NULL.\n");
2920 sglist = (struct scatterlist *)tw_dev->srb[request_id]->request_buffer;
2921 srb = tw_dev->srb[request_id];
2923 /* Initialize command packet */
2924 command_que_addr = tw_dev->registers.command_que_addr;
2925 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
2926 if (command_packet == NULL) {
2927 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): Bad command packet virtual address.\n");
2931 if (srb->cmnd[0] == READ_6 || srb->cmnd[0] == READ_10) {
2932 command_packet->byte0.opcode = TW_OP_READ;
2934 command_packet->byte0.opcode = TW_OP_WRITE;
2937 command_packet->byte0.sgl_offset = 3;
2938 command_packet->size = 3;
2939 command_packet->request_id = request_id;
2940 command_packet->byte3.unit = srb->target;
2941 command_packet->byte3.host_id = 0;
2942 command_packet->status = 0;
2943 command_packet->flags = 0;
2945 if (srb->cmnd[0] == WRITE_10) {
2946 if ((srb->cmnd[1] & 0x8) || (srb->cmnd[1] & 0x10))
2947 command_packet->flags = 1;
2950 if (srb->cmnd[0] == READ_6 || srb->cmnd[0] == WRITE_6) {
2951 lba = ((u32)srb->cmnd[1] << 16) | ((u32)srb->cmnd[2] << 8) | (u32)srb->cmnd[3];
2952 num_sectors = (u32)srb->cmnd[4];
2954 lba = ((u32)srb->cmnd[2] << 24) | ((u32)srb->cmnd[3] << 16) | ((u32)srb->cmnd[4] << 8) | (u32)srb->cmnd[5];
2955 num_sectors = (u32)srb->cmnd[8] | ((u32)srb->cmnd[7] << 8);
2958 /* Update sector statistic */
2959 tw_dev->sector_count = num_sectors;
2960 if (tw_dev->sector_count > tw_dev->max_sector_count)
2961 tw_dev->max_sector_count = tw_dev->sector_count;
2963 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): lba = 0x%x num_sectors = 0x%x\n", lba, num_sectors);
2964 command_packet->byte8.io.lba = lba;
2965 command_packet->byte6.block_count = num_sectors;
2967 if ((tw_dev->is_raid_five[tw_dev->srb[request_id]->target] == 0) || (srb->cmnd[0] == READ_6) || (srb->cmnd[0] == READ_10) || (tw_dev->tw_pci_dev->device == TW_DEVICE_ID2)) {
2968 /* Do this if there are no sg list entries */
2969 if (tw_dev->srb[request_id]->use_sg == 0) {
2970 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): SG = 0\n");
2971 buffaddr = tw_map_scsi_single_data(tw_dev->tw_pci_dev, tw_dev->srb[request_id]);
2975 command_packet->byte8.io.sgl[0].address = buffaddr;
2976 command_packet->byte8.io.sgl[0].length = tw_dev->srb[request_id]->request_bufflen;
2977 command_packet->size+=2;
2980 /* Do this if we have multiple sg list entries */
2981 if (tw_dev->srb[request_id]->use_sg > 0) {
2982 use_sg = tw_map_scsi_sg_data(tw_dev->tw_pci_dev, tw_dev->srb[request_id]);
2986 for (i=0;i<use_sg; i++) {
2987 command_packet->byte8.io.sgl[i].address = sg_dma_address(&sglist[i]);
2988 command_packet->byte8.io.sgl[i].length = sg_dma_len(&sglist[i]);
2989 command_packet->size+=2;
2993 /* Do this if there are no sg list entries for raid 5 */
2994 if (tw_dev->srb[request_id]->use_sg == 0) {
2995 dprintk(KERN_WARNING "doing raid 5 write use_sg = 0, bounce_buffer[%d] = 0x%p\n", request_id, tw_dev->bounce_buffer[request_id]);
2996 memcpy(tw_dev->bounce_buffer[request_id], tw_dev->srb[request_id]->request_buffer, tw_dev->srb[request_id]->request_bufflen);
2997 command_packet->byte8.io.sgl[0].address = tw_dev->bounce_buffer_phys[request_id];
2998 command_packet->byte8.io.sgl[0].length = tw_dev->srb[request_id]->request_bufflen;
2999 command_packet->size+=2;
3002 /* Do this if we have multiple sg list entries for raid 5 */
3003 if (tw_dev->srb[request_id]->use_sg > 0) {
3004 dprintk(KERN_WARNING "doing raid 5 write use_sg = %d, sglist[0].length = %d\n", tw_dev->srb[request_id]->use_sg, sglist[0].length);
3005 for (i=0;i<tw_dev->srb[request_id]->use_sg; i++) {
3006 memcpy((char *)(tw_dev->bounce_buffer[request_id])+count, sglist[i].address, sglist[i].length);
3007 count+=sglist[i].length;
3009 command_packet->byte8.io.sgl[0].address = tw_dev->bounce_buffer_phys[request_id];
3010 command_packet->byte8.io.sgl[0].length = count;
3011 command_packet->size = 5; /* single sgl */
3015 /* Update SG statistics */
3016 tw_dev->sgl_entries = tw_dev->srb[request_id]->use_sg;
3017 if (tw_dev->sgl_entries > tw_dev->max_sgl_entries)
3018 tw_dev->max_sgl_entries = tw_dev->sgl_entries;
3020 command_que_value = tw_dev->command_packet_physical_address[request_id];
3021 if (command_que_value == 0) {
3022 dprintk(KERN_WARNING "3w-xxxx: tw_scsiop_read_write(): Bad command packet physical address.\n");
3026 /* Now try to post the command to the board */
3027 tw_post_command_packet(tw_dev, request_id);
3030 } /* End tw_scsiop_read_write() */
3032 /* This function will handle the request sense scsi command */
3033 int tw_scsiop_request_sense(TW_Device_Extension *tw_dev, int request_id)
3035 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_request_sense()\n");
3037 /* For now we just zero the request buffer */
3038 memset(tw_dev->srb[request_id]->request_buffer, 0, tw_dev->srb[request_id]->request_bufflen);
3040 tw_dev->state[request_id] = TW_S_COMPLETED;
3041 tw_state_request_finish(tw_dev, request_id);
3043 /* If we got a request_sense, we probably want a reset, return error */
3044 tw_dev->srb[request_id]->result = (DID_ERROR << 16);
3045 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
3048 } /* End tw_scsiop_request_sense() */
3050 /* This function will handle synchronize cache scsi command */
3051 int tw_scsiop_synchronize_cache(TW_Device_Extension *tw_dev, int request_id)
3053 TW_Command *command_packet;
3054 unsigned long command_que_value;
3056 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_synchronize_cache()\n");
3058 /* Send firmware flush command for this unit */
3059 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
3060 if (command_packet == NULL) {
3061 printk(KERN_WARNING "3w-xxxx: tw_scsiop_synchronize_cache(): Bad command packet virtual address.\n");
3065 /* Setup the command packet */
3066 memset(command_packet, 0, sizeof(TW_Sector));
3067 command_packet->byte0.opcode = TW_OP_FLUSH_CACHE;
3068 command_packet->byte0.sgl_offset = 0;
3069 command_packet->size = 2;
3070 command_packet->request_id = request_id;
3071 command_packet->byte3.unit = tw_dev->srb[request_id]->target;
3072 command_packet->byte3.host_id = 0;
3073 command_packet->status = 0;
3074 command_packet->flags = 0;
3075 command_packet->byte6.parameter_count = 1;
3076 command_que_value = tw_dev->command_packet_physical_address[request_id];
3077 if (command_que_value == 0) {
3078 printk(KERN_WARNING "3w-xxxx: tw_scsiop_synchronize_cache(): Bad command packet physical address.\n");
3082 /* Now try to post the command packet */
3083 tw_post_command_packet(tw_dev, request_id);
3086 } /* End tw_scsiop_synchronize_cache() */
3088 /* This function will handle test unit ready scsi command */
3089 int tw_scsiop_test_unit_ready(TW_Device_Extension *tw_dev, int request_id)
3091 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_test_unit_ready()\n");
3093 /* Tell the scsi layer were done */
3094 tw_dev->state[request_id] = TW_S_COMPLETED;
3095 tw_state_request_finish(tw_dev, request_id);
3096 tw_dev->srb[request_id]->result = (DID_OK << 16);
3097 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
3100 } /* End tw_scsiop_test_unit_ready() */
3102 /* Set a value in the features table */
3103 int tw_setfeature(TW_Device_Extension *tw_dev, int parm, int param_size,
3107 TW_Command *command_packet;
3108 TW_Response_Queue response_queue;
3110 unsigned long command_que_value;
3111 u32 command_que_addr;
3112 u32 response_que_addr;
3113 unsigned long param_value;
3115 /* Initialize SetParam command packet */
3116 if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
3117 printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad command packet virtual address.\n");
3120 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
3121 memset(command_packet, 0, sizeof(TW_Sector));
3122 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
3124 command_packet->byte0.opcode = TW_OP_SET_PARAM;
3125 command_packet->byte0.sgl_offset = 2;
3126 param->table_id = 0x404; /* Features table */
3127 param->parameter_id = parm;
3128 param->parameter_size_bytes = param_size;
3129 memcpy(param->data, val, param_size);
3131 param_value = tw_dev->alignment_physical_address[request_id];
3132 if (param_value == 0) {
3133 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Bad alignment physical address.\n");
3134 tw_dev->state[request_id] = TW_S_COMPLETED;
3135 tw_state_request_finish(tw_dev, request_id);
3136 tw_dev->srb[request_id]->result = (DID_OK << 16);
3137 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
3139 command_packet->byte8.param.sgl[0].address = param_value;
3140 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
3142 command_packet->size = 4;
3143 command_packet->request_id = request_id;
3144 command_packet->byte6.parameter_count = 1;
3146 command_que_value = tw_dev->command_packet_physical_address[request_id];
3147 if (command_que_value == 0) {
3148 printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad command packet physical address.\n");
3151 command_que_addr = tw_dev->registers.command_que_addr;
3152 response_que_addr = tw_dev->registers.response_que_addr;
3154 /* Send command packet to the board */
3155 outl(command_que_value, command_que_addr);
3157 /* Poll for completion */
3158 if (tw_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, 30) == 0) {
3159 response_queue.value = inl(response_que_addr);
3160 request_id = (unsigned char)response_queue.u.response_id;
3161 if (request_id != 0) {
3162 /* unexpected request id */
3163 printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Unexpected request id.\n");
3166 if (command_packet->status != 0) {
3168 tw_decode_sense(tw_dev, request_id, 0);
3174 } /* End tw_setfeature() */
3176 /* This function will setup the interrupt handler */
3177 int tw_setup_irq(TW_Device_Extension *tw_dev)
3179 char *device = TW_DEVICE_NAME;
3182 dprintk(KERN_NOTICE "3w-xxxx: tw_setup_irq()\n");
3183 error = request_irq(tw_dev->tw_pci_dev->irq, tw_interrupt, SA_SHIRQ, device, tw_dev);
3186 printk(KERN_WARNING "3w-xxxx: scsi%d: Error requesting IRQ: %d.\n", tw_dev->host->host_no, tw_dev->tw_pci_dev->irq);
3190 } /* End tw_setup_irq() */
3192 /* This function will tell the controller we're shutting down by sending
3193 initconnection with a 1 */
3194 int tw_shutdown_device(TW_Device_Extension *tw_dev)
3198 /* Disable interrupts */
3199 tw_disable_interrupts(tw_dev);
3201 /* poke the board */
3202 error = tw_initconnection(tw_dev, 1);
3204 printk(KERN_WARNING "3w-xxxx: scsi%d: Connection shutdown failed.\n", tw_dev->host->host_no);
3206 printk(KERN_NOTICE "3w-xxxx: Shutdown complete.\n");
3209 /* Re-enable interrupts */
3210 tw_enable_and_clear_interrupts(tw_dev);
3213 } /* End tw_shutdown_device() */
3215 /* This function will soft reset the controller */
3216 void tw_soft_reset(TW_Device_Extension *tw_dev)
3218 u32 control_reg_addr, control_reg_value;
3220 control_reg_addr = tw_dev->registers.control_reg_addr;
3221 control_reg_value = ( TW_CONTROL_ISSUE_SOFT_RESET |
3222 TW_CONTROL_CLEAR_HOST_INTERRUPT |
3223 TW_CONTROL_CLEAR_ATTENTION_INTERRUPT |
3224 TW_CONTROL_MASK_COMMAND_INTERRUPT |
3225 TW_CONTROL_MASK_RESPONSE_INTERRUPT |
3226 TW_CONTROL_CLEAR_ERROR_STATUS |
3227 TW_CONTROL_DISABLE_INTERRUPTS);
3228 outl(control_reg_value, control_reg_addr);
3229 } /* End tw_soft_reset() */
3231 /* This function will free a request_id */
3232 int tw_state_request_finish(TW_Device_Extension *tw_dev, int request_id)
3234 dprintk(KERN_NOTICE "3w-xxxx: tw_state_request_finish()\n");
3237 if (tw_dev->free_tail == tw_dev->free_wrap) {
3238 tw_dev->free_tail = TW_Q_START;
3240 tw_dev->free_tail = tw_dev->free_tail + 1;
3242 } while ((tw_dev->state[tw_dev->free_queue[tw_dev->free_tail]] != TW_S_COMPLETED));
3244 tw_dev->free_queue[tw_dev->free_tail] = request_id;
3246 tw_dev->state[request_id] = TW_S_FINISHED;
3247 dprintk(KERN_NOTICE "3w-xxxx: tw_state_request_finish(): Freeing request_id %d\n", request_id);
3250 } /* End tw_state_request_finish() */
3252 /* This function will assign an available request_id */
3253 int tw_state_request_start(TW_Device_Extension *tw_dev, int *request_id)
3257 dprintk(KERN_NOTICE "3w-xxxx: tw_state_request_start()\n");
3259 /* Obtain next free request_id */
3261 if (tw_dev->free_head == tw_dev->free_wrap) {
3262 tw_dev->free_head = TW_Q_START;
3264 tw_dev->free_head = tw_dev->free_head + 1;
3266 } while (tw_dev->state[tw_dev->free_queue[tw_dev->free_head]] & TW_START_MASK);
3268 id = tw_dev->free_queue[tw_dev->free_head];
3270 dprintk(KERN_NOTICE "3w-xxxx: tw_state_request_start(): id = %d.\n", id);
3272 tw_dev->state[id] = TW_S_STARTED;
3275 } /* End tw_state_request_start() */
3277 static void tw_unmap_scsi_data(struct pci_dev *pdev, Scsi_Cmnd *cmd)
3279 int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
3281 dprintk(KERN_WARNING "3w-xxxx: tw_unamp_scsi_data()\n");
3283 switch(cmd->SCp.phase) {
3285 #ifdef BLK_BOUNCE_HIGH
3286 pci_unmap_page(pdev, cmd->SCp.have_data_in, cmd->request_bufflen, dma_dir);
3288 pci_unmap_single(pdev, cmd->SCp.have_data_in, cmd->request_bufflen, dma_dir);
3292 pci_unmap_sg(pdev, cmd->request_buffer, cmd->use_sg, dma_dir);
3295 } /* End tw_unmap_scsi_data() */
3297 /* This function will unmask the command interrupt on the controller */
3298 void tw_unmask_command_interrupt(TW_Device_Extension *tw_dev)
3300 u32 control_reg_addr, control_reg_value;
3302 control_reg_addr = tw_dev->registers.control_reg_addr;
3303 control_reg_value = TW_CONTROL_UNMASK_COMMAND_INTERRUPT;
3304 outl(control_reg_value, control_reg_addr);
3305 } /* End tw_unmask_command_interrupt() */
3307 /* Now get things going */
3308 static Scsi_Host_Template driver_template = TWXXXX;
3309 #include "scsi_module.c"