2 3w-xxxx.c -- 3ware Storage Controller device driver for Linux.
4 Written By: Adam Radford <linuxraid@amcc.com>
5 Modifications By: Joel Jacobson <linux@3ware.com>
6 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
7 Brad Strand <linux@3ware.com>
9 Copyright (C) 1999-2004 3ware Inc.
11 Kernel compatiblity By: Andre Hedrick <andre@suse.com>
12 Non-Copyright (C) 2000 Andre Hedrick <andre@suse.com>
14 Further tiny build fixes and trivial hoovering Alan Cox
16 This program is free software; you can redistribute it and/or modify
17 it under the terms of the GNU General Public License as published by
18 the Free Software Foundation; version 2 of the License.
20 This program is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 GNU General Public License for more details.
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 Remove raid5 bounce buffers for raid5 for 6XXX for kernel 2.5
123 Add tw_map/unmap_scsi_sg/single_data() for kernel 2.5
124 Replace io_request_lock with host_lock for kernel 2.5
125 Set max_cmd_len to 16 for 3dm for kernel 2.5
126 1.02.00.016 - Set host->max_sectors back up to 256.
127 1.02.00.017 - Modified pci parity error handling/clearing from config space
128 during initialization.
129 1.02.00.018 - Better handling of request sense opcode and sense information
130 for failed commands. Add tw_decode_sense().
131 Replace all mdelay()'s with scsi_sleep().
132 1.02.00.019 - Revert mdelay's and scsi_sleep's, this caused problems on
134 1.02.00.020 - Add pci_set_dma_mask(), rewrite kmalloc()/virt_to_bus() to
135 pci_alloc/free_consistent().
136 Better alignment checking in tw_allocate_memory().
137 Cleanup tw_initialize_device_extension().
138 1.02.00.021 - Bump cmd_per_lun in SHT to 255 for better jbod performance.
139 Improve handling of errors in tw_interrupt().
140 Add handling/clearing of controller queue error.
141 Empty stale responses before draining aen queue.
142 Fix tw_scsi_eh_abort() to not reset on every io abort.
143 Set can_queue in SHT to 255 to prevent hang from AEN.
144 1.02.00.022 - Fix possible null pointer dereference in tw_scsi_release().
145 1.02.00.023 - Fix bug in tw_aen_drain_queue() where unit # was always zero.
146 1.02.00.024 - Add severity levels to AEN strings.
147 1.02.00.025 - Fix command interrupt spurious error messages.
148 Fix bug in raw command post with data ioctl method.
149 Fix bug where rollcall sometimes failed with cable errors.
150 Print unit # on all command timeouts.
151 1.02.00.026 - Fix possible infinite retry bug with power glitch induced
153 Cleanup some AEN severity levels.
154 1.02.00.027 - Add drive not supported AEN code for SATA controllers.
155 Remove spurious unknown ioctl error message.
156 1.02.00.028 - Fix bug where multiple controllers with no units were the
158 Fix bug where cards were being shut down more than once.
159 1.02.00.029 - Add missing pci_free_consistent() in tw_allocate_memory().
160 Replace pci_map_single() with pci_map_page() for highmem.
161 Check for tw_setfeature() failure.
162 1.02.00.030 - Make driver 64-bit clean.
163 1.02.00.031 - Cleanup polling timeouts/routines in several places.
164 Add support for mode sense opcode.
165 Add support for cache mode page.
166 Add support for synchronize cache opcode.
167 1.02.00.032 - Fix small multicard rollcall bug.
168 Make driver stay loaded with no units for hot add/swap.
169 Add support for "twe" character device for ioctls.
170 Clean up request_id queueing code.
171 Fix tw_scsi_queue() spinlocks.
172 1.02.00.033 - Fix tw_aen_complete() to not queue 'queue empty' AEN's.
173 Initialize queues correctly when loading with no valid units.
174 1.02.00.034 - Fix tw_decode_bits() to handle multiple errors.
175 Add support for user configurable cmd_per_lun.
176 Add support for sht->slave_configure().
177 1.02.00.035 - Improve tw_allocate_memory() memory allocation.
178 Fix tw_chrdev_ioctl() to sleep correctly.
179 1.02.00.036 - Increase character ioctl timeout to 60 seconds.
180 1.02.00.037 - Fix tw_ioctl() to handle all non-data ATA passthru cmds
181 for 'smartmontools' support.
182 1.26.00.038 - Roll driver minor version to 26 to denote kernel 2.6.
183 Add support for cmds_per_lun module parameter.
184 1.26.00.039 - Fix bug in tw_chrdev_ioctl() polling code.
185 Fix data_buffer_length usage in tw_chrdev_ioctl().
186 Update contact information.
189 #include <linux/module.h>
191 MODULE_AUTHOR ("3ware Inc.");
193 MODULE_DESCRIPTION ("3ware Storage Controller Linux Driver (SMP)");
195 MODULE_DESCRIPTION ("3ware Storage Controller Linux Driver");
197 MODULE_LICENSE("GPL");
199 #include <linux/kernel.h>
200 #include <linux/pci.h>
201 #include <linux/time.h>
202 #include <linux/proc_fs.h>
203 #include <linux/sched.h>
204 #include <linux/ioport.h>
205 #include <linux/blkdev.h>
206 #include <linux/hdreg.h>
207 #include <linux/string.h>
208 #include <linux/delay.h>
209 #include <linux/smp.h>
210 #include <linux/reboot.h>
211 #include <linux/spinlock.h>
212 #include <linux/interrupt.h>
213 #include <linux/moduleparam.h>
215 #include <asm/errno.h>
218 #include <asm/uaccess.h>
220 #define __3W_C /* let 3w-xxxx.h know it is use */
223 #include <scsi/scsi_host.h>
227 static int tw_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
228 static int tw_chrdev_open(struct inode *inode, struct file *file);
229 static int tw_chrdev_release(struct inode *inode, struct file *file);
230 static int tw_copy_info(TW_Info *info, char *fmt, ...);
231 static void tw_copy_mem_info(TW_Info *info, char *data, int len);
232 static int tw_halt(struct notifier_block *nb, ulong event, void *buf);
233 static int tw_map_scsi_sg_data(struct pci_dev *pdev, Scsi_Cmnd *cmd);
234 static u32 tw_map_scsi_single_data(struct pci_dev *pdev, Scsi_Cmnd *cmd);
235 static void tw_unmap_scsi_data(struct pci_dev *pdev, Scsi_Cmnd *cmd);
237 /* Notifier block to get a notify on system shutdown/halt/reboot */
238 static struct notifier_block tw_notifier = {
242 /* File operations struct for character device */
243 static struct file_operations tw_fops = {
244 .owner = THIS_MODULE,
245 .ioctl = tw_chrdev_ioctl,
246 .open = tw_chrdev_open,
247 .release = tw_chrdev_release
251 char *tw_driver_version="1.26.00.039";
252 TW_Device_Extension *tw_device_extension_list[TW_MAX_SLOT];
253 int tw_device_extension_count = 0;
254 static int twe_major = -1;
255 static int cmds_per_lun;
257 /* Module parameters */
258 module_param(cmds_per_lun, int, 0);
259 MODULE_PARM_DESC(cmds_per_lun, "Maximum commands per LUN");
263 /* This function will complete an aen request from the isr */
264 int tw_aen_complete(TW_Device_Extension *tw_dev, int request_id)
268 int error = 0, table_max = 0;
270 dprintk(KERN_WARNING "3w-xxxx: tw_aen_complete()\n");
271 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
272 printk(KERN_WARNING "3w-xxxx: tw_aen_complete(): Bad alignment virtual address.\n");
275 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
276 aen = *(unsigned short *)(param->data);
277 dprintk(KERN_NOTICE "3w-xxxx: tw_aen_complete(): Queue'd code 0x%x\n", aen);
279 /* Print some useful info when certain aen codes come out */
281 printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: INFO: AEN queue overflow.\n", tw_dev->host->host_no);
283 table_max = sizeof(tw_aen_string)/sizeof(char *);
284 if ((aen & 0x0ff) < table_max) {
285 if ((tw_aen_string[aen & 0xff][strlen(tw_aen_string[aen & 0xff])-1]) == '#') {
286 printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: %s%d.\n", tw_dev->host->host_no, tw_aen_string[aen & 0xff], aen >> 8);
289 printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: %s.\n", tw_dev->host->host_no, tw_aen_string[aen & 0xff]);
292 printk(KERN_WARNING "3w-xxxx: scsi%d: Received AEN %d.\n", tw_dev->host->host_no, aen);
295 if (aen != TW_AEN_QUEUE_EMPTY) {
298 /* Now queue the code */
299 tw_dev->aen_queue[tw_dev->aen_tail] = aen;
300 if (tw_dev->aen_tail == TW_Q_LENGTH - 1) {
301 tw_dev->aen_tail = TW_Q_START;
303 tw_dev->aen_tail = tw_dev->aen_tail + 1;
305 if (tw_dev->aen_head == tw_dev->aen_tail) {
306 if (tw_dev->aen_head == TW_Q_LENGTH - 1) {
307 tw_dev->aen_head = TW_Q_START;
309 tw_dev->aen_head = tw_dev->aen_head + 1;
313 error = tw_aen_read_queue(tw_dev, request_id);
315 printk(KERN_WARNING "3w-xxxx: scsi%d: Error completing AEN.\n", tw_dev->host->host_no);
316 tw_dev->state[request_id] = TW_S_COMPLETED;
317 tw_state_request_finish(tw_dev, request_id);
320 tw_dev->state[request_id] = TW_S_COMPLETED;
321 tw_state_request_finish(tw_dev, request_id);
325 } /* End tw_aen_complete() */
327 /* This function will drain the aen queue after a soft reset */
328 int tw_aen_drain_queue(TW_Device_Extension *tw_dev)
330 TW_Command *command_packet;
333 u32 command_que_addr;
334 unsigned long command_que_value;
335 unsigned long param_value;
336 TW_Response_Queue response_queue;
337 u32 response_que_addr;
339 unsigned short aen_code;
343 int found = 0, table_max = 0;
345 dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue()\n");
347 command_que_addr = tw_dev->registers.command_que_addr;
348 response_que_addr = tw_dev->registers.response_que_addr;
350 if (tw_poll_status(tw_dev, TW_STATUS_ATTENTION_INTERRUPT | TW_STATUS_MICROCONTROLLER_READY, 30)) {
351 dprintk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): No attention interrupt for card %d.\n", tw_device_extension_count);
354 tw_clear_attention_interrupt(tw_dev);
356 /* Empty response queue */
357 tw_empty_response_que(tw_dev);
359 /* Initialize command packet */
360 if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
361 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad command packet virtual address.\n");
364 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
365 memset(command_packet, 0, sizeof(TW_Sector));
366 command_packet->byte0.opcode = TW_OP_GET_PARAM;
367 command_packet->byte0.sgl_offset = 2;
368 command_packet->size = 4;
369 command_packet->request_id = request_id;
370 command_packet->byte3.unit = 0;
371 command_packet->byte3.host_id = 0;
372 command_packet->status = 0;
373 command_packet->flags = 0;
374 command_packet->byte6.parameter_count = 1;
375 command_que_value = tw_dev->command_packet_physical_address[request_id];
376 if (command_que_value == 0) {
377 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad command packet physical address.\n");
381 /* Now setup the param */
382 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
383 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad alignment virtual address.\n");
386 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
387 memset(param, 0, sizeof(TW_Sector));
388 param->table_id = 0x401; /* AEN table */
389 param->parameter_id = 2; /* Unit code */
390 param->parameter_size_bytes = 2;
391 param_value = tw_dev->alignment_physical_address[request_id];
392 if (param_value == 0) {
393 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad alignment physical address.\n");
396 command_packet->byte8.param.sgl[0].address = param_value;
397 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
399 /* Now drain the controller's aen queue */
401 /* Post command packet */
402 outl(command_que_value, command_que_addr);
404 /* Now poll for completion */
405 if (tw_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, 30) == 0) {
406 response_queue.value = inl(response_que_addr);
407 request_id = (unsigned char)response_queue.u.response_id;
409 if (request_id != 0) {
410 /* Unexpected request id */
411 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Unexpected request id.\n");
415 if (command_packet->status != 0) {
416 if (command_packet->flags != TW_AEN_TABLE_UNDEFINED) {
418 tw_decode_sense(tw_dev, request_id, 0);
421 /* We know this is a 3w-1x00, and doesn't support aen's */
426 /* Now check the aen */
427 aen = *(unsigned short *)(param->data);
428 aen_code = (aen & 0x0ff);
431 case TW_AEN_QUEUE_EMPTY:
432 dprintk(KERN_WARNING "3w-xxxx: AEN: %s.\n", tw_aen_string[aen & 0xff]);
433 if (first_reset != 1) {
439 case TW_AEN_SOFT_RESET:
440 if (first_reset == 0) {
443 printk(KERN_WARNING "3w-xxxx: AEN: %s.\n", tw_aen_string[aen & 0xff]);
450 printk(KERN_WARNING "3w-xxxx: AEN: INFO: AEN queue overflow.\n");
452 table_max = sizeof(tw_aen_string)/sizeof(char *);
453 if ((aen & 0x0ff) < table_max) {
454 if ((tw_aen_string[aen & 0xff][strlen(tw_aen_string[aen & 0xff])-1]) == '#') {
455 printk(KERN_WARNING "3w-xxxx: AEN: %s%d.\n", tw_aen_string[aen & 0xff], aen >> 8);
457 printk(KERN_WARNING "3w-xxxx: AEN: %s.\n", tw_aen_string[aen & 0xff]);
460 printk(KERN_WARNING "3w-xxxx: Received AEN %d.\n", aen);
466 /* Now put the aen on the aen_queue */
468 tw_dev->aen_queue[tw_dev->aen_tail] = aen;
469 if (tw_dev->aen_tail == TW_Q_LENGTH - 1) {
470 tw_dev->aen_tail = TW_Q_START;
472 tw_dev->aen_tail = tw_dev->aen_tail + 1;
474 if (tw_dev->aen_head == tw_dev->aen_tail) {
475 if (tw_dev->aen_head == TW_Q_LENGTH - 1) {
476 tw_dev->aen_head = TW_Q_START;
478 tw_dev->aen_head = tw_dev->aen_head + 1;
485 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Response never received.\n");
488 } while (finished == 0);
491 } /* End tw_aen_drain_queue() */
493 /* This function will read the aen queue from the isr */
494 int tw_aen_read_queue(TW_Device_Extension *tw_dev, int request_id)
496 TW_Command *command_packet;
498 u32 command_que_addr;
499 unsigned long command_que_value;
500 u32 status_reg_value = 0, status_reg_addr;
501 unsigned long param_value = 0;
503 dprintk(KERN_NOTICE "3w-xxxx: tw_aen_read_queue()\n");
504 command_que_addr = tw_dev->registers.command_que_addr;
505 status_reg_addr = tw_dev->registers.status_reg_addr;
507 status_reg_value = inl(status_reg_addr);
508 if (tw_check_bits(status_reg_value)) {
509 dprintk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Unexpected bits.\n");
510 tw_decode_bits(tw_dev, status_reg_value, 1);
513 if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
514 printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad command packet virtual address.\n");
517 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
518 memset(command_packet, 0, sizeof(TW_Sector));
519 command_packet->byte0.opcode = TW_OP_GET_PARAM;
520 command_packet->byte0.sgl_offset = 2;
521 command_packet->size = 4;
522 command_packet->request_id = request_id;
523 command_packet->byte3.unit = 0;
524 command_packet->byte3.host_id = 0;
525 command_packet->status = 0;
526 command_packet->flags = 0;
527 command_packet->byte6.parameter_count = 1;
528 command_que_value = tw_dev->command_packet_physical_address[request_id];
529 if (command_que_value == 0) {
530 printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad command packet physical address.\n");
533 /* Now setup the param */
534 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
535 printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad alignment virtual address.\n");
538 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
539 memset(param, 0, sizeof(TW_Sector));
540 param->table_id = 0x401; /* AEN table */
541 param->parameter_id = 2; /* Unit code */
542 param->parameter_size_bytes = 2;
543 param_value = tw_dev->alignment_physical_address[request_id];
544 if (param_value == 0) {
545 printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad alignment physical address.\n");
548 command_packet->byte8.param.sgl[0].address = param_value;
549 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
551 /* Now post the command packet */
552 if ((status_reg_value & TW_STATUS_COMMAND_QUEUE_FULL) == 0) {
553 dprintk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Post succeeded.\n");
554 tw_dev->srb[request_id] = 0; /* Flag internal command */
555 tw_dev->state[request_id] = TW_S_POSTED;
556 outl(command_que_value, command_que_addr);
558 printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Post failed, will retry.\n");
563 } /* End tw_aen_read_queue() */
565 /* This function will allocate memory */
566 int tw_allocate_memory(TW_Device_Extension *tw_dev, int size, int which)
569 dma_addr_t dma_handle;
570 unsigned long *cpu_addr = NULL;
572 dprintk(KERN_NOTICE "3w-xxxx: tw_allocate_memory()\n");
574 cpu_addr = pci_alloc_consistent(tw_dev->tw_pci_dev, size*TW_Q_LENGTH, &dma_handle);
575 if (cpu_addr == NULL) {
576 printk(KERN_WARNING "3w-xxxx: pci_alloc_consistent() failed.\n");
580 if ((unsigned long)cpu_addr % (tw_dev->tw_pci_dev->device == TW_DEVICE_ID ? TW_ALIGNMENT_6000 : TW_ALIGNMENT_7000)) {
581 printk(KERN_WARNING "3w-xxxx: Couldn't allocate correctly aligned memory.\n");
582 pci_free_consistent(tw_dev->tw_pci_dev, size*TW_Q_LENGTH, cpu_addr, dma_handle);
586 memset(cpu_addr, 0, size*TW_Q_LENGTH);
588 for (i=0;i<TW_Q_LENGTH;i++) {
591 tw_dev->command_packet_physical_address[i] = dma_handle+(i*size);
592 tw_dev->command_packet_virtual_address[i] = (unsigned long *)((unsigned char *)cpu_addr + (i*size));
595 tw_dev->alignment_physical_address[i] = dma_handle+(i*size);
596 tw_dev->alignment_virtual_address[i] = (unsigned long *)((unsigned char *)cpu_addr + (i*size));
599 printk(KERN_WARNING "3w-xxxx: tw_allocate_memory(): case slip in tw_allocate_memory()\n");
605 } /* End tw_allocate_memory() */
607 /* This function will check the status register for unexpected bits */
608 int tw_check_bits(u32 status_reg_value)
610 if ((status_reg_value & TW_STATUS_EXPECTED_BITS) != TW_STATUS_EXPECTED_BITS) {
611 dprintk(KERN_WARNING "3w-xxxx: tw_check_bits(): No expected bits (0x%x).\n", status_reg_value);
614 if ((status_reg_value & TW_STATUS_UNEXPECTED_BITS) != 0) {
615 dprintk(KERN_WARNING "3w-xxxx: tw_check_bits(): Found unexpected bits (0x%x).\n", status_reg_value);
620 } /* End tw_check_bits() */
622 /* This function will report controller error status */
623 int tw_check_errors(TW_Device_Extension *tw_dev)
625 u32 status_reg_addr, status_reg_value;
627 status_reg_addr = tw_dev->registers.status_reg_addr;
628 status_reg_value = inl(status_reg_addr);
630 if (TW_STATUS_ERRORS(status_reg_value) || tw_check_bits(status_reg_value)) {
631 tw_decode_bits(tw_dev, status_reg_value, 0);
636 } /* End tw_check_errors() */
638 /* This function handles ioctl for the character device */
639 static int tw_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
641 int error, request_id;
642 dma_addr_t dma_handle;
643 unsigned short tw_aen_code;
645 unsigned int data_buffer_length = 0;
646 unsigned long data_buffer_length_adjusted = 0;
647 unsigned long *cpu_addr;
649 TW_New_Ioctl *tw_ioctl;
650 TW_Passthru *passthru;
651 TW_Device_Extension *tw_dev = tw_device_extension_list[iminor(inode)];
652 int retval = -EFAULT;
653 void __user *argp = (void __user *)arg;
655 dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl()\n");
657 /* Only let one of these through at a time */
658 if (down_interruptible(&tw_dev->ioctl_sem))
661 /* First copy down the buffer length */
662 error = copy_from_user(&data_buffer_length, argp, sizeof(unsigned int));
667 if (data_buffer_length > TW_MAX_SECTORS * 512) {
672 /* Hardware can only do multiple of 512 byte transfers */
673 data_buffer_length_adjusted = (data_buffer_length + 511) & ~511;
675 /* Now allocate ioctl buf memory */
676 cpu_addr = pci_alloc_consistent(tw_dev->tw_pci_dev, data_buffer_length_adjusted+sizeof(TW_New_Ioctl) - 1, &dma_handle);
677 if (cpu_addr == NULL) {
682 tw_ioctl = (TW_New_Ioctl *)cpu_addr;
684 /* Now copy down the entire ioctl */
685 error = copy_from_user(tw_ioctl, argp, data_buffer_length + sizeof(TW_New_Ioctl) - 1);
689 passthru = (TW_Passthru *)&tw_ioctl->firmware_command;
691 /* See which ioctl we are doing */
694 dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl(): caught TW_OP_NOP.\n");
696 case TW_OP_AEN_LISTEN:
697 dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl(): caught TW_AEN_LISTEN.\n");
698 memset(tw_ioctl->data_buffer, 0, data_buffer_length);
700 spin_lock_irqsave(tw_dev->host->host_lock, flags);
701 if (tw_dev->aen_head == tw_dev->aen_tail) {
702 tw_aen_code = TW_AEN_QUEUE_EMPTY;
704 tw_aen_code = tw_dev->aen_queue[tw_dev->aen_head];
705 if (tw_dev->aen_head == TW_Q_LENGTH - 1) {
706 tw_dev->aen_head = TW_Q_START;
708 tw_dev->aen_head = tw_dev->aen_head + 1;
711 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
712 memcpy(tw_ioctl->data_buffer, &tw_aen_code, sizeof(tw_aen_code));
714 case TW_CMD_PACKET_WITH_DATA:
715 dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl(): caught TW_CMD_PACKET_WITH_DATA.\n");
716 spin_lock_irqsave(&tw_dev->tw_lock, flags);
718 tw_state_request_start(tw_dev, &request_id);
720 /* Flag internal command */
721 tw_dev->srb[request_id] = 0;
723 /* Flag chrdev ioctl */
724 tw_dev->chrdev_request_id = request_id;
726 tw_ioctl->firmware_command.request_id = request_id;
728 /* Load the sg list */
729 switch (tw_ioctl->firmware_command.byte0.sgl_offset) {
731 tw_ioctl->firmware_command.byte8.param.sgl[0].address = dma_handle + sizeof(TW_New_Ioctl) - 1;
732 tw_ioctl->firmware_command.byte8.param.sgl[0].length = data_buffer_length_adjusted;
735 tw_ioctl->firmware_command.byte8.io.sgl[0].address = dma_handle + sizeof(TW_New_Ioctl) - 1;
736 tw_ioctl->firmware_command.byte8.io.sgl[0].length = data_buffer_length_adjusted;
739 passthru->sg_list[0].address = dma_handle + sizeof(TW_New_Ioctl) - 1;
740 passthru->sg_list[0].length = data_buffer_length_adjusted;
744 memcpy(tw_dev->command_packet_virtual_address[request_id], &(tw_ioctl->firmware_command), sizeof(TW_Command));
746 /* Now post the command packet to the controller */
747 tw_post_command_packet(tw_dev, request_id);
748 spin_unlock_irqrestore(&tw_dev->tw_lock, flags);
750 timeout = TW_IOCTL_CHRDEV_TIMEOUT*HZ;
752 /* Now wait for the command to complete */
753 timeout = wait_event_interruptible_timeout(tw_dev->ioctl_wqueue, tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE, timeout);
755 /* Check if we timed out, got a signal, or didn't get
757 if ((timeout <= 0) && (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE)) {
758 /* Now we need to reset the board */
759 if (timeout == -ERESTARTSYS) {
762 printk(KERN_WARNING "3w-xxxx: scsi%d: Character ioctl (0x%x) timed out, resetting card.\n", tw_dev->host->host_no, cmd);
765 spin_lock_irqsave(&tw_dev->tw_lock, flags);
766 tw_dev->state[request_id] = TW_S_COMPLETED;
767 tw_state_request_finish(tw_dev, request_id);
768 tw_dev->posted_request_count--;
769 if (tw_reset_device_extension(tw_dev)) {
770 printk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl(): Reset failed for card %d.\n", tw_dev->host->host_no);
772 spin_unlock_irqrestore(&tw_dev->tw_lock, flags);
776 /* Now copy in the command packet response */
777 memcpy(&(tw_ioctl->firmware_command), tw_dev->command_packet_virtual_address[request_id], sizeof(TW_Command));
779 /* Now complete the io */
780 spin_lock_irqsave(&tw_dev->tw_lock, flags);
781 tw_dev->posted_request_count--;
782 tw_dev->state[request_id] = TW_S_COMPLETED;
783 tw_state_request_finish(tw_dev, request_id);
784 spin_unlock_irqrestore(&tw_dev->tw_lock, flags);
791 /* Now copy the response to userspace */
792 error = copy_to_user(argp, tw_ioctl, sizeof(TW_New_Ioctl) + data_buffer_length - 1);
796 /* Now free ioctl buf memory */
797 pci_free_consistent(tw_dev->tw_pci_dev, data_buffer_length_adjusted+sizeof(TW_New_Ioctl) - 1, cpu_addr, dma_handle);
799 up(&tw_dev->ioctl_sem);
801 } /* End tw_chrdev_ioctl() */
803 /* This function handles open for the character device */
804 static int tw_chrdev_open(struct inode *inode, struct file *file)
806 unsigned int minor_number;
808 dprintk(KERN_WARNING "3w-xxxx: tw_ioctl_open()\n");
810 minor_number = iminor(inode);
811 if (minor_number >= tw_device_extension_count)
815 } /* End tw_chrdev_open() */
817 /* This function handles close for the character device */
818 static int tw_chrdev_release(struct inode *inode, struct file *file)
820 dprintk(KERN_WARNING "3w-xxxx: tw_ioctl_release()\n");
823 } /* End tw_chrdev_release() */
825 /* This function will clear all interrupts on the controller */
826 void tw_clear_all_interrupts(TW_Device_Extension *tw_dev)
828 u32 control_reg_addr, control_reg_value;
830 control_reg_addr = tw_dev->registers.control_reg_addr;
831 control_reg_value = TW_STATUS_VALID_INTERRUPT;
832 outl(control_reg_value, control_reg_addr);
833 } /* End tw_clear_all_interrupts() */
835 /* This function will clear the attention interrupt */
836 void tw_clear_attention_interrupt(TW_Device_Extension *tw_dev)
838 u32 control_reg_addr, control_reg_value;
840 control_reg_addr = tw_dev->registers.control_reg_addr;
841 control_reg_value = TW_CONTROL_CLEAR_ATTENTION_INTERRUPT;
842 outl(control_reg_value, control_reg_addr);
843 } /* End tw_clear_attention_interrupt() */
845 /* This function will clear the host interrupt */
846 void tw_clear_host_interrupt(TW_Device_Extension *tw_dev)
848 u32 control_reg_addr, control_reg_value;
850 control_reg_addr = tw_dev->registers.control_reg_addr;
851 control_reg_value = TW_CONTROL_CLEAR_HOST_INTERRUPT;
852 outl(control_reg_value, control_reg_addr);
853 } /* End tw_clear_host_interrupt() */
855 /* This function is called by tw_scsi_proc_info */
856 static int tw_copy_info(TW_Info *info, char *fmt, ...)
863 len = vsprintf(buf, fmt, args);
865 tw_copy_mem_info(info, buf, len);
867 } /* End tw_copy_info() */
869 /* This function is called by tw_scsi_proc_info */
870 static void tw_copy_mem_info(TW_Info *info, char *data, int len)
872 if (info->position + len > info->length)
873 len = info->length - info->position;
875 if (info->position + len < info->offset) {
876 info->position += len;
879 if (info->position < info->offset) {
880 data += (info->offset - info->position);
881 len -= (info->offset - info->position);
884 memcpy(info->buffer + info->position, data, len);
885 info->position += len;
887 } /* End tw_copy_mem_info() */
889 /* This function will print readable messages from status register errors */
890 int tw_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value, int print_host)
894 dprintk(KERN_WARNING "3w-xxxx: tw_decode_bits()\n");
897 sprintf(host, " scsi%d:", tw_dev->host->host_no);
901 if (status_reg_value & TW_STATUS_PCI_PARITY_ERROR) {
902 printk(KERN_WARNING "3w-xxxx:%s PCI Parity Error: clearing.\n", host);
903 outl(TW_CONTROL_CLEAR_PARITY_ERROR, tw_dev->registers.control_reg_addr);
906 if (status_reg_value & TW_STATUS_PCI_ABORT) {
907 printk(KERN_WARNING "3w-xxxx:%s PCI Abort: clearing.\n", host);
908 outl(TW_CONTROL_CLEAR_PCI_ABORT, tw_dev->registers.control_reg_addr);
909 pci_write_config_word(tw_dev->tw_pci_dev, PCI_STATUS, TW_PCI_CLEAR_PCI_ABORT);
912 if (status_reg_value & TW_STATUS_QUEUE_ERROR) {
913 printk(KERN_WARNING "3w-xxxx:%s Controller Queue Error: clearing.\n", host);
914 outl(TW_CONTROL_CLEAR_QUEUE_ERROR, tw_dev->registers.control_reg_addr);
917 if (status_reg_value & TW_STATUS_SBUF_WRITE_ERROR) {
918 printk(KERN_WARNING "3w-xxxx:%s SBUF Write Error: clearing.\n", host);
919 outl(TW_CONTROL_CLEAR_SBUF_WRITE_ERROR, tw_dev->registers.control_reg_addr);
922 if (status_reg_value & TW_STATUS_MICROCONTROLLER_ERROR) {
923 if (tw_dev->reset_print == 0) {
924 printk(KERN_WARNING "3w-xxxx:%s Microcontroller Error: clearing.\n", host);
925 tw_dev->reset_print = 1;
931 } /* End tw_decode_bits() */
933 /* This function will return valid sense buffer information for failed cmds */
934 int tw_decode_sense(TW_Device_Extension *tw_dev, int request_id, int fill_sense)
939 dprintk(KERN_WARNING "3w-xxxx: tw_decode_sense()\n");
940 command = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
942 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);
944 /* Attempt to return intelligent sense information */
946 if ((command->status == 0xc7) || (command->status == 0xcb)) {
947 for (i=0;i<(sizeof(tw_sense_table)/sizeof(tw_sense_table[0]));i++) {
948 if (command->flags == tw_sense_table[i][0]) {
950 /* Valid bit and 'current errors' */
951 tw_dev->srb[request_id]->sense_buffer[0] = (0x1 << 7 | 0x70);
954 tw_dev->srb[request_id]->sense_buffer[2] = tw_sense_table[i][1];
956 /* Additional sense length */
957 tw_dev->srb[request_id]->sense_buffer[7] = 0xa; /* 10 bytes */
959 /* Additional sense code */
960 tw_dev->srb[request_id]->sense_buffer[12] = tw_sense_table[i][2];
962 /* Additional sense code qualifier */
963 tw_dev->srb[request_id]->sense_buffer[13] = tw_sense_table[i][3];
965 tw_dev->srb[request_id]->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
966 return TW_ISR_DONT_RESULT; /* Special case for isr to not over-write result */
971 /* If no table match, error so we get a reset */
976 } /* End tw_decode_sense() */
978 /* This function will disable interrupts on the controller */
979 void tw_disable_interrupts(TW_Device_Extension *tw_dev)
981 u32 control_reg_value, control_reg_addr;
983 control_reg_addr = tw_dev->registers.control_reg_addr;
984 control_reg_value = TW_CONTROL_DISABLE_INTERRUPTS;
985 outl(control_reg_value, control_reg_addr);
986 } /* End tw_disable_interrupts() */
988 /* This function will empty the response que */
989 void tw_empty_response_que(TW_Device_Extension *tw_dev)
991 u32 status_reg_addr, status_reg_value;
992 u32 response_que_addr, response_que_value;
994 status_reg_addr = tw_dev->registers.status_reg_addr;
995 response_que_addr = tw_dev->registers.response_que_addr;
997 status_reg_value = inl(status_reg_addr);
999 while ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
1000 response_que_value = inl(response_que_addr);
1001 status_reg_value = inl(status_reg_addr);
1003 } /* End tw_empty_response_que() */
1005 /* This function will enable interrupts on the controller */
1006 void tw_enable_interrupts(TW_Device_Extension *tw_dev)
1008 u32 control_reg_value, control_reg_addr;
1010 control_reg_addr = tw_dev->registers.control_reg_addr;
1011 control_reg_value = (TW_CONTROL_ENABLE_INTERRUPTS |
1012 TW_CONTROL_UNMASK_RESPONSE_INTERRUPT);
1013 outl(control_reg_value, control_reg_addr);
1014 } /* End tw_enable_interrupts() */
1016 /* This function will enable interrupts on the controller */
1017 void tw_enable_and_clear_interrupts(TW_Device_Extension *tw_dev)
1019 u32 control_reg_value, control_reg_addr;
1021 control_reg_addr = tw_dev->registers.control_reg_addr;
1022 control_reg_value = (TW_CONTROL_CLEAR_ATTENTION_INTERRUPT |
1023 TW_CONTROL_UNMASK_RESPONSE_INTERRUPT |
1024 TW_CONTROL_ENABLE_INTERRUPTS);
1025 outl(control_reg_value, control_reg_addr);
1026 } /* End tw_enable_and_clear_interrupts() */
1028 /* This function will find and initialize all cards */
1029 int tw_findcards(Scsi_Host_Template *tw_host)
1031 int numcards = 0, tries = 0, error = 0;
1032 struct Scsi_Host *host;
1033 TW_Device_Extension *tw_dev;
1034 TW_Device_Extension *tw_dev2;
1035 struct pci_dev *tw_pci_dev = NULL;
1036 u32 status_reg_value;
1037 unsigned char c = 1;
1039 u16 device[TW_NUMDEVICES] = { TW_DEVICE_ID, TW_DEVICE_ID2 };
1041 dprintk(KERN_NOTICE "3w-xxxx: tw_findcards()\n");
1043 for (i=0;i<TW_NUMDEVICES;i++) {
1044 while ((tw_pci_dev = pci_find_device(TW_VENDOR_ID, device[i], tw_pci_dev))) {
1046 if (pci_enable_device(tw_pci_dev))
1049 /* We only need 32-bit addressing for 5,6,7xxx cards */
1050 if (pci_set_dma_mask(tw_pci_dev, 0xffffffff)) {
1051 printk(KERN_WARNING "3w-xxxx: No suitable DMA available.\n");
1055 /* Prepare temporary device extension */
1056 tw_dev=(TW_Device_Extension *)kmalloc(sizeof(TW_Device_Extension), GFP_ATOMIC);
1057 if (tw_dev == NULL) {
1058 printk(KERN_WARNING "3w-xxxx: tw_findcards(): kmalloc() failed for card %d.\n", j);
1061 memset(tw_dev, 0, sizeof(TW_Device_Extension));
1063 /* Save pci_dev struct to device extension */
1064 tw_dev->tw_pci_dev = tw_pci_dev;
1066 error = tw_initialize_device_extension(tw_dev);
1068 printk(KERN_WARNING "3w-xxxx: tw_findcards(): Couldn't initialize device extension for card %d.\n", j);
1069 tw_free_device_extension(tw_dev);
1074 /* Calculate the cards register addresses */
1075 tw_dev->registers.base_addr = pci_resource_start(tw_pci_dev, 0);
1076 tw_dev->registers.control_reg_addr = pci_resource_start(tw_pci_dev, 0);
1077 tw_dev->registers.status_reg_addr = pci_resource_start(tw_pci_dev, 0) + 0x4;
1078 tw_dev->registers.command_que_addr = pci_resource_start(tw_pci_dev, 0) + 0x8;
1079 tw_dev->registers.response_que_addr = pci_resource_start(tw_pci_dev, 0) + 0xC;
1081 /* Check for errors and clear them */
1082 status_reg_value = inl(tw_dev->registers.status_reg_addr);
1083 if (TW_STATUS_ERRORS(status_reg_value))
1084 tw_decode_bits(tw_dev, status_reg_value, 0);
1086 /* Poll status register for 60 secs for 'Controller Ready' flag */
1087 if (tw_poll_status(tw_dev, TW_STATUS_MICROCONTROLLER_READY, 60)) {
1088 printk(KERN_WARNING "3w-xxxx: tw_findcards(): Microcontroller not ready for card %d.\n", j);
1089 tw_free_device_extension(tw_dev);
1094 /* Disable interrupts on the card */
1095 tw_disable_interrupts(tw_dev);
1099 while (tries < TW_MAX_RESET_TRIES) {
1101 tw_soft_reset(tw_dev);
1103 error = tw_aen_drain_queue(tw_dev);
1105 printk(KERN_WARNING "3w-xxxx: AEN drain failed for card %d.\n", j);
1110 /* Check for controller errors */
1111 if (tw_check_errors(tw_dev)) {
1112 printk(KERN_WARNING "3w-xxxx: Controller errors found, retrying for card %d.\n", j);
1117 /* Now the controller is in a good state */
1121 if (tries >= TW_MAX_RESET_TRIES) {
1122 printk(KERN_WARNING "3w-xxxx: Controller errors, card not responding, check all cabling for card %d.\n", j);
1123 tw_free_device_extension(tw_dev);
1128 /* Reserve the io address space */
1129 if (!request_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE, TW_DEVICE_NAME)) {
1130 printk(KERN_WARNING "3w-xxxx: tw_findcards(): Couldn't get io range 0x%lx-0x%lx for card %d.\n",
1131 (tw_dev->tw_pci_dev->resource[0].start),
1132 (tw_dev->tw_pci_dev->resource[0].start) +
1133 TW_IO_ADDRESS_RANGE, j);
1134 tw_free_device_extension(tw_dev);
1139 error = tw_initialize_units(tw_dev);
1141 printk(KERN_WARNING "3w-xxxx: No valid units for 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 tw_dev->free_head = TW_Q_START;
1157 tw_dev->free_tail = TW_Q_START;
1158 tw_dev->free_wrap = TW_Q_LENGTH - 1;
1160 /* Register the card with the kernel SCSI layer */
1161 host = scsi_register(tw_host, sizeof(TW_Device_Extension));
1163 printk(KERN_WARNING "3w-xxxx: tw_findcards(): scsi_register() failed for card %d.\n", j);
1164 release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
1165 tw_free_device_extension(tw_dev);
1170 /* Set max target id's */
1171 host->max_id = TW_MAX_UNITS;
1173 /* Set max cdb size in bytes */
1174 host->max_cmd_len = 16;
1176 /* Set max sectors per io */
1177 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7)
1178 host->max_sectors = TW_MAX_SECTORS;
1181 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
1182 scsi_set_device(host, &tw_pci_dev->dev);
1183 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4)
1184 scsi_set_pci_device(host, tw_pci_dev);
1187 status_reg_value = inl(tw_dev->registers.status_reg_addr);
1189 printk(KERN_NOTICE "scsi%d : Found a 3ware Storage Controller at 0x%x, IRQ: %d, P-chip: %d.%d\n", host->host_no,
1190 (u32)(tw_pci_dev->resource[0].start), tw_pci_dev->irq,
1191 (status_reg_value & TW_STATUS_MAJOR_VERSION_MASK) >> 28,
1192 (status_reg_value & TW_STATUS_MINOR_VERSION_MASK) >> 24);
1194 if (host->hostdata) {
1195 tw_dev2 = (TW_Device_Extension *)host->hostdata;
1196 memcpy(tw_dev2, tw_dev, sizeof(TW_Device_Extension));
1197 /* Need to init the sem/wqueue after the copy */
1198 init_MUTEX(&tw_dev2->ioctl_sem);
1199 init_waitqueue_head(&tw_dev2->ioctl_wqueue);
1201 tw_device_extension_list[tw_device_extension_count] = tw_dev2;
1203 tw_device_extension_count = numcards;
1204 tw_dev2->host = host;
1206 printk(KERN_WARNING "3w-xxxx: tw_findcards(): Bad scsi host data for card %d.\n", j);
1207 scsi_unregister(host);
1208 release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
1209 tw_free_device_extension(tw_dev);
1214 /* Tell the firmware we support shutdown notification*/
1215 error = tw_setfeature(tw_dev2, 2, 1, &c);
1217 printk(KERN_WARNING "3w-xxxx: Unable to set features for card %d, old firmware or card.\n", j);
1220 /* Now setup the interrupt handler */
1221 error = tw_setup_irq(tw_dev2);
1223 printk(KERN_WARNING "3w-xxxx: tw_findcards(): Error requesting irq for card %d.\n", j);
1224 scsi_unregister(host);
1225 release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
1227 tw_free_device_extension(tw_dev);
1233 /* Re-enable interrupts on the card */
1234 tw_enable_interrupts(tw_dev2);
1236 /* Free the temporary device extension */
1242 if (numcards == 0) {
1243 printk(KERN_WARNING "3w-xxxx: No cards found.\n");
1245 register_reboot_notifier(&tw_notifier);
1246 if ((twe_major = register_chrdev (0, "twe", &tw_fops)) < 0) {
1247 printk(KERN_WARNING "3w-xxxx: Unable to register \"twe\" character device, error = %d.\n", twe_major);
1252 } /* End tw_findcards() */
1254 /* This function will free up device extension resources */
1255 void tw_free_device_extension(TW_Device_Extension *tw_dev)
1257 dprintk(KERN_NOTICE "3w-xxxx: tw_free_device_extension()\n");
1259 /* Free command packet and generic buffer memory */
1260 if (tw_dev->command_packet_virtual_address[0])
1261 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]);
1263 if (tw_dev->alignment_virtual_address[0])
1264 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]);
1265 } /* End tw_free_device_extension() */
1267 /* Clean shutdown routine */
1268 static int tw_halt(struct notifier_block *nb, ulong event, void *buf)
1272 for (i=0;i<tw_device_extension_count;i++) {
1273 if (tw_device_extension_list[i]->online == 1) {
1274 printk(KERN_NOTICE "3w-xxxx: Shutting down card %d.\n", i);
1275 tw_shutdown_device(tw_device_extension_list[i]);
1276 tw_device_extension_list[i]->online = 0;
1279 unregister_reboot_notifier(&tw_notifier);
1282 } /* End tw_halt() */
1284 /* This function will send an initconnection command to controller */
1285 int tw_initconnection(TW_Device_Extension *tw_dev, int message_credits)
1287 unsigned long command_que_value;
1288 u32 command_que_addr;
1289 u32 response_que_addr;
1290 TW_Command *command_packet;
1291 TW_Response_Queue response_queue;
1294 dprintk(KERN_NOTICE "3w-xxxx: tw_initconnection()\n");
1295 command_que_addr = tw_dev->registers.command_que_addr;
1296 response_que_addr = tw_dev->registers.response_que_addr;
1298 /* Initialize InitConnection command packet */
1299 if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
1300 printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad command packet virtual address.\n");
1304 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1305 memset(command_packet, 0, sizeof(TW_Sector));
1306 command_packet->byte0.opcode = TW_OP_INIT_CONNECTION;
1307 command_packet->byte0.sgl_offset = 0x0;
1308 command_packet->size = TW_INIT_COMMAND_PACKET_SIZE;
1309 command_packet->request_id = request_id;
1310 command_packet->byte3.unit = 0x0;
1311 command_packet->byte3.host_id = 0x0;
1312 command_packet->status = 0x0;
1313 command_packet->flags = 0x0;
1314 command_packet->byte6.message_credits = message_credits;
1315 command_packet->byte8.init_connection.response_queue_pointer = 0x0;
1316 command_que_value = tw_dev->command_packet_physical_address[request_id];
1318 if (command_que_value == 0) {
1319 printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad command packet physical address.\n");
1323 /* Send command packet to the board */
1324 outl(command_que_value, command_que_addr);
1326 /* Poll for completion */
1327 if (tw_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, 30) == 0) {
1328 response_queue.value = inl(response_que_addr);
1329 request_id = (unsigned char)response_queue.u.response_id;
1330 if (request_id != 0) {
1331 /* unexpected request id */
1332 printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Unexpected request id.\n");
1335 if (command_packet->status != 0) {
1337 tw_decode_sense(tw_dev, request_id, 0);
1342 } /* End tw_initconnection() */
1344 /* This function will initialize the fields of a device extension */
1345 int tw_initialize_device_extension(TW_Device_Extension *tw_dev)
1349 dprintk(KERN_NOTICE "3w-xxxx: tw_initialize_device_extension()\n");
1351 /* Initialize command packet buffers */
1352 error = tw_allocate_memory(tw_dev, sizeof(TW_Command), 0);
1354 printk(KERN_WARNING "3w-xxxx: Command packet memory allocation failed.\n");
1358 /* Initialize generic buffer */
1359 error = tw_allocate_memory(tw_dev, sizeof(TW_Sector), 1);
1361 printk(KERN_WARNING "3w-xxxx: Generic memory allocation failed.\n");
1365 for (i=0;i<TW_Q_LENGTH;i++) {
1366 tw_dev->free_queue[i] = i;
1367 tw_dev->state[i] = TW_S_INITIAL;
1370 tw_dev->pending_head = TW_Q_START;
1371 tw_dev->pending_tail = TW_Q_START;
1372 spin_lock_init(&tw_dev->tw_lock);
1373 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1376 } /* End tw_initialize_device_extension() */
1378 /* This function will get unit info from the controller */
1379 int tw_initialize_units(TW_Device_Extension *tw_dev)
1382 unsigned char request_id = 0;
1383 TW_Command *command_packet;
1385 int i, imax, num_units = 0;
1386 unsigned long command_que_value;
1387 u32 command_que_addr;
1388 u32 response_que_addr;
1389 TW_Response_Queue response_queue;
1390 unsigned long param_value;
1391 unsigned char *is_unit_present;
1393 dprintk(KERN_NOTICE "3w-xxxx: tw_initialize_units()\n");
1395 command_que_addr = tw_dev->registers.command_que_addr;
1396 response_que_addr = tw_dev->registers.response_que_addr;
1398 /* Setup the command packet */
1399 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1400 if (command_packet == NULL) {
1401 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad command packet virtual address.\n");
1404 memset(command_packet, 0, sizeof(TW_Sector));
1405 command_packet->byte0.opcode = TW_OP_GET_PARAM;
1406 command_packet->byte0.sgl_offset = 2;
1407 command_packet->size = 4;
1408 command_packet->request_id = request_id;
1409 command_packet->byte3.unit = 0;
1410 command_packet->byte3.host_id = 0;
1411 command_packet->status = 0;
1412 command_packet->flags = 0;
1413 command_packet->byte6.block_count = 1;
1415 /* Now setup the param */
1416 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
1417 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad alignment virtual address.\n");
1420 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1421 memset(param, 0, sizeof(TW_Sector));
1422 param->table_id = 3; /* unit summary table */
1423 param->parameter_id = 3; /* unitstatus parameter */
1424 param->parameter_size_bytes = TW_MAX_UNITS;
1425 param_value = tw_dev->alignment_physical_address[request_id];
1426 if (param_value == 0) {
1427 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad alignment physical address.\n");
1431 command_packet->byte8.param.sgl[0].address = param_value;
1432 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
1434 /* Post the command packet to the board */
1435 command_que_value = tw_dev->command_packet_physical_address[request_id];
1436 if (command_que_value == 0) {
1437 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad command packet physical address.\n");
1440 outl(command_que_value, command_que_addr);
1442 /* Poll for completion */
1443 if (tw_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, 30) == 0) {
1444 response_queue.value = inl(response_que_addr);
1445 request_id = (unsigned char)response_queue.u.response_id;
1446 if (request_id != 0) {
1447 /* unexpected request id */
1448 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Unexpected request id.\n");
1451 if (command_packet->status != 0) {
1453 tw_decode_sense(tw_dev, request_id, 0);
1459 /* response never received */
1460 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): No response.\n");
1464 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1465 is_unit_present = (unsigned char *)&(param->data[0]);
1467 /* Show all units present */
1468 imax = TW_MAX_UNITS;
1469 for(i=0; i<imax; i++) {
1470 if (is_unit_present[i] == 0) {
1471 tw_dev->is_unit_present[i] = FALSE;
1473 if (is_unit_present[i] & TW_UNIT_ONLINE) {
1474 dprintk(KERN_NOTICE "3w-xxxx: tw_initialize_units(): Unit %d found.\n", i);
1475 tw_dev->is_unit_present[i] = TRUE;
1480 tw_dev->num_units = num_units;
1482 if (num_units == 0) {
1483 dprintk(KERN_NOTICE "3w-xxxx: tw_initialize_units(): No units found.\n");
1488 } /* End tw_initialize_units() */
1490 /* This function is the interrupt service routine */
1491 static irqreturn_t tw_interrupt(int irq, void *dev_instance,
1492 struct pt_regs *regs)
1495 u32 status_reg_addr, status_reg_value;
1496 u32 response_que_addr;
1497 TW_Device_Extension *tw_dev = (TW_Device_Extension *)dev_instance;
1498 TW_Response_Queue response_que;
1499 int error = 0, retval = 0;
1500 unsigned long flags = 0;
1501 TW_Command *command_packet;
1504 dprintk(KERN_WARNING "3w-xxxx: tw_interrupt()\n");
1506 /* See if we are already running on another processor */
1507 if (test_and_set_bit(TW_IN_INTR, &tw_dev->flags))
1510 /* Get the host lock for io completions */
1511 spin_lock_irqsave(tw_dev->host->host_lock, flags);
1513 /* See if the interrupt matches this instance */
1514 if (tw_dev->tw_pci_dev->irq == irq) {
1517 /* Make sure io isn't queueing */
1518 spin_lock(&tw_dev->tw_lock);
1520 /* Read the registers */
1521 status_reg_addr = tw_dev->registers.status_reg_addr;
1522 response_que_addr = tw_dev->registers.response_que_addr;
1523 status_reg_value = inl(status_reg_addr);
1525 /* Check if this is our interrupt, otherwise bail */
1526 if (!(status_reg_value & TW_STATUS_VALID_INTERRUPT))
1527 goto tw_interrupt_bail;
1529 /* Check controller for errors */
1530 if (tw_check_bits(status_reg_value)) {
1531 dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n");
1532 if (tw_decode_bits(tw_dev, status_reg_value, 1)) {
1533 tw_clear_all_interrupts(tw_dev);
1534 goto tw_interrupt_bail;
1538 /* Handle host interrupt */
1539 if (status_reg_value & TW_STATUS_HOST_INTERRUPT) {
1540 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Received host interrupt.\n");
1541 tw_clear_host_interrupt(tw_dev);
1544 /* Handle attention interrupt */
1545 if (status_reg_value & TW_STATUS_ATTENTION_INTERRUPT) {
1546 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Received attention interrupt.\n");
1547 tw_clear_attention_interrupt(tw_dev);
1548 tw_state_request_start(tw_dev, &request_id);
1549 error = tw_aen_read_queue(tw_dev, request_id);
1551 printk(KERN_WARNING "3w-xxxx: scsi%d: Error reading aen queue.\n", tw_dev->host->host_no);
1552 tw_dev->state[request_id] = TW_S_COMPLETED;
1553 tw_state_request_finish(tw_dev, request_id);
1557 /* Handle command interrupt */
1558 if (status_reg_value & TW_STATUS_COMMAND_INTERRUPT) {
1559 /* Drain as many pending commands as we can */
1560 while (tw_dev->pending_request_count > 0) {
1561 request_id = tw_dev->pending_queue[tw_dev->pending_head];
1562 if (tw_dev->state[request_id] != TW_S_PENDING) {
1563 printk(KERN_WARNING "3w-xxxx: scsi%d: Found request id that wasn't pending.\n", tw_dev->host->host_no);
1566 if (tw_post_command_packet(tw_dev, request_id)==0) {
1567 if (tw_dev->pending_head == TW_Q_LENGTH-1) {
1568 tw_dev->pending_head = TW_Q_START;
1570 tw_dev->pending_head = tw_dev->pending_head + 1;
1572 tw_dev->pending_request_count--;
1574 /* If we get here, we will continue re-posting on the next command interrupt */
1578 /* If there are no more pending requests, we mask command interrupt */
1579 if (tw_dev->pending_request_count == 0)
1580 tw_mask_command_interrupt(tw_dev);
1583 /* Handle response interrupt */
1584 if (status_reg_value & TW_STATUS_RESPONSE_INTERRUPT) {
1585 /* Drain the response queue from the board */
1586 while ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
1587 /* Read response queue register */
1588 response_que.value = inl(response_que_addr);
1589 request_id = response_que.u.response_id;
1590 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1593 /* Check for bad response */
1594 if (command_packet->status != 0) {
1595 /* If internal command, don't error, don't fill sense */
1596 if (tw_dev->srb[request_id] == 0) {
1597 tw_decode_sense(tw_dev, request_id, 0);
1599 error = tw_decode_sense(tw_dev, request_id, 1);
1603 /* Check for correct state */
1604 if (tw_dev->state[request_id] != TW_S_POSTED) {
1605 /* Handle timed out ioctl's */
1606 if (tw_dev->srb[request_id] != 0) {
1607 if (tw_dev->srb[request_id]->cmnd[0] != TW_IOCTL) {
1608 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);
1614 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Response queue request id: %d.\n", request_id);
1616 /* Check for internal command completion */
1617 if (tw_dev->srb[request_id] == 0) {
1618 dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Found internally posted command.\n");
1619 /* Check for chrdev ioctl completion */
1620 if (request_id != tw_dev->chrdev_request_id) {
1621 retval = tw_aen_complete(tw_dev, request_id);
1623 printk(KERN_WARNING "3w-xxxx: scsi%d: Error completing aen.\n", tw_dev->host->host_no);
1626 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1627 wake_up(&tw_dev->ioctl_wqueue);
1630 switch (tw_dev->srb[request_id]->cmnd[0]) {
1633 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught READ_10/READ_6\n");
1637 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught WRITE_10/WRITE_6\n");
1639 case TEST_UNIT_READY:
1640 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught TEST_UNIT_READY\n");
1641 error = tw_scsiop_test_unit_ready_complete(tw_dev, request_id);
1644 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught INQUIRY\n");
1645 error = tw_scsiop_inquiry_complete(tw_dev, request_id);
1648 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught READ_CAPACITY\n");
1649 error = tw_scsiop_read_capacity_complete(tw_dev, request_id);
1652 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught MODE_SENSE\n");
1653 error = tw_scsiop_mode_sense_complete(tw_dev, request_id);
1655 case SYNCHRONIZE_CACHE:
1656 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught SYNCHRONIZE_CACHE\n");
1659 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught TW_IOCTL\n");
1660 error = tw_ioctl_complete(tw_dev, request_id);
1663 printk(KERN_WARNING "3w-xxxx: case slip in tw_interrupt()\n");
1667 /* If no error command was a success */
1669 tw_dev->srb[request_id]->result = (DID_OK << 16);
1672 /* If error, command failed */
1674 /* Ask for a host reset */
1675 tw_dev->srb[request_id]->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
1678 /* Now complete the io */
1679 if ((error != TW_ISR_DONT_COMPLETE)) {
1680 tw_dev->state[request_id] = TW_S_COMPLETED;
1681 tw_state_request_finish(tw_dev, request_id);
1682 tw_dev->posted_request_count--;
1683 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1685 tw_unmap_scsi_data(tw_dev->tw_pci_dev, tw_dev->srb[request_id]);
1689 /* Check for valid status after each drain */
1690 status_reg_value = inl(status_reg_addr);
1691 if (tw_check_bits(status_reg_value)) {
1692 dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n");
1693 if (tw_decode_bits(tw_dev, status_reg_value, 1)) {
1694 tw_clear_all_interrupts(tw_dev);
1695 goto tw_interrupt_bail;
1701 spin_unlock(&tw_dev->tw_lock);
1703 dprintk(KERN_WARNING "3w-xxxx: tw_interrupt() called for wrong instance.\n");
1705 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
1706 clear_bit(TW_IN_INTR, &tw_dev->flags);
1707 return IRQ_RETVAL(handled);
1708 } /* End tw_interrupt() */
1710 /* This function handles ioctls from userspace to the driver */
1711 int tw_ioctl(TW_Device_Extension *tw_dev, int request_id)
1713 unsigned char opcode;
1714 int bufflen, error = 0;
1716 TW_Command *command_packet, *command_save;
1717 unsigned long param_value;
1718 TW_Ioctl *ioctl = NULL;
1719 TW_Passthru *passthru = NULL;
1720 int tw_aen_code, i, use_sg;
1721 unsigned long *data_ptr;
1722 int total_bytes = 0, posted = 0;
1723 dma_addr_t dma_handle;
1724 struct timeval before, timeout;
1726 ioctl = (TW_Ioctl *)tw_dev->srb[request_id]->request_buffer;
1727 if (ioctl == NULL) {
1728 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Request buffer NULL.\n");
1729 tw_dev->state[request_id] = TW_S_COMPLETED;
1730 tw_state_request_finish(tw_dev, request_id);
1731 tw_dev->srb[request_id]->result = (DID_OK << 16);
1732 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1735 bufflen = tw_dev->srb[request_id]->request_bufflen;
1737 /* Initialize command packet */
1738 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1739 if (command_packet == NULL) {
1740 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Bad command packet virtual address.\n");
1741 tw_dev->state[request_id] = TW_S_COMPLETED;
1742 tw_state_request_finish(tw_dev, request_id);
1743 tw_dev->srb[request_id]->result = (DID_OK << 16);
1744 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1747 memset(command_packet, 0, sizeof(TW_Sector));
1749 /* Initialize param */
1750 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
1751 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Bad alignment virtual address.\n");
1752 tw_dev->state[request_id] = TW_S_COMPLETED;
1753 tw_state_request_finish(tw_dev, request_id);
1754 tw_dev->srb[request_id]->result = (DID_OK << 16);
1755 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1758 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1759 memset(param, 0, sizeof(TW_Sector));
1761 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);
1762 opcode = ioctl->opcode;
1766 dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): caught TW_OP_NOP.\n");
1767 command_packet->byte0.opcode = TW_OP_NOP;
1769 case TW_OP_GET_PARAM:
1770 dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): caught TW_OP_GET_PARAM.\n");
1771 command_packet->byte0.opcode = TW_OP_GET_PARAM;
1772 command_packet->byte3.unit = ioctl->unit_index;
1773 param->table_id = ioctl->table_id;
1774 param->parameter_id = ioctl->parameter_id;
1775 param->parameter_size_bytes = ioctl->parameter_size_bytes;
1776 tw_dev->ioctl_size[request_id] = ioctl->parameter_size_bytes;
1777 dprintk(KERN_NOTICE "table_id = %d parameter_id = %d parameter_size_bytes %d\n", param->table_id, param->parameter_id, param->parameter_size_bytes);
1779 case TW_OP_SET_PARAM:
1780 dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): caught TW_OP_SET_PARAM: table_id = %d, parameter_id = %d, parameter_size_bytes = %d.\n",
1781 ioctl->table_id, ioctl->parameter_id, ioctl->parameter_size_bytes);
1782 if (ioctl->data != NULL) {
1783 command_packet->byte0.opcode = TW_OP_SET_PARAM;
1784 param->table_id = ioctl->table_id;
1785 param->parameter_id = ioctl->parameter_id;
1786 param->parameter_size_bytes = ioctl->parameter_size_bytes;
1787 memcpy(param->data, ioctl->data, ioctl->parameter_size_bytes);
1790 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): ioctl->data NULL.\n");
1793 case TW_OP_AEN_LISTEN:
1794 dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): caught TW_OP_AEN_LISTEN.\n");
1795 if (tw_dev->aen_head == tw_dev->aen_tail) {
1796 /* aen queue empty */
1797 dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): Aen queue empty.\n");
1798 tw_aen_code = TW_AEN_QUEUE_EMPTY;
1799 memcpy(tw_dev->srb[request_id]->request_buffer, &tw_aen_code, ioctl->parameter_size_bytes);
1801 /* Copy aen queue entry to request buffer */
1802 dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): Returning aen 0x%x\n", tw_dev->aen_queue[tw_dev->aen_head]);
1803 tw_aen_code = tw_dev->aen_queue[tw_dev->aen_head];
1804 memcpy(tw_dev->srb[request_id]->request_buffer, &tw_aen_code, ioctl->parameter_size_bytes);
1805 if (tw_dev->aen_head == TW_Q_LENGTH - 1) {
1806 tw_dev->aen_head = TW_Q_START;
1808 tw_dev->aen_head = tw_dev->aen_head + 1;
1811 tw_dev->state[request_id] = TW_S_COMPLETED;
1812 tw_state_request_finish(tw_dev, request_id);
1813 tw_dev->srb[request_id]->result = (DID_OK << 16);
1814 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1816 case TW_ATA_PASSTHRU:
1817 if (ioctl->data != NULL) {
1818 memcpy(command_packet, ioctl->data, sizeof(TW_Command));
1819 command_packet->request_id = request_id;
1821 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): ioctl->data NULL.\n");
1825 passthru = (TW_Passthru *)tw_dev->command_packet_virtual_address[request_id];
1826 /* Don't load sg_list for non-data ATA cmds */
1827 if ((passthru->param != 0) && (passthru->param != 0x8)) {
1828 passthru->sg_list[0].length = passthru->sector_count*512;
1829 if (passthru->sg_list[0].length > TW_MAX_PASSTHRU_BYTES) {
1830 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Passthru size (%d) too big.\n", passthru->sg_list[0].length);
1833 passthru->sg_list[0].address = tw_dev->alignment_physical_address[request_id];
1835 tw_post_command_packet(tw_dev, request_id);
1838 dprintk(KERN_WARNING "3w-xxxx: tw_ioctl(): caught TW_CMD_PACKET.\n");
1839 if (ioctl->data != NULL) {
1840 memcpy(command_packet, ioctl->data, sizeof(TW_Command));
1841 command_packet->request_id = request_id;
1842 tw_post_command_packet(tw_dev, request_id);
1845 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): ioctl->data NULL.\n");
1848 case TW_CMD_PACKET_WITH_DATA:
1849 dprintk(KERN_WARNING "3w-xxxx: tw_ioctl(): caught TW_CMD_PACKET_WITH_DATA.\n");
1850 command_save = (TW_Command *)tw_dev->alignment_virtual_address[request_id];
1851 if (command_save == NULL) {
1852 printk(KERN_WARNING "3w-xxxx: scsi%d: tw_ioctl(): Bad alignment virtual address.\n", tw_dev->host->host_no);
1855 if (ioctl->data != NULL) {
1856 /* Copy down the command packet */
1857 memcpy(command_packet, ioctl->data, sizeof(TW_Command));
1858 memcpy(command_save, ioctl->data, sizeof(TW_Command));
1859 command_packet->request_id = request_id;
1861 /* Now deal with the two possible sglists */
1862 if (command_packet->byte0.sgl_offset == 2) {
1863 use_sg = command_packet->size - 3;
1864 for (i=0;i<use_sg;i++)
1865 total_bytes+=command_packet->byte8.param.sgl[i].length;
1866 tw_dev->ioctl_data[request_id] = pci_alloc_consistent(tw_dev->tw_pci_dev, total_bytes, &dma_handle);
1868 if (!tw_dev->ioctl_data[request_id]) {
1869 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);
1873 /* Copy param sglist into the kernel */
1874 data_ptr = tw_dev->ioctl_data[request_id];
1875 for (i=0;i<use_sg;i++) {
1876 if (command_packet->byte8.param.sgl[i].address != 0) {
1877 error = copy_from_user(data_ptr, (void *)(unsigned long)command_packet->byte8.param.sgl[i].address, command_packet->byte8.param.sgl[i].length);
1879 dprintk(KERN_WARNING "3w-xxxx: scsi%d: Error copying param sglist from userspace.\n", tw_dev->host->host_no);
1883 printk(KERN_WARNING "3w-xxxx: scsi%d: tw_ioctl(): Bad param sgl address.\n", tw_dev->host->host_no);
1884 tw_dev->srb[request_id]->result = (DID_RESET << 16);
1887 data_ptr+=command_packet->byte8.param.sgl[i].length;
1889 command_packet->size = 4;
1890 command_packet->byte8.param.sgl[0].address = dma_handle;
1891 command_packet->byte8.param.sgl[0].length = total_bytes;
1893 if (command_packet->byte0.sgl_offset == 3) {
1894 use_sg = command_packet->size - 4;
1895 for (i=0;i<use_sg;i++)
1896 total_bytes+=command_packet->byte8.io.sgl[i].length;
1897 tw_dev->ioctl_data[request_id] = pci_alloc_consistent(tw_dev->tw_pci_dev, total_bytes, &dma_handle);
1899 if (!tw_dev->ioctl_data[request_id]) {
1900 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);
1903 if (command_packet->byte0.opcode == TW_OP_WRITE) {
1904 /* Copy io sglist into the kernel */
1905 data_ptr = tw_dev->ioctl_data[request_id];
1906 for (i=0;i<use_sg;i++) {
1907 if (command_packet->byte8.io.sgl[i].address != 0) {
1908 error = copy_from_user(data_ptr, (void *)(unsigned long)command_packet->byte8.io.sgl[i].address, command_packet->byte8.io.sgl[i].length);
1910 dprintk(KERN_WARNING "3w-xxxx: scsi%d: Error copying io sglist from userspace.\n", tw_dev->host->host_no);
1914 printk(KERN_WARNING "3w-xxxx: scsi%d: tw_ioctl(): Bad io sgl address.\n", tw_dev->host->host_no);
1915 tw_dev->srb[request_id]->result = (DID_RESET << 16);
1918 data_ptr+=command_packet->byte8.io.sgl[i].length;
1921 command_packet->size = 5;
1922 command_packet->byte8.io.sgl[0].address = dma_handle;
1923 command_packet->byte8.io.sgl[0].length = total_bytes;
1926 spin_unlock(&tw_dev->tw_lock);
1927 spin_unlock_irq(tw_dev->host->host_lock);
1929 set_bit(TW_IN_IOCTL, &tw_dev->flags);
1931 /* Finally post the command packet */
1932 tw_post_command_packet(tw_dev, request_id);
1934 do_gettimeofday(&before);
1937 mdelay(TW_IOCTL_WAIT_TIME);
1938 if (test_bit(TW_IN_IOCTL, &tw_dev->flags)) {
1939 do_gettimeofday(&timeout);
1940 if (before.tv_sec + TW_IOCTL_TIMEOUT < timeout.tv_sec) {
1941 spin_lock_irq(tw_dev->host->host_lock);
1942 spin_lock(&tw_dev->tw_lock);
1945 goto tw_ioctl_retry;
1949 spin_lock_irq(tw_dev->host->host_lock);
1950 spin_lock(&tw_dev->tw_lock);
1952 if (signal_pending(current)) {
1953 dprintk(KERN_WARNING "3w-xxxx: scsi%d: tw_ioctl(): Signal pending, aborting ioctl().\n", tw_dev->host->host_no);
1954 tw_dev->srb[request_id]->result = (DID_OK << 16);
1958 tw_dev->srb[request_id]->result = (DID_OK << 16);
1959 /* Now copy up the param or io sglist to userspace */
1960 if (command_packet->byte0.sgl_offset == 2) {
1961 use_sg = command_save->size - 3;
1962 data_ptr = tw_dev->ioctl_data[request_id];
1963 for (i=0;i<use_sg;i++) {
1964 if (command_save->byte8.param.sgl[i].address != 0) {
1965 error = copy_to_user((void *)(unsigned long)command_save->byte8.param.sgl[i].address, data_ptr, command_save->byte8.param.sgl[i].length);
1967 dprintk(KERN_WARNING "3w-xxxx: scsi%d: Error copying param sglist to userspace.\n", tw_dev->host->host_no);
1970 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);
1971 data_ptr+=command_save->byte8.param.sgl[i].length;
1973 printk(KERN_WARNING "3w-xxxx: scsi%d: tw_ioctl(): Bad param sgl address.\n", tw_dev->host->host_no);
1974 tw_dev->srb[request_id]->result = (DID_RESET << 16);
1979 if (command_packet->byte0.sgl_offset == 3) {
1980 use_sg = command_save->size - 4;
1981 if (command_packet->byte0.opcode == TW_OP_READ) {
1982 data_ptr = tw_dev->ioctl_data[request_id];
1983 for(i=0;i<use_sg;i++) {
1984 if (command_save->byte8.io.sgl[i].address != 0) {
1985 error = copy_to_user((void *)(unsigned long)command_save->byte8.io.sgl[i].address, data_ptr, command_save->byte8.io.sgl[i].length);
1987 dprintk(KERN_WARNING "3w-xxxx: scsi%d: Error copying io sglist to userspace.\n", tw_dev->host->host_no);
1990 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);
1991 data_ptr+=command_save->byte8.io.sgl[i].length;
1993 printk(KERN_WARNING "3w-xxxx: scsi%d: tw_ioctl(): Bad io sgl address.\n", tw_dev->host->host_no);
1994 tw_dev->srb[request_id]->result = (DID_RESET << 16);
2003 /* Free up sglist memory */
2004 if (tw_dev->ioctl_data[request_id])
2005 pci_free_consistent(tw_dev->tw_pci_dev, total_bytes, tw_dev->ioctl_data[request_id], dma_handle);
2007 printk(KERN_WARNING "3w-xxxx: scsi%d: tw_ioctl(): Error freeing ioctl data.\n", tw_dev->host->host_no);
2009 /* Now complete the io */
2010 tw_dev->state[request_id] = TW_S_COMPLETED;
2011 tw_state_request_finish(tw_dev, request_id);
2013 tw_dev->posted_request_count--;
2014 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
2017 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): ioctl->data NULL.\n");
2021 dprintk(KERN_WARNING "3w-xxxx: Unknown ioctl 0x%x.\n", opcode);
2022 tw_dev->state[request_id] = TW_S_COMPLETED;
2023 tw_state_request_finish(tw_dev, request_id);
2024 tw_dev->srb[request_id]->result = (DID_OK << 16);
2025 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
2029 param_value = tw_dev->alignment_physical_address[request_id];
2030 if (param_value == 0) {
2031 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Bad alignment physical address.\n");
2032 tw_dev->state[request_id] = TW_S_COMPLETED;
2033 tw_state_request_finish(tw_dev, request_id);
2034 tw_dev->srb[request_id]->result = (DID_OK << 16);
2035 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
2038 command_packet->byte8.param.sgl[0].address = param_value;
2039 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
2041 command_packet->byte0.sgl_offset = 2;
2042 command_packet->size = 4;
2043 command_packet->request_id = request_id;
2044 command_packet->byte3.host_id = 0;
2045 command_packet->status = 0;
2046 command_packet->flags = 0;
2047 command_packet->byte6.parameter_count = 1;
2049 /* Now try to post the command to the board */
2050 tw_post_command_packet(tw_dev, request_id);
2053 } /* End tw_ioctl() */
2055 /* This function is called by the isr to complete ioctl requests */
2056 int tw_ioctl_complete(TW_Device_Extension *tw_dev, int request_id)
2058 unsigned char *param_data;
2059 unsigned char *buff;
2061 TW_Ioctl *ioctl = NULL;
2062 TW_Passthru *passthru = NULL;
2063 TW_Command *command_packet;
2065 ioctl = (TW_Ioctl *)tw_dev->srb[request_id]->request_buffer;
2066 dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl_complete()\n");
2067 buff = tw_dev->srb[request_id]->request_buffer;
2069 printk(KERN_WARNING "3w-xxxx: tw_ioctl_complete(): Request buffer NULL.\n");
2073 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
2074 if (command_packet == NULL) {
2075 printk(KERN_WARNING "3w-xxxx: scsi%d: tw_ioctl_complete(): Bad command packet virtual address.\n", tw_dev->host->host_no);
2079 dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl_complete(): Request_bufflen = %d\n", tw_dev->srb[request_id]->request_bufflen);
2081 ioctl = (TW_Ioctl *)buff;
2082 switch (ioctl->opcode) {
2083 case TW_ATA_PASSTHRU:
2084 passthru = (TW_Passthru *)ioctl->data;
2085 /* Don't return data for non-data ATA cmds */
2086 if ((passthru->param != 0) && (passthru->param != 0x8))
2087 memcpy(buff, tw_dev->alignment_virtual_address[request_id], passthru->sector_count * 512);
2089 /* For non-data cmds, return cmd pkt */
2090 if (tw_dev->srb[request_id]->request_bufflen >= sizeof(TW_Command))
2091 memcpy(buff, tw_dev->command_packet_virtual_address[request_id], sizeof(TW_Command));
2094 case TW_CMD_PACKET_WITH_DATA:
2095 dprintk(KERN_WARNING "3w-xxxx: tw_ioctl_complete(): caught TW_CMD_PACKET_WITH_DATA.\n");
2096 clear_bit(TW_IN_IOCTL, &tw_dev->flags);
2097 return TW_ISR_DONT_COMPLETE; /* Special case for isr to not complete io */
2099 memset(buff, 0, tw_dev->srb[request_id]->request_bufflen);
2100 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
2101 if (param == NULL) {
2102 printk(KERN_WARNING "3w-xxxx: tw_ioctl_complete(): Bad alignment virtual address.\n");
2105 param_data = &(param->data[0]);
2106 memcpy(buff, param_data, tw_dev->ioctl_size[request_id]);
2109 } /* End tw_ioctl_complete() */
2111 static int tw_map_scsi_sg_data(struct pci_dev *pdev, Scsi_Cmnd *cmd)
2114 int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
2116 dprintk(KERN_WARNING "3w-xxxx: tw_map_scsi_sg_data()\n");
2118 if (cmd->use_sg == 0)
2121 use_sg = pci_map_sg(pdev, cmd->buffer, cmd->use_sg, dma_dir);
2124 printk(KERN_WARNING "3w-xxxx: tw_map_scsi_sg_data(): pci_map_sg() failed.\n");
2129 cmd->SCp.have_data_in = use_sg;
2132 } /* End tw_map_scsi_sg_data() */
2134 static u32 tw_map_scsi_single_data(struct pci_dev *pdev, Scsi_Cmnd *cmd)
2137 int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
2139 dprintk(KERN_WARNING "3w-xxxx: tw_map_scsi_single_data()\n");
2141 if (cmd->request_bufflen == 0)
2144 mapping = pci_map_page(pdev, virt_to_page(cmd->request_buffer), offset_in_page(cmd->request_buffer), cmd->request_bufflen, dma_dir);
2147 printk(KERN_WARNING "3w-xxxx: tw_map_scsi_single_data(): pci_map_page() failed.\n");
2152 cmd->SCp.have_data_in = mapping;
2155 } /* End tw_map_scsi_single_data() */
2157 /* This function will mask the command interrupt */
2158 void tw_mask_command_interrupt(TW_Device_Extension *tw_dev)
2160 u32 control_reg_addr, control_reg_value;
2162 control_reg_addr = tw_dev->registers.control_reg_addr;
2163 control_reg_value = TW_CONTROL_MASK_COMMAND_INTERRUPT;
2164 outl(control_reg_value, control_reg_addr);
2165 } /* End tw_mask_command_interrupt() */
2167 /* This function will poll the status register for a flag */
2168 int tw_poll_status(TW_Device_Extension *tw_dev, u32 flag, int seconds)
2170 u32 status_reg_addr, status_reg_value;
2171 struct timeval before, timeout;
2173 status_reg_addr = tw_dev->registers.status_reg_addr;
2174 do_gettimeofday(&before);
2175 status_reg_value = inl(status_reg_addr);
2177 if (tw_check_bits(status_reg_value)) {
2178 dprintk(KERN_WARNING "3w-xxxx: tw_poll_status(): Unexpected bits.\n");
2179 tw_decode_bits(tw_dev, status_reg_value, 0);
2182 while ((status_reg_value & flag) != flag) {
2183 status_reg_value = inl(status_reg_addr);
2185 if (tw_check_bits(status_reg_value)) {
2186 dprintk(KERN_WARNING "3w-xxxx: tw_poll_status(): Unexpected bits.\n");
2187 tw_decode_bits(tw_dev, status_reg_value, 0);
2190 do_gettimeofday(&timeout);
2191 if (before.tv_sec + seconds < timeout.tv_sec) {
2192 dprintk(KERN_WARNING "3w-xxxx: tw_poll_status(): Flag 0x%x not found.\n", flag);
2198 } /* End tw_poll_status() */
2200 /* This function will poll the status register for disappearance of a flag */
2201 int tw_poll_status_gone(TW_Device_Extension *tw_dev, u32 flag, int seconds)
2203 u32 status_reg_addr, status_reg_value;
2204 struct timeval before, timeout;
2206 status_reg_addr = tw_dev->registers.status_reg_addr;
2207 do_gettimeofday(&before);
2208 status_reg_value = inl(status_reg_addr);
2210 if (tw_check_bits(status_reg_value)) {
2211 dprintk(KERN_WARNING "3w-xxxx: tw_poll_status_gone(): Unexpected bits.\n");
2212 tw_decode_bits(tw_dev, status_reg_value, 0);
2215 while ((status_reg_value & flag) != 0) {
2216 status_reg_value = inl(status_reg_addr);
2218 if (tw_check_bits(status_reg_value)) {
2219 dprintk(KERN_WARNING "3w-xxxx: tw_poll_status_gone(): Unexpected bits.\n");
2220 tw_decode_bits(tw_dev, status_reg_value, 0);
2223 do_gettimeofday(&timeout);
2224 if (before.tv_sec + seconds < timeout.tv_sec) {
2225 dprintk(KERN_WARNING "3w-xxxx: tw_poll_status_gone(): Flag 0x%x never disappeared.\n", flag);
2231 } /* End tw_poll_status_gone() */
2233 /* This function will attempt to post a command packet to the board */
2234 int tw_post_command_packet(TW_Device_Extension *tw_dev, int request_id)
2236 u32 status_reg_addr, status_reg_value;
2237 unsigned long command_que_value;
2238 u32 command_que_addr;
2240 dprintk(KERN_NOTICE "3w-xxxx: tw_post_command_packet()\n");
2241 command_que_addr = tw_dev->registers.command_que_addr;
2242 command_que_value = tw_dev->command_packet_physical_address[request_id];
2243 status_reg_addr = tw_dev->registers.status_reg_addr;
2244 status_reg_value = inl(status_reg_addr);
2246 if (tw_check_bits(status_reg_value)) {
2247 dprintk(KERN_WARNING "3w-xxxx: tw_post_command_packet(): Unexpected bits.\n");
2248 tw_decode_bits(tw_dev, status_reg_value, 1);
2251 if ((status_reg_value & TW_STATUS_COMMAND_QUEUE_FULL) == 0) {
2252 /* We successfully posted the command packet */
2253 outl(command_que_value, command_que_addr);
2254 tw_dev->state[request_id] = TW_S_POSTED;
2255 tw_dev->posted_request_count++;
2256 if (tw_dev->posted_request_count > tw_dev->max_posted_request_count) {
2257 tw_dev->max_posted_request_count = tw_dev->posted_request_count;
2260 /* Couldn't post the command packet, so we do it in the isr */
2261 if (tw_dev->state[request_id] != TW_S_PENDING) {
2262 tw_dev->state[request_id] = TW_S_PENDING;
2263 tw_dev->pending_request_count++;
2264 if (tw_dev->pending_request_count > tw_dev->max_pending_request_count) {
2265 tw_dev->max_pending_request_count = tw_dev->pending_request_count;
2267 tw_dev->pending_queue[tw_dev->pending_tail] = request_id;
2268 if (tw_dev->pending_tail == TW_Q_LENGTH-1) {
2269 tw_dev->pending_tail = TW_Q_START;
2271 tw_dev->pending_tail = tw_dev->pending_tail + 1;
2274 tw_unmask_command_interrupt(tw_dev);
2278 } /* End tw_post_command_packet() */
2280 /* This function will reset a device extension */
2281 int tw_reset_device_extension(TW_Device_Extension *tw_dev)
2287 dprintk(KERN_NOTICE "3w-xxxx: tw_reset_device_extension()\n");
2290 if (tw_reset_sequence(tw_dev)) {
2291 printk(KERN_WARNING "3w-xxxx: scsi%d: Reset sequence failed.\n", tw_dev->host->host_no);
2295 /* Abort all requests that are in progress */
2296 for (i=0;i<imax;i++) {
2297 if ((tw_dev->state[i] != TW_S_FINISHED) &&
2298 (tw_dev->state[i] != TW_S_INITIAL) &&
2299 (tw_dev->state[i] != TW_S_COMPLETED)) {
2300 srb = tw_dev->srb[i];
2302 srb->result = (DID_RESET << 16);
2303 tw_dev->srb[i]->scsi_done(tw_dev->srb[i]);
2304 tw_unmap_scsi_data(tw_dev->tw_pci_dev, tw_dev->srb[i]);
2309 /* Reset queues and counts */
2310 for (i=0;i<imax;i++) {
2311 tw_dev->free_queue[i] = i;
2312 tw_dev->state[i] = TW_S_INITIAL;
2314 tw_dev->free_head = TW_Q_START;
2315 tw_dev->free_tail = TW_Q_START;
2316 tw_dev->posted_request_count = 0;
2317 tw_dev->pending_request_count = 0;
2318 tw_dev->pending_head = TW_Q_START;
2319 tw_dev->pending_tail = TW_Q_START;
2320 tw_dev->reset_print = 0;
2321 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
2324 } /* End tw_reset_device_extension() */
2326 /* This function will reset a controller */
2327 int tw_reset_sequence(TW_Device_Extension *tw_dev)
2332 /* Disable interrupts */
2333 tw_disable_interrupts(tw_dev);
2335 /* Reset the board */
2336 while (tries < TW_MAX_RESET_TRIES) {
2337 tw_soft_reset(tw_dev);
2339 error = tw_aen_drain_queue(tw_dev);
2341 printk(KERN_WARNING "3w-xxxx: scsi%d: AEN drain failed, retrying.\n", tw_dev->host->host_no);
2346 /* Check for controller errors */
2347 if (tw_check_errors(tw_dev)) {
2348 printk(KERN_WARNING "3w-xxxx: scsi%d: Controller errors found, retrying.\n", tw_dev->host->host_no);
2353 /* Now the controller is in a good state */
2357 if (tries >= TW_MAX_RESET_TRIES) {
2358 printk(KERN_WARNING "3w-xxxx: scsi%d: Controller errors, card not responding, check all cabling.\n", tw_dev->host->host_no);
2362 error = tw_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS);
2364 printk(KERN_WARNING "3w-xxxx: scsi%d: Connection initialization failed.\n", tw_dev->host->host_no);
2368 /* Re-enable interrupts */
2369 tw_enable_and_clear_interrupts(tw_dev);
2372 } /* End tw_reset_sequence() */
2374 /* This funciton returns unit geometry in cylinders/heads/sectors */
2375 int tw_scsi_biosparam(struct scsi_device *sdev, struct block_device *bdev,
2376 sector_t capacity, int geom[])
2378 int heads, sectors, cylinders;
2379 TW_Device_Extension *tw_dev;
2381 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_biosparam()\n");
2382 tw_dev = (TW_Device_Extension *)sdev->host->hostdata;
2386 cylinders = (unsigned long)capacity / (heads * sectors);
2388 if (capacity >= 0x200000) {
2391 cylinders = (unsigned long)capacity / (heads * sectors);
2394 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_biosparam(): heads = %d, sectors = %d, cylinders = %d\n", heads, sectors, cylinders);
2397 geom[2] = cylinders;
2400 } /* End tw_scsi_biosparam() */
2402 /* This function will find and initialize any cards */
2403 int tw_scsi_detect(Scsi_Host_Template *tw_host)
2407 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_detect()\n");
2409 printk(KERN_WARNING "3ware Storage Controller device driver for Linux v%s.\n", tw_driver_version);
2411 ret = tw_findcards(tw_host);
2414 } /* End tw_scsi_detect() */
2416 /* This is the new scsi eh abort function */
2417 int tw_scsi_eh_abort(Scsi_Cmnd *SCpnt)
2419 TW_Device_Extension *tw_dev=NULL;
2422 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_eh_abort()\n");
2425 printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Invalid Scsi_Cmnd.\n");
2429 tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
2430 if (tw_dev == NULL) {
2431 printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Invalid device extension.\n");
2435 spin_lock(&tw_dev->tw_lock);
2436 tw_dev->num_aborts++;
2438 /* If the command hasn't been posted yet, we can do the abort */
2439 for (i=0;i<TW_Q_LENGTH;i++) {
2440 if (tw_dev->srb[i] == SCpnt) {
2441 if (tw_dev->state[i] == TW_S_STARTED) {
2442 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]->device->id, SCpnt);
2443 tw_dev->state[i] = TW_S_COMPLETED;
2444 tw_state_request_finish(tw_dev, i);
2445 spin_unlock(&tw_dev->tw_lock);
2448 if (tw_dev->state[i] == TW_S_PENDING) {
2449 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]->device->id, SCpnt);
2450 if (tw_dev->pending_head == TW_Q_LENGTH-1) {
2451 tw_dev->pending_head = TW_Q_START;
2453 tw_dev->pending_head = tw_dev->pending_head + 1;
2455 tw_dev->pending_request_count--;
2456 tw_dev->state[i] = TW_S_COMPLETED;
2457 tw_state_request_finish(tw_dev, i);
2458 spin_unlock(&tw_dev->tw_lock);
2461 if (tw_dev->state[i] == TW_S_POSTED) {
2462 /* If the command has already been posted, we have to reset the card */
2463 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]->device->id, SCpnt);
2464 /* We have to let AEN requests through before the reset */
2465 spin_unlock(&tw_dev->tw_lock);
2466 spin_unlock_irq(tw_dev->host->host_lock);
2467 mdelay(TW_AEN_WAIT_TIME);
2468 spin_lock_irq(tw_dev->host->host_lock);
2469 spin_lock(&tw_dev->tw_lock);
2471 if (tw_reset_device_extension(tw_dev)) {
2472 dprintk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Reset failed for card %d.\n", tw_dev->host->host_no);
2473 spin_unlock(&tw_dev->tw_lock);
2480 spin_unlock(&tw_dev->tw_lock);
2482 } /* End tw_scsi_eh_abort() */
2484 /* This is the new scsi eh reset function */
2485 int tw_scsi_eh_reset(Scsi_Cmnd *SCpnt)
2487 TW_Device_Extension *tw_dev=NULL;
2489 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_eh_reset()\n");
2492 printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_reset(): Invalid Scsi_Cmnd.\n");
2496 tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
2497 if (tw_dev == NULL) {
2498 printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_reset(): Invalid device extension.\n");
2502 /* We have to let AEN requests through before the reset */
2503 spin_unlock_irq(tw_dev->host->host_lock);
2504 mdelay(TW_AEN_WAIT_TIME);
2505 spin_lock_irq(tw_dev->host->host_lock);
2507 spin_lock(&tw_dev->tw_lock);
2508 tw_dev->num_resets++;
2510 /* Now reset the card and some of the device extension data */
2511 if (tw_reset_device_extension(tw_dev)) {
2512 printk(KERN_WARNING "3w-xxxx: scsi%d: Reset failed.\n", tw_dev->host->host_no);
2513 spin_unlock(&tw_dev->tw_lock);
2516 printk(KERN_WARNING "3w-xxxx: scsi%d: Reset succeeded.\n", tw_dev->host->host_no);
2517 spin_unlock(&tw_dev->tw_lock);
2520 } /* End tw_scsi_eh_reset() */
2522 /* This function handles input and output from /proc/scsi/3w-xxxx/x */
2523 int tw_scsi_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
2524 off_t offset, int length, int inout)
2526 TW_Device_Extension *tw_dev = NULL;
2531 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_proc_info()\n");
2533 /* Find the correct device extension */
2534 for (i=0;i<tw_device_extension_count;i++)
2535 if (tw_device_extension_list[i]->host->host_no == shost->host_no)
2536 tw_dev = tw_device_extension_list[i];
2537 if (tw_dev == NULL) {
2538 printk(KERN_WARNING "3w-xxxx: tw_scsi_proc_info(): Couldn't locate device extension.\n");
2542 info.buffer = buffer;
2543 info.length = length;
2544 info.offset = offset;
2549 if (strncmp(buffer, "debug", 5) == 0) {
2550 printk(KERN_INFO "3w-xxxx: Posted commands:\n");
2551 for (j=0;j<TW_Q_LENGTH;j++) {
2552 if (tw_dev->state[j] == TW_S_POSTED) {
2553 TW_Command *command = (TW_Command *)tw_dev->command_packet_virtual_address[j];
2554 printk(KERN_INFO "3w-xxxx: Request_id: %d\n", j);
2555 printk(KERN_INFO "Opcode: 0x%x\n", command->byte0.opcode);
2556 printk(KERN_INFO "Block_count: 0x%x\n", command->byte6.block_count);
2557 printk(KERN_INFO "LBA: 0x%x\n", command->byte8.io.lba);
2558 printk(KERN_INFO "Physical command packet addr: 0x%lx\n", tw_dev->command_packet_physical_address[j]);
2559 printk(KERN_INFO "Scsi_Cmnd: %p\n", tw_dev->srb[j]);
2562 printk(KERN_INFO "3w-xxxx: Free_head: %3d\n", tw_dev->free_head);
2563 printk(KERN_INFO "3w-xxxx: Free_tail: %3d\n", tw_dev->free_tail);
2571 tw_copy_info(&info, "scsi%d: 3ware Storage Controller\n", shost->host_no);
2572 tw_copy_info(&info, "Driver version: %s\n", tw_driver_version);
2573 tw_copy_info(&info, "Current commands posted: %3d\n", tw_dev->posted_request_count);
2574 tw_copy_info(&info, "Max commands posted: %3d\n", tw_dev->max_posted_request_count);
2575 tw_copy_info(&info, "Current pending commands: %3d\n", tw_dev->pending_request_count);
2576 tw_copy_info(&info, "Max pending commands: %3d\n", tw_dev->max_pending_request_count);
2577 tw_copy_info(&info, "Last sgl length: %3d\n", tw_dev->sgl_entries);
2578 tw_copy_info(&info, "Max sgl length: %3d\n", tw_dev->max_sgl_entries);
2579 tw_copy_info(&info, "Last sector count: %3d\n", tw_dev->sector_count);
2580 tw_copy_info(&info, "Max sector count: %3d\n", tw_dev->max_sector_count);
2581 tw_copy_info(&info, "Resets: %3d\n", tw_dev->num_resets);
2582 tw_copy_info(&info, "Aborts: %3d\n", tw_dev->num_aborts);
2583 tw_copy_info(&info, "AEN's: %3d\n", tw_dev->aen_count);
2585 if (info.position > info.offset) {
2586 return (info.position - info.offset);
2590 } /* End tw_scsi_proc_info() */
2592 /* This is the main scsi queue function to handle scsi opcodes */
2593 int tw_scsi_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
2595 unsigned char *command = SCpnt->cmnd;
2598 TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
2600 if (tw_dev == NULL) {
2601 printk(KERN_WARNING "3w-xxxx: tw_scsi_queue(): Invalid device extension.\n");
2602 SCpnt->result = (DID_ERROR << 16);
2607 spin_lock(&tw_dev->tw_lock);
2608 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue()\n");
2610 /* Skip scsi command if it isn't for us */
2611 if ((SCpnt->device->channel != 0) || (SCpnt->device->lun != 0)) {
2612 SCpnt->result = (DID_BAD_TARGET << 16);
2614 spin_unlock(&tw_dev->tw_lock);
2618 /* Save done function into Scsi_Cmnd struct */
2619 SCpnt->scsi_done = done;
2621 /* Queue the command and get a request id */
2622 tw_state_request_start(tw_dev, &request_id);
2624 /* Save the scsi command for use by the ISR */
2625 tw_dev->srb[request_id] = SCpnt;
2627 /* Initialize phase to zero */
2628 SCpnt->SCp.phase = 0;
2635 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught READ/WRITE.\n");
2636 error = tw_scsiop_read_write(tw_dev, request_id);
2638 case TEST_UNIT_READY:
2639 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught TEST_UNIT_READY.\n");
2640 error = tw_scsiop_test_unit_ready(tw_dev, request_id);
2643 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught INQUIRY.\n");
2644 error = tw_scsiop_inquiry(tw_dev, request_id);
2647 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught READ_CAPACITY.\n");
2648 error = tw_scsiop_read_capacity(tw_dev, request_id);
2651 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught REQUEST_SENSE.\n");
2652 error = tw_scsiop_request_sense(tw_dev, request_id);
2655 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught MODE_SENSE.\n");
2656 error = tw_scsiop_mode_sense(tw_dev, request_id);
2658 case SYNCHRONIZE_CACHE:
2659 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught SYNCHRONIZE_CACHE.\n");
2660 error = tw_scsiop_synchronize_cache(tw_dev, request_id);
2663 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught TW_SCSI_IOCTL.\n");
2664 error = tw_ioctl(tw_dev, request_id);
2667 printk(KERN_NOTICE "3w-xxxx: scsi%d: Unknown scsi opcode: 0x%x\n", tw_dev->host->host_no, *command);
2668 tw_dev->state[request_id] = TW_S_COMPLETED;
2669 tw_state_request_finish(tw_dev, request_id);
2670 SCpnt->result = (DID_BAD_TARGET << 16);
2674 tw_dev->state[request_id] = TW_S_COMPLETED;
2675 tw_state_request_finish(tw_dev, request_id);
2676 SCpnt->result = (DID_ERROR << 16);
2679 spin_unlock(&tw_dev->tw_lock);
2682 } /* End tw_scsi_queue() */
2684 /* This function will release the resources on an rmmod call */
2685 int tw_scsi_release(struct Scsi_Host *tw_host)
2687 TW_Device_Extension *tw_dev;
2688 tw_dev = (TW_Device_Extension *)tw_host->hostdata;
2690 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_release()\n");
2692 /* Fake like we just shut down, so notify the card that
2693 * we "shut down cleanly".
2695 tw_halt(0, 0, 0); // parameters aren't actually used
2697 /* Free up the IO region */
2698 release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
2700 /* Free up the IRQ */
2701 free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
2703 /* Unregister character device */
2704 if (twe_major >= 0) {
2705 unregister_chrdev(twe_major, "twe");
2709 /* Free up device extension resources */
2710 tw_free_device_extension(tw_dev);
2712 /* Tell kernel scsi-layer we are gone */
2713 scsi_unregister(tw_host);
2716 } /* End tw_scsi_release() */
2718 /* This function handles scsi inquiry commands */
2719 int tw_scsiop_inquiry(TW_Device_Extension *tw_dev, int request_id)
2722 TW_Command *command_packet;
2723 unsigned long command_que_value;
2724 u32 command_que_addr;
2725 unsigned long param_value;
2727 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry()\n");
2729 /* Initialize command packet */
2730 command_que_addr = tw_dev->registers.command_que_addr;
2731 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
2732 if (command_packet == NULL) {
2733 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad command packet virtual address.\n");
2736 memset(command_packet, 0, sizeof(TW_Sector));
2737 command_packet->byte0.opcode = TW_OP_GET_PARAM;
2738 command_packet->byte0.sgl_offset = 2;
2739 command_packet->size = 4;
2740 command_packet->request_id = request_id;
2741 command_packet->byte3.unit = 0;
2742 command_packet->byte3.host_id = 0;
2743 command_packet->status = 0;
2744 command_packet->flags = 0;
2745 command_packet->byte6.parameter_count = 1;
2747 /* Now setup the param */
2748 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
2749 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad alignment virtual address.\n");
2752 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
2753 memset(param, 0, sizeof(TW_Sector));
2754 param->table_id = 3; /* unit summary table */
2755 param->parameter_id = 3; /* unitsstatus parameter */
2756 param->parameter_size_bytes = TW_MAX_UNITS;
2757 param_value = tw_dev->alignment_physical_address[request_id];
2758 if (param_value == 0) {
2759 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad alignment physical address.\n");
2763 command_packet->byte8.param.sgl[0].address = param_value;
2764 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
2765 command_que_value = tw_dev->command_packet_physical_address[request_id];
2766 if (command_que_value == 0) {
2767 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad command packet physical address.\n");
2771 /* Now try to post the command packet */
2772 tw_post_command_packet(tw_dev, request_id);
2775 } /* End tw_scsiop_inquiry() */
2777 /* This function is called by the isr to complete an inquiry command */
2778 int tw_scsiop_inquiry_complete(TW_Device_Extension *tw_dev, int request_id)
2780 unsigned char *is_unit_present;
2781 unsigned char *request_buffer;
2784 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry_complete()\n");
2786 /* Fill request buffer */
2787 if (tw_dev->srb[request_id]->request_buffer == NULL) {
2788 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry_complete(): Request buffer NULL.\n");
2791 request_buffer = tw_dev->srb[request_id]->request_buffer;
2792 memset(request_buffer, 0, tw_dev->srb[request_id]->request_bufflen);
2793 request_buffer[0] = TYPE_DISK; /* Peripheral device type */
2794 request_buffer[1] = 0; /* Device type modifier */
2795 request_buffer[2] = 0; /* No ansi/iso compliance */
2796 request_buffer[4] = 31; /* Additional length */
2797 memcpy(&request_buffer[8], "3ware ", 8); /* Vendor ID */
2798 sprintf(&request_buffer[16], "Logical Disk %-2d ", tw_dev->srb[request_id]->device->id);
2799 memcpy(&request_buffer[32], tw_driver_version, 3);
2801 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
2802 if (param == NULL) {
2803 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry_complete(): Bad alignment virtual address.\n");
2806 is_unit_present = &(param->data[0]);
2808 if (is_unit_present[tw_dev->srb[request_id]->device->id] & TW_UNIT_ONLINE) {
2809 tw_dev->is_unit_present[tw_dev->srb[request_id]->device->id] = TRUE;
2811 tw_dev->is_unit_present[tw_dev->srb[request_id]->device->id] = FALSE;
2812 tw_dev->srb[request_id]->result = (DID_BAD_TARGET << 16);
2813 return TW_ISR_DONT_RESULT;
2817 } /* End tw_scsiop_inquiry_complete() */
2819 /* This function handles scsi mode_sense commands */
2820 int tw_scsiop_mode_sense(TW_Device_Extension *tw_dev, int request_id)
2823 TW_Command *command_packet;
2824 unsigned long command_que_value;
2825 unsigned long param_value;
2827 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_mode_sense()\n");
2829 /* Only page control = 0, page code = 0x8 (cache page) supported */
2830 if (tw_dev->srb[request_id]->cmnd[2] != 0x8) {
2831 tw_dev->state[request_id] = TW_S_COMPLETED;
2832 tw_state_request_finish(tw_dev, request_id);
2833 tw_dev->srb[request_id]->result = (DID_OK << 16);
2834 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
2838 /* Now read firmware cache setting for this unit */
2839 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
2840 if (command_packet == NULL) {
2841 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad command packet virtual address.\n");
2845 /* Setup the command packet */
2846 memset(command_packet, 0, sizeof(TW_Sector));
2847 command_packet->byte0.opcode = TW_OP_GET_PARAM;
2848 command_packet->byte0.sgl_offset = 2;
2849 command_packet->size = 4;
2850 command_packet->request_id = request_id;
2851 command_packet->byte3.unit = 0;
2852 command_packet->byte3.host_id = 0;
2853 command_packet->status = 0;
2854 command_packet->flags = 0;
2855 command_packet->byte6.parameter_count = 1;
2857 /* Setup the param */
2858 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
2859 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad alignment virtual address.\n");
2863 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
2864 memset(param, 0, sizeof(TW_Sector));
2865 param->table_id = TW_UNIT_INFORMATION_TABLE_BASE + tw_dev->srb[request_id]->device->id;
2866 param->parameter_id = 7; /* unit flags */
2867 param->parameter_size_bytes = 1;
2868 param_value = tw_dev->alignment_physical_address[request_id];
2869 if (param_value == 0) {
2870 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad alignment physical address.\n");
2874 command_packet->byte8.param.sgl[0].address = param_value;
2875 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
2876 command_que_value = tw_dev->command_packet_physical_address[request_id];
2877 if (command_que_value == 0) {
2878 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad command packet physical address.\n");
2882 /* Now try to post the command packet */
2883 tw_post_command_packet(tw_dev, request_id);
2886 } /* End tw_scsiop_mode_sense() */
2888 /* This function is called by the isr to complete a mode sense command */
2889 int tw_scsiop_mode_sense_complete(TW_Device_Extension *tw_dev, int request_id)
2892 unsigned char *flags;
2893 unsigned char *request_buffer;
2895 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_mode_sense_complete()\n");
2897 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
2898 if (param == NULL) {
2899 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense_complete(): Bad alignment virtual address.\n");
2902 flags = (char *)&(param->data[0]);
2903 request_buffer = tw_dev->srb[request_id]->buffer;
2904 memset(request_buffer, 0, tw_dev->srb[request_id]->request_bufflen);
2906 request_buffer[0] = 0xf; /* mode data length */
2907 request_buffer[1] = 0; /* default medium type */
2908 request_buffer[2] = 0x10; /* dpo/fua support on */
2909 request_buffer[3] = 0; /* no block descriptors */
2910 request_buffer[4] = 0x8; /* caching page */
2911 request_buffer[5] = 0xa; /* page length */
2913 request_buffer[6] = 0x4; /* WCE on */
2915 request_buffer[6] = 0x0; /* WCE off */
2918 } /* End tw_scsiop_mode_sense_complete() */
2920 /* This function handles scsi read_capacity commands */
2921 int tw_scsiop_read_capacity(TW_Device_Extension *tw_dev, int request_id)
2924 TW_Command *command_packet;
2925 unsigned long command_que_value;
2926 u32 command_que_addr;
2927 unsigned long param_value;
2929 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity()\n");
2931 /* Initialize command packet */
2932 command_que_addr = tw_dev->registers.command_que_addr;
2933 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
2935 if (command_packet == NULL) {
2936 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad command packet virtual address.\n");
2939 memset(command_packet, 0, sizeof(TW_Sector));
2940 command_packet->byte0.opcode = TW_OP_GET_PARAM;
2941 command_packet->byte0.sgl_offset = 2;
2942 command_packet->size = 4;
2943 command_packet->request_id = request_id;
2944 command_packet->byte3.unit = tw_dev->srb[request_id]->device->id;
2945 command_packet->byte3.host_id = 0;
2946 command_packet->status = 0;
2947 command_packet->flags = 0;
2948 command_packet->byte6.block_count = 1;
2950 /* Now setup the param */
2951 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
2952 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad alignment virtual address.\n");
2955 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
2956 memset(param, 0, sizeof(TW_Sector));
2957 param->table_id = TW_UNIT_INFORMATION_TABLE_BASE +
2958 tw_dev->srb[request_id]->device->id;
2959 param->parameter_id = 4; /* unitcapacity parameter */
2960 param->parameter_size_bytes = 4;
2961 param_value = tw_dev->alignment_physical_address[request_id];
2962 if (param_value == 0) {
2963 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad alignment physical address.\n");
2967 command_packet->byte8.param.sgl[0].address = param_value;
2968 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
2969 command_que_value = tw_dev->command_packet_physical_address[request_id];
2970 if (command_que_value == 0) {
2971 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad command packet physical address.\n");
2975 /* Now try to post the command to the board */
2976 tw_post_command_packet(tw_dev, request_id);
2979 } /* End tw_scsiop_read_capacity() */
2981 /* This function is called by the isr to complete a readcapacity command */
2982 int tw_scsiop_read_capacity_complete(TW_Device_Extension *tw_dev, int request_id)
2984 unsigned char *param_data;
2989 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity_complete()\n");
2991 buff = tw_dev->srb[request_id]->request_buffer;
2993 printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_capacity_complete(): Request buffer NULL.\n");
2996 memset(buff, 0, tw_dev->srb[request_id]->request_bufflen);
2997 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
2998 if (param == NULL) {
2999 printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_capacity_complete(): Bad alignment virtual address.\n");
3002 param_data = &(param->data[0]);
3004 capacity = (param_data[3] << 24) | (param_data[2] << 16) |
3005 (param_data[1] << 8) | param_data[0];
3007 /* Subtract one sector to fix get last sector ioctl */
3010 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity_complete(): Capacity = 0x%x.\n", capacity);
3012 /* Number of LBA's */
3013 buff[0] = (capacity >> 24);
3014 buff[1] = (capacity >> 16) & 0xff;
3015 buff[2] = (capacity >> 8) & 0xff;
3016 buff[3] = capacity & 0xff;
3018 /* Block size in bytes (512) */
3019 buff[4] = (TW_BLOCK_SIZE >> 24);
3020 buff[5] = (TW_BLOCK_SIZE >> 16) & 0xff;
3021 buff[6] = (TW_BLOCK_SIZE >> 8) & 0xff;
3022 buff[7] = TW_BLOCK_SIZE & 0xff;
3025 } /* End tw_scsiop_read_capacity_complete() */
3027 /* This function handles scsi read or write commands */
3028 int tw_scsiop_read_write(TW_Device_Extension *tw_dev, int request_id)
3030 TW_Command *command_packet;
3031 unsigned long command_que_value;
3032 u32 command_que_addr = 0x0;
3033 u32 lba = 0x0, num_sectors = 0x0, buffaddr = 0x0;
3036 struct scatterlist *sglist;
3038 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write()\n");
3040 if (tw_dev->srb[request_id]->request_buffer == NULL) {
3041 printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_write(): Request buffer NULL.\n");
3044 sglist = (struct scatterlist *)tw_dev->srb[request_id]->request_buffer;
3045 srb = tw_dev->srb[request_id];
3047 /* Initialize command packet */
3048 command_que_addr = tw_dev->registers.command_que_addr;
3049 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
3050 if (command_packet == NULL) {
3051 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): Bad command packet virtual address.\n");
3055 if (srb->cmnd[0] == READ_6 || srb->cmnd[0] == READ_10) {
3056 command_packet->byte0.opcode = TW_OP_READ;
3058 command_packet->byte0.opcode = TW_OP_WRITE;
3061 command_packet->byte0.sgl_offset = 3;
3062 command_packet->size = 3;
3063 command_packet->request_id = request_id;
3064 command_packet->byte3.unit = srb->device->id;
3065 command_packet->byte3.host_id = 0;
3066 command_packet->status = 0;
3067 command_packet->flags = 0;
3069 if (srb->cmnd[0] == WRITE_10) {
3070 if ((srb->cmnd[1] & 0x8) || (srb->cmnd[1] & 0x10))
3071 command_packet->flags = 1;
3074 if (srb->cmnd[0] == READ_6 || srb->cmnd[0] == WRITE_6) {
3075 lba = ((u32)srb->cmnd[1] << 16) | ((u32)srb->cmnd[2] << 8) | (u32)srb->cmnd[3];
3076 num_sectors = (u32)srb->cmnd[4];
3078 lba = ((u32)srb->cmnd[2] << 24) | ((u32)srb->cmnd[3] << 16) | ((u32)srb->cmnd[4] << 8) | (u32)srb->cmnd[5];
3079 num_sectors = (u32)srb->cmnd[8] | ((u32)srb->cmnd[7] << 8);
3082 /* Update sector statistic */
3083 tw_dev->sector_count = num_sectors;
3084 if (tw_dev->sector_count > tw_dev->max_sector_count)
3085 tw_dev->max_sector_count = tw_dev->sector_count;
3087 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): lba = 0x%x num_sectors = 0x%x\n", lba, num_sectors);
3088 command_packet->byte8.io.lba = lba;
3089 command_packet->byte6.block_count = num_sectors;
3091 /* Do this if there are no sg list entries */
3092 if (tw_dev->srb[request_id]->use_sg == 0) {
3093 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): SG = 0\n");
3094 buffaddr = tw_map_scsi_single_data(tw_dev->tw_pci_dev, tw_dev->srb[request_id]);
3098 command_packet->byte8.io.sgl[0].address = buffaddr;
3099 command_packet->byte8.io.sgl[0].length = tw_dev->srb[request_id]->request_bufflen;
3100 command_packet->size+=2;
3103 /* Do this if we have multiple sg list entries */
3104 if (tw_dev->srb[request_id]->use_sg > 0) {
3105 use_sg = tw_map_scsi_sg_data(tw_dev->tw_pci_dev, tw_dev->srb[request_id]);
3109 for (i=0;i<use_sg; i++) {
3110 command_packet->byte8.io.sgl[i].address = sg_dma_address(&sglist[i]);
3111 command_packet->byte8.io.sgl[i].length = sg_dma_len(&sglist[i]);
3112 command_packet->size+=2;
3116 /* Update SG statistics */
3117 tw_dev->sgl_entries = tw_dev->srb[request_id]->use_sg;
3118 if (tw_dev->sgl_entries > tw_dev->max_sgl_entries)
3119 tw_dev->max_sgl_entries = tw_dev->sgl_entries;
3121 command_que_value = tw_dev->command_packet_physical_address[request_id];
3122 if (command_que_value == 0) {
3123 dprintk(KERN_WARNING "3w-xxxx: tw_scsiop_read_write(): Bad command packet physical address.\n");
3127 /* Now try to post the command to the board */
3128 tw_post_command_packet(tw_dev, request_id);
3131 } /* End tw_scsiop_read_write() */
3133 /* This function will handle the request sense scsi command */
3134 int tw_scsiop_request_sense(TW_Device_Extension *tw_dev, int request_id)
3136 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_request_sense()\n");
3138 /* For now we just zero the request buffer */
3139 memset(tw_dev->srb[request_id]->request_buffer, 0, tw_dev->srb[request_id]->request_bufflen);
3140 tw_dev->state[request_id] = TW_S_COMPLETED;
3141 tw_state_request_finish(tw_dev, request_id);
3143 /* If we got a request_sense, we probably want a reset, return error */
3144 tw_dev->srb[request_id]->result = (DID_ERROR << 16);
3145 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
3148 } /* End tw_scsiop_request_sense() */
3150 /* This function will handle synchronize cache scsi command */
3151 int tw_scsiop_synchronize_cache(TW_Device_Extension *tw_dev, int request_id)
3153 TW_Command *command_packet;
3154 unsigned long command_que_value;
3156 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_synchronize_cache()\n");
3158 /* Send firmware flush command for this unit */
3159 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
3160 if (command_packet == NULL) {
3161 printk(KERN_WARNING "3w-xxxx: tw_scsiop_synchronize_cache(): Bad command packet virtual address.\n");
3165 /* Setup the command packet */
3166 memset(command_packet, 0, sizeof(TW_Sector));
3167 command_packet->byte0.opcode = TW_OP_FLUSH_CACHE;
3168 command_packet->byte0.sgl_offset = 0;
3169 command_packet->size = 2;
3170 command_packet->request_id = request_id;
3171 command_packet->byte3.unit = tw_dev->srb[request_id]->device->id;
3172 command_packet->byte3.host_id = 0;
3173 command_packet->status = 0;
3174 command_packet->flags = 0;
3175 command_packet->byte6.parameter_count = 1;
3176 command_que_value = tw_dev->command_packet_physical_address[request_id];
3177 if (command_que_value == 0) {
3178 printk(KERN_WARNING "3w-xxxx: tw_scsiop_synchronize_cache(): Bad command packet physical address.\n");
3182 /* Now try to post the command packet */
3183 tw_post_command_packet(tw_dev, request_id);
3186 } /* End tw_scsiop_synchronize_cache() */
3188 /* This function will handle test unit ready scsi command */
3189 int tw_scsiop_test_unit_ready(TW_Device_Extension *tw_dev, int request_id)
3192 TW_Command *command_packet;
3193 unsigned long command_que_value;
3194 u32 command_que_addr;
3195 unsigned long param_value;
3197 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_test_unit_ready()\n");
3199 /* Initialize command packet */
3200 command_que_addr = tw_dev->registers.command_que_addr;
3201 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
3202 if (command_packet == NULL) {
3203 printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready(): Bad command packet virtual address.\n");
3206 memset(command_packet, 0, sizeof(TW_Sector));
3207 command_packet->byte0.opcode = TW_OP_GET_PARAM;
3208 command_packet->byte0.sgl_offset = 2;
3209 command_packet->size = 4;
3210 command_packet->request_id = request_id;
3211 command_packet->byte3.unit = 0;
3212 command_packet->byte3.host_id = 0;
3213 command_packet->status = 0;
3214 command_packet->flags = 0;
3215 command_packet->byte6.parameter_count = 1;
3217 /* Now setup the param */
3218 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
3219 printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready(): Bad alignment virtual address.\n");
3222 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
3223 memset(param, 0, sizeof(TW_Sector));
3224 param->table_id = 3; /* unit summary table */
3225 param->parameter_id = 3; /* unitsstatus parameter */
3226 param->parameter_size_bytes = TW_MAX_UNITS;
3227 param_value = tw_dev->alignment_physical_address[request_id];
3228 if (param_value == 0) {
3229 printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready(): Bad alignment physical address.\n");
3233 command_packet->byte8.param.sgl[0].address = param_value;
3234 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
3235 command_que_value = tw_dev->command_packet_physical_address[request_id];
3236 if (command_que_value == 0) {
3237 printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready(): Bad command packet physical address.\n");
3241 /* Now try to post the command packet */
3242 tw_post_command_packet(tw_dev, request_id);
3245 } /* End tw_scsiop_test_unit_ready() */
3247 /* This function is called by the isr to complete a testunitready command */
3248 int tw_scsiop_test_unit_ready_complete(TW_Device_Extension *tw_dev, int request_id)
3250 unsigned char *is_unit_present;
3253 dprintk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready_complete()\n");
3255 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
3256 if (param == NULL) {
3257 printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready_complete(): Bad alignment virtual address.\n");
3260 is_unit_present = &(param->data[0]);
3262 if (is_unit_present[tw_dev->srb[request_id]->device->id] & TW_UNIT_ONLINE) {
3263 tw_dev->is_unit_present[tw_dev->srb[request_id]->device->id] = TRUE;
3265 tw_dev->is_unit_present[tw_dev->srb[request_id]->device->id] = FALSE;
3266 tw_dev->srb[request_id]->result = (DID_BAD_TARGET << 16);
3267 return TW_ISR_DONT_RESULT;
3271 } /* End tw_scsiop_test_unit_ready_complete() */
3273 /* Set a value in the features table */
3274 int tw_setfeature(TW_Device_Extension *tw_dev, int parm, int param_size,
3278 TW_Command *command_packet;
3279 TW_Response_Queue response_queue;
3281 unsigned long command_que_value;
3282 u32 command_que_addr;
3283 u32 response_que_addr;
3284 unsigned long param_value;
3286 /* Initialize SetParam command packet */
3287 if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
3288 printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad command packet virtual address.\n");
3291 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
3292 memset(command_packet, 0, sizeof(TW_Sector));
3293 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
3295 command_packet->byte0.opcode = TW_OP_SET_PARAM;
3296 command_packet->byte0.sgl_offset = 2;
3297 param->table_id = 0x404; /* Features table */
3298 param->parameter_id = parm;
3299 param->parameter_size_bytes = param_size;
3300 memcpy(param->data, val, param_size);
3302 param_value = tw_dev->alignment_physical_address[request_id];
3303 if (param_value == 0) {
3304 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Bad alignment physical address.\n");
3305 tw_dev->state[request_id] = TW_S_COMPLETED;
3306 tw_state_request_finish(tw_dev, request_id);
3307 tw_dev->srb[request_id]->result = (DID_OK << 16);
3308 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
3310 command_packet->byte8.param.sgl[0].address = param_value;
3311 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
3313 command_packet->size = 4;
3314 command_packet->request_id = request_id;
3315 command_packet->byte6.parameter_count = 1;
3317 command_que_value = tw_dev->command_packet_physical_address[request_id];
3318 if (command_que_value == 0) {
3319 printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad command packet physical address.\n");
3322 command_que_addr = tw_dev->registers.command_que_addr;
3323 response_que_addr = tw_dev->registers.response_que_addr;
3325 /* Send command packet to the board */
3326 outl(command_que_value, command_que_addr);
3328 /* Poll for completion */
3329 if (tw_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, 30) == 0) {
3330 response_queue.value = inl(response_que_addr);
3331 request_id = (unsigned char)response_queue.u.response_id;
3332 if (request_id != 0) {
3333 /* unexpected request id */
3334 printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Unexpected request id.\n");
3337 if (command_packet->status != 0) {
3339 tw_decode_sense(tw_dev, request_id, 0);
3345 } /* End tw_setfeature() */
3347 /* This function will setup the interrupt handler */
3348 int tw_setup_irq(TW_Device_Extension *tw_dev)
3350 char *device = TW_DEVICE_NAME;
3353 dprintk(KERN_NOTICE "3w-xxxx: tw_setup_irq()\n");
3354 error = request_irq(tw_dev->tw_pci_dev->irq, tw_interrupt, SA_SHIRQ, device, tw_dev);
3357 printk(KERN_WARNING "3w-xxxx: scsi%d: Error requesting IRQ: %d.\n", tw_dev->host->host_no, tw_dev->tw_pci_dev->irq);
3361 } /* End tw_setup_irq() */
3363 /* This function will tell the controller we're shutting down by sending
3364 initconnection with a 1 */
3365 int tw_shutdown_device(TW_Device_Extension *tw_dev)
3369 /* Disable interrupts */
3370 tw_disable_interrupts(tw_dev);
3372 /* poke the board */
3373 error = tw_initconnection(tw_dev, 1);
3375 printk(KERN_WARNING "3w-xxxx: scsi%d: Connection shutdown failed.\n", tw_dev->host->host_no);
3377 printk(KERN_NOTICE "3w-xxxx: Shutdown complete.\n");
3380 /* Re-enable interrupts */
3381 tw_enable_and_clear_interrupts(tw_dev);
3384 } /* End tw_shutdown_device() */
3386 /* This function will configure individual target parameters */
3387 int tw_slave_configure(Scsi_Device *SDptr)
3391 dprintk(KERN_WARNING "3w-xxxx: tw_slave_configure()\n");
3394 max_cmds = cmds_per_lun;
3395 if (max_cmds > TW_MAX_CMDS_PER_LUN)
3396 max_cmds = TW_MAX_CMDS_PER_LUN;
3398 max_cmds = TW_MAX_CMDS_PER_LUN;
3400 scsi_adjust_queue_depth(SDptr, MSG_ORDERED_TAG, max_cmds);
3403 } /* End tw_slave_configure() */
3405 /* This function will soft reset the controller */
3406 void tw_soft_reset(TW_Device_Extension *tw_dev)
3408 u32 control_reg_addr, control_reg_value;
3410 control_reg_addr = tw_dev->registers.control_reg_addr;
3411 control_reg_value = ( TW_CONTROL_ISSUE_SOFT_RESET |
3412 TW_CONTROL_CLEAR_HOST_INTERRUPT |
3413 TW_CONTROL_CLEAR_ATTENTION_INTERRUPT |
3414 TW_CONTROL_MASK_COMMAND_INTERRUPT |
3415 TW_CONTROL_MASK_RESPONSE_INTERRUPT |
3416 TW_CONTROL_CLEAR_ERROR_STATUS |
3417 TW_CONTROL_DISABLE_INTERRUPTS);
3418 outl(control_reg_value, control_reg_addr);
3419 } /* End tw_soft_reset() */
3421 /* This function will free a request_id */
3422 int tw_state_request_finish(TW_Device_Extension *tw_dev, int request_id)
3424 dprintk(KERN_NOTICE "3w-xxxx: tw_state_request_finish()\n");
3426 tw_dev->free_queue[tw_dev->free_tail] = request_id;
3427 tw_dev->state[request_id] = TW_S_FINISHED;
3428 if (tw_dev->free_tail == tw_dev->free_wrap)
3429 tw_dev->free_tail = TW_Q_START;
3431 tw_dev->free_tail++;
3433 dprintk(KERN_NOTICE "3w-xxxx: tw_state_request_finish(): Freeing request_id %d\n", request_id);
3436 } /* End tw_state_request_finish() */
3438 /* This function will assign an available request_id */
3439 int tw_state_request_start(TW_Device_Extension *tw_dev, int *request_id)
3443 dprintk(KERN_NOTICE "3w-xxxx: tw_state_request_start()\n");
3445 /* Obtain next free request_id */
3446 id = tw_dev->free_queue[tw_dev->free_head];
3447 if (tw_dev->free_head == tw_dev->free_wrap)
3448 tw_dev->free_head = TW_Q_START;
3450 tw_dev->free_head++;
3453 tw_dev->state[id] = TW_S_STARTED;
3455 dprintk(KERN_NOTICE "3w-xxxx: tw_state_request_start(): id = %d.\n", id);
3457 } /* End tw_state_request_start() */
3459 static void tw_unmap_scsi_data(struct pci_dev *pdev, Scsi_Cmnd *cmd)
3461 int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
3463 dprintk(KERN_WARNING "3w-xxxx: tw_unmap_scsi_data()\n");
3465 switch(cmd->SCp.phase) {
3467 pci_unmap_page(pdev, cmd->SCp.have_data_in, cmd->request_bufflen, dma_dir);
3470 pci_unmap_sg(pdev, cmd->request_buffer, cmd->use_sg, dma_dir);
3473 } /* End tw_unmap_scsi_data() */
3475 /* This function will unmask the command interrupt on the controller */
3476 void tw_unmask_command_interrupt(TW_Device_Extension *tw_dev)
3478 u32 control_reg_addr, control_reg_value;
3480 control_reg_addr = tw_dev->registers.control_reg_addr;
3481 control_reg_value = TW_CONTROL_UNMASK_COMMAND_INTERRUPT;
3482 outl(control_reg_value, control_reg_addr);
3483 } /* End tw_unmask_command_interrupt() */
3485 static Scsi_Host_Template driver_template = {
3486 .proc_name = "3w-xxxx",
3487 .proc_info = tw_scsi_proc_info,
3488 .name = "3ware Storage Controller",
3489 .detect = tw_scsi_detect,
3490 .release = tw_scsi_release,
3491 .queuecommand = tw_scsi_queue,
3492 .eh_abort_handler = tw_scsi_eh_abort,
3493 .eh_host_reset_handler = tw_scsi_eh_reset,
3494 .bios_param = tw_scsi_biosparam,
3495 .slave_configure = tw_slave_configure,
3496 .can_queue = TW_Q_LENGTH-2,
3498 .sg_tablesize = TW_MAX_SGL_LENGTH,
3499 .max_sectors = TW_MAX_SECTORS,
3500 .cmd_per_lun = TW_MAX_CMDS_PER_LUN,
3501 .use_clustering = ENABLE_CLUSTERING,
3504 #include "scsi_module.c"