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-2003 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.
163 1.02.00.032 - Fix small multicard rollcall bug.
164 Make driver stay loaded with no units for hot add/swap.
165 Add support for "twe" character device for ioctls.
166 Clean up request_id queueing code.
167 Fix tw_scsi_queue() spinlocks.
168 1.02.00.033 - Fix tw_aen_complete() to not queue 'queue empty' AEN's.
169 Initialize queues correctly when loading with no valid units.
170 1.02.00.034 - Fix tw_decode_bits() to handle multiple errors.
171 Add support for user configurable cmd_per_lun.
172 Add support for sht->select_queue_depths.
173 1.02.00.035 - Improve tw_allocate_memory() memory allocation.
174 Fix tw_chrdev_ioctl() to sleep correctly.
175 1.02.00.036 - Increase character ioctl timeout to 60 seconds.
176 1.02.00.037 - Fix tw_ioctl() to handle all non-data ATA passthru cmds
177 for 'smartmontools' support.
180 #include <linux/module.h>
182 MODULE_AUTHOR ("3ware Inc.");
184 MODULE_DESCRIPTION ("3ware Storage Controller Linux Driver (SMP)");
186 MODULE_DESCRIPTION ("3ware Storage Controller Linux Driver");
189 #include <linux/kernel.h>
190 #include <linux/pci.h>
191 #include <linux/time.h>
192 #include <linux/proc_fs.h>
193 #include <linux/sched.h>
194 #include <linux/ioport.h>
195 #include <linux/blk.h>
196 #include <linux/hdreg.h>
197 #include <linux/string.h>
198 #include <linux/delay.h>
199 #include <linux/smp.h>
200 #include <linux/reboot.h>
201 #include <linux/spinlock.h>
203 #include <asm/errno.h>
206 #include <asm/uaccess.h>
208 #define __3W_C /* let 3w-xxxx.h know it is use */
216 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,10)
217 MODULE_LICENSE("GPL");
220 static int tw_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
221 static int tw_chrdev_open(struct inode *inode, struct file *file);
222 static int tw_chrdev_release(struct inode *inode, struct file *file);
223 static int tw_copy_info(TW_Info *info, char *fmt, ...);
224 static void tw_copy_mem_info(TW_Info *info, char *data, int len);
225 static void tw_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
226 static int tw_halt(struct notifier_block *nb, ulong event, void *buf);
227 static int tw_map_scsi_sg_data(struct pci_dev *pdev, Scsi_Cmnd *cmd);
228 static u32 tw_map_scsi_single_data(struct pci_dev *pdev, Scsi_Cmnd *cmd);
229 static void tw_unmap_scsi_data(struct pci_dev *pdev, Scsi_Cmnd *cmd);
231 /* Notifier block to get a notify on system shutdown/halt/reboot */
232 static struct notifier_block tw_notifier = {
236 /* File operations struct for character device */
237 static struct file_operations tw_fops = {
239 ioctl: tw_chrdev_ioctl,
240 open: tw_chrdev_open,
241 release: tw_chrdev_release
245 char *tw_driver_version="1.02.00.037";
246 TW_Device_Extension *tw_device_extension_list[TW_MAX_SLOT];
247 int tw_device_extension_count = 0;
248 static int twe_major = -1;
252 /* This function will complete an aen request from the isr */
253 int tw_aen_complete(TW_Device_Extension *tw_dev, int request_id)
257 int error = 0, table_max = 0;
259 dprintk(KERN_WARNING "3w-xxxx: tw_aen_complete()\n");
260 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
261 printk(KERN_WARNING "3w-xxxx: tw_aen_complete(): Bad alignment virtual address.\n");
264 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
265 aen = *(unsigned short *)(param->data);
266 dprintk(KERN_NOTICE "3w-xxxx: tw_aen_complete(): Queue'd code 0x%x\n", aen);
268 /* Print some useful info when certain aen codes come out */
270 printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: INFO: AEN queue overflow.\n", tw_dev->host->host_no);
272 table_max = sizeof(tw_aen_string)/sizeof(char *);
273 if ((aen & 0x0ff) < table_max) {
274 if ((tw_aen_string[aen & 0xff][strlen(tw_aen_string[aen & 0xff])-1]) == '#') {
275 printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: %s%d.\n", tw_dev->host->host_no, tw_aen_string[aen & 0xff], aen >> 8);
278 printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: %s.\n", tw_dev->host->host_no, tw_aen_string[aen & 0xff]);
281 printk(KERN_WARNING "3w-xxxx: scsi%d: Received AEN %d.\n", tw_dev->host->host_no, aen);
284 if (aen != TW_AEN_QUEUE_EMPTY) {
287 /* Now queue the code */
288 tw_dev->aen_queue[tw_dev->aen_tail] = aen;
289 if (tw_dev->aen_tail == TW_Q_LENGTH - 1) {
290 tw_dev->aen_tail = TW_Q_START;
292 tw_dev->aen_tail = tw_dev->aen_tail + 1;
294 if (tw_dev->aen_head == tw_dev->aen_tail) {
295 if (tw_dev->aen_head == TW_Q_LENGTH - 1) {
296 tw_dev->aen_head = TW_Q_START;
298 tw_dev->aen_head = tw_dev->aen_head + 1;
302 error = tw_aen_read_queue(tw_dev, request_id);
304 printk(KERN_WARNING "3w-xxxx: scsi%d: Error completing AEN.\n", tw_dev->host->host_no);
305 tw_dev->state[request_id] = TW_S_COMPLETED;
306 tw_state_request_finish(tw_dev, request_id);
309 tw_dev->state[request_id] = TW_S_COMPLETED;
310 tw_state_request_finish(tw_dev, request_id);
314 } /* End tw_aen_complete() */
316 /* This function will drain the aen queue after a soft reset */
317 int tw_aen_drain_queue(TW_Device_Extension *tw_dev)
319 TW_Command *command_packet;
322 u32 command_que_addr;
323 unsigned long command_que_value;
324 unsigned long param_value;
325 TW_Response_Queue response_queue;
326 u32 response_que_addr;
328 unsigned short aen_code;
332 int found = 0, table_max = 0;
334 dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue()\n");
336 command_que_addr = tw_dev->registers.command_que_addr;
337 response_que_addr = tw_dev->registers.response_que_addr;
339 if (tw_poll_status(tw_dev, TW_STATUS_ATTENTION_INTERRUPT | TW_STATUS_MICROCONTROLLER_READY, 30)) {
340 dprintk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): No attention interrupt for card %d.\n", tw_device_extension_count);
343 tw_clear_attention_interrupt(tw_dev);
345 /* Empty response queue */
346 tw_empty_response_que(tw_dev);
348 /* Initialize command packet */
349 if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
350 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad command packet virtual address.\n");
353 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
354 memset(command_packet, 0, sizeof(TW_Sector));
355 command_packet->byte0.opcode = TW_OP_GET_PARAM;
356 command_packet->byte0.sgl_offset = 2;
357 command_packet->size = 4;
358 command_packet->request_id = request_id;
359 command_packet->byte3.unit = 0;
360 command_packet->byte3.host_id = 0;
361 command_packet->status = 0;
362 command_packet->flags = 0;
363 command_packet->byte6.parameter_count = 1;
364 command_que_value = tw_dev->command_packet_physical_address[request_id];
365 if (command_que_value == 0) {
366 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad command packet physical address.\n");
370 /* Now setup the param */
371 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
372 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad alignment virtual address.\n");
375 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
376 memset(param, 0, sizeof(TW_Sector));
377 param->table_id = 0x401; /* AEN table */
378 param->parameter_id = 2; /* Unit code */
379 param->parameter_size_bytes = 2;
380 param_value = tw_dev->alignment_physical_address[request_id];
381 if (param_value == 0) {
382 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad alignment physical address.\n");
385 command_packet->byte8.param.sgl[0].address = param_value;
386 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
388 /* Now drain the controller's aen queue */
390 /* Post command packet */
391 outl(command_que_value, command_que_addr);
393 /* Now poll for completion */
394 if (tw_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, 30) == 0) {
395 response_queue.value = inl(response_que_addr);
396 request_id = (unsigned char)response_queue.u.response_id;
397 if (request_id != 0) {
398 /* Unexpected request id */
399 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Unexpected request id.\n");
403 if (command_packet->status != 0) {
404 if (command_packet->flags != TW_AEN_TABLE_UNDEFINED) {
406 tw_decode_sense(tw_dev, request_id, 0);
409 /* We know this is a 3w-1x00, and doesn't support aen's */
414 /* Now check the aen */
415 aen = *(unsigned short *)(param->data);
416 aen_code = (aen & 0x0ff);
419 case TW_AEN_QUEUE_EMPTY:
420 dprintk(KERN_WARNING "3w-xxxx: AEN: %s.\n", tw_aen_string[aen & 0xff]);
421 if (first_reset != 1) {
427 case TW_AEN_SOFT_RESET:
428 if (first_reset == 0) {
431 printk(KERN_WARNING "3w-xxxx: AEN: %s.\n", tw_aen_string[aen & 0xff]);
438 printk(KERN_WARNING "3w-xxxx: AEN: INFO: AEN queue overflow.\n");
440 table_max = sizeof(tw_aen_string)/sizeof(char *);
441 if ((aen & 0x0ff) < table_max) {
442 if ((tw_aen_string[aen & 0xff][strlen(tw_aen_string[aen & 0xff])-1]) == '#') {
443 printk(KERN_WARNING "3w-xxxx: AEN: %s%d.\n", tw_aen_string[aen & 0xff], aen >> 8);
445 printk(KERN_WARNING "3w-xxxx: AEN: %s.\n", tw_aen_string[aen & 0xff]);
448 printk(KERN_WARNING "3w-xxxx: Received AEN %d.\n", aen);
454 /* Now put the aen on the aen_queue */
456 tw_dev->aen_queue[tw_dev->aen_tail] = aen;
457 if (tw_dev->aen_tail == TW_Q_LENGTH - 1) {
458 tw_dev->aen_tail = TW_Q_START;
460 tw_dev->aen_tail = tw_dev->aen_tail + 1;
462 if (tw_dev->aen_head == tw_dev->aen_tail) {
463 if (tw_dev->aen_head == TW_Q_LENGTH - 1) {
464 tw_dev->aen_head = TW_Q_START;
466 tw_dev->aen_head = tw_dev->aen_head + 1;
473 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Response never received.\n");
476 } while (finished == 0);
479 } /* End tw_aen_drain_queue() */
481 /* This function will read the aen queue from the isr */
482 int tw_aen_read_queue(TW_Device_Extension *tw_dev, int request_id)
484 TW_Command *command_packet;
486 u32 command_que_addr;
487 unsigned long command_que_value;
488 u32 status_reg_value = 0, status_reg_addr;
489 unsigned long param_value = 0;
491 dprintk(KERN_NOTICE "3w-xxxx: tw_aen_read_queue()\n");
492 command_que_addr = tw_dev->registers.command_que_addr;
493 status_reg_addr = tw_dev->registers.status_reg_addr;
495 status_reg_value = inl(status_reg_addr);
496 if (tw_check_bits(status_reg_value)) {
497 dprintk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Unexpected bits.\n");
498 tw_decode_bits(tw_dev, status_reg_value, 1);
501 if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
502 printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad command packet virtual address.\n");
505 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
506 memset(command_packet, 0, sizeof(TW_Sector));
507 command_packet->byte0.opcode = TW_OP_GET_PARAM;
508 command_packet->byte0.sgl_offset = 2;
509 command_packet->size = 4;
510 command_packet->request_id = request_id;
511 command_packet->byte3.unit = 0;
512 command_packet->byte3.host_id = 0;
513 command_packet->status = 0;
514 command_packet->flags = 0;
515 command_packet->byte6.parameter_count = 1;
516 command_que_value = tw_dev->command_packet_physical_address[request_id];
517 if (command_que_value == 0) {
518 printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad command packet physical address.\n");
521 /* Now setup the param */
522 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
523 printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad alignment virtual address.\n");
526 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
527 memset(param, 0, sizeof(TW_Sector));
528 param->table_id = 0x401; /* AEN table */
529 param->parameter_id = 2; /* Unit code */
530 param->parameter_size_bytes = 2;
531 param_value = tw_dev->alignment_physical_address[request_id];
532 if (param_value == 0) {
533 printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad alignment physical address.\n");
536 command_packet->byte8.param.sgl[0].address = param_value;
537 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
539 /* Now post the command packet */
540 if ((status_reg_value & TW_STATUS_COMMAND_QUEUE_FULL) == 0) {
541 dprintk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Post succeeded.\n");
542 tw_dev->srb[request_id] = 0; /* Flag internal command */
543 tw_dev->state[request_id] = TW_S_POSTED;
544 outl(command_que_value, command_que_addr);
546 printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Post failed, will retry.\n");
551 } /* End tw_aen_read_queue() */
553 /* This function will allocate memory and check if it is 16 d-word aligned */
554 int tw_allocate_memory(TW_Device_Extension *tw_dev, int size, int which)
557 dma_addr_t dma_handle;
558 unsigned long *cpu_addr = NULL;
560 dprintk(KERN_NOTICE "3w-xxxx: tw_allocate_memory()\n");
564 imax = TW_MAX_BOUNCEBUF;
568 cpu_addr = pci_alloc_consistent(tw_dev->tw_pci_dev, size*imax, &dma_handle);
569 if (cpu_addr == NULL) {
570 printk(KERN_WARNING "3w-xxxx: pci_alloc_consistent() failed.\n");
574 if ((unsigned long)cpu_addr % (tw_dev->tw_pci_dev->device == TW_DEVICE_ID ? TW_ALIGNMENT_6000 : TW_ALIGNMENT_7000)) {
575 printk(KERN_WARNING "3w-xxxx: Couldn't allocate correctly aligned memory.\n");
576 pci_free_consistent(tw_dev->tw_pci_dev, size*imax, cpu_addr, dma_handle);
580 memset(cpu_addr, 0, size*imax);
582 for (i=0;i<imax;i++) {
585 tw_dev->command_packet_physical_address[i] = dma_handle+(i*size);
586 tw_dev->command_packet_virtual_address[i] = (unsigned long *)((unsigned char *)cpu_addr + (i*size));
589 tw_dev->alignment_physical_address[i] = dma_handle+(i*size);
590 tw_dev->alignment_virtual_address[i] = (unsigned long *)((unsigned char *)cpu_addr + (i*size));
593 tw_dev->bounce_buffer_phys[i] = dma_handle+(i*size);
594 tw_dev->bounce_buffer[i] = (unsigned long *)((unsigned char *)cpu_addr + (i*size));
597 printk(KERN_WARNING "3w-xxxx: tw_allocate_memory(): case slip in tw_allocate_memory()\n");
603 } /* End tw_allocate_memory() */
605 /* This function will check the status register for unexpected bits */
606 int tw_check_bits(u32 status_reg_value)
608 if ((status_reg_value & TW_STATUS_EXPECTED_BITS) != TW_STATUS_EXPECTED_BITS) {
609 dprintk(KERN_WARNING "3w-xxxx: tw_check_bits(): No expected bits (0x%x).\n", status_reg_value);
612 if ((status_reg_value & TW_STATUS_UNEXPECTED_BITS) != 0) {
613 dprintk(KERN_WARNING "3w-xxxx: tw_check_bits(): Found unexpected bits (0x%x).\n", status_reg_value);
618 } /* End tw_check_bits() */
620 /* This function will report controller error status */
621 int tw_check_errors(TW_Device_Extension *tw_dev)
623 u32 status_reg_addr, status_reg_value;
625 status_reg_addr = tw_dev->registers.status_reg_addr;
626 status_reg_value = inl(status_reg_addr);
628 if (TW_STATUS_ERRORS(status_reg_value) || tw_check_bits(status_reg_value)) {
629 tw_decode_bits(tw_dev, status_reg_value, 0);
634 } /* End tw_check_errors() */
636 /* This function handles ioctl for the character device */
637 static int tw_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
639 int error, request_id;
640 dma_addr_t dma_handle;
641 unsigned short tw_aen_code;
643 unsigned int data_buffer_length = 0;
644 unsigned long data_buffer_length_adjusted = 0;
645 unsigned long *cpu_addr;
647 TW_New_Ioctl *tw_ioctl;
648 TW_Passthru *passthru;
649 TW_Device_Extension *tw_dev = tw_device_extension_list[MINOR(inode->i_rdev)];
650 int retval = -EFAULT;
652 dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl()\n");
654 /* Only let one of these through at a time */
655 if (down_interruptible(&tw_dev->ioctl_sem))
658 /* First copy down the buffer length */
659 error = copy_from_user(&data_buffer_length, (void *)arg, sizeof(unsigned int));
664 if (data_buffer_length > TW_MAX_SECTORS * 512) {
669 /* Hardware can only do multiple of 512 byte transfers */
670 data_buffer_length_adjusted = (data_buffer_length + 511) & ~511;
672 /* Now allocate ioctl buf memory */
673 cpu_addr = pci_alloc_consistent(tw_dev->tw_pci_dev, data_buffer_length_adjusted+sizeof(TW_New_Ioctl) - 1, &dma_handle);
674 if (cpu_addr == NULL) {
679 tw_ioctl = (TW_New_Ioctl *)cpu_addr;
681 /* Now copy down the entire ioctl */
682 error = copy_from_user(tw_ioctl, (void *)arg, data_buffer_length + sizeof(TW_New_Ioctl) - 1);
686 passthru = (TW_Passthru *)&tw_ioctl->firmware_command;
688 /* See which ioctl we are doing */
691 dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl(): caught TW_OP_NOP.\n");
693 case TW_OP_AEN_LISTEN:
694 dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl(): caught TW_AEN_LISTEN.\n");
695 memset(tw_ioctl->data_buffer, 0, tw_ioctl->data_buffer_length);
696 spin_lock_irqsave(&tw_dev->tw_lock, flags);
697 if (tw_dev->aen_head == tw_dev->aen_tail) {
698 tw_aen_code = TW_AEN_QUEUE_EMPTY;
700 tw_aen_code = tw_dev->aen_queue[tw_dev->aen_head];
701 if (tw_dev->aen_head == TW_Q_LENGTH - 1) {
702 tw_dev->aen_head = TW_Q_START;
704 tw_dev->aen_head = tw_dev->aen_head + 1;
707 spin_unlock_irqrestore(&tw_dev->tw_lock, flags);
708 memcpy(tw_ioctl->data_buffer, &tw_aen_code, sizeof(tw_aen_code));
710 case TW_CMD_PACKET_WITH_DATA:
711 dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl(): caught TW_CMD_PACKET_WITH_DATA.\n");
712 spin_lock_irqsave(&tw_dev->tw_lock, flags);
714 tw_state_request_start(tw_dev, &request_id);
716 /* Flag internal command */
717 tw_dev->srb[request_id] = 0;
719 /* Flag chrdev ioctl */
720 tw_dev->chrdev_request_id = request_id;
722 tw_ioctl->firmware_command.request_id = request_id;
724 /* Load the sg list */
725 switch (tw_ioctl->firmware_command.byte0.sgl_offset) {
727 tw_ioctl->firmware_command.byte8.param.sgl[0].address = dma_handle + sizeof(TW_New_Ioctl) - 1;
728 tw_ioctl->firmware_command.byte8.param.sgl[0].length = data_buffer_length_adjusted;
731 tw_ioctl->firmware_command.byte8.io.sgl[0].address = dma_handle + sizeof(TW_New_Ioctl) - 1;
732 tw_ioctl->firmware_command.byte8.io.sgl[0].length = data_buffer_length_adjusted;
735 passthru->sg_list[0].address = dma_handle + sizeof(TW_New_Ioctl) - 1;
736 passthru->sg_list[0].length = data_buffer_length_adjusted;
740 memcpy(tw_dev->command_packet_virtual_address[request_id], &(tw_ioctl->firmware_command), sizeof(TW_Command));
742 /* Now post the command packet to the controller */
743 tw_post_command_packet(tw_dev, request_id);
744 spin_unlock_irqrestore(&tw_dev->tw_lock, flags);
746 timeout = TW_IOCTL_CHRDEV_TIMEOUT*HZ;
748 /* Now wait for the command to complete */
749 tw_wait_event_interruptible_timeout(tw_dev->ioctl_wqueue, tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE, timeout);
751 /* Check if we timed out, got a signal, or didn't get
753 if ((timeout <= 0) && (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE)) {
754 /* Now we need to reset the board */
755 if (timeout == -ERESTARTSYS) {
758 printk(KERN_WARNING "3w-xxxx: scsi%d: Character ioctl (0x%x) timed out, resetting card.\n", tw_dev->host->host_no, cmd);
761 spin_lock_irqsave(&tw_dev->tw_lock, flags);
762 tw_dev->state[request_id] = TW_S_COMPLETED;
763 tw_state_request_finish(tw_dev, request_id);
764 tw_dev->posted_request_count--;
765 if (tw_reset_device_extension(tw_dev)) {
766 printk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl(): Reset failed for card %d.\n", tw_dev->host->host_no);
768 spin_unlock_irqrestore(&tw_dev->tw_lock, flags);
772 /* Now copy in the command packet response */
773 memcpy(&(tw_ioctl->firmware_command), tw_dev->command_packet_virtual_address[request_id], sizeof(TW_Command));
775 /* Now complete the io */
776 spin_lock_irqsave(&tw_dev->tw_lock, flags);
777 tw_dev->posted_request_count--;
778 tw_dev->state[request_id] = TW_S_COMPLETED;
779 tw_state_request_finish(tw_dev, request_id);
780 spin_unlock_irqrestore(&tw_dev->tw_lock, flags);
787 /* Now copy the entire response to userspace */
788 error = copy_to_user((void *)arg, tw_ioctl, sizeof(TW_New_Ioctl) + tw_ioctl->data_buffer_length - 1);
792 /* Now free ioctl buf memory */
793 pci_free_consistent(tw_dev->tw_pci_dev, data_buffer_length_adjusted+sizeof(TW_New_Ioctl) - 1, cpu_addr, dma_handle);
795 up(&tw_dev->ioctl_sem);
797 } /* End tw_chrdev_ioctl() */
799 /* This function handles open for the character device */
800 static int tw_chrdev_open(struct inode *inode, struct file *file)
802 unsigned int minor_number;
804 dprintk(KERN_WARNING "3w-xxxx: tw_ioctl_open()\n");
806 minor_number = MINOR(inode->i_rdev);
807 if (minor_number >= tw_device_extension_count)
811 } /* End tw_chrdev_open() */
813 /* This function handles close for the character device */
814 static int tw_chrdev_release(struct inode *inode, struct file *file)
816 dprintk(KERN_WARNING "3w-xxxx: tw_ioctl_release()\n");
819 } /* End tw_chrdev_release() */
821 /* This function will clear all interrupts on the controller */
822 void tw_clear_all_interrupts(TW_Device_Extension *tw_dev)
824 u32 control_reg_addr, control_reg_value;
826 control_reg_addr = tw_dev->registers.control_reg_addr;
827 control_reg_value = TW_STATUS_VALID_INTERRUPT;
828 outl(control_reg_value, control_reg_addr);
829 } /* End tw_clear_all_interrupts() */
831 /* This function will clear the attention interrupt */
832 void tw_clear_attention_interrupt(TW_Device_Extension *tw_dev)
834 u32 control_reg_addr, control_reg_value;
836 control_reg_addr = tw_dev->registers.control_reg_addr;
837 control_reg_value = TW_CONTROL_CLEAR_ATTENTION_INTERRUPT;
838 outl(control_reg_value, control_reg_addr);
839 } /* End tw_clear_attention_interrupt() */
841 /* This function will clear the host interrupt */
842 void tw_clear_host_interrupt(TW_Device_Extension *tw_dev)
844 u32 control_reg_addr, control_reg_value;
846 control_reg_addr = tw_dev->registers.control_reg_addr;
847 control_reg_value = TW_CONTROL_CLEAR_HOST_INTERRUPT;
848 outl(control_reg_value, control_reg_addr);
849 } /* End tw_clear_host_interrupt() */
851 /* This function is called by tw_scsi_proc_info */
852 static int tw_copy_info(TW_Info *info, char *fmt, ...)
859 len = vsprintf(buf, fmt, args);
861 tw_copy_mem_info(info, buf, len);
863 } /* End tw_copy_info() */
865 /* This function is called by tw_scsi_proc_info */
866 static void tw_copy_mem_info(TW_Info *info, char *data, int len)
868 if (info->position + len > info->length)
869 len = info->length - info->position;
871 if (info->position + len < info->offset) {
872 info->position += len;
875 if (info->position < info->offset) {
876 data += (info->offset - info->position);
877 len -= (info->offset - info->position);
880 memcpy(info->buffer + info->position, data, len);
881 info->position += len;
883 } /* End tw_copy_mem_info() */
885 /* This function will print readable messages from status register errors */
886 int tw_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value, int print_host)
890 dprintk(KERN_WARNING "3w-xxxx: tw_decode_bits()\n");
893 sprintf(host, " scsi%d:", tw_dev->host->host_no);
897 if (status_reg_value & TW_STATUS_PCI_PARITY_ERROR) {
898 printk(KERN_WARNING "3w-xxxx:%s PCI Parity Error: clearing.\n", host);
899 outl(TW_CONTROL_CLEAR_PARITY_ERROR, tw_dev->registers.control_reg_addr);
902 if (status_reg_value & TW_STATUS_PCI_ABORT) {
903 printk(KERN_WARNING "3w-xxxx:%s PCI Abort: clearing.\n", host);
904 outl(TW_CONTROL_CLEAR_PCI_ABORT, tw_dev->registers.control_reg_addr);
905 pci_write_config_word(tw_dev->tw_pci_dev, PCI_STATUS, TW_PCI_CLEAR_PCI_ABORT);
908 if (status_reg_value & TW_STATUS_QUEUE_ERROR) {
909 printk(KERN_WARNING "3w-xxxx:%s Controller Queue Error: clearing.\n", host);
910 outl(TW_CONTROL_CLEAR_QUEUE_ERROR, tw_dev->registers.control_reg_addr);
913 if (status_reg_value & TW_STATUS_SBUF_WRITE_ERROR) {
914 printk(KERN_WARNING "3w-xxxx:%s SBUF Write Error: clearing.\n", host);
915 outl(TW_CONTROL_CLEAR_SBUF_WRITE_ERROR, tw_dev->registers.control_reg_addr);
918 if (status_reg_value & TW_STATUS_MICROCONTROLLER_ERROR) {
919 if (tw_dev->reset_print == 0) {
920 printk(KERN_WARNING "3w-xxxx:%s Microcontroller Error: clearing.\n", host);
921 tw_dev->reset_print = 1;
927 } /* End tw_decode_bits() */
929 /* This function will return valid sense buffer information for failed cmds */
930 int tw_decode_sense(TW_Device_Extension *tw_dev, int request_id, int fill_sense)
935 dprintk(KERN_WARNING "3w-xxxx: tw_decode_sense()\n");
936 command = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
938 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);
940 /* Attempt to return intelligent sense information */
942 if ((command->status == 0xc7) || (command->status == 0xcb)) {
943 for (i=0;i<(sizeof(tw_sense_table)/sizeof(tw_sense_table[0]));i++) {
944 if (command->flags == tw_sense_table[i][0]) {
946 /* Valid bit and 'current errors' */
947 tw_dev->srb[request_id]->sense_buffer[0] = (0x1 << 7 | 0x70);
950 tw_dev->srb[request_id]->sense_buffer[2] = tw_sense_table[i][1];
952 /* Additional sense length */
953 tw_dev->srb[request_id]->sense_buffer[7] = 0xa; /* 10 bytes */
955 /* Additional sense code */
956 tw_dev->srb[request_id]->sense_buffer[12] = tw_sense_table[i][2];
958 /* Additional sense code qualifier */
959 tw_dev->srb[request_id]->sense_buffer[13] = tw_sense_table[i][3];
961 tw_dev->srb[request_id]->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
962 return TW_ISR_DONT_RESULT; /* Special case for isr to not over-write result */
967 /* If no table match, error so we get a reset */
972 } /* End tw_decode_sense() */
974 /* This function will disable interrupts on the controller */
975 void tw_disable_interrupts(TW_Device_Extension *tw_dev)
977 u32 control_reg_value, control_reg_addr;
979 control_reg_addr = tw_dev->registers.control_reg_addr;
980 control_reg_value = TW_CONTROL_DISABLE_INTERRUPTS;
981 outl(control_reg_value, control_reg_addr);
982 } /* End tw_disable_interrupts() */
984 /* This function will empty the response que */
985 void tw_empty_response_que(TW_Device_Extension *tw_dev)
987 u32 status_reg_addr, status_reg_value;
988 u32 response_que_addr, response_que_value;
990 status_reg_addr = tw_dev->registers.status_reg_addr;
991 response_que_addr = tw_dev->registers.response_que_addr;
993 status_reg_value = inl(status_reg_addr);
995 while ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
996 response_que_value = inl(response_que_addr);
997 status_reg_value = inl(status_reg_addr);
999 } /* End tw_empty_response_que() */
1001 /* This function will enable interrupts on the controller */
1002 void tw_enable_interrupts(TW_Device_Extension *tw_dev)
1004 u32 control_reg_value, control_reg_addr;
1006 control_reg_addr = tw_dev->registers.control_reg_addr;
1007 control_reg_value = (TW_CONTROL_ENABLE_INTERRUPTS |
1008 TW_CONTROL_UNMASK_RESPONSE_INTERRUPT);
1009 outl(control_reg_value, control_reg_addr);
1010 } /* End tw_enable_interrupts() */
1012 /* This function will enable interrupts on the controller */
1013 void tw_enable_and_clear_interrupts(TW_Device_Extension *tw_dev)
1015 u32 control_reg_value, control_reg_addr;
1017 control_reg_addr = tw_dev->registers.control_reg_addr;
1018 control_reg_value = (TW_CONTROL_CLEAR_ATTENTION_INTERRUPT |
1019 TW_CONTROL_UNMASK_RESPONSE_INTERRUPT |
1020 TW_CONTROL_ENABLE_INTERRUPTS);
1021 outl(control_reg_value, control_reg_addr);
1022 } /* End tw_enable_and_clear_interrupts() */
1024 /* This function will find and initialize all cards */
1025 int tw_findcards(Scsi_Host_Template *tw_host)
1027 int numcards = 0, tries = 0, error = 0;
1028 struct Scsi_Host *host;
1029 TW_Device_Extension *tw_dev;
1030 TW_Device_Extension *tw_dev2;
1031 struct pci_dev *tw_pci_dev = NULL;
1032 u32 status_reg_value;
1033 unsigned char c = 1;
1035 u16 device[TW_NUMDEVICES] = { TW_DEVICE_ID, TW_DEVICE_ID2 };
1037 dprintk(KERN_NOTICE "3w-xxxx: tw_findcards()\n");
1039 for (i=0;i<TW_NUMDEVICES;i++) {
1040 while ((tw_pci_dev = pci_find_device(TW_VENDOR_ID, device[i], tw_pci_dev))) {
1042 if (pci_enable_device(tw_pci_dev))
1045 /* We only need 32-bit addressing for 5,6,7xxx cards */
1046 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4)
1047 if (pci_set_dma_mask(tw_pci_dev, 0xffffffff)) {
1048 printk(KERN_WARNING "3w-xxxx: No suitable DMA available.\n");
1053 /* Prepare temporary device extension */
1054 tw_dev=(TW_Device_Extension *)kmalloc(sizeof(TW_Device_Extension), GFP_ATOMIC);
1055 if (tw_dev == NULL) {
1056 printk(KERN_WARNING "3w-xxxx: tw_findcards(): kmalloc() failed for card %d.\n", j);
1059 memset(tw_dev, 0, sizeof(TW_Device_Extension));
1061 /* Save pci_dev struct to device extension */
1062 tw_dev->tw_pci_dev = tw_pci_dev;
1064 error = tw_initialize_device_extension(tw_dev);
1066 printk(KERN_WARNING "3w-xxxx: tw_findcards(): Couldn't initialize device extension for card %d.\n", j);
1067 tw_free_device_extension(tw_dev);
1072 /* Calculate the cards register addresses */
1073 tw_dev->registers.base_addr = pci_resource_start(tw_pci_dev, 0);
1074 tw_dev->registers.control_reg_addr = pci_resource_start(tw_pci_dev, 0);
1075 tw_dev->registers.status_reg_addr = pci_resource_start(tw_pci_dev, 0) + 0x4;
1076 tw_dev->registers.command_que_addr = pci_resource_start(tw_pci_dev, 0) + 0x8;
1077 tw_dev->registers.response_que_addr = pci_resource_start(tw_pci_dev, 0) + 0xC;
1079 /* Check for errors and clear them */
1080 status_reg_value = inl(tw_dev->registers.status_reg_addr);
1081 if (TW_STATUS_ERRORS(status_reg_value))
1082 tw_decode_bits(tw_dev, status_reg_value, 0);
1084 /* Poll status register for 60 secs for 'Controller Ready' flag */
1085 if (tw_poll_status(tw_dev, TW_STATUS_MICROCONTROLLER_READY, 60)) {
1086 printk(KERN_WARNING "3w-xxxx: tw_findcards(): Microcontroller not ready for card %d.\n", j);
1087 tw_free_device_extension(tw_dev);
1092 /* Disable interrupts on the card */
1093 tw_disable_interrupts(tw_dev);
1097 while (tries < TW_MAX_RESET_TRIES) {
1099 tw_soft_reset(tw_dev);
1101 error = tw_aen_drain_queue(tw_dev);
1103 printk(KERN_WARNING "3w-xxxx: AEN drain failed for card %d.\n", j);
1108 /* Check for controller errors */
1109 if (tw_check_errors(tw_dev)) {
1110 printk(KERN_WARNING "3w-xxxx: Controller errors found, retrying for card %d.\n", j);
1115 /* Now the controller is in a good state */
1119 if (tries >= TW_MAX_RESET_TRIES) {
1120 printk(KERN_WARNING "3w-xxxx: Controller errors, card not responding, check all cabling for card %d.\n", j);
1121 tw_free_device_extension(tw_dev);
1126 /* Make sure that io region isn't already taken */
1127 if (check_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE)) {
1128 printk(KERN_WARNING "3w-xxxx: tw_findcards(): Couldn't get io range 0x%lx-0x%lx for card %d.\n",
1129 (tw_dev->tw_pci_dev->resource[0].start),
1130 (tw_dev->tw_pci_dev->resource[0].start) +
1131 TW_IO_ADDRESS_RANGE, j);
1132 tw_free_device_extension(tw_dev);
1137 /* Reserve the io address space */
1138 request_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE, TW_DEVICE_NAME);
1139 error = tw_initialize_units(tw_dev);
1141 printk(KERN_WARNING "3w-xxxx: No valid units for card %d.\n", j);
1144 error = tw_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS);
1146 printk(KERN_WARNING "3w-xxxx: Connection initialization failed for card %d.\n", j);
1147 release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
1148 tw_free_device_extension(tw_dev);
1153 /* Set card status as online */
1156 /* Calculate max cmds per lun, and setup queues */
1157 if ((tw_dev->num_raid_five > 0) && (tw_dev->tw_pci_dev->device == TW_DEVICE_ID)) {
1158 tw_host->cmd_per_lun = (TW_MAX_BOUNCEBUF-2)/tw_dev->num_units;
1159 tw_dev->free_head = TW_Q_START;
1160 tw_dev->free_tail = TW_Q_START;
1161 tw_dev->free_wrap = TW_MAX_BOUNCEBUF - 1;
1163 /* Check for user configured cmd_per_lun */
1164 #ifdef CONFIG_3W_XXXX_CMD_PER_LUN
1165 tw_host->cmd_per_lun = CONFIG_3W_XXXX_CMD_PER_LUN;
1166 if (tw_host->cmd_per_lun > TW_MAX_CMDS_PER_LUN)
1167 tw_host->cmd_per_lun = TW_MAX_CMDS_PER_LUN;
1169 /* Use SHT cmd_per_lun default */
1170 tw_host->cmd_per_lun = TW_MAX_CMDS_PER_LUN;
1172 tw_dev->free_head = TW_Q_START;
1173 tw_dev->free_tail = TW_Q_START;
1174 tw_dev->free_wrap = TW_Q_LENGTH - 1;
1177 /* Register the card with the kernel SCSI layer */
1178 host = scsi_register(tw_host, sizeof(TW_Device_Extension));
1180 printk(KERN_WARNING "3w-xxxx: tw_findcards(): scsi_register() failed for card %d.\n", j);
1181 release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
1182 tw_free_device_extension(tw_dev);
1187 /* Set max target id's */
1188 host->max_id = TW_MAX_UNITS;
1190 /* Set max cdb size in bytes */
1191 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,15)
1192 host->max_cmd_len = TW_MAX_CDB_LEN;
1195 /* Set max sectors per io */
1196 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7)
1197 if ((tw_dev->num_raid_five > 0) && (tw_dev->tw_pci_dev->device == TW_DEVICE_ID))
1198 host->max_sectors = TW_MAX_BOUNCE_SECTORS;
1200 host->max_sectors = TW_MAX_SECTORS;
1203 host->select_queue_depths = tw_select_queue_depths;
1205 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4)
1206 scsi_set_pci_device(host, tw_pci_dev);
1209 status_reg_value = inl(tw_dev->registers.status_reg_addr);
1211 printk(KERN_NOTICE "scsi%d : Found a 3ware Storage Controller at 0x%x, IRQ: %d, P-chip: %d.%d\n", host->host_no,
1212 (u32)(tw_pci_dev->resource[0].start), tw_pci_dev->irq,
1213 (status_reg_value & TW_STATUS_MAJOR_VERSION_MASK) >> 28,
1214 (status_reg_value & TW_STATUS_MINOR_VERSION_MASK) >> 24);
1216 if (host->hostdata) {
1217 tw_dev2 = (TW_Device_Extension *)host->hostdata;
1218 memcpy(tw_dev2, tw_dev, sizeof(TW_Device_Extension));
1219 /* Need to init the sem/wqueue after the copy */
1220 init_MUTEX(&tw_dev2->ioctl_sem);
1221 init_waitqueue_head(&tw_dev2->ioctl_wqueue);
1223 tw_device_extension_list[tw_device_extension_count] = tw_dev2;
1225 tw_device_extension_count = numcards;
1226 tw_dev2->host = host;
1228 printk(KERN_WARNING "3w-xxxx: tw_findcards(): Bad scsi host data for card %d.\n", j);
1229 scsi_unregister(host);
1230 release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
1231 tw_free_device_extension(tw_dev);
1236 /* Tell the firmware we support shutdown notification*/
1237 error = tw_setfeature(tw_dev2, 2, 1, &c);
1239 printk(KERN_WARNING "3w-xxxx: Unable to set features for card %d, old firmware or card.\n", j);
1242 /* Now setup the interrupt handler */
1243 error = tw_setup_irq(tw_dev2);
1245 printk(KERN_WARNING "3w-xxxx: tw_findcards(): Error requesting irq for card %d.\n", j);
1246 scsi_unregister(host);
1247 release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
1249 tw_free_device_extension(tw_dev);
1255 /* Re-enable interrupts on the card */
1256 tw_enable_interrupts(tw_dev2);
1258 /* Free the temporary device extension */
1264 if (numcards == 0) {
1265 printk(KERN_WARNING "3w-xxxx: No cards found.\n");
1267 register_reboot_notifier(&tw_notifier);
1268 if ((twe_major = register_chrdev (0, "twe", &tw_fops)) < 0) {
1269 printk(KERN_WARNING "3w-xxxx: Unable to register \"twe\" character device, error = %d.\n", twe_major);
1274 } /* End tw_findcards() */
1276 /* This function will free up device extension resources */
1277 void tw_free_device_extension(TW_Device_Extension *tw_dev)
1279 dprintk(KERN_NOTICE "3w-xxxx: tw_free_device_extension()\n");
1281 /* Free command packet and generic buffer memory */
1282 if (tw_dev->command_packet_physical_address[0])
1283 pci_free_consistent(tw_dev->tw_pci_dev, sizeof(TW_Command)*TW_Q_LENGTH, tw_dev->command_packet_virtual_address[0], tw_dev->command_packet_physical_address[0]);
1285 if (tw_dev->alignment_physical_address[0])
1286 pci_free_consistent(tw_dev->tw_pci_dev, sizeof(TW_Sector)*TW_Q_LENGTH, tw_dev->alignment_virtual_address[0], tw_dev->alignment_physical_address[0]);
1288 if (tw_dev->bounce_buffer[0])
1289 pci_free_consistent(tw_dev->tw_pci_dev, sizeof(TW_Sector)*TW_MAX_BOUNCE_SECTORS*TW_MAX_BOUNCEBUF, tw_dev->bounce_buffer[0], tw_dev->bounce_buffer_phys[0]);
1290 } /* End tw_free_device_extension() */
1292 /* Clean shutdown routine */
1293 static int tw_halt(struct notifier_block *nb, ulong event, void *buf)
1297 for (i=0;i<tw_device_extension_count;i++) {
1298 if (tw_device_extension_list[i]->online == 1) {
1299 printk(KERN_NOTICE "3w-xxxx: Shutting down card %d.\n", i);
1300 tw_shutdown_device(tw_device_extension_list[i]);
1301 tw_device_extension_list[i]->online = 0;
1304 unregister_reboot_notifier(&tw_notifier);
1307 } /* End tw_halt() */
1309 /* This function will send an initconnection command to controller */
1310 int tw_initconnection(TW_Device_Extension *tw_dev, int message_credits)
1312 unsigned long command_que_value;
1313 u32 command_que_addr;
1314 u32 response_que_addr;
1315 TW_Command *command_packet;
1316 TW_Response_Queue response_queue;
1319 dprintk(KERN_NOTICE "3w-xxxx: tw_initconnection()\n");
1320 command_que_addr = tw_dev->registers.command_que_addr;
1321 response_que_addr = tw_dev->registers.response_que_addr;
1323 /* Initialize InitConnection command packet */
1324 if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
1325 printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad command packet virtual address.\n");
1329 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1330 memset(command_packet, 0, sizeof(TW_Sector));
1331 command_packet->byte0.opcode = TW_OP_INIT_CONNECTION;
1332 command_packet->byte0.sgl_offset = 0x0;
1333 command_packet->size = TW_INIT_COMMAND_PACKET_SIZE;
1334 command_packet->request_id = request_id;
1335 command_packet->byte3.unit = 0x0;
1336 command_packet->byte3.host_id = 0x0;
1337 command_packet->status = 0x0;
1338 command_packet->flags = 0x0;
1339 command_packet->byte6.message_credits = message_credits;
1340 command_packet->byte8.init_connection.response_queue_pointer = 0x0;
1341 command_que_value = tw_dev->command_packet_physical_address[request_id];
1343 if (command_que_value == 0) {
1344 printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad command packet physical address.\n");
1348 /* Send command packet to the board */
1349 outl(command_que_value, command_que_addr);
1351 /* Poll for completion */
1352 if (tw_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, 30) == 0) {
1353 response_queue.value = inl(response_que_addr);
1354 request_id = (unsigned char)response_queue.u.response_id;
1355 if (request_id != 0) {
1356 /* unexpected request id */
1357 printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Unexpected request id.\n");
1360 if (command_packet->status != 0) {
1362 tw_decode_sense(tw_dev, request_id, 0);
1367 } /* End tw_initconnection() */
1369 /* This function will initialize the fields of a device extension */
1370 int tw_initialize_device_extension(TW_Device_Extension *tw_dev)
1374 dprintk(KERN_NOTICE "3w-xxxx: tw_initialize_device_extension()\n");
1376 /* Initialize command packet buffers */
1377 error = tw_allocate_memory(tw_dev, sizeof(TW_Command), 0);
1379 printk(KERN_WARNING "3w-xxxx: Command packet memory allocation failed.\n");
1383 /* Initialize generic buffer */
1384 error = tw_allocate_memory(tw_dev, sizeof(TW_Sector), 1);
1386 printk(KERN_WARNING "3w-xxxx: Generic memory allocation failed.\n");
1390 for (i=0;i<TW_Q_LENGTH;i++) {
1391 tw_dev->free_queue[i] = i;
1392 tw_dev->state[i] = TW_S_INITIAL;
1395 tw_dev->pending_head = TW_Q_START;
1396 tw_dev->pending_tail = TW_Q_START;
1397 spin_lock_init(&tw_dev->tw_lock);
1398 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1401 } /* End tw_initialize_device_extension() */
1403 /* This function will get unit info from the controller */
1404 int tw_initialize_units(TW_Device_Extension *tw_dev)
1406 int found = 0, error = 0;
1407 unsigned char request_id = 0;
1408 TW_Command *command_packet;
1410 int i, j, imax, num_units = 0, num_raid_five = 0;
1411 unsigned long command_que_value;
1412 u32 command_que_addr;
1413 u32 response_que_addr;
1414 TW_Response_Queue response_queue;
1415 unsigned long param_value;
1416 unsigned char *is_unit_present;
1417 unsigned char *raid_level;
1419 dprintk(KERN_NOTICE "3w-xxxx: tw_initialize_units()\n");
1421 command_que_addr = tw_dev->registers.command_que_addr;
1422 response_que_addr = tw_dev->registers.response_que_addr;
1424 /* Setup the command packet */
1425 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1426 if (command_packet == NULL) {
1427 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad command packet virtual address.\n");
1430 memset(command_packet, 0, sizeof(TW_Sector));
1431 command_packet->byte0.opcode = TW_OP_GET_PARAM;
1432 command_packet->byte0.sgl_offset = 2;
1433 command_packet->size = 4;
1434 command_packet->request_id = request_id;
1435 command_packet->byte3.unit = 0;
1436 command_packet->byte3.host_id = 0;
1437 command_packet->status = 0;
1438 command_packet->flags = 0;
1439 command_packet->byte6.block_count = 1;
1441 /* Now setup the param */
1442 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
1443 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad alignment virtual address.\n");
1446 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1447 memset(param, 0, sizeof(TW_Sector));
1448 param->table_id = 3; /* unit summary table */
1449 param->parameter_id = 3; /* unitstatus parameter */
1450 param->parameter_size_bytes = TW_MAX_UNITS;
1451 param_value = tw_dev->alignment_physical_address[request_id];
1452 if (param_value == 0) {
1453 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad alignment physical address.\n");
1457 command_packet->byte8.param.sgl[0].address = param_value;
1458 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
1460 /* Post the command packet to the board */
1461 command_que_value = tw_dev->command_packet_physical_address[request_id];
1462 if (command_que_value == 0) {
1463 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad command packet physical address.\n");
1466 outl(command_que_value, command_que_addr);
1468 /* Poll for completion */
1469 if (tw_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, 30) == 0) {
1470 response_queue.value = inl(response_que_addr);
1471 request_id = (unsigned char)response_queue.u.response_id;
1472 if (request_id != 0) {
1473 /* unexpected request id */
1474 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Unexpected request id.\n");
1477 if (command_packet->status != 0) {
1479 tw_decode_sense(tw_dev, request_id, 0);
1485 /* response never received */
1486 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): No response.\n");
1490 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1491 is_unit_present = (unsigned char *)&(param->data[0]);
1493 /* Show all units present */
1494 imax = TW_MAX_UNITS;
1495 for(i=0; i<imax; i++) {
1496 if (is_unit_present[i] == 0) {
1497 tw_dev->is_unit_present[i] = FALSE;
1499 if (is_unit_present[i] & TW_UNIT_ONLINE) {
1500 dprintk(KERN_NOTICE "3w-xxxx: tw_initialize_units(): Unit %d found.\n", i);
1501 tw_dev->is_unit_present[i] = TRUE;
1506 tw_dev->num_units = num_units;
1508 if (num_units == 0) {
1509 dprintk(KERN_NOTICE "3w-xxxx: tw_initialize_units(): No units found.\n");
1513 /* Find raid 5 arrays */
1514 for (j=0;j<TW_MAX_UNITS;j++) {
1515 if (tw_dev->is_unit_present[j] == 0)
1517 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1518 if (command_packet == NULL) {
1519 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad command packet virtual address.\n");
1522 memset(command_packet, 0, sizeof(TW_Sector));
1523 command_packet->byte0.opcode = TW_OP_GET_PARAM;
1524 command_packet->byte0.sgl_offset = 2;
1525 command_packet->size = 4;
1526 command_packet->request_id = request_id;
1527 command_packet->byte3.unit = 0;
1528 command_packet->byte3.host_id = 0;
1529 command_packet->status = 0;
1530 command_packet->flags = 0;
1531 command_packet->byte6.block_count = 1;
1533 /* Now setup the param */
1534 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
1535 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad alignment virtual address.\n");
1538 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1539 memset(param, 0, sizeof(TW_Sector));
1540 param->table_id = 0x300+j; /* unit summary table */
1541 param->parameter_id = 0x6; /* unit descriptor */
1542 param->parameter_size_bytes = 0xc;
1543 param_value = tw_dev->alignment_physical_address[request_id];
1544 if (param_value == 0) {
1545 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad alignment physical address.\n");
1549 command_packet->byte8.param.sgl[0].address = param_value;
1550 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
1552 /* Post the command packet to the board */
1553 command_que_value = tw_dev->command_packet_physical_address[request_id];
1554 if (command_que_value == 0) {
1555 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad command packet physical address.\n");
1558 outl(command_que_value, command_que_addr);
1560 /* Poll for completion */
1561 if (tw_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, 30) == 0) {
1562 response_queue.value = inl(response_que_addr);
1563 request_id = (unsigned char)response_queue.u.response_id;
1564 if (request_id != 0) {
1565 /* unexpected request id */
1566 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Unexpected request id.\n");
1569 if (command_packet->status != 0) {
1571 tw_decode_sense(tw_dev, request_id, 0);
1577 /* response never received */
1578 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): No response.\n");
1582 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1583 raid_level = (unsigned char *)&(param->data[1]);
1584 if (*raid_level == 5) {
1585 dprintk(KERN_WARNING "3w-xxxx: Found unit %d to be a raid5 unit.\n", j);
1586 tw_dev->is_raid_five[j] = 1;
1590 tw_dev->num_raid_five = num_raid_five;
1592 /* Now allocate raid5 bounce buffers */
1593 if ((num_raid_five != 0) && (tw_dev->tw_pci_dev->device == TW_DEVICE_ID)) {
1594 error = tw_allocate_memory(tw_dev, sizeof(TW_Sector)*TW_MAX_BOUNCE_SECTORS, 2);
1596 printk(KERN_WARNING "3w-xxxx: Bounce buffer allocation failed.\n");
1602 } /* End tw_initialize_units() */
1604 /* This function is the interrupt service routine */
1605 static void tw_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
1608 u32 status_reg_addr, status_reg_value;
1609 u32 response_que_addr;
1610 TW_Device_Extension *tw_dev = (TW_Device_Extension *)dev_instance;
1611 TW_Response_Queue response_que;
1612 int error = 0, retval = 0;
1613 unsigned long flags = 0;
1614 TW_Command *command_packet;
1616 dprintk(KERN_WARNING "3w-xxxx: tw_interrupt()\n");
1618 /* See if we are already running on another processor */
1619 if (test_and_set_bit(TW_IN_INTR, &tw_dev->flags))
1622 /* Get the block layer lock for io completions */
1623 spin_lock_irqsave(&io_request_lock, flags);
1625 /* See if the interrupt matches this instance */
1626 if (tw_dev->tw_pci_dev->irq == irq) {
1628 /* Make sure io isn't queueing */
1629 spin_lock(&tw_dev->tw_lock);
1631 /* Read the registers */
1632 status_reg_addr = tw_dev->registers.status_reg_addr;
1633 response_que_addr = tw_dev->registers.response_que_addr;
1634 status_reg_value = inl(status_reg_addr);
1636 /* Check if this is our interrupt, otherwise bail */
1637 if (!(status_reg_value & TW_STATUS_VALID_INTERRUPT))
1638 goto tw_interrupt_bail;
1640 /* Check controller for errors */
1641 if (tw_check_bits(status_reg_value)) {
1642 dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n");
1643 if (tw_decode_bits(tw_dev, status_reg_value, 1)) {
1644 tw_clear_all_interrupts(tw_dev);
1645 goto tw_interrupt_bail;
1649 /* Handle host interrupt */
1650 if (status_reg_value & TW_STATUS_HOST_INTERRUPT) {
1651 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Received host interrupt.\n");
1652 tw_clear_host_interrupt(tw_dev);
1655 /* Handle attention interrupt */
1656 if (status_reg_value & TW_STATUS_ATTENTION_INTERRUPT) {
1657 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Received attention interrupt.\n");
1658 tw_clear_attention_interrupt(tw_dev);
1659 tw_state_request_start(tw_dev, &request_id);
1660 error = tw_aen_read_queue(tw_dev, request_id);
1662 printk(KERN_WARNING "3w-xxxx: scsi%d: Error reading aen queue.\n", tw_dev->host->host_no);
1663 tw_dev->state[request_id] = TW_S_COMPLETED;
1664 tw_state_request_finish(tw_dev, request_id);
1668 /* Handle command interrupt */
1669 if (status_reg_value & TW_STATUS_COMMAND_INTERRUPT) {
1670 /* Drain as many pending commands as we can */
1671 while (tw_dev->pending_request_count > 0) {
1672 request_id = tw_dev->pending_queue[tw_dev->pending_head];
1673 if (tw_dev->state[request_id] != TW_S_PENDING) {
1674 printk(KERN_WARNING "3w-xxxx: scsi%d: Found request id that wasn't pending.\n", tw_dev->host->host_no);
1677 if (tw_post_command_packet(tw_dev, request_id)==0) {
1678 if (tw_dev->pending_head == TW_Q_LENGTH-1) {
1679 tw_dev->pending_head = TW_Q_START;
1681 tw_dev->pending_head = tw_dev->pending_head + 1;
1683 tw_dev->pending_request_count--;
1685 /* If we get here, we will continue re-posting on the next command interrupt */
1689 /* If there are no more pending requests, we mask command interrupt */
1690 if (tw_dev->pending_request_count == 0)
1691 tw_mask_command_interrupt(tw_dev);
1694 /* Handle response interrupt */
1695 if (status_reg_value & TW_STATUS_RESPONSE_INTERRUPT) {
1696 /* Drain the response queue from the board */
1697 while ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
1698 /* Read response queue register */
1699 response_que.value = inl(response_que_addr);
1700 request_id = response_que.u.response_id;
1701 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1704 /* Check for bad response */
1705 if (command_packet->status != 0) {
1706 /* If internal command, don't error, don't fill sense */
1707 if (tw_dev->srb[request_id] == 0) {
1708 tw_decode_sense(tw_dev, request_id, 0);
1710 error = tw_decode_sense(tw_dev, request_id, 1);
1714 /* Check for correct state */
1715 if (tw_dev->state[request_id] != TW_S_POSTED) {
1716 /* Handle timed out ioctl's */
1717 if (tw_dev->srb[request_id] != 0) {
1718 if (tw_dev->srb[request_id]->cmnd[0] != TW_IOCTL) {
1719 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);
1725 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Response queue request id: %d.\n", request_id);
1727 /* Check for internal command completion */
1728 if (tw_dev->srb[request_id] == 0) {
1729 dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Found internally posted command.\n");
1730 /* Check for chrdev ioctl completion */
1731 if (request_id != tw_dev->chrdev_request_id) {
1732 retval = tw_aen_complete(tw_dev, request_id);
1734 printk(KERN_WARNING "3w-xxxx: scsi%d: Error completing aen.\n", tw_dev->host->host_no);
1737 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1738 wake_up(&tw_dev->ioctl_wqueue);
1741 switch (tw_dev->srb[request_id]->cmnd[0]) {
1744 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught READ_10/READ_6\n");
1748 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught WRITE_10/WRITE_6\n");
1750 case TEST_UNIT_READY:
1751 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught TEST_UNIT_READY\n");
1752 error = tw_scsiop_test_unit_ready_complete(tw_dev, request_id);
1755 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught INQUIRY\n");
1756 error = tw_scsiop_inquiry_complete(tw_dev, request_id);
1759 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught READ_CAPACITY\n");
1760 error = tw_scsiop_read_capacity_complete(tw_dev, request_id);
1763 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught MODE_SENSE\n");
1764 error = tw_scsiop_mode_sense_complete(tw_dev, request_id);
1766 case SYNCHRONIZE_CACHE:
1767 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught SYNCHRONIZE_CACHE\n");
1770 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught TW_IOCTL\n");
1771 error = tw_ioctl_complete(tw_dev, request_id);
1774 printk(KERN_WARNING "3w-xxxx: case slip in tw_interrupt()\n");
1778 /* If no error command was a success */
1780 tw_dev->srb[request_id]->result = (DID_OK << 16);
1783 /* If error, command failed */
1785 /* Ask for a host reset */
1786 tw_dev->srb[request_id]->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
1789 /* Now complete the io */
1790 if ((error != TW_ISR_DONT_COMPLETE)) {
1791 tw_dev->state[request_id] = TW_S_COMPLETED;
1792 tw_state_request_finish(tw_dev, request_id);
1793 tw_dev->posted_request_count--;
1794 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1795 tw_unmap_scsi_data(tw_dev->tw_pci_dev, tw_dev->srb[request_id]);
1799 /* Check for valid status after each drain */
1800 status_reg_value = inl(status_reg_addr);
1801 if (tw_check_bits(status_reg_value)) {
1802 dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n");
1803 if (tw_decode_bits(tw_dev, status_reg_value, 1)) {
1804 tw_clear_all_interrupts(tw_dev);
1805 goto tw_interrupt_bail;
1811 spin_unlock(&tw_dev->tw_lock);
1813 dprintk(KERN_WARNING "3w-xxxx: tw_interrupt() called for wrong instance.\n");
1815 spin_unlock_irqrestore(&io_request_lock, flags);
1816 clear_bit(TW_IN_INTR, &tw_dev->flags);
1817 } /* End tw_interrupt() */
1819 /* This function handles ioctls from userspace to the driver */
1820 int tw_ioctl(TW_Device_Extension *tw_dev, int request_id)
1822 unsigned char opcode;
1823 int bufflen, error = 0;
1825 TW_Command *command_packet, *command_save;
1826 unsigned long param_value;
1827 TW_Ioctl *ioctl = NULL;
1828 TW_Passthru *passthru = NULL;
1829 int tw_aen_code, i, use_sg;
1830 unsigned long *data_ptr;
1831 int total_bytes = 0, posted = 0;
1832 dma_addr_t dma_handle;
1833 struct timeval before, timeout;
1835 ioctl = (TW_Ioctl *)tw_dev->srb[request_id]->request_buffer;
1836 if (ioctl == NULL) {
1837 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Request buffer NULL.\n");
1838 tw_dev->state[request_id] = TW_S_COMPLETED;
1839 tw_state_request_finish(tw_dev, request_id);
1840 tw_dev->srb[request_id]->result = (DID_OK << 16);
1841 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1844 bufflen = tw_dev->srb[request_id]->request_bufflen;
1846 /* Initialize command packet */
1847 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1848 if (command_packet == NULL) {
1849 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Bad command packet virtual address.\n");
1850 tw_dev->state[request_id] = TW_S_COMPLETED;
1851 tw_state_request_finish(tw_dev, request_id);
1852 tw_dev->srb[request_id]->result = (DID_OK << 16);
1853 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1856 memset(command_packet, 0, sizeof(TW_Sector));
1858 /* Initialize param */
1859 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
1860 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Bad alignment virtual address.\n");
1861 tw_dev->state[request_id] = TW_S_COMPLETED;
1862 tw_state_request_finish(tw_dev, request_id);
1863 tw_dev->srb[request_id]->result = (DID_OK << 16);
1864 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1867 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1868 memset(param, 0, sizeof(TW_Sector));
1870 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);
1871 opcode = ioctl->opcode;
1875 dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): caught TW_OP_NOP.\n");
1876 command_packet->byte0.opcode = TW_OP_NOP;
1878 case TW_OP_GET_PARAM:
1879 dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): caught TW_OP_GET_PARAM.\n");
1880 command_packet->byte0.opcode = TW_OP_GET_PARAM;
1881 command_packet->byte3.unit = ioctl->unit_index;
1882 param->table_id = ioctl->table_id;
1883 param->parameter_id = ioctl->parameter_id;
1884 param->parameter_size_bytes = ioctl->parameter_size_bytes;
1885 tw_dev->ioctl_size[request_id] = ioctl->parameter_size_bytes;
1886 dprintk(KERN_NOTICE "table_id = %d parameter_id = %d parameter_size_bytes %d\n", param->table_id, param->parameter_id, param->parameter_size_bytes);
1888 case TW_OP_SET_PARAM:
1889 dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): caught TW_OP_SET_PARAM: table_id = %d, parameter_id = %d, parameter_size_bytes = %d.\n",
1890 ioctl->table_id, ioctl->parameter_id, ioctl->parameter_size_bytes);
1891 if (ioctl->data != NULL) {
1892 command_packet->byte0.opcode = TW_OP_SET_PARAM;
1893 param->table_id = ioctl->table_id;
1894 param->parameter_id = ioctl->parameter_id;
1895 param->parameter_size_bytes = ioctl->parameter_size_bytes;
1896 memcpy(param->data, ioctl->data, ioctl->parameter_size_bytes);
1899 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): ioctl->data NULL.\n");
1902 case TW_OP_AEN_LISTEN:
1903 dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): caught TW_OP_AEN_LISTEN.\n");
1904 if (tw_dev->aen_head == tw_dev->aen_tail) {
1905 /* aen queue empty */
1906 dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): Aen queue empty.\n");
1907 tw_aen_code = TW_AEN_QUEUE_EMPTY;
1908 memcpy(tw_dev->srb[request_id]->request_buffer, &tw_aen_code, ioctl->parameter_size_bytes);
1910 /* Copy aen queue entry to request buffer */
1911 dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): Returning aen 0x%x\n", tw_dev->aen_queue[tw_dev->aen_head]);
1912 tw_aen_code = tw_dev->aen_queue[tw_dev->aen_head];
1913 memcpy(tw_dev->srb[request_id]->request_buffer, &tw_aen_code, ioctl->parameter_size_bytes);
1914 if (tw_dev->aen_head == TW_Q_LENGTH - 1) {
1915 tw_dev->aen_head = TW_Q_START;
1917 tw_dev->aen_head = tw_dev->aen_head + 1;
1920 tw_dev->state[request_id] = TW_S_COMPLETED;
1921 tw_state_request_finish(tw_dev, request_id);
1922 tw_dev->srb[request_id]->result = (DID_OK << 16);
1923 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1925 case TW_ATA_PASSTHRU:
1926 if (ioctl->data != NULL) {
1927 memcpy(command_packet, ioctl->data, sizeof(TW_Command));
1928 command_packet->request_id = request_id;
1930 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): ioctl->data NULL.\n");
1934 passthru = (TW_Passthru *)tw_dev->command_packet_virtual_address[request_id];
1935 /* Don't load sg_list for non-data ATA cmds */
1936 if ((passthru->param != 0) && (passthru->param != 0x8)) {
1937 passthru->sg_list[0].length = passthru->sector_count*512;
1938 if (passthru->sg_list[0].length > TW_MAX_PASSTHRU_BYTES) {
1939 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Passthru size (%d) too big.\n", passthru->sg_list[0].length);
1942 passthru->sg_list[0].address = tw_dev->alignment_physical_address[request_id];
1944 tw_post_command_packet(tw_dev, request_id);
1947 dprintk(KERN_WARNING "3w-xxxx: tw_ioctl(): caught TW_CMD_PACKET.\n");
1948 if (ioctl->data != NULL) {
1949 memcpy(command_packet, ioctl->data, sizeof(TW_Command));
1950 command_packet->request_id = request_id;
1951 tw_post_command_packet(tw_dev, request_id);
1954 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): ioctl->data NULL.\n");
1957 case TW_CMD_PACKET_WITH_DATA:
1958 dprintk(KERN_WARNING "3w-xxxx: tw_ioctl(): caught TW_CMD_PACKET_WITH_DATA.\n");
1959 command_save = (TW_Command *)tw_dev->alignment_virtual_address[request_id];
1960 if (command_save == NULL) {
1961 printk(KERN_WARNING "3w-xxxx: scsi%d: tw_ioctl(): Bad alignment virtual address.\n", tw_dev->host->host_no);
1964 if (ioctl->data != NULL) {
1965 /* Copy down the command packet */
1966 memcpy(command_packet, ioctl->data, sizeof(TW_Command));
1967 memcpy(command_save, ioctl->data, sizeof(TW_Command));
1968 command_packet->request_id = request_id;
1970 /* Now deal with the two possible sglists */
1971 if (command_packet->byte0.sgl_offset == 2) {
1972 use_sg = command_packet->size - 3;
1973 for (i=0;i<use_sg;i++)
1974 total_bytes+=command_packet->byte8.param.sgl[i].length;
1975 tw_dev->ioctl_data[request_id] = pci_alloc_consistent(tw_dev->tw_pci_dev, total_bytes, &dma_handle);
1977 if (!tw_dev->ioctl_data[request_id]) {
1978 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);
1982 /* Copy param sglist into the kernel */
1983 data_ptr = tw_dev->ioctl_data[request_id];
1984 for (i=0;i<use_sg;i++) {
1985 if (command_packet->byte8.param.sgl[i].address != 0) {
1986 error = copy_from_user(data_ptr, (void *)(unsigned long)command_packet->byte8.param.sgl[i].address, command_packet->byte8.param.sgl[i].length);
1988 dprintk(KERN_WARNING "3w-xxxx: scsi%d: Error copying param sglist from userspace.\n", tw_dev->host->host_no);
1992 printk(KERN_WARNING "3w-xxxx: scsi%d: tw_ioctl(): Bad param sgl address.\n", tw_dev->host->host_no);
1993 tw_dev->srb[request_id]->result = (DID_RESET << 16);
1996 data_ptr+=command_packet->byte8.param.sgl[i].length;
1998 command_packet->size = 4;
1999 command_packet->byte8.param.sgl[0].address = dma_handle;
2000 command_packet->byte8.param.sgl[0].length = total_bytes;
2002 if (command_packet->byte0.sgl_offset == 3) {
2003 use_sg = command_packet->size - 4;
2004 for (i=0;i<use_sg;i++)
2005 total_bytes+=command_packet->byte8.io.sgl[i].length;
2006 tw_dev->ioctl_data[request_id] = pci_alloc_consistent(tw_dev->tw_pci_dev, total_bytes, &dma_handle);
2008 if (!tw_dev->ioctl_data[request_id]) {
2009 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);
2012 if (command_packet->byte0.opcode == TW_OP_WRITE) {
2013 /* Copy io sglist into the kernel */
2014 data_ptr = tw_dev->ioctl_data[request_id];
2015 for (i=0;i<use_sg;i++) {
2016 if (command_packet->byte8.io.sgl[i].address != 0) {
2017 error = copy_from_user(data_ptr, (void *)(unsigned long)command_packet->byte8.io.sgl[i].address, command_packet->byte8.io.sgl[i].length);
2019 dprintk(KERN_WARNING "3w-xxxx: scsi%d: Error copying io sglist from userspace.\n", tw_dev->host->host_no);
2023 printk(KERN_WARNING "3w-xxxx: scsi%d: tw_ioctl(): Bad io sgl address.\n", tw_dev->host->host_no);
2024 tw_dev->srb[request_id]->result = (DID_RESET << 16);
2027 data_ptr+=command_packet->byte8.io.sgl[i].length;
2030 command_packet->size = 5;
2031 command_packet->byte8.io.sgl[0].address = dma_handle;
2032 command_packet->byte8.io.sgl[0].length = total_bytes;
2035 spin_unlock(&tw_dev->tw_lock);
2036 spin_unlock_irq(&io_request_lock);
2038 set_bit(TW_IN_IOCTL, &tw_dev->flags);
2040 /* Finally post the command packet */
2041 tw_post_command_packet(tw_dev, request_id);
2043 do_gettimeofday(&before);
2046 mdelay(TW_IOCTL_WAIT_TIME);
2047 if (test_bit(TW_IN_IOCTL, &tw_dev->flags)) {
2048 do_gettimeofday(&timeout);
2049 if (before.tv_sec + TW_IOCTL_TIMEOUT < timeout.tv_sec) {
2050 spin_lock_irq(&io_request_lock);
2051 spin_lock(&tw_dev->tw_lock);
2054 goto tw_ioctl_retry;
2058 spin_lock_irq(&io_request_lock);
2059 spin_lock(&tw_dev->tw_lock);
2061 if (signal_pending(current)) {
2062 dprintk(KERN_WARNING "3w-xxxx: scsi%d: tw_ioctl(): Signal pending, aborting ioctl().\n", tw_dev->host->host_no);
2063 tw_dev->srb[request_id]->result = (DID_OK << 16);
2067 tw_dev->srb[request_id]->result = (DID_OK << 16);
2068 /* Now copy up the param or io sglist to userspace */
2069 if (command_packet->byte0.sgl_offset == 2) {
2070 use_sg = command_save->size - 3;
2071 data_ptr = tw_dev->ioctl_data[request_id];
2072 for (i=0;i<use_sg;i++) {
2073 if (command_save->byte8.param.sgl[i].address != 0) {
2074 error = copy_to_user((void *)(unsigned long)command_save->byte8.param.sgl[i].address, data_ptr, command_save->byte8.param.sgl[i].length);
2076 dprintk(KERN_WARNING "3w-xxxx: scsi%d: Error copying param sglist to userspace.\n", tw_dev->host->host_no);
2079 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);
2080 data_ptr+=command_save->byte8.param.sgl[i].length;
2082 printk(KERN_WARNING "3w-xxxx: scsi%d: tw_ioctl(): Bad param sgl address.\n", tw_dev->host->host_no);
2083 tw_dev->srb[request_id]->result = (DID_RESET << 16);
2088 if (command_packet->byte0.sgl_offset == 3) {
2089 use_sg = command_save->size - 4;
2090 if (command_packet->byte0.opcode == TW_OP_READ) {
2091 data_ptr = tw_dev->ioctl_data[request_id];
2092 for(i=0;i<use_sg;i++) {
2093 if (command_save->byte8.io.sgl[i].address != 0) {
2094 error = copy_to_user((void *)(unsigned long)command_save->byte8.io.sgl[i].address, data_ptr, command_save->byte8.io.sgl[i].length);
2096 dprintk(KERN_WARNING "3w-xxxx: scsi%d: Error copying io sglist to userspace.\n", tw_dev->host->host_no);
2099 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);
2100 data_ptr+=command_save->byte8.io.sgl[i].length;
2102 printk(KERN_WARNING "3w-xxxx: scsi%d: tw_ioctl(): Bad io sgl address.\n", tw_dev->host->host_no);
2103 tw_dev->srb[request_id]->result = (DID_RESET << 16);
2112 /* Free up sglist memory */
2113 if (tw_dev->ioctl_data[request_id])
2114 pci_free_consistent(tw_dev->tw_pci_dev, total_bytes, tw_dev->ioctl_data[request_id], dma_handle);
2116 printk(KERN_WARNING "3w-xxxx: scsi%d: tw_ioctl(): Error freeing ioctl data.\n", tw_dev->host->host_no);
2118 /* Now complete the io */
2119 tw_dev->state[request_id] = TW_S_COMPLETED;
2120 tw_state_request_finish(tw_dev, request_id);
2122 tw_dev->posted_request_count--;
2123 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
2126 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): ioctl->data NULL.\n");
2130 dprintk(KERN_WARNING "3w-xxxx: Unknown ioctl 0x%x.\n", opcode);
2131 tw_dev->state[request_id] = TW_S_COMPLETED;
2132 tw_state_request_finish(tw_dev, request_id);
2133 tw_dev->srb[request_id]->result = (DID_OK << 16);
2134 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
2138 param_value = tw_dev->alignment_physical_address[request_id];
2139 if (param_value == 0) {
2140 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Bad alignment physical address.\n");
2141 tw_dev->state[request_id] = TW_S_COMPLETED;
2142 tw_state_request_finish(tw_dev, request_id);
2143 tw_dev->srb[request_id]->result = (DID_OK << 16);
2144 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
2147 command_packet->byte8.param.sgl[0].address = param_value;
2148 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
2150 command_packet->byte0.sgl_offset = 2;
2151 command_packet->size = 4;
2152 command_packet->request_id = request_id;
2153 command_packet->byte3.host_id = 0;
2154 command_packet->status = 0;
2155 command_packet->flags = 0;
2156 command_packet->byte6.parameter_count = 1;
2158 /* Now try to post the command to the board */
2159 tw_post_command_packet(tw_dev, request_id);
2162 } /* End tw_ioctl() */
2164 /* This function is called by the isr to complete ioctl requests */
2165 int tw_ioctl_complete(TW_Device_Extension *tw_dev, int request_id)
2167 unsigned char *param_data;
2168 unsigned char *buff;
2170 TW_Ioctl *ioctl = NULL;
2171 TW_Passthru *passthru = NULL;
2172 TW_Command *command_packet;
2174 ioctl = (TW_Ioctl *)tw_dev->srb[request_id]->request_buffer;
2175 dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl_complete()\n");
2176 buff = tw_dev->srb[request_id]->request_buffer;
2178 printk(KERN_WARNING "3w-xxxx: tw_ioctl_complete(): Request buffer NULL.\n");
2182 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
2183 if (command_packet == NULL) {
2184 printk(KERN_WARNING "3w-xxxx: scsi%d: tw_ioctl_complete(): Bad command packet virtual address.\n", tw_dev->host->host_no);
2188 dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl_complete(): Request_bufflen = %d\n", tw_dev->srb[request_id]->request_bufflen);
2190 ioctl = (TW_Ioctl *)buff;
2191 switch (ioctl->opcode) {
2192 case TW_ATA_PASSTHRU:
2193 passthru = (TW_Passthru *)ioctl->data;
2194 /* Don't return data for non-data ATA cmds */
2195 if ((passthru->param != 0) && (passthru->param != 0x8))
2196 memcpy(buff, tw_dev->alignment_virtual_address[request_id], passthru->sector_count * 512);
2198 /* For non-data cmds, return cmd pkt */
2199 if (tw_dev->srb[request_id]->request_bufflen >= sizeof(TW_Command))
2200 memcpy(buff, tw_dev->command_packet_virtual_address[request_id], sizeof(TW_Command));
2203 case TW_CMD_PACKET_WITH_DATA:
2204 dprintk(KERN_WARNING "3w-xxxx: tw_ioctl_complete(): caught TW_CMD_PACKET_WITH_DATA.\n");
2205 clear_bit(TW_IN_IOCTL, &tw_dev->flags);
2206 return TW_ISR_DONT_COMPLETE; /* Special case for isr to not complete io */
2208 memset(buff, 0, tw_dev->srb[request_id]->request_bufflen);
2209 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
2210 if (param == NULL) {
2211 printk(KERN_WARNING "3w-xxxx: tw_ioctl_complete(): Bad alignment virtual address.\n");
2214 param_data = &(param->data[0]);
2215 memcpy(buff, param_data, tw_dev->ioctl_size[request_id]);
2218 } /* End tw_ioctl_complete() */
2220 static int tw_map_scsi_sg_data(struct pci_dev *pdev, Scsi_Cmnd *cmd)
2223 int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
2225 dprintk(KERN_WARNING "3w-xxxx: tw_map_scsi_sg_data()\n");
2227 if (cmd->use_sg == 0)
2230 use_sg = pci_map_sg(pdev, cmd->buffer, cmd->use_sg, dma_dir);
2233 printk(KERN_WARNING "3w-xxxx: tw_map_scsi_sg_data(): pci_map_sg() failed.\n");
2238 cmd->SCp.have_data_in = use_sg;
2241 } /* End tw_map_scsi_sg_data() */
2243 static u32 tw_map_scsi_single_data(struct pci_dev *pdev, Scsi_Cmnd *cmd)
2246 int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
2248 dprintk(KERN_WARNING "3w-xxxx: tw_map_scsi_single_data()\n");
2250 if (cmd->request_bufflen == 0)
2252 #ifdef BLK_BOUNCE_HIGH
2253 mapping = pci_map_page(pdev, virt_to_page(cmd->request_buffer), ((unsigned long)cmd->request_buffer & ~PAGE_MASK), cmd->request_bufflen, dma_dir);
2255 mapping = pci_map_single(pdev, cmd->request_buffer, cmd->request_bufflen, dma_dir);
2259 printk(KERN_WARNING "3w-xxxx: tw_map_scsi_single_data(): pci_map_page() failed.\n");
2264 cmd->SCp.have_data_in = mapping;
2267 } /* End tw_map_scsi_single_data() */
2269 /* This function will mask the command interrupt */
2270 void tw_mask_command_interrupt(TW_Device_Extension *tw_dev)
2272 u32 control_reg_addr, control_reg_value;
2274 control_reg_addr = tw_dev->registers.control_reg_addr;
2275 control_reg_value = TW_CONTROL_MASK_COMMAND_INTERRUPT;
2276 outl(control_reg_value, control_reg_addr);
2277 } /* End tw_mask_command_interrupt() */
2279 /* This function will poll the status register for a flag */
2280 int tw_poll_status(TW_Device_Extension *tw_dev, u32 flag, int seconds)
2282 u32 status_reg_addr, status_reg_value;
2283 struct timeval before, timeout;
2285 status_reg_addr = tw_dev->registers.status_reg_addr;
2286 do_gettimeofday(&before);
2287 status_reg_value = inl(status_reg_addr);
2289 if (tw_check_bits(status_reg_value)) {
2290 dprintk(KERN_WARNING "3w-xxxx: tw_poll_status(): Unexpected bits.\n");
2291 tw_decode_bits(tw_dev, status_reg_value, 0);
2294 while ((status_reg_value & flag) != flag) {
2295 status_reg_value = inl(status_reg_addr);
2297 if (tw_check_bits(status_reg_value)) {
2298 dprintk(KERN_WARNING "3w-xxxx: tw_poll_status(): Unexpected bits.\n");
2299 tw_decode_bits(tw_dev, status_reg_value, 0);
2302 do_gettimeofday(&timeout);
2303 if (before.tv_sec + seconds < timeout.tv_sec) {
2304 dprintk(KERN_WARNING "3w-xxxx: tw_poll_status(): Flag 0x%x not found.\n", flag);
2310 } /* End tw_poll_status() */
2312 /* This function will poll the status register for disappearance of a flag */
2313 int tw_poll_status_gone(TW_Device_Extension *tw_dev, u32 flag, int seconds)
2315 u32 status_reg_addr, status_reg_value;
2316 struct timeval before, timeout;
2318 status_reg_addr = tw_dev->registers.status_reg_addr;
2319 do_gettimeofday(&before);
2320 status_reg_value = inl(status_reg_addr);
2322 if (tw_check_bits(status_reg_value)) {
2323 dprintk(KERN_WARNING "3w-xxxx: tw_poll_status_gone(): Unexpected bits.\n");
2324 tw_decode_bits(tw_dev, status_reg_value, 0);
2327 while ((status_reg_value & flag) != 0) {
2328 status_reg_value = inl(status_reg_addr);
2330 if (tw_check_bits(status_reg_value)) {
2331 dprintk(KERN_WARNING "3w-xxxx: tw_poll_status_gone(): Unexpected bits.\n");
2332 tw_decode_bits(tw_dev, status_reg_value, 0);
2335 do_gettimeofday(&timeout);
2336 if (before.tv_sec + seconds < timeout.tv_sec) {
2337 dprintk(KERN_WARNING "3w-xxxx: tw_poll_status_gone(): Flag 0x%x never disappeared.\n", flag);
2343 } /* End tw_poll_status_gone() */
2345 /* This function will attempt to post a command packet to the board */
2346 int tw_post_command_packet(TW_Device_Extension *tw_dev, int request_id)
2348 u32 status_reg_addr, status_reg_value;
2349 unsigned long command_que_value;
2350 u32 command_que_addr;
2352 dprintk(KERN_NOTICE "3w-xxxx: tw_post_command_packet()\n");
2353 command_que_addr = tw_dev->registers.command_que_addr;
2354 command_que_value = tw_dev->command_packet_physical_address[request_id];
2355 status_reg_addr = tw_dev->registers.status_reg_addr;
2356 status_reg_value = inl(status_reg_addr);
2358 if (tw_check_bits(status_reg_value)) {
2359 dprintk(KERN_WARNING "3w-xxxx: tw_post_command_packet(): Unexpected bits.\n");
2360 tw_decode_bits(tw_dev, status_reg_value, 1);
2363 if ((status_reg_value & TW_STATUS_COMMAND_QUEUE_FULL) == 0) {
2364 /* We successfully posted the command packet */
2365 outl(command_que_value, command_que_addr);
2366 tw_dev->state[request_id] = TW_S_POSTED;
2367 tw_dev->posted_request_count++;
2368 if (tw_dev->posted_request_count > tw_dev->max_posted_request_count) {
2369 tw_dev->max_posted_request_count = tw_dev->posted_request_count;
2372 /* Couldn't post the command packet, so we do it in the isr */
2373 if (tw_dev->state[request_id] != TW_S_PENDING) {
2374 tw_dev->state[request_id] = TW_S_PENDING;
2375 tw_dev->pending_request_count++;
2376 if (tw_dev->pending_request_count > tw_dev->max_pending_request_count) {
2377 tw_dev->max_pending_request_count = tw_dev->pending_request_count;
2379 tw_dev->pending_queue[tw_dev->pending_tail] = request_id;
2380 if (tw_dev->pending_tail == TW_Q_LENGTH-1) {
2381 tw_dev->pending_tail = TW_Q_START;
2383 tw_dev->pending_tail = tw_dev->pending_tail + 1;
2386 tw_unmask_command_interrupt(tw_dev);
2390 } /* End tw_post_command_packet() */
2392 /* This function will reset a device extension */
2393 int tw_reset_device_extension(TW_Device_Extension *tw_dev)
2399 dprintk(KERN_NOTICE "3w-xxxx: tw_reset_device_extension()\n");
2402 if (tw_reset_sequence(tw_dev)) {
2403 printk(KERN_WARNING "3w-xxxx: scsi%d: Reset sequence failed.\n", tw_dev->host->host_no);
2407 /* Abort all requests that are in progress */
2408 for (i=0;i<imax;i++) {
2409 if ((tw_dev->state[i] != TW_S_FINISHED) &&
2410 (tw_dev->state[i] != TW_S_INITIAL) &&
2411 (tw_dev->state[i] != TW_S_COMPLETED)) {
2412 srb = tw_dev->srb[i];
2414 srb->result = (DID_RESET << 16);
2415 tw_dev->srb[i]->scsi_done(tw_dev->srb[i]);
2416 tw_unmap_scsi_data(tw_dev->tw_pci_dev, tw_dev->srb[i]);
2421 /* Reset queues and counts */
2422 for (i=0;i<imax;i++) {
2423 tw_dev->free_queue[i] = i;
2424 tw_dev->state[i] = TW_S_INITIAL;
2426 tw_dev->free_head = TW_Q_START;
2427 tw_dev->free_tail = TW_Q_START;
2428 tw_dev->posted_request_count = 0;
2429 tw_dev->pending_request_count = 0;
2430 tw_dev->pending_head = TW_Q_START;
2431 tw_dev->pending_tail = TW_Q_START;
2432 tw_dev->reset_print = 0;
2433 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
2436 } /* End tw_reset_device_extension() */
2438 /* This function will reset a controller */
2439 int tw_reset_sequence(TW_Device_Extension *tw_dev)
2444 /* Disable interrupts */
2445 tw_disable_interrupts(tw_dev);
2447 /* Reset the board */
2448 while (tries < TW_MAX_RESET_TRIES) {
2449 tw_soft_reset(tw_dev);
2451 error = tw_aen_drain_queue(tw_dev);
2453 printk(KERN_WARNING "3w-xxxx: scsi%d: AEN drain failed, retrying.\n", tw_dev->host->host_no);
2458 /* Check for controller errors */
2459 if (tw_check_errors(tw_dev)) {
2460 printk(KERN_WARNING "3w-xxxx: scsi%d: Controller errors found, retrying.\n", tw_dev->host->host_no);
2465 /* Now the controller is in a good state */
2469 if (tries >= TW_MAX_RESET_TRIES) {
2470 printk(KERN_WARNING "3w-xxxx: scsi%d: Controller errors, card not responding, check all cabling.\n", tw_dev->host->host_no);
2474 error = tw_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS);
2476 printk(KERN_WARNING "3w-xxxx: scsi%d: Connection initialization failed.\n", tw_dev->host->host_no);
2480 /* Re-enable interrupts */
2481 tw_enable_and_clear_interrupts(tw_dev);
2484 } /* End tw_reset_sequence() */
2486 /* This funciton returns unit geometry in cylinders/heads/sectors */
2487 int tw_scsi_biosparam(Disk *disk, kdev_t dev, int geom[])
2489 int heads, sectors, cylinders;
2490 TW_Device_Extension *tw_dev;
2492 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_biosparam()\n");
2493 tw_dev = (TW_Device_Extension *)disk->device->host->hostdata;
2497 cylinders = disk->capacity / (heads * sectors);
2499 if (disk->capacity >= 0x200000) {
2502 cylinders = disk->capacity / (heads * sectors);
2505 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_biosparam(): heads = %d, sectors = %d, cylinders = %d\n", heads, sectors, cylinders);
2508 geom[2] = cylinders;
2511 } /* End tw_scsi_biosparam() */
2513 /* This function will find and initialize any cards */
2514 int tw_scsi_detect(Scsi_Host_Template *tw_host)
2518 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_detect()\n");
2520 printk(KERN_WARNING "3ware Storage Controller device driver for Linux v%s.\n", tw_driver_version);
2522 /* Check if the kernel has PCI interface compiled in */
2523 if (!pci_present()) {
2524 printk(KERN_WARNING "3w-xxxx: tw_scsi_detect(): No pci interface present.\n");
2528 spin_unlock_irq(&io_request_lock);
2529 ret = tw_findcards(tw_host);
2530 spin_lock_irq(&io_request_lock);
2533 } /* End tw_scsi_detect() */
2535 /* This is the new scsi eh abort function */
2536 int tw_scsi_eh_abort(Scsi_Cmnd *SCpnt)
2538 TW_Device_Extension *tw_dev=NULL;
2541 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_eh_abort()\n");
2544 printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Invalid Scsi_Cmnd.\n");
2548 tw_dev = (TW_Device_Extension *)SCpnt->host->hostdata;
2549 if (tw_dev == NULL) {
2550 printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Invalid device extension.\n");
2554 spin_lock(&tw_dev->tw_lock);
2555 tw_dev->num_aborts++;
2557 /* If the command hasn't been posted yet, we can do the abort */
2558 for (i=0;i<TW_Q_LENGTH;i++) {
2559 if (tw_dev->srb[i] == SCpnt) {
2560 if (tw_dev->state[i] == TW_S_STARTED) {
2561 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);
2562 tw_dev->state[i] = TW_S_COMPLETED;
2563 tw_state_request_finish(tw_dev, i);
2564 spin_unlock(&tw_dev->tw_lock);
2567 if (tw_dev->state[i] == TW_S_PENDING) {
2568 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);
2569 if (tw_dev->pending_head == TW_Q_LENGTH-1) {
2570 tw_dev->pending_head = TW_Q_START;
2572 tw_dev->pending_head = tw_dev->pending_head + 1;
2574 tw_dev->pending_request_count--;
2575 tw_dev->state[i] = TW_S_COMPLETED;
2576 tw_state_request_finish(tw_dev, i);
2577 spin_unlock(&tw_dev->tw_lock);
2580 if (tw_dev->state[i] == TW_S_POSTED) {
2581 /* If the command has already been posted, we have to reset the card */
2582 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);
2583 /* We have to let AEN requests through before the reset */
2584 spin_unlock(&tw_dev->tw_lock);
2585 spin_unlock_irq(&io_request_lock);
2586 mdelay(TW_AEN_WAIT_TIME);
2587 spin_lock_irq(&io_request_lock);
2588 spin_lock(&tw_dev->tw_lock);
2590 if (tw_reset_device_extension(tw_dev)) {
2591 dprintk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Reset failed for card %d.\n", tw_dev->host->host_no);
2592 spin_unlock(&tw_dev->tw_lock);
2599 spin_unlock(&tw_dev->tw_lock);
2601 } /* End tw_scsi_eh_abort() */
2603 /* This is the new scsi eh reset function */
2604 int tw_scsi_eh_reset(Scsi_Cmnd *SCpnt)
2606 TW_Device_Extension *tw_dev=NULL;
2608 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_eh_reset()\n");
2611 printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_reset(): Invalid Scsi_Cmnd.\n");
2615 tw_dev = (TW_Device_Extension *)SCpnt->host->hostdata;
2616 if (tw_dev == NULL) {
2617 printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_reset(): Invalid device extension.\n");
2621 /* We have to let AEN requests through before the reset */
2622 spin_unlock_irq(&io_request_lock);
2623 mdelay(TW_AEN_WAIT_TIME);
2624 spin_lock_irq(&io_request_lock);
2626 spin_lock(&tw_dev->tw_lock);
2627 tw_dev->num_resets++;
2629 /* Now reset the card and some of the device extension data */
2630 if (tw_reset_device_extension(tw_dev)) {
2631 printk(KERN_WARNING "3w-xxxx: scsi%d: Reset failed.\n", tw_dev->host->host_no);
2632 spin_unlock(&tw_dev->tw_lock);
2635 printk(KERN_WARNING "3w-xxxx: scsi%d: Reset succeeded.\n", tw_dev->host->host_no);
2636 spin_unlock(&tw_dev->tw_lock);
2639 } /* End tw_scsi_eh_reset() */
2641 /* This function handles input and output from /proc/scsi/3w-xxxx/x */
2642 int tw_scsi_proc_info(char *buffer, char **start, off_t offset, int length, int hostno, int inout)
2644 TW_Device_Extension *tw_dev = NULL;
2649 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_proc_info()\n");
2651 /* Find the correct device extension */
2652 for (i=0;i<tw_device_extension_count;i++)
2653 if (tw_device_extension_list[i]->host->host_no == hostno)
2654 tw_dev = tw_device_extension_list[i];
2655 if (tw_dev == NULL) {
2656 printk(KERN_WARNING "3w-xxxx: tw_scsi_proc_info(): Couldn't locate device extension.\n");
2660 info.buffer = buffer;
2661 info.length = length;
2662 info.offset = offset;
2667 if (strncmp(buffer, "debug", 5) == 0) {
2668 printk(KERN_INFO "3w-xxxx: Posted commands:\n");
2669 for (j=0;j<TW_Q_LENGTH;j++) {
2670 if (tw_dev->state[j] == TW_S_POSTED) {
2671 TW_Command *command = (TW_Command *)tw_dev->command_packet_virtual_address[j];
2672 printk(KERN_INFO "3w-xxxx: Request_id: %d\n", j);
2673 printk(KERN_INFO "Opcode: 0x%x\n", command->byte0.opcode);
2674 printk(KERN_INFO "Block_count: 0x%x\n", command->byte6.block_count);
2675 printk(KERN_INFO "LBA: 0x%x\n", command->byte8.io.lba);
2676 printk(KERN_INFO "Physical command packet addr: 0x%lx\n", tw_dev->command_packet_physical_address[j]);
2677 printk(KERN_INFO "Scsi_Cmnd: %p\n", tw_dev->srb[j]);
2680 printk(KERN_INFO "3w-xxxx: Free_head: %3d\n", tw_dev->free_head);
2681 printk(KERN_INFO "3w-xxxx: Free_tail: %3d\n", tw_dev->free_tail);
2689 tw_copy_info(&info, "scsi%d: 3ware Storage Controller\n", hostno);
2690 tw_copy_info(&info, "Driver version: %s\n", tw_driver_version);
2691 tw_copy_info(&info, "Current commands posted: %3d\n", tw_dev->posted_request_count);
2692 tw_copy_info(&info, "Max commands posted: %3d\n", tw_dev->max_posted_request_count);
2693 tw_copy_info(&info, "Current pending commands: %3d\n", tw_dev->pending_request_count);
2694 tw_copy_info(&info, "Max pending commands: %3d\n", tw_dev->max_pending_request_count);
2695 tw_copy_info(&info, "Last sgl length: %3d\n", tw_dev->sgl_entries);
2696 tw_copy_info(&info, "Max sgl length: %3d\n", tw_dev->max_sgl_entries);
2697 tw_copy_info(&info, "Last sector count: %3d\n", tw_dev->sector_count);
2698 tw_copy_info(&info, "Max sector count: %3d\n", tw_dev->max_sector_count);
2699 tw_copy_info(&info, "Resets: %3d\n", tw_dev->num_resets);
2700 tw_copy_info(&info, "Aborts: %3d\n", tw_dev->num_aborts);
2701 tw_copy_info(&info, "AEN's: %3d\n", tw_dev->aen_count);
2703 if (info.position > info.offset) {
2704 return (info.position - info.offset);
2708 } /* End tw_scsi_proc_info() */
2710 /* This is the main scsi queue function to handle scsi opcodes */
2711 int tw_scsi_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
2713 unsigned char *command = SCpnt->cmnd;
2716 TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->host->hostdata;
2718 if (tw_dev == NULL) {
2719 printk(KERN_WARNING "3w-xxxx: tw_scsi_queue(): Invalid device extension.\n");
2720 SCpnt->result = (DID_ERROR << 16);
2725 spin_lock(&tw_dev->tw_lock);
2726 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue()\n");
2728 /* Skip scsi command if it isn't for us */
2729 if ((SCpnt->channel != 0) || (SCpnt->lun != 0)) {
2730 SCpnt->result = (DID_BAD_TARGET << 16);
2732 spin_unlock(&tw_dev->tw_lock);
2736 /* Save done function into Scsi_Cmnd struct */
2737 SCpnt->scsi_done = done;
2739 /* Queue the command and get a request id */
2740 tw_state_request_start(tw_dev, &request_id);
2742 /* Save the scsi command for use by the ISR */
2743 tw_dev->srb[request_id] = SCpnt;
2745 /* Initialize phase to zero */
2746 SCpnt->SCp.phase = 0;
2753 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught READ/WRITE.\n");
2754 error = tw_scsiop_read_write(tw_dev, request_id);
2756 case TEST_UNIT_READY:
2757 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught TEST_UNIT_READY.\n");
2758 error = tw_scsiop_test_unit_ready(tw_dev, request_id);
2761 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught INQUIRY.\n");
2762 error = tw_scsiop_inquiry(tw_dev, request_id);
2765 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught READ_CAPACITY.\n");
2766 error = tw_scsiop_read_capacity(tw_dev, request_id);
2769 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught REQUEST_SENSE.\n");
2770 error = tw_scsiop_request_sense(tw_dev, request_id);
2773 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught MODE_SENSE.\n");
2774 error = tw_scsiop_mode_sense(tw_dev, request_id);
2776 case SYNCHRONIZE_CACHE:
2777 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught SYNCHRONIZE_CACHE.\n");
2778 error = tw_scsiop_synchronize_cache(tw_dev, request_id);
2781 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught TW_SCSI_IOCTL.\n");
2782 error = tw_ioctl(tw_dev, request_id);
2785 printk(KERN_NOTICE "3w-xxxx: scsi%d: Unknown scsi opcode: 0x%x\n", tw_dev->host->host_no, *command);
2786 tw_dev->state[request_id] = TW_S_COMPLETED;
2787 tw_state_request_finish(tw_dev, request_id);
2788 SCpnt->result = (DID_BAD_TARGET << 16);
2792 tw_dev->state[request_id] = TW_S_COMPLETED;
2793 tw_state_request_finish(tw_dev, request_id);
2794 SCpnt->result = (DID_ERROR << 16);
2797 spin_unlock(&tw_dev->tw_lock);
2800 } /* End tw_scsi_queue() */
2802 /* This function will release the resources on an rmmod call */
2803 int tw_scsi_release(struct Scsi_Host *tw_host)
2805 TW_Device_Extension *tw_dev;
2806 tw_dev = (TW_Device_Extension *)tw_host->hostdata;
2808 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_release()\n");
2810 /* Fake like we just shut down, so notify the card that
2811 * we "shut down cleanly".
2813 tw_halt(0, 0, 0); // parameters aren't actually used
2815 /* Free up the IO region */
2816 release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
2818 /* Free up the IRQ */
2819 free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
2821 /* Unregister character device */
2822 if (twe_major >= 0) {
2823 unregister_chrdev(twe_major, "twe");
2827 /* Free up device extension resources */
2828 tw_free_device_extension(tw_dev);
2830 /* Tell kernel scsi-layer we are gone */
2831 scsi_unregister(tw_host);
2834 } /* End tw_scsi_release() */
2836 /* This function handles scsi inquiry commands */
2837 int tw_scsiop_inquiry(TW_Device_Extension *tw_dev, int request_id)
2840 TW_Command *command_packet;
2841 unsigned long command_que_value;
2842 u32 command_que_addr;
2843 unsigned long param_value;
2845 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry()\n");
2847 /* Initialize command packet */
2848 command_que_addr = tw_dev->registers.command_que_addr;
2849 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
2850 if (command_packet == NULL) {
2851 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad command packet virtual address.\n");
2854 memset(command_packet, 0, sizeof(TW_Sector));
2855 command_packet->byte0.opcode = TW_OP_GET_PARAM;
2856 command_packet->byte0.sgl_offset = 2;
2857 command_packet->size = 4;
2858 command_packet->request_id = request_id;
2859 command_packet->byte3.unit = 0;
2860 command_packet->byte3.host_id = 0;
2861 command_packet->status = 0;
2862 command_packet->flags = 0;
2863 command_packet->byte6.parameter_count = 1;
2865 /* Now setup the param */
2866 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
2867 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad alignment virtual address.\n");
2870 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
2871 memset(param, 0, sizeof(TW_Sector));
2872 param->table_id = 3; /* unit summary table */
2873 param->parameter_id = 3; /* unitsstatus parameter */
2874 param->parameter_size_bytes = TW_MAX_UNITS;
2875 param_value = tw_dev->alignment_physical_address[request_id];
2876 if (param_value == 0) {
2877 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad alignment physical address.\n");
2881 command_packet->byte8.param.sgl[0].address = param_value;
2882 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
2883 command_que_value = tw_dev->command_packet_physical_address[request_id];
2884 if (command_que_value == 0) {
2885 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad command packet physical address.\n");
2889 /* Now try to post the command packet */
2890 tw_post_command_packet(tw_dev, request_id);
2893 } /* End tw_scsiop_inquiry() */
2895 /* This function is called by the isr to complete an inquiry command */
2896 int tw_scsiop_inquiry_complete(TW_Device_Extension *tw_dev, int request_id)
2898 unsigned char *is_unit_present;
2899 unsigned char *request_buffer;
2902 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry_complete()\n");
2904 /* Fill request buffer */
2905 if (tw_dev->srb[request_id]->request_buffer == NULL) {
2906 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry_complete(): Request buffer NULL.\n");
2909 request_buffer = tw_dev->srb[request_id]->request_buffer;
2910 memset(request_buffer, 0, tw_dev->srb[request_id]->request_bufflen);
2911 request_buffer[0] = TYPE_DISK; /* Peripheral device type */
2912 request_buffer[1] = 0; /* Device type modifier */
2913 request_buffer[2] = 0; /* No ansi/iso compliance */
2914 request_buffer[4] = 31; /* Additional length */
2915 memcpy(&request_buffer[8], "3ware ", 8); /* Vendor ID */
2916 sprintf(&request_buffer[16], "Logical Disk %-2d ", tw_dev->srb[request_id]->target);
2917 memcpy(&request_buffer[32], tw_driver_version, 3);
2919 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
2920 if (param == NULL) {
2921 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry_complete(): Bad alignment virtual address.\n");
2924 is_unit_present = &(param->data[0]);
2926 if (is_unit_present[tw_dev->srb[request_id]->target] & TW_UNIT_ONLINE) {
2927 tw_dev->is_unit_present[tw_dev->srb[request_id]->target] = TRUE;
2929 tw_dev->is_unit_present[tw_dev->srb[request_id]->target] = FALSE;
2930 tw_dev->srb[request_id]->result = (DID_BAD_TARGET << 16);
2931 return TW_ISR_DONT_RESULT;
2935 } /* End tw_scsiop_inquiry_complete() */
2937 /* This function handles scsi mode_sense commands */
2938 int tw_scsiop_mode_sense(TW_Device_Extension *tw_dev, int request_id)
2941 TW_Command *command_packet;
2942 unsigned long command_que_value;
2943 unsigned long param_value;
2945 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_mode_sense()\n");
2947 /* Only page control = 0, page code = 0x8 (cache page) supported */
2948 if (tw_dev->srb[request_id]->cmnd[2] != 0x8) {
2949 tw_dev->state[request_id] = TW_S_COMPLETED;
2950 tw_state_request_finish(tw_dev, request_id);
2951 tw_dev->srb[request_id]->result = (DID_OK << 16);
2952 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
2956 /* Now read firmware cache setting for this unit */
2957 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
2958 if (command_packet == NULL) {
2959 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad command packet virtual address.\n");
2963 /* Setup the command packet */
2964 memset(command_packet, 0, sizeof(TW_Sector));
2965 command_packet->byte0.opcode = TW_OP_GET_PARAM;
2966 command_packet->byte0.sgl_offset = 2;
2967 command_packet->size = 4;
2968 command_packet->request_id = request_id;
2969 command_packet->byte3.unit = 0;
2970 command_packet->byte3.host_id = 0;
2971 command_packet->status = 0;
2972 command_packet->flags = 0;
2973 command_packet->byte6.parameter_count = 1;
2975 /* Setup the param */
2976 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
2977 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad alignment virtual address.\n");
2981 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
2982 memset(param, 0, sizeof(TW_Sector));
2983 param->table_id = TW_UNIT_INFORMATION_TABLE_BASE + tw_dev->srb[request_id]->target;
2984 param->parameter_id = 7; /* unit flags */
2985 param->parameter_size_bytes = 1;
2986 param_value = tw_dev->alignment_physical_address[request_id];
2987 if (param_value == 0) {
2988 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad alignment physical address.\n");
2992 command_packet->byte8.param.sgl[0].address = param_value;
2993 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
2994 command_que_value = tw_dev->command_packet_physical_address[request_id];
2995 if (command_que_value == 0) {
2996 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad command packet physical address.\n");
3000 /* Now try to post the command packet */
3001 tw_post_command_packet(tw_dev, request_id);
3004 } /* End tw_scsiop_mode_sense() */
3006 /* This function is called by the isr to complete a mode sense command */
3007 int tw_scsiop_mode_sense_complete(TW_Device_Extension *tw_dev, int request_id)
3010 unsigned char *flags;
3011 unsigned char *request_buffer;
3013 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_mode_sense_complete()\n");
3015 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
3016 if (param == NULL) {
3017 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense_complete(): Bad alignment virtual address.\n");
3020 flags = (char *)&(param->data[0]);
3021 request_buffer = tw_dev->srb[request_id]->buffer;
3022 memset(request_buffer, 0, tw_dev->srb[request_id]->request_bufflen);
3024 request_buffer[0] = 0xf; /* mode data length */
3025 request_buffer[1] = 0; /* default medium type */
3026 request_buffer[2] = 0x10; /* dpo/fua support on */
3027 request_buffer[3] = 0; /* no block descriptors */
3028 request_buffer[4] = 0x8; /* caching page */
3029 request_buffer[5] = 0xa; /* page length */
3031 request_buffer[6] = 0x4; /* WCE on */
3033 request_buffer[6] = 0x0; /* WCE off */
3036 } /* End tw_scsiop_mode_sense_complete() */
3038 /* This function handles scsi read_capacity commands */
3039 int tw_scsiop_read_capacity(TW_Device_Extension *tw_dev, int request_id)
3042 TW_Command *command_packet;
3043 unsigned long command_que_value;
3044 u32 command_que_addr;
3045 unsigned long param_value;
3047 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity()\n");
3049 /* Initialize command packet */
3050 command_que_addr = tw_dev->registers.command_que_addr;
3051 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
3053 if (command_packet == NULL) {
3054 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad command packet virtual address.\n");
3057 memset(command_packet, 0, sizeof(TW_Sector));
3058 command_packet->byte0.opcode = TW_OP_GET_PARAM;
3059 command_packet->byte0.sgl_offset = 2;
3060 command_packet->size = 4;
3061 command_packet->request_id = request_id;
3062 command_packet->byte3.unit = tw_dev->srb[request_id]->target;
3063 command_packet->byte3.host_id = 0;
3064 command_packet->status = 0;
3065 command_packet->flags = 0;
3066 command_packet->byte6.block_count = 1;
3068 /* Now setup the param */
3069 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
3070 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad alignment virtual address.\n");
3073 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
3074 memset(param, 0, sizeof(TW_Sector));
3075 param->table_id = TW_UNIT_INFORMATION_TABLE_BASE +
3076 tw_dev->srb[request_id]->target;
3077 param->parameter_id = 4; /* unitcapacity parameter */
3078 param->parameter_size_bytes = 4;
3079 param_value = tw_dev->alignment_physical_address[request_id];
3080 if (param_value == 0) {
3081 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad alignment physical address.\n");
3085 command_packet->byte8.param.sgl[0].address = param_value;
3086 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
3087 command_que_value = tw_dev->command_packet_physical_address[request_id];
3088 if (command_que_value == 0) {
3089 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad command packet physical address.\n");
3093 /* Now try to post the command to the board */
3094 tw_post_command_packet(tw_dev, request_id);
3097 } /* End tw_scsiop_read_capacity() */
3099 /* This function is called by the isr to complete a readcapacity command */
3100 int tw_scsiop_read_capacity_complete(TW_Device_Extension *tw_dev, int request_id)
3102 unsigned char *param_data;
3107 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity_complete()\n");
3109 buff = tw_dev->srb[request_id]->request_buffer;
3111 printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_capacity_complete(): Request buffer NULL.\n");
3114 memset(buff, 0, tw_dev->srb[request_id]->request_bufflen);
3115 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
3116 if (param == NULL) {
3117 printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_capacity_complete(): Bad alignment virtual address.\n");
3120 param_data = &(param->data[0]);
3122 capacity = (param_data[3] << 24) | (param_data[2] << 16) |
3123 (param_data[1] << 8) | param_data[0];
3125 /* Subtract one sector to fix get last sector ioctl */
3128 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity_complete(): Capacity = 0x%x.\n", capacity);
3130 /* Number of LBA's */
3131 buff[0] = (capacity >> 24);
3132 buff[1] = (capacity >> 16) & 0xff;
3133 buff[2] = (capacity >> 8) & 0xff;
3134 buff[3] = capacity & 0xff;
3136 /* Block size in bytes (512) */
3137 buff[4] = (TW_BLOCK_SIZE >> 24);
3138 buff[5] = (TW_BLOCK_SIZE >> 16) & 0xff;
3139 buff[6] = (TW_BLOCK_SIZE >> 8) & 0xff;
3140 buff[7] = TW_BLOCK_SIZE & 0xff;
3143 } /* End tw_scsiop_read_capacity_complete() */
3145 /* This function handles scsi read or write commands */
3146 int tw_scsiop_read_write(TW_Device_Extension *tw_dev, int request_id)
3148 TW_Command *command_packet;
3149 unsigned long command_que_value;
3150 u32 command_que_addr = 0x0;
3151 u32 lba = 0x0, num_sectors = 0x0, buffaddr = 0x0;
3152 int i, use_sg, count = 0;
3154 struct scatterlist *sglist;
3156 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write()\n");
3158 if (tw_dev->srb[request_id]->request_buffer == NULL) {
3159 printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_write(): Request buffer NULL.\n");
3162 sglist = (struct scatterlist *)tw_dev->srb[request_id]->request_buffer;
3163 srb = tw_dev->srb[request_id];
3165 /* Initialize command packet */
3166 command_que_addr = tw_dev->registers.command_que_addr;
3167 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
3168 if (command_packet == NULL) {
3169 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): Bad command packet virtual address.\n");
3173 if (srb->cmnd[0] == READ_6 || srb->cmnd[0] == READ_10) {
3174 command_packet->byte0.opcode = TW_OP_READ;
3176 command_packet->byte0.opcode = TW_OP_WRITE;
3179 command_packet->byte0.sgl_offset = 3;
3180 command_packet->size = 3;
3181 command_packet->request_id = request_id;
3182 command_packet->byte3.unit = srb->target;
3183 command_packet->byte3.host_id = 0;
3184 command_packet->status = 0;
3185 command_packet->flags = 0;
3187 if (srb->cmnd[0] == WRITE_10) {
3188 if ((srb->cmnd[1] & 0x8) || (srb->cmnd[1] & 0x10))
3189 command_packet->flags = 1;
3192 if (srb->cmnd[0] == READ_6 || srb->cmnd[0] == WRITE_6) {
3193 lba = ((u32)srb->cmnd[1] << 16) | ((u32)srb->cmnd[2] << 8) | (u32)srb->cmnd[3];
3194 num_sectors = (u32)srb->cmnd[4];
3196 lba = ((u32)srb->cmnd[2] << 24) | ((u32)srb->cmnd[3] << 16) | ((u32)srb->cmnd[4] << 8) | (u32)srb->cmnd[5];
3197 num_sectors = (u32)srb->cmnd[8] | ((u32)srb->cmnd[7] << 8);
3200 /* Update sector statistic */
3201 tw_dev->sector_count = num_sectors;
3202 if (tw_dev->sector_count > tw_dev->max_sector_count)
3203 tw_dev->max_sector_count = tw_dev->sector_count;
3205 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): lba = 0x%x num_sectors = 0x%x\n", lba, num_sectors);
3206 command_packet->byte8.io.lba = lba;
3207 command_packet->byte6.block_count = num_sectors;
3209 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)) {
3210 /* Do this if there are no sg list entries */
3211 if (tw_dev->srb[request_id]->use_sg == 0) {
3212 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): SG = 0\n");
3213 buffaddr = tw_map_scsi_single_data(tw_dev->tw_pci_dev, tw_dev->srb[request_id]);
3217 command_packet->byte8.io.sgl[0].address = buffaddr;
3218 command_packet->byte8.io.sgl[0].length = tw_dev->srb[request_id]->request_bufflen;
3219 command_packet->size+=2;
3222 /* Do this if we have multiple sg list entries */
3223 if (tw_dev->srb[request_id]->use_sg > 0) {
3224 use_sg = tw_map_scsi_sg_data(tw_dev->tw_pci_dev, tw_dev->srb[request_id]);
3228 for (i=0;i<use_sg; i++) {
3229 command_packet->byte8.io.sgl[i].address = sg_dma_address(&sglist[i]);
3230 command_packet->byte8.io.sgl[i].length = sg_dma_len(&sglist[i]);
3231 command_packet->size+=2;
3235 /* Do this if there are no sg list entries for raid 5 */
3236 if (tw_dev->srb[request_id]->use_sg == 0) {
3237 dprintk(KERN_WARNING "doing raid 5 write use_sg = 0, bounce_buffer[%d] = 0x%p\n", request_id, tw_dev->bounce_buffer[request_id]);
3238 buffaddr = tw_map_scsi_single_data(tw_dev->tw_pci_dev, tw_dev->srb[request_id]);
3242 memcpy(tw_dev->bounce_buffer[request_id], bus_to_virt(buffaddr), tw_dev->srb[request_id]->request_bufflen);
3243 command_packet->byte8.io.sgl[0].address = tw_dev->bounce_buffer_phys[request_id];
3244 command_packet->byte8.io.sgl[0].length = tw_dev->srb[request_id]->request_bufflen;
3245 command_packet->size+=2;
3248 /* Do this if we have multiple sg list entries for raid 5 */
3249 if (tw_dev->srb[request_id]->use_sg > 0) {
3250 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);
3251 use_sg = tw_map_scsi_sg_data(tw_dev->tw_pci_dev, tw_dev->srb[request_id]);
3255 for (i=0;i<use_sg; i++) {
3256 memcpy((char *)tw_dev->bounce_buffer[request_id]+count, bus_to_virt(sg_dma_address(&sglist[i])), sg_dma_len(&sglist[i]));
3257 count+=sg_dma_len(&sglist[i]);
3259 command_packet->byte8.io.sgl[0].address = tw_dev->bounce_buffer_phys[request_id];
3260 command_packet->byte8.io.sgl[0].length = count;
3261 command_packet->size = 5; /* single sgl */
3265 /* Update SG statistics */
3266 tw_dev->sgl_entries = tw_dev->srb[request_id]->use_sg;
3267 if (tw_dev->sgl_entries > tw_dev->max_sgl_entries)
3268 tw_dev->max_sgl_entries = tw_dev->sgl_entries;
3270 command_que_value = tw_dev->command_packet_physical_address[request_id];
3271 if (command_que_value == 0) {
3272 dprintk(KERN_WARNING "3w-xxxx: tw_scsiop_read_write(): Bad command packet physical address.\n");
3276 /* Now try to post the command to the board */
3277 tw_post_command_packet(tw_dev, request_id);
3280 } /* End tw_scsiop_read_write() */
3282 /* This function will handle the request sense scsi command */
3283 int tw_scsiop_request_sense(TW_Device_Extension *tw_dev, int request_id)
3285 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_request_sense()\n");
3287 /* For now we just zero the request buffer */
3288 memset(tw_dev->srb[request_id]->request_buffer, 0, tw_dev->srb[request_id]->request_bufflen);
3290 tw_dev->state[request_id] = TW_S_COMPLETED;
3291 tw_state_request_finish(tw_dev, request_id);
3293 /* If we got a request_sense, we probably want a reset, return error */
3294 tw_dev->srb[request_id]->result = (DID_ERROR << 16);
3295 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
3298 } /* End tw_scsiop_request_sense() */
3300 /* This function will handle synchronize cache scsi command */
3301 int tw_scsiop_synchronize_cache(TW_Device_Extension *tw_dev, int request_id)
3303 TW_Command *command_packet;
3304 unsigned long command_que_value;
3306 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_synchronize_cache()\n");
3308 /* Send firmware flush command for this unit */
3309 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
3310 if (command_packet == NULL) {
3311 printk(KERN_WARNING "3w-xxxx: tw_scsiop_synchronize_cache(): Bad command packet virtual address.\n");
3315 /* Setup the command packet */
3316 memset(command_packet, 0, sizeof(TW_Sector));
3317 command_packet->byte0.opcode = TW_OP_FLUSH_CACHE;
3318 command_packet->byte0.sgl_offset = 0;
3319 command_packet->size = 2;
3320 command_packet->request_id = request_id;
3321 command_packet->byte3.unit = tw_dev->srb[request_id]->target;
3322 command_packet->byte3.host_id = 0;
3323 command_packet->status = 0;
3324 command_packet->flags = 0;
3325 command_packet->byte6.parameter_count = 1;
3326 command_que_value = tw_dev->command_packet_physical_address[request_id];
3327 if (command_que_value == 0) {
3328 printk(KERN_WARNING "3w-xxxx: tw_scsiop_synchronize_cache(): Bad command packet physical address.\n");
3332 /* Now try to post the command packet */
3333 tw_post_command_packet(tw_dev, request_id);
3336 } /* End tw_scsiop_synchronize_cache() */
3338 /* This function will handle test unit ready scsi command */
3339 int tw_scsiop_test_unit_ready(TW_Device_Extension *tw_dev, int request_id)
3343 TW_Command *command_packet;
3344 unsigned long command_que_value;
3345 u32 command_que_addr;
3346 unsigned long param_value;
3348 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_test_unit_ready()\n");
3350 /* Initialize command packet */
3351 command_que_addr = tw_dev->registers.command_que_addr;
3352 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
3353 if (command_packet == NULL) {
3354 printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready(): Bad command packet virtual address.\n");
3357 memset(command_packet, 0, sizeof(TW_Sector));
3358 command_packet->byte0.opcode = TW_OP_GET_PARAM;
3359 command_packet->byte0.sgl_offset = 2;
3360 command_packet->size = 4;
3361 command_packet->request_id = request_id;
3362 command_packet->byte3.unit = 0;
3363 command_packet->byte3.host_id = 0;
3364 command_packet->status = 0;
3365 command_packet->flags = 0;
3366 command_packet->byte6.parameter_count = 1;
3368 /* Now setup the param */
3369 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
3370 printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready(): Bad alignment virtual address.\n");
3373 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
3374 memset(param, 0, sizeof(TW_Sector));
3375 param->table_id = 3; /* unit summary table */
3376 param->parameter_id = 3; /* unitsstatus parameter */
3377 param->parameter_size_bytes = TW_MAX_UNITS;
3378 param_value = tw_dev->alignment_physical_address[request_id];
3379 if (param_value == 0) {
3380 printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready(): Bad alignment physical address.\n");
3384 command_packet->byte8.param.sgl[0].address = param_value;
3385 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
3386 command_que_value = tw_dev->command_packet_physical_address[request_id];
3387 if (command_que_value == 0) {
3388 printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready(): Bad command packet physical address.\n");
3392 /* Now try to post the command packet */
3393 tw_post_command_packet(tw_dev, request_id);
3396 } /* End tw_scsiop_test_unit_ready() */
3398 /* This function is called by the isr to complete a testunitready command */
3399 int tw_scsiop_test_unit_ready_complete(TW_Device_Extension *tw_dev, int request_id)
3401 unsigned char *is_unit_present;
3404 dprintk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready_complete()\n");
3406 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
3407 if (param == NULL) {
3408 printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready_complete(): Bad alignment virtual address.\n");
3411 is_unit_present = &(param->data[0]);
3413 if (is_unit_present[tw_dev->srb[request_id]->target] & TW_UNIT_ONLINE) {
3414 tw_dev->is_unit_present[tw_dev->srb[request_id]->target] = TRUE;
3416 tw_dev->is_unit_present[tw_dev->srb[request_id]->target] = FALSE;
3417 tw_dev->srb[request_id]->result = (DID_BAD_TARGET << 16);
3418 return TW_ISR_DONT_RESULT;
3422 } /* End tw_scsiop_test_unit_ready_complete() */
3424 /* This function will select queue depths for a target */
3425 void tw_select_queue_depths(struct Scsi_Host *host, Scsi_Device *dev)
3428 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
3430 dprintk(KERN_WARNING "3w-xxxx: tw_select_queue_depths()\n");
3432 for (ptr = dev; ptr != NULL; ptr = ptr->next) {
3433 if (ptr->host == host) {
3434 if ((tw_dev->num_raid_five > 0) && (tw_dev->tw_pci_dev->device == TW_DEVICE_ID)) {
3435 ptr->queue_depth = (TW_MAX_BOUNCEBUF-2)/tw_dev->num_units;
3437 #ifdef CONFIG_3W_XXXX_CMD_PER_LUN
3438 ptr->queue_depth = CONFIG_3W_XXXX_CMD_PER_LUN;
3439 if (ptr->queue_depth > TW_MAX_CMDS_PER_LUN)
3440 ptr->queue_depth = TW_MAX_CMDS_PER_LUN;
3442 ptr->queue_depth = TW_MAX_CMDS_PER_LUN;
3447 } /* End tw_select_queue_depths() */
3449 /* Set a value in the features table */
3450 int tw_setfeature(TW_Device_Extension *tw_dev, int parm, int param_size,
3454 TW_Command *command_packet;
3455 TW_Response_Queue response_queue;
3457 unsigned long command_que_value;
3458 u32 command_que_addr;
3459 u32 response_que_addr;
3460 unsigned long param_value;
3462 /* Initialize SetParam command packet */
3463 if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
3464 printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad command packet virtual address.\n");
3467 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
3468 memset(command_packet, 0, sizeof(TW_Sector));
3469 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
3471 command_packet->byte0.opcode = TW_OP_SET_PARAM;
3472 command_packet->byte0.sgl_offset = 2;
3473 param->table_id = 0x404; /* Features table */
3474 param->parameter_id = parm;
3475 param->parameter_size_bytes = param_size;
3476 memcpy(param->data, val, param_size);
3478 param_value = tw_dev->alignment_physical_address[request_id];
3479 if (param_value == 0) {
3480 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Bad alignment physical address.\n");
3481 tw_dev->state[request_id] = TW_S_COMPLETED;
3482 tw_state_request_finish(tw_dev, request_id);
3483 tw_dev->srb[request_id]->result = (DID_OK << 16);
3484 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
3486 command_packet->byte8.param.sgl[0].address = param_value;
3487 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
3489 command_packet->size = 4;
3490 command_packet->request_id = request_id;
3491 command_packet->byte6.parameter_count = 1;
3493 command_que_value = tw_dev->command_packet_physical_address[request_id];
3494 if (command_que_value == 0) {
3495 printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad command packet physical address.\n");
3498 command_que_addr = tw_dev->registers.command_que_addr;
3499 response_que_addr = tw_dev->registers.response_que_addr;
3501 /* Send command packet to the board */
3502 outl(command_que_value, command_que_addr);
3504 /* Poll for completion */
3505 if (tw_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, 30) == 0) {
3506 response_queue.value = inl(response_que_addr);
3507 request_id = (unsigned char)response_queue.u.response_id;
3508 if (request_id != 0) {
3509 /* unexpected request id */
3510 printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Unexpected request id.\n");
3513 if (command_packet->status != 0) {
3515 tw_decode_sense(tw_dev, request_id, 0);
3521 } /* End tw_setfeature() */
3523 /* This function will setup the interrupt handler */
3524 int tw_setup_irq(TW_Device_Extension *tw_dev)
3526 char *device = TW_DEVICE_NAME;
3529 dprintk(KERN_NOTICE "3w-xxxx: tw_setup_irq()\n");
3530 error = request_irq(tw_dev->tw_pci_dev->irq, tw_interrupt, SA_SHIRQ, device, tw_dev);
3533 printk(KERN_WARNING "3w-xxxx: scsi%d: Error requesting IRQ: %d.\n", tw_dev->host->host_no, tw_dev->tw_pci_dev->irq);
3537 } /* End tw_setup_irq() */
3539 /* This function will tell the controller we're shutting down by sending
3540 initconnection with a 1 */
3541 int tw_shutdown_device(TW_Device_Extension *tw_dev)
3545 /* Disable interrupts */
3546 tw_disable_interrupts(tw_dev);
3548 /* poke the board */
3549 error = tw_initconnection(tw_dev, 1);
3551 printk(KERN_WARNING "3w-xxxx: scsi%d: Connection shutdown failed.\n", tw_dev->host->host_no);
3553 printk(KERN_NOTICE "3w-xxxx: Shutdown complete.\n");
3556 /* Re-enable interrupts */
3557 tw_enable_and_clear_interrupts(tw_dev);
3560 } /* End tw_shutdown_device() */
3562 /* This function will soft reset the controller */
3563 void tw_soft_reset(TW_Device_Extension *tw_dev)
3565 u32 control_reg_addr, control_reg_value;
3567 control_reg_addr = tw_dev->registers.control_reg_addr;
3568 control_reg_value = ( TW_CONTROL_ISSUE_SOFT_RESET |
3569 TW_CONTROL_CLEAR_HOST_INTERRUPT |
3570 TW_CONTROL_CLEAR_ATTENTION_INTERRUPT |
3571 TW_CONTROL_MASK_COMMAND_INTERRUPT |
3572 TW_CONTROL_MASK_RESPONSE_INTERRUPT |
3573 TW_CONTROL_CLEAR_ERROR_STATUS |
3574 TW_CONTROL_DISABLE_INTERRUPTS);
3575 outl(control_reg_value, control_reg_addr);
3576 } /* End tw_soft_reset() */
3578 /* This function will free a request_id */
3579 int tw_state_request_finish(TW_Device_Extension *tw_dev, int request_id)
3581 dprintk(KERN_NOTICE "3w-xxxx: tw_state_request_finish()\n");
3583 tw_dev->free_queue[tw_dev->free_tail] = request_id;
3584 tw_dev->state[request_id] = TW_S_FINISHED;
3585 if (tw_dev->free_tail == tw_dev->free_wrap)
3586 tw_dev->free_tail = TW_Q_START;
3588 tw_dev->free_tail++;
3590 dprintk(KERN_NOTICE "3w-xxxx: tw_state_request_finish(): Freeing request_id %d\n", request_id);
3593 } /* End tw_state_request_finish() */
3595 /* This function will assign an available request_id */
3596 int tw_state_request_start(TW_Device_Extension *tw_dev, int *request_id)
3600 dprintk(KERN_NOTICE "3w-xxxx: tw_state_request_start()\n");
3602 /* Obtain next free request_id */
3603 id = tw_dev->free_queue[tw_dev->free_head];
3604 if (tw_dev->free_head == tw_dev->free_wrap)
3605 tw_dev->free_head = TW_Q_START;
3607 tw_dev->free_head++;
3610 tw_dev->state[id] = TW_S_STARTED;
3612 dprintk(KERN_NOTICE "3w-xxxx: tw_state_request_start(): id = %d.\n", id);
3614 } /* End tw_state_request_start() */
3616 static void tw_unmap_scsi_data(struct pci_dev *pdev, Scsi_Cmnd *cmd)
3618 int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
3620 dprintk(KERN_WARNING "3w-xxxx: tw_unamp_scsi_data()\n");
3622 switch(cmd->SCp.phase) {
3624 #ifdef BLK_BOUNCE_HIGH
3625 pci_unmap_page(pdev, cmd->SCp.have_data_in, cmd->request_bufflen, dma_dir);
3627 pci_unmap_single(pdev, cmd->SCp.have_data_in, cmd->request_bufflen, dma_dir);
3631 pci_unmap_sg(pdev, cmd->request_buffer, cmd->use_sg, dma_dir);
3634 } /* End tw_unmap_scsi_data() */
3636 /* This function will unmask the command interrupt on the controller */
3637 void tw_unmask_command_interrupt(TW_Device_Extension *tw_dev)
3639 u32 control_reg_addr, control_reg_value;
3641 control_reg_addr = tw_dev->registers.control_reg_addr;
3642 control_reg_value = TW_CONTROL_UNMASK_COMMAND_INTERRUPT;
3643 outl(control_reg_value, control_reg_addr);
3644 } /* End tw_unmask_command_interrupt() */
3646 /* Now get things going */
3647 static Scsi_Host_Template driver_template = TWXXXX;
3648 #include "scsi_module.c"