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 */
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;
654 dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl()\n");
656 /* Only let one of these through at a time */
657 if (down_interruptible(&tw_dev->ioctl_sem))
660 /* First copy down the buffer length */
661 error = copy_from_user(&data_buffer_length, (void *)arg, sizeof(unsigned int));
666 if (data_buffer_length > TW_MAX_SECTORS * 512) {
671 /* Hardware can only do multiple of 512 byte transfers */
672 data_buffer_length_adjusted = (data_buffer_length + 511) & ~511;
674 /* Now allocate ioctl buf memory */
675 cpu_addr = pci_alloc_consistent(tw_dev->tw_pci_dev, data_buffer_length_adjusted+sizeof(TW_New_Ioctl) - 1, &dma_handle);
676 if (cpu_addr == NULL) {
681 tw_ioctl = (TW_New_Ioctl *)cpu_addr;
683 /* Now copy down the entire ioctl */
684 error = copy_from_user(tw_ioctl, (void *)arg, data_buffer_length + sizeof(TW_New_Ioctl) - 1);
688 passthru = (TW_Passthru *)&tw_ioctl->firmware_command;
690 /* See which ioctl we are doing */
693 dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl(): caught TW_OP_NOP.\n");
695 case TW_OP_AEN_LISTEN:
696 dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl(): caught TW_AEN_LISTEN.\n");
697 memset(tw_ioctl->data_buffer, 0, data_buffer_length);
699 spin_lock_irqsave(tw_dev->host->host_lock, flags);
700 if (tw_dev->aen_head == tw_dev->aen_tail) {
701 tw_aen_code = TW_AEN_QUEUE_EMPTY;
703 tw_aen_code = tw_dev->aen_queue[tw_dev->aen_head];
704 if (tw_dev->aen_head == TW_Q_LENGTH - 1) {
705 tw_dev->aen_head = TW_Q_START;
707 tw_dev->aen_head = tw_dev->aen_head + 1;
710 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
711 memcpy(tw_ioctl->data_buffer, &tw_aen_code, sizeof(tw_aen_code));
713 case TW_CMD_PACKET_WITH_DATA:
714 dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl(): caught TW_CMD_PACKET_WITH_DATA.\n");
715 spin_lock_irqsave(&tw_dev->tw_lock, flags);
717 tw_state_request_start(tw_dev, &request_id);
719 /* Flag internal command */
720 tw_dev->srb[request_id] = 0;
722 /* Flag chrdev ioctl */
723 tw_dev->chrdev_request_id = request_id;
725 tw_ioctl->firmware_command.request_id = request_id;
727 /* Load the sg list */
728 switch (tw_ioctl->firmware_command.byte0.sgl_offset) {
730 tw_ioctl->firmware_command.byte8.param.sgl[0].address = dma_handle + sizeof(TW_New_Ioctl) - 1;
731 tw_ioctl->firmware_command.byte8.param.sgl[0].length = data_buffer_length_adjusted;
734 tw_ioctl->firmware_command.byte8.io.sgl[0].address = dma_handle + sizeof(TW_New_Ioctl) - 1;
735 tw_ioctl->firmware_command.byte8.io.sgl[0].length = data_buffer_length_adjusted;
738 passthru->sg_list[0].address = dma_handle + sizeof(TW_New_Ioctl) - 1;
739 passthru->sg_list[0].length = data_buffer_length_adjusted;
743 memcpy(tw_dev->command_packet_virtual_address[request_id], &(tw_ioctl->firmware_command), sizeof(TW_Command));
745 /* Now post the command packet to the controller */
746 tw_post_command_packet(tw_dev, request_id);
747 spin_unlock_irqrestore(&tw_dev->tw_lock, flags);
749 timeout = TW_IOCTL_CHRDEV_TIMEOUT*HZ;
751 /* Now wait for the command to complete */
752 timeout = wait_event_interruptible_timeout(tw_dev->ioctl_wqueue, tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE, timeout);
754 /* Check if we timed out, got a signal, or didn't get
756 if ((timeout <= 0) && (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE)) {
757 /* Now we need to reset the board */
758 if (timeout == -ERESTARTSYS) {
761 printk(KERN_WARNING "3w-xxxx: scsi%d: Character ioctl (0x%x) timed out, resetting card.\n", tw_dev->host->host_no, cmd);
764 spin_lock_irqsave(&tw_dev->tw_lock, flags);
765 tw_dev->state[request_id] = TW_S_COMPLETED;
766 tw_state_request_finish(tw_dev, request_id);
767 tw_dev->posted_request_count--;
768 if (tw_reset_device_extension(tw_dev)) {
769 printk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl(): Reset failed for card %d.\n", tw_dev->host->host_no);
771 spin_unlock_irqrestore(&tw_dev->tw_lock, flags);
775 /* Now copy in the command packet response */
776 memcpy(&(tw_ioctl->firmware_command), tw_dev->command_packet_virtual_address[request_id], sizeof(TW_Command));
778 /* Now complete the io */
779 spin_lock_irqsave(&tw_dev->tw_lock, flags);
780 tw_dev->posted_request_count--;
781 tw_dev->state[request_id] = TW_S_COMPLETED;
782 tw_state_request_finish(tw_dev, request_id);
783 spin_unlock_irqrestore(&tw_dev->tw_lock, flags);
790 /* Now copy the response to userspace */
791 error = copy_to_user((void *)arg, tw_ioctl, sizeof(TW_New_Ioctl) + data_buffer_length - 1);
795 /* Now free ioctl buf memory */
796 pci_free_consistent(tw_dev->tw_pci_dev, data_buffer_length_adjusted+sizeof(TW_New_Ioctl) - 1, cpu_addr, dma_handle);
798 up(&tw_dev->ioctl_sem);
800 } /* End tw_chrdev_ioctl() */
802 /* This function handles open for the character device */
803 static int tw_chrdev_open(struct inode *inode, struct file *file)
805 unsigned int minor_number;
807 dprintk(KERN_WARNING "3w-xxxx: tw_ioctl_open()\n");
809 minor_number = iminor(inode);
810 if (minor_number >= tw_device_extension_count)
814 } /* End tw_chrdev_open() */
816 /* This function handles close for the character device */
817 static int tw_chrdev_release(struct inode *inode, struct file *file)
819 dprintk(KERN_WARNING "3w-xxxx: tw_ioctl_release()\n");
822 } /* End tw_chrdev_release() */
824 /* This function will clear all interrupts on the controller */
825 void tw_clear_all_interrupts(TW_Device_Extension *tw_dev)
827 u32 control_reg_addr, control_reg_value;
829 control_reg_addr = tw_dev->registers.control_reg_addr;
830 control_reg_value = TW_STATUS_VALID_INTERRUPT;
831 outl(control_reg_value, control_reg_addr);
832 } /* End tw_clear_all_interrupts() */
834 /* This function will clear the attention interrupt */
835 void tw_clear_attention_interrupt(TW_Device_Extension *tw_dev)
837 u32 control_reg_addr, control_reg_value;
839 control_reg_addr = tw_dev->registers.control_reg_addr;
840 control_reg_value = TW_CONTROL_CLEAR_ATTENTION_INTERRUPT;
841 outl(control_reg_value, control_reg_addr);
842 } /* End tw_clear_attention_interrupt() */
844 /* This function will clear the host interrupt */
845 void tw_clear_host_interrupt(TW_Device_Extension *tw_dev)
847 u32 control_reg_addr, control_reg_value;
849 control_reg_addr = tw_dev->registers.control_reg_addr;
850 control_reg_value = TW_CONTROL_CLEAR_HOST_INTERRUPT;
851 outl(control_reg_value, control_reg_addr);
852 } /* End tw_clear_host_interrupt() */
854 /* This function is called by tw_scsi_proc_info */
855 static int tw_copy_info(TW_Info *info, char *fmt, ...)
862 len = vsprintf(buf, fmt, args);
864 tw_copy_mem_info(info, buf, len);
866 } /* End tw_copy_info() */
868 /* This function is called by tw_scsi_proc_info */
869 static void tw_copy_mem_info(TW_Info *info, char *data, int len)
871 if (info->position + len > info->length)
872 len = info->length - info->position;
874 if (info->position + len < info->offset) {
875 info->position += len;
878 if (info->position < info->offset) {
879 data += (info->offset - info->position);
880 len -= (info->offset - info->position);
883 memcpy(info->buffer + info->position, data, len);
884 info->position += len;
886 } /* End tw_copy_mem_info() */
888 /* This function will print readable messages from status register errors */
889 int tw_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value, int print_host)
893 dprintk(KERN_WARNING "3w-xxxx: tw_decode_bits()\n");
896 sprintf(host, " scsi%d:", tw_dev->host->host_no);
900 if (status_reg_value & TW_STATUS_PCI_PARITY_ERROR) {
901 printk(KERN_WARNING "3w-xxxx:%s PCI Parity Error: clearing.\n", host);
902 outl(TW_CONTROL_CLEAR_PARITY_ERROR, tw_dev->registers.control_reg_addr);
905 if (status_reg_value & TW_STATUS_PCI_ABORT) {
906 printk(KERN_WARNING "3w-xxxx:%s PCI Abort: clearing.\n", host);
907 outl(TW_CONTROL_CLEAR_PCI_ABORT, tw_dev->registers.control_reg_addr);
908 pci_write_config_word(tw_dev->tw_pci_dev, PCI_STATUS, TW_PCI_CLEAR_PCI_ABORT);
911 if (status_reg_value & TW_STATUS_QUEUE_ERROR) {
912 printk(KERN_WARNING "3w-xxxx:%s Controller Queue Error: clearing.\n", host);
913 outl(TW_CONTROL_CLEAR_QUEUE_ERROR, tw_dev->registers.control_reg_addr);
916 if (status_reg_value & TW_STATUS_SBUF_WRITE_ERROR) {
917 printk(KERN_WARNING "3w-xxxx:%s SBUF Write Error: clearing.\n", host);
918 outl(TW_CONTROL_CLEAR_SBUF_WRITE_ERROR, tw_dev->registers.control_reg_addr);
921 if (status_reg_value & TW_STATUS_MICROCONTROLLER_ERROR) {
922 if (tw_dev->reset_print == 0) {
923 printk(KERN_WARNING "3w-xxxx:%s Microcontroller Error: clearing.\n", host);
924 tw_dev->reset_print = 1;
930 } /* End tw_decode_bits() */
932 /* This function will return valid sense buffer information for failed cmds */
933 int tw_decode_sense(TW_Device_Extension *tw_dev, int request_id, int fill_sense)
938 dprintk(KERN_WARNING "3w-xxxx: tw_decode_sense()\n");
939 command = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
941 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);
943 /* Attempt to return intelligent sense information */
945 if ((command->status == 0xc7) || (command->status == 0xcb)) {
946 for (i=0;i<(sizeof(tw_sense_table)/sizeof(tw_sense_table[0]));i++) {
947 if (command->flags == tw_sense_table[i][0]) {
949 /* Valid bit and 'current errors' */
950 tw_dev->srb[request_id]->sense_buffer[0] = (0x1 << 7 | 0x70);
953 tw_dev->srb[request_id]->sense_buffer[2] = tw_sense_table[i][1];
955 /* Additional sense length */
956 tw_dev->srb[request_id]->sense_buffer[7] = 0xa; /* 10 bytes */
958 /* Additional sense code */
959 tw_dev->srb[request_id]->sense_buffer[12] = tw_sense_table[i][2];
961 /* Additional sense code qualifier */
962 tw_dev->srb[request_id]->sense_buffer[13] = tw_sense_table[i][3];
964 tw_dev->srb[request_id]->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
965 return TW_ISR_DONT_RESULT; /* Special case for isr to not over-write result */
970 /* If no table match, error so we get a reset */
975 } /* End tw_decode_sense() */
977 /* This function will disable interrupts on the controller */
978 void tw_disable_interrupts(TW_Device_Extension *tw_dev)
980 u32 control_reg_value, control_reg_addr;
982 control_reg_addr = tw_dev->registers.control_reg_addr;
983 control_reg_value = TW_CONTROL_DISABLE_INTERRUPTS;
984 outl(control_reg_value, control_reg_addr);
985 } /* End tw_disable_interrupts() */
987 /* This function will empty the response que */
988 void tw_empty_response_que(TW_Device_Extension *tw_dev)
990 u32 status_reg_addr, status_reg_value;
991 u32 response_que_addr, response_que_value;
993 status_reg_addr = tw_dev->registers.status_reg_addr;
994 response_que_addr = tw_dev->registers.response_que_addr;
996 status_reg_value = inl(status_reg_addr);
998 while ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
999 response_que_value = inl(response_que_addr);
1000 status_reg_value = inl(status_reg_addr);
1002 } /* End tw_empty_response_que() */
1004 /* This function will enable interrupts on the controller */
1005 void tw_enable_interrupts(TW_Device_Extension *tw_dev)
1007 u32 control_reg_value, control_reg_addr;
1009 control_reg_addr = tw_dev->registers.control_reg_addr;
1010 control_reg_value = (TW_CONTROL_ENABLE_INTERRUPTS |
1011 TW_CONTROL_UNMASK_RESPONSE_INTERRUPT);
1012 outl(control_reg_value, control_reg_addr);
1013 } /* End tw_enable_interrupts() */
1015 /* This function will enable interrupts on the controller */
1016 void tw_enable_and_clear_interrupts(TW_Device_Extension *tw_dev)
1018 u32 control_reg_value, control_reg_addr;
1020 control_reg_addr = tw_dev->registers.control_reg_addr;
1021 control_reg_value = (TW_CONTROL_CLEAR_ATTENTION_INTERRUPT |
1022 TW_CONTROL_UNMASK_RESPONSE_INTERRUPT |
1023 TW_CONTROL_ENABLE_INTERRUPTS);
1024 outl(control_reg_value, control_reg_addr);
1025 } /* End tw_enable_and_clear_interrupts() */
1027 /* This function will find and initialize all cards */
1028 int tw_findcards(Scsi_Host_Template *tw_host)
1030 int numcards = 0, tries = 0, error = 0;
1031 struct Scsi_Host *host;
1032 TW_Device_Extension *tw_dev;
1033 TW_Device_Extension *tw_dev2;
1034 struct pci_dev *tw_pci_dev = NULL;
1035 u32 status_reg_value;
1036 unsigned char c = 1;
1038 u16 device[TW_NUMDEVICES] = { TW_DEVICE_ID, TW_DEVICE_ID2 };
1040 dprintk(KERN_NOTICE "3w-xxxx: tw_findcards()\n");
1042 for (i=0;i<TW_NUMDEVICES;i++) {
1043 while ((tw_pci_dev = pci_find_device(TW_VENDOR_ID, device[i], tw_pci_dev))) {
1045 if (pci_enable_device(tw_pci_dev))
1048 /* We only need 32-bit addressing for 5,6,7xxx cards */
1049 if (pci_set_dma_mask(tw_pci_dev, 0xffffffff)) {
1050 printk(KERN_WARNING "3w-xxxx: No suitable DMA available.\n");
1054 /* Prepare temporary device extension */
1055 tw_dev=(TW_Device_Extension *)kmalloc(sizeof(TW_Device_Extension), GFP_ATOMIC);
1056 if (tw_dev == NULL) {
1057 printk(KERN_WARNING "3w-xxxx: tw_findcards(): kmalloc() failed for card %d.\n", j);
1060 memset(tw_dev, 0, sizeof(TW_Device_Extension));
1062 /* Save pci_dev struct to device extension */
1063 tw_dev->tw_pci_dev = tw_pci_dev;
1065 error = tw_initialize_device_extension(tw_dev);
1067 printk(KERN_WARNING "3w-xxxx: tw_findcards(): Couldn't initialize device extension for card %d.\n", j);
1068 tw_free_device_extension(tw_dev);
1073 /* Calculate the cards register addresses */
1074 tw_dev->registers.base_addr = pci_resource_start(tw_pci_dev, 0);
1075 tw_dev->registers.control_reg_addr = pci_resource_start(tw_pci_dev, 0);
1076 tw_dev->registers.status_reg_addr = pci_resource_start(tw_pci_dev, 0) + 0x4;
1077 tw_dev->registers.command_que_addr = pci_resource_start(tw_pci_dev, 0) + 0x8;
1078 tw_dev->registers.response_que_addr = pci_resource_start(tw_pci_dev, 0) + 0xC;
1080 /* Check for errors and clear them */
1081 status_reg_value = inl(tw_dev->registers.status_reg_addr);
1082 if (TW_STATUS_ERRORS(status_reg_value))
1083 tw_decode_bits(tw_dev, status_reg_value, 0);
1085 /* Poll status register for 60 secs for 'Controller Ready' flag */
1086 if (tw_poll_status(tw_dev, TW_STATUS_MICROCONTROLLER_READY, 60)) {
1087 printk(KERN_WARNING "3w-xxxx: tw_findcards(): Microcontroller not ready for card %d.\n", j);
1088 tw_free_device_extension(tw_dev);
1093 /* Disable interrupts on the card */
1094 tw_disable_interrupts(tw_dev);
1098 while (tries < TW_MAX_RESET_TRIES) {
1100 tw_soft_reset(tw_dev);
1102 error = tw_aen_drain_queue(tw_dev);
1104 printk(KERN_WARNING "3w-xxxx: AEN drain failed for card %d.\n", j);
1109 /* Check for controller errors */
1110 if (tw_check_errors(tw_dev)) {
1111 printk(KERN_WARNING "3w-xxxx: Controller errors found, retrying for card %d.\n", j);
1116 /* Now the controller is in a good state */
1120 if (tries >= TW_MAX_RESET_TRIES) {
1121 printk(KERN_WARNING "3w-xxxx: Controller errors, card not responding, check all cabling for card %d.\n", j);
1122 tw_free_device_extension(tw_dev);
1127 /* Reserve the io address space */
1128 if (!request_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE, TW_DEVICE_NAME)) {
1129 printk(KERN_WARNING "3w-xxxx: tw_findcards(): Couldn't get io range 0x%lx-0x%lx for card %d.\n",
1130 (tw_dev->tw_pci_dev->resource[0].start),
1131 (tw_dev->tw_pci_dev->resource[0].start) +
1132 TW_IO_ADDRESS_RANGE, j);
1133 tw_free_device_extension(tw_dev);
1138 error = tw_initialize_units(tw_dev);
1140 printk(KERN_WARNING "3w-xxxx: No valid units for for card %d.\n", j);
1143 error = tw_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS);
1145 printk(KERN_WARNING "3w-xxxx: Connection initialization failed for card %d.\n", j);
1146 release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
1147 tw_free_device_extension(tw_dev);
1152 /* Set card status as online */
1155 tw_dev->free_head = TW_Q_START;
1156 tw_dev->free_tail = TW_Q_START;
1157 tw_dev->free_wrap = TW_Q_LENGTH - 1;
1159 /* Register the card with the kernel SCSI layer */
1160 host = scsi_register(tw_host, sizeof(TW_Device_Extension));
1162 printk(KERN_WARNING "3w-xxxx: tw_findcards(): scsi_register() failed for card %d.\n", j);
1163 release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
1164 tw_free_device_extension(tw_dev);
1169 /* Set max target id's */
1170 host->max_id = TW_MAX_UNITS;
1172 /* Set max cdb size in bytes */
1173 host->max_cmd_len = 16;
1175 /* Set max sectors per io */
1176 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7)
1177 host->max_sectors = TW_MAX_SECTORS;
1180 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
1181 scsi_set_device(host, &tw_pci_dev->dev);
1182 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4)
1183 scsi_set_pci_device(host, tw_pci_dev);
1186 status_reg_value = inl(tw_dev->registers.status_reg_addr);
1188 printk(KERN_NOTICE "scsi%d : Found a 3ware Storage Controller at 0x%x, IRQ: %d, P-chip: %d.%d\n", host->host_no,
1189 (u32)(tw_pci_dev->resource[0].start), tw_pci_dev->irq,
1190 (status_reg_value & TW_STATUS_MAJOR_VERSION_MASK) >> 28,
1191 (status_reg_value & TW_STATUS_MINOR_VERSION_MASK) >> 24);
1193 if (host->hostdata) {
1194 tw_dev2 = (TW_Device_Extension *)host->hostdata;
1195 memcpy(tw_dev2, tw_dev, sizeof(TW_Device_Extension));
1196 /* Need to init the sem/wqueue after the copy */
1197 init_MUTEX(&tw_dev2->ioctl_sem);
1198 init_waitqueue_head(&tw_dev2->ioctl_wqueue);
1200 tw_device_extension_list[tw_device_extension_count] = tw_dev2;
1202 tw_device_extension_count = numcards;
1203 tw_dev2->host = host;
1205 printk(KERN_WARNING "3w-xxxx: tw_findcards(): Bad scsi host data for card %d.\n", j);
1206 scsi_unregister(host);
1207 release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
1208 tw_free_device_extension(tw_dev);
1213 /* Tell the firmware we support shutdown notification*/
1214 error = tw_setfeature(tw_dev2, 2, 1, &c);
1216 printk(KERN_WARNING "3w-xxxx: Unable to set features for card %d, old firmware or card.\n", j);
1219 /* Now setup the interrupt handler */
1220 error = tw_setup_irq(tw_dev2);
1222 printk(KERN_WARNING "3w-xxxx: tw_findcards(): Error requesting irq for card %d.\n", j);
1223 scsi_unregister(host);
1224 release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
1226 tw_free_device_extension(tw_dev);
1232 /* Re-enable interrupts on the card */
1233 tw_enable_interrupts(tw_dev2);
1235 /* Free the temporary device extension */
1241 if (numcards == 0) {
1242 printk(KERN_WARNING "3w-xxxx: No cards found.\n");
1244 register_reboot_notifier(&tw_notifier);
1245 if ((twe_major = register_chrdev (0, "twe", &tw_fops)) < 0) {
1246 printk(KERN_WARNING "3w-xxxx: Unable to register \"twe\" character device, error = %d.\n", twe_major);
1251 } /* End tw_findcards() */
1253 /* This function will free up device extension resources */
1254 void tw_free_device_extension(TW_Device_Extension *tw_dev)
1256 dprintk(KERN_NOTICE "3w-xxxx: tw_free_device_extension()\n");
1258 /* Free command packet and generic buffer memory */
1259 if (tw_dev->command_packet_virtual_address[0])
1260 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]);
1262 if (tw_dev->alignment_virtual_address[0])
1263 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]);
1264 } /* End tw_free_device_extension() */
1266 /* Clean shutdown routine */
1267 static int tw_halt(struct notifier_block *nb, ulong event, void *buf)
1271 for (i=0;i<tw_device_extension_count;i++) {
1272 if (tw_device_extension_list[i]->online == 1) {
1273 printk(KERN_NOTICE "3w-xxxx: Shutting down card %d.\n", i);
1274 tw_shutdown_device(tw_device_extension_list[i]);
1275 tw_device_extension_list[i]->online = 0;
1278 unregister_reboot_notifier(&tw_notifier);
1281 } /* End tw_halt() */
1283 /* This function will send an initconnection command to controller */
1284 int tw_initconnection(TW_Device_Extension *tw_dev, int message_credits)
1286 unsigned long command_que_value;
1287 u32 command_que_addr;
1288 u32 response_que_addr;
1289 TW_Command *command_packet;
1290 TW_Response_Queue response_queue;
1293 dprintk(KERN_NOTICE "3w-xxxx: tw_initconnection()\n");
1294 command_que_addr = tw_dev->registers.command_que_addr;
1295 response_que_addr = tw_dev->registers.response_que_addr;
1297 /* Initialize InitConnection command packet */
1298 if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
1299 printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad command packet virtual address.\n");
1303 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1304 memset(command_packet, 0, sizeof(TW_Sector));
1305 command_packet->byte0.opcode = TW_OP_INIT_CONNECTION;
1306 command_packet->byte0.sgl_offset = 0x0;
1307 command_packet->size = TW_INIT_COMMAND_PACKET_SIZE;
1308 command_packet->request_id = request_id;
1309 command_packet->byte3.unit = 0x0;
1310 command_packet->byte3.host_id = 0x0;
1311 command_packet->status = 0x0;
1312 command_packet->flags = 0x0;
1313 command_packet->byte6.message_credits = message_credits;
1314 command_packet->byte8.init_connection.response_queue_pointer = 0x0;
1315 command_que_value = tw_dev->command_packet_physical_address[request_id];
1317 if (command_que_value == 0) {
1318 printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad command packet physical address.\n");
1322 /* Send command packet to the board */
1323 outl(command_que_value, command_que_addr);
1325 /* Poll for completion */
1326 if (tw_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, 30) == 0) {
1327 response_queue.value = inl(response_que_addr);
1328 request_id = (unsigned char)response_queue.u.response_id;
1329 if (request_id != 0) {
1330 /* unexpected request id */
1331 printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Unexpected request id.\n");
1334 if (command_packet->status != 0) {
1336 tw_decode_sense(tw_dev, request_id, 0);
1341 } /* End tw_initconnection() */
1343 /* This function will initialize the fields of a device extension */
1344 int tw_initialize_device_extension(TW_Device_Extension *tw_dev)
1348 dprintk(KERN_NOTICE "3w-xxxx: tw_initialize_device_extension()\n");
1350 /* Initialize command packet buffers */
1351 error = tw_allocate_memory(tw_dev, sizeof(TW_Command), 0);
1353 printk(KERN_WARNING "3w-xxxx: Command packet memory allocation failed.\n");
1357 /* Initialize generic buffer */
1358 error = tw_allocate_memory(tw_dev, sizeof(TW_Sector), 1);
1360 printk(KERN_WARNING "3w-xxxx: Generic memory allocation failed.\n");
1364 for (i=0;i<TW_Q_LENGTH;i++) {
1365 tw_dev->free_queue[i] = i;
1366 tw_dev->state[i] = TW_S_INITIAL;
1369 tw_dev->pending_head = TW_Q_START;
1370 tw_dev->pending_tail = TW_Q_START;
1371 spin_lock_init(&tw_dev->tw_lock);
1372 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1375 } /* End tw_initialize_device_extension() */
1377 /* This function will get unit info from the controller */
1378 int tw_initialize_units(TW_Device_Extension *tw_dev)
1381 unsigned char request_id = 0;
1382 TW_Command *command_packet;
1384 int i, imax, num_units = 0;
1385 unsigned long command_que_value;
1386 u32 command_que_addr;
1387 u32 response_que_addr;
1388 TW_Response_Queue response_queue;
1389 unsigned long param_value;
1390 unsigned char *is_unit_present;
1392 dprintk(KERN_NOTICE "3w-xxxx: tw_initialize_units()\n");
1394 command_que_addr = tw_dev->registers.command_que_addr;
1395 response_que_addr = tw_dev->registers.response_que_addr;
1397 /* Setup the command packet */
1398 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1399 if (command_packet == NULL) {
1400 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad command packet virtual address.\n");
1403 memset(command_packet, 0, sizeof(TW_Sector));
1404 command_packet->byte0.opcode = TW_OP_GET_PARAM;
1405 command_packet->byte0.sgl_offset = 2;
1406 command_packet->size = 4;
1407 command_packet->request_id = request_id;
1408 command_packet->byte3.unit = 0;
1409 command_packet->byte3.host_id = 0;
1410 command_packet->status = 0;
1411 command_packet->flags = 0;
1412 command_packet->byte6.block_count = 1;
1414 /* Now setup the param */
1415 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
1416 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad alignment virtual address.\n");
1419 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1420 memset(param, 0, sizeof(TW_Sector));
1421 param->table_id = 3; /* unit summary table */
1422 param->parameter_id = 3; /* unitstatus parameter */
1423 param->parameter_size_bytes = TW_MAX_UNITS;
1424 param_value = tw_dev->alignment_physical_address[request_id];
1425 if (param_value == 0) {
1426 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad alignment physical address.\n");
1430 command_packet->byte8.param.sgl[0].address = param_value;
1431 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
1433 /* Post the command packet to the board */
1434 command_que_value = tw_dev->command_packet_physical_address[request_id];
1435 if (command_que_value == 0) {
1436 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad command packet physical address.\n");
1439 outl(command_que_value, command_que_addr);
1441 /* Poll for completion */
1442 if (tw_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, 30) == 0) {
1443 response_queue.value = inl(response_que_addr);
1444 request_id = (unsigned char)response_queue.u.response_id;
1445 if (request_id != 0) {
1446 /* unexpected request id */
1447 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Unexpected request id.\n");
1450 if (command_packet->status != 0) {
1452 tw_decode_sense(tw_dev, request_id, 0);
1458 /* response never received */
1459 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): No response.\n");
1463 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1464 is_unit_present = (unsigned char *)&(param->data[0]);
1466 /* Show all units present */
1467 imax = TW_MAX_UNITS;
1468 for(i=0; i<imax; i++) {
1469 if (is_unit_present[i] == 0) {
1470 tw_dev->is_unit_present[i] = FALSE;
1472 if (is_unit_present[i] & TW_UNIT_ONLINE) {
1473 dprintk(KERN_NOTICE "3w-xxxx: tw_initialize_units(): Unit %d found.\n", i);
1474 tw_dev->is_unit_present[i] = TRUE;
1479 tw_dev->num_units = num_units;
1481 if (num_units == 0) {
1482 dprintk(KERN_NOTICE "3w-xxxx: tw_initialize_units(): No units found.\n");
1487 } /* End tw_initialize_units() */
1489 /* This function is the interrupt service routine */
1490 static irqreturn_t tw_interrupt(int irq, void *dev_instance,
1491 struct pt_regs *regs)
1494 u32 status_reg_addr, status_reg_value;
1495 u32 response_que_addr;
1496 TW_Device_Extension *tw_dev = (TW_Device_Extension *)dev_instance;
1497 TW_Response_Queue response_que;
1498 int error = 0, retval = 0;
1499 unsigned long flags = 0;
1500 TW_Command *command_packet;
1503 dprintk(KERN_WARNING "3w-xxxx: tw_interrupt()\n");
1505 /* See if we are already running on another processor */
1506 if (test_and_set_bit(TW_IN_INTR, &tw_dev->flags))
1509 /* Get the host lock for io completions */
1510 spin_lock_irqsave(tw_dev->host->host_lock, flags);
1512 /* See if the interrupt matches this instance */
1513 if (tw_dev->tw_pci_dev->irq == irq) {
1516 /* Make sure io isn't queueing */
1517 spin_lock(&tw_dev->tw_lock);
1519 /* Read the registers */
1520 status_reg_addr = tw_dev->registers.status_reg_addr;
1521 response_que_addr = tw_dev->registers.response_que_addr;
1522 status_reg_value = inl(status_reg_addr);
1524 /* Check if this is our interrupt, otherwise bail */
1525 if (!(status_reg_value & TW_STATUS_VALID_INTERRUPT))
1526 goto tw_interrupt_bail;
1528 /* Check controller for errors */
1529 if (tw_check_bits(status_reg_value)) {
1530 dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n");
1531 if (tw_decode_bits(tw_dev, status_reg_value, 1)) {
1532 tw_clear_all_interrupts(tw_dev);
1533 goto tw_interrupt_bail;
1537 /* Handle host interrupt */
1538 if (status_reg_value & TW_STATUS_HOST_INTERRUPT) {
1539 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Received host interrupt.\n");
1540 tw_clear_host_interrupt(tw_dev);
1543 /* Handle attention interrupt */
1544 if (status_reg_value & TW_STATUS_ATTENTION_INTERRUPT) {
1545 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Received attention interrupt.\n");
1546 tw_clear_attention_interrupt(tw_dev);
1547 tw_state_request_start(tw_dev, &request_id);
1548 error = tw_aen_read_queue(tw_dev, request_id);
1550 printk(KERN_WARNING "3w-xxxx: scsi%d: Error reading aen queue.\n", tw_dev->host->host_no);
1551 tw_dev->state[request_id] = TW_S_COMPLETED;
1552 tw_state_request_finish(tw_dev, request_id);
1556 /* Handle command interrupt */
1557 if (status_reg_value & TW_STATUS_COMMAND_INTERRUPT) {
1558 /* Drain as many pending commands as we can */
1559 while (tw_dev->pending_request_count > 0) {
1560 request_id = tw_dev->pending_queue[tw_dev->pending_head];
1561 if (tw_dev->state[request_id] != TW_S_PENDING) {
1562 printk(KERN_WARNING "3w-xxxx: scsi%d: Found request id that wasn't pending.\n", tw_dev->host->host_no);
1565 if (tw_post_command_packet(tw_dev, request_id)==0) {
1566 if (tw_dev->pending_head == TW_Q_LENGTH-1) {
1567 tw_dev->pending_head = TW_Q_START;
1569 tw_dev->pending_head = tw_dev->pending_head + 1;
1571 tw_dev->pending_request_count--;
1573 /* If we get here, we will continue re-posting on the next command interrupt */
1577 /* If there are no more pending requests, we mask command interrupt */
1578 if (tw_dev->pending_request_count == 0)
1579 tw_mask_command_interrupt(tw_dev);
1582 /* Handle response interrupt */
1583 if (status_reg_value & TW_STATUS_RESPONSE_INTERRUPT) {
1584 /* Drain the response queue from the board */
1585 while ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
1586 /* Read response queue register */
1587 response_que.value = inl(response_que_addr);
1588 request_id = response_que.u.response_id;
1589 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1592 /* Check for bad response */
1593 if (command_packet->status != 0) {
1594 /* If internal command, don't error, don't fill sense */
1595 if (tw_dev->srb[request_id] == 0) {
1596 tw_decode_sense(tw_dev, request_id, 0);
1598 error = tw_decode_sense(tw_dev, request_id, 1);
1602 /* Check for correct state */
1603 if (tw_dev->state[request_id] != TW_S_POSTED) {
1604 /* Handle timed out ioctl's */
1605 if (tw_dev->srb[request_id] != 0) {
1606 if (tw_dev->srb[request_id]->cmnd[0] != TW_IOCTL) {
1607 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);
1613 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Response queue request id: %d.\n", request_id);
1615 /* Check for internal command completion */
1616 if (tw_dev->srb[request_id] == 0) {
1617 dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Found internally posted command.\n");
1618 /* Check for chrdev ioctl completion */
1619 if (request_id != tw_dev->chrdev_request_id) {
1620 retval = tw_aen_complete(tw_dev, request_id);
1622 printk(KERN_WARNING "3w-xxxx: scsi%d: Error completing aen.\n", tw_dev->host->host_no);
1625 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1626 wake_up(&tw_dev->ioctl_wqueue);
1629 switch (tw_dev->srb[request_id]->cmnd[0]) {
1632 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught READ_10/READ_6\n");
1636 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught WRITE_10/WRITE_6\n");
1638 case TEST_UNIT_READY:
1639 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught TEST_UNIT_READY\n");
1640 error = tw_scsiop_test_unit_ready_complete(tw_dev, request_id);
1643 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught INQUIRY\n");
1644 error = tw_scsiop_inquiry_complete(tw_dev, request_id);
1647 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught READ_CAPACITY\n");
1648 error = tw_scsiop_read_capacity_complete(tw_dev, request_id);
1651 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught MODE_SENSE\n");
1652 error = tw_scsiop_mode_sense_complete(tw_dev, request_id);
1654 case SYNCHRONIZE_CACHE:
1655 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught SYNCHRONIZE_CACHE\n");
1658 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught TW_IOCTL\n");
1659 error = tw_ioctl_complete(tw_dev, request_id);
1662 printk(KERN_WARNING "3w-xxxx: case slip in tw_interrupt()\n");
1666 /* If no error command was a success */
1668 tw_dev->srb[request_id]->result = (DID_OK << 16);
1671 /* If error, command failed */
1673 /* Ask for a host reset */
1674 tw_dev->srb[request_id]->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
1677 /* Now complete the io */
1678 if ((error != TW_ISR_DONT_COMPLETE)) {
1679 tw_dev->state[request_id] = TW_S_COMPLETED;
1680 tw_state_request_finish(tw_dev, request_id);
1681 tw_dev->posted_request_count--;
1682 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1684 tw_unmap_scsi_data(tw_dev->tw_pci_dev, tw_dev->srb[request_id]);
1688 /* Check for valid status after each drain */
1689 status_reg_value = inl(status_reg_addr);
1690 if (tw_check_bits(status_reg_value)) {
1691 dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n");
1692 if (tw_decode_bits(tw_dev, status_reg_value, 1)) {
1693 tw_clear_all_interrupts(tw_dev);
1694 goto tw_interrupt_bail;
1700 spin_unlock(&tw_dev->tw_lock);
1702 dprintk(KERN_WARNING "3w-xxxx: tw_interrupt() called for wrong instance.\n");
1704 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
1705 clear_bit(TW_IN_INTR, &tw_dev->flags);
1706 return IRQ_RETVAL(handled);
1707 } /* End tw_interrupt() */
1709 /* This function handles ioctls from userspace to the driver */
1710 int tw_ioctl(TW_Device_Extension *tw_dev, int request_id)
1712 unsigned char opcode;
1713 int bufflen, error = 0;
1715 TW_Command *command_packet, *command_save;
1716 unsigned long param_value;
1717 TW_Ioctl *ioctl = NULL;
1718 TW_Passthru *passthru = NULL;
1719 int tw_aen_code, i, use_sg;
1720 unsigned long *data_ptr;
1721 int total_bytes = 0, posted = 0;
1722 dma_addr_t dma_handle;
1723 struct timeval before, timeout;
1725 ioctl = (TW_Ioctl *)tw_dev->srb[request_id]->request_buffer;
1726 if (ioctl == NULL) {
1727 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Request buffer NULL.\n");
1728 tw_dev->state[request_id] = TW_S_COMPLETED;
1729 tw_state_request_finish(tw_dev, request_id);
1730 tw_dev->srb[request_id]->result = (DID_OK << 16);
1731 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1734 bufflen = tw_dev->srb[request_id]->request_bufflen;
1736 /* Initialize command packet */
1737 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1738 if (command_packet == NULL) {
1739 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Bad command packet virtual address.\n");
1740 tw_dev->state[request_id] = TW_S_COMPLETED;
1741 tw_state_request_finish(tw_dev, request_id);
1742 tw_dev->srb[request_id]->result = (DID_OK << 16);
1743 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1746 memset(command_packet, 0, sizeof(TW_Sector));
1748 /* Initialize param */
1749 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
1750 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Bad alignment virtual address.\n");
1751 tw_dev->state[request_id] = TW_S_COMPLETED;
1752 tw_state_request_finish(tw_dev, request_id);
1753 tw_dev->srb[request_id]->result = (DID_OK << 16);
1754 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1757 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1758 memset(param, 0, sizeof(TW_Sector));
1760 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);
1761 opcode = ioctl->opcode;
1765 dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): caught TW_OP_NOP.\n");
1766 command_packet->byte0.opcode = TW_OP_NOP;
1768 case TW_OP_GET_PARAM:
1769 dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): caught TW_OP_GET_PARAM.\n");
1770 command_packet->byte0.opcode = TW_OP_GET_PARAM;
1771 command_packet->byte3.unit = ioctl->unit_index;
1772 param->table_id = ioctl->table_id;
1773 param->parameter_id = ioctl->parameter_id;
1774 param->parameter_size_bytes = ioctl->parameter_size_bytes;
1775 tw_dev->ioctl_size[request_id] = ioctl->parameter_size_bytes;
1776 dprintk(KERN_NOTICE "table_id = %d parameter_id = %d parameter_size_bytes %d\n", param->table_id, param->parameter_id, param->parameter_size_bytes);
1778 case TW_OP_SET_PARAM:
1779 dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): caught TW_OP_SET_PARAM: table_id = %d, parameter_id = %d, parameter_size_bytes = %d.\n",
1780 ioctl->table_id, ioctl->parameter_id, ioctl->parameter_size_bytes);
1781 if (ioctl->data != NULL) {
1782 command_packet->byte0.opcode = TW_OP_SET_PARAM;
1783 param->table_id = ioctl->table_id;
1784 param->parameter_id = ioctl->parameter_id;
1785 param->parameter_size_bytes = ioctl->parameter_size_bytes;
1786 memcpy(param->data, ioctl->data, ioctl->parameter_size_bytes);
1789 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): ioctl->data NULL.\n");
1792 case TW_OP_AEN_LISTEN:
1793 dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): caught TW_OP_AEN_LISTEN.\n");
1794 if (tw_dev->aen_head == tw_dev->aen_tail) {
1795 /* aen queue empty */
1796 dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): Aen queue empty.\n");
1797 tw_aen_code = TW_AEN_QUEUE_EMPTY;
1798 memcpy(tw_dev->srb[request_id]->request_buffer, &tw_aen_code, ioctl->parameter_size_bytes);
1800 /* Copy aen queue entry to request buffer */
1801 dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): Returning aen 0x%x\n", tw_dev->aen_queue[tw_dev->aen_head]);
1802 tw_aen_code = tw_dev->aen_queue[tw_dev->aen_head];
1803 memcpy(tw_dev->srb[request_id]->request_buffer, &tw_aen_code, ioctl->parameter_size_bytes);
1804 if (tw_dev->aen_head == TW_Q_LENGTH - 1) {
1805 tw_dev->aen_head = TW_Q_START;
1807 tw_dev->aen_head = tw_dev->aen_head + 1;
1810 tw_dev->state[request_id] = TW_S_COMPLETED;
1811 tw_state_request_finish(tw_dev, request_id);
1812 tw_dev->srb[request_id]->result = (DID_OK << 16);
1813 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1815 case TW_ATA_PASSTHRU:
1816 if (ioctl->data != NULL) {
1817 memcpy(command_packet, ioctl->data, sizeof(TW_Command));
1818 command_packet->request_id = request_id;
1820 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): ioctl->data NULL.\n");
1824 passthru = (TW_Passthru *)tw_dev->command_packet_virtual_address[request_id];
1825 /* Don't load sg_list for non-data ATA cmds */
1826 if ((passthru->param != 0) && (passthru->param != 0x8)) {
1827 passthru->sg_list[0].length = passthru->sector_count*512;
1828 if (passthru->sg_list[0].length > TW_MAX_PASSTHRU_BYTES) {
1829 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Passthru size (%d) too big.\n", passthru->sg_list[0].length);
1832 passthru->sg_list[0].address = tw_dev->alignment_physical_address[request_id];
1834 tw_post_command_packet(tw_dev, request_id);
1837 dprintk(KERN_WARNING "3w-xxxx: tw_ioctl(): caught TW_CMD_PACKET.\n");
1838 if (ioctl->data != NULL) {
1839 memcpy(command_packet, ioctl->data, sizeof(TW_Command));
1840 command_packet->request_id = request_id;
1841 tw_post_command_packet(tw_dev, request_id);
1844 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): ioctl->data NULL.\n");
1847 case TW_CMD_PACKET_WITH_DATA:
1848 dprintk(KERN_WARNING "3w-xxxx: tw_ioctl(): caught TW_CMD_PACKET_WITH_DATA.\n");
1849 command_save = (TW_Command *)tw_dev->alignment_virtual_address[request_id];
1850 if (command_save == NULL) {
1851 printk(KERN_WARNING "3w-xxxx: scsi%d: tw_ioctl(): Bad alignment virtual address.\n", tw_dev->host->host_no);
1854 if (ioctl->data != NULL) {
1855 /* Copy down the command packet */
1856 memcpy(command_packet, ioctl->data, sizeof(TW_Command));
1857 memcpy(command_save, ioctl->data, sizeof(TW_Command));
1858 command_packet->request_id = request_id;
1860 /* Now deal with the two possible sglists */
1861 if (command_packet->byte0.sgl_offset == 2) {
1862 use_sg = command_packet->size - 3;
1863 for (i=0;i<use_sg;i++)
1864 total_bytes+=command_packet->byte8.param.sgl[i].length;
1865 tw_dev->ioctl_data[request_id] = pci_alloc_consistent(tw_dev->tw_pci_dev, total_bytes, &dma_handle);
1867 if (!tw_dev->ioctl_data[request_id]) {
1868 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);
1872 /* Copy param sglist into the kernel */
1873 data_ptr = tw_dev->ioctl_data[request_id];
1874 for (i=0;i<use_sg;i++) {
1875 if (command_packet->byte8.param.sgl[i].address != 0) {
1876 error = copy_from_user(data_ptr, (void *)(unsigned long)command_packet->byte8.param.sgl[i].address, command_packet->byte8.param.sgl[i].length);
1878 dprintk(KERN_WARNING "3w-xxxx: scsi%d: Error copying param sglist from userspace.\n", tw_dev->host->host_no);
1882 printk(KERN_WARNING "3w-xxxx: scsi%d: tw_ioctl(): Bad param sgl address.\n", tw_dev->host->host_no);
1883 tw_dev->srb[request_id]->result = (DID_RESET << 16);
1886 data_ptr+=command_packet->byte8.param.sgl[i].length;
1888 command_packet->size = 4;
1889 command_packet->byte8.param.sgl[0].address = dma_handle;
1890 command_packet->byte8.param.sgl[0].length = total_bytes;
1892 if (command_packet->byte0.sgl_offset == 3) {
1893 use_sg = command_packet->size - 4;
1894 for (i=0;i<use_sg;i++)
1895 total_bytes+=command_packet->byte8.io.sgl[i].length;
1896 tw_dev->ioctl_data[request_id] = pci_alloc_consistent(tw_dev->tw_pci_dev, total_bytes, &dma_handle);
1898 if (!tw_dev->ioctl_data[request_id]) {
1899 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);
1902 if (command_packet->byte0.opcode == TW_OP_WRITE) {
1903 /* Copy io sglist into the kernel */
1904 data_ptr = tw_dev->ioctl_data[request_id];
1905 for (i=0;i<use_sg;i++) {
1906 if (command_packet->byte8.io.sgl[i].address != 0) {
1907 error = copy_from_user(data_ptr, (void *)(unsigned long)command_packet->byte8.io.sgl[i].address, command_packet->byte8.io.sgl[i].length);
1909 dprintk(KERN_WARNING "3w-xxxx: scsi%d: Error copying io sglist from userspace.\n", tw_dev->host->host_no);
1913 printk(KERN_WARNING "3w-xxxx: scsi%d: tw_ioctl(): Bad io sgl address.\n", tw_dev->host->host_no);
1914 tw_dev->srb[request_id]->result = (DID_RESET << 16);
1917 data_ptr+=command_packet->byte8.io.sgl[i].length;
1920 command_packet->size = 5;
1921 command_packet->byte8.io.sgl[0].address = dma_handle;
1922 command_packet->byte8.io.sgl[0].length = total_bytes;
1925 spin_unlock(&tw_dev->tw_lock);
1926 spin_unlock_irq(tw_dev->host->host_lock);
1928 set_bit(TW_IN_IOCTL, &tw_dev->flags);
1930 /* Finally post the command packet */
1931 tw_post_command_packet(tw_dev, request_id);
1933 do_gettimeofday(&before);
1936 mdelay(TW_IOCTL_WAIT_TIME);
1937 if (test_bit(TW_IN_IOCTL, &tw_dev->flags)) {
1938 do_gettimeofday(&timeout);
1939 if (before.tv_sec + TW_IOCTL_TIMEOUT < timeout.tv_sec) {
1940 spin_lock_irq(tw_dev->host->host_lock);
1941 spin_lock(&tw_dev->tw_lock);
1944 goto tw_ioctl_retry;
1948 spin_lock_irq(tw_dev->host->host_lock);
1949 spin_lock(&tw_dev->tw_lock);
1951 if (signal_pending(current)) {
1952 dprintk(KERN_WARNING "3w-xxxx: scsi%d: tw_ioctl(): Signal pending, aborting ioctl().\n", tw_dev->host->host_no);
1953 tw_dev->srb[request_id]->result = (DID_OK << 16);
1957 tw_dev->srb[request_id]->result = (DID_OK << 16);
1958 /* Now copy up the param or io sglist to userspace */
1959 if (command_packet->byte0.sgl_offset == 2) {
1960 use_sg = command_save->size - 3;
1961 data_ptr = tw_dev->ioctl_data[request_id];
1962 for (i=0;i<use_sg;i++) {
1963 if (command_save->byte8.param.sgl[i].address != 0) {
1964 error = copy_to_user((void *)(unsigned long)command_save->byte8.param.sgl[i].address, data_ptr, command_save->byte8.param.sgl[i].length);
1966 dprintk(KERN_WARNING "3w-xxxx: scsi%d: Error copying param sglist to userspace.\n", tw_dev->host->host_no);
1969 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);
1970 data_ptr+=command_save->byte8.param.sgl[i].length;
1972 printk(KERN_WARNING "3w-xxxx: scsi%d: tw_ioctl(): Bad param sgl address.\n", tw_dev->host->host_no);
1973 tw_dev->srb[request_id]->result = (DID_RESET << 16);
1978 if (command_packet->byte0.sgl_offset == 3) {
1979 use_sg = command_save->size - 4;
1980 if (command_packet->byte0.opcode == TW_OP_READ) {
1981 data_ptr = tw_dev->ioctl_data[request_id];
1982 for(i=0;i<use_sg;i++) {
1983 if (command_save->byte8.io.sgl[i].address != 0) {
1984 error = copy_to_user((void *)(unsigned long)command_save->byte8.io.sgl[i].address, data_ptr, command_save->byte8.io.sgl[i].length);
1986 dprintk(KERN_WARNING "3w-xxxx: scsi%d: Error copying io sglist to userspace.\n", tw_dev->host->host_no);
1989 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);
1990 data_ptr+=command_save->byte8.io.sgl[i].length;
1992 printk(KERN_WARNING "3w-xxxx: scsi%d: tw_ioctl(): Bad io sgl address.\n", tw_dev->host->host_no);
1993 tw_dev->srb[request_id]->result = (DID_RESET << 16);
2002 /* Free up sglist memory */
2003 if (tw_dev->ioctl_data[request_id])
2004 pci_free_consistent(tw_dev->tw_pci_dev, total_bytes, tw_dev->ioctl_data[request_id], dma_handle);
2006 printk(KERN_WARNING "3w-xxxx: scsi%d: tw_ioctl(): Error freeing ioctl data.\n", tw_dev->host->host_no);
2008 /* Now complete the io */
2009 tw_dev->state[request_id] = TW_S_COMPLETED;
2010 tw_state_request_finish(tw_dev, request_id);
2012 tw_dev->posted_request_count--;
2013 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
2016 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): ioctl->data NULL.\n");
2020 dprintk(KERN_WARNING "3w-xxxx: Unknown ioctl 0x%x.\n", opcode);
2021 tw_dev->state[request_id] = TW_S_COMPLETED;
2022 tw_state_request_finish(tw_dev, request_id);
2023 tw_dev->srb[request_id]->result = (DID_OK << 16);
2024 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
2028 param_value = tw_dev->alignment_physical_address[request_id];
2029 if (param_value == 0) {
2030 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Bad alignment physical address.\n");
2031 tw_dev->state[request_id] = TW_S_COMPLETED;
2032 tw_state_request_finish(tw_dev, request_id);
2033 tw_dev->srb[request_id]->result = (DID_OK << 16);
2034 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
2037 command_packet->byte8.param.sgl[0].address = param_value;
2038 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
2040 command_packet->byte0.sgl_offset = 2;
2041 command_packet->size = 4;
2042 command_packet->request_id = request_id;
2043 command_packet->byte3.host_id = 0;
2044 command_packet->status = 0;
2045 command_packet->flags = 0;
2046 command_packet->byte6.parameter_count = 1;
2048 /* Now try to post the command to the board */
2049 tw_post_command_packet(tw_dev, request_id);
2052 } /* End tw_ioctl() */
2054 /* This function is called by the isr to complete ioctl requests */
2055 int tw_ioctl_complete(TW_Device_Extension *tw_dev, int request_id)
2057 unsigned char *param_data;
2058 unsigned char *buff;
2060 TW_Ioctl *ioctl = NULL;
2061 TW_Passthru *passthru = NULL;
2062 TW_Command *command_packet;
2064 ioctl = (TW_Ioctl *)tw_dev->srb[request_id]->request_buffer;
2065 dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl_complete()\n");
2066 buff = tw_dev->srb[request_id]->request_buffer;
2068 printk(KERN_WARNING "3w-xxxx: tw_ioctl_complete(): Request buffer NULL.\n");
2072 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
2073 if (command_packet == NULL) {
2074 printk(KERN_WARNING "3w-xxxx: scsi%d: tw_ioctl_complete(): Bad command packet virtual address.\n", tw_dev->host->host_no);
2078 dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl_complete(): Request_bufflen = %d\n", tw_dev->srb[request_id]->request_bufflen);
2080 ioctl = (TW_Ioctl *)buff;
2081 switch (ioctl->opcode) {
2082 case TW_ATA_PASSTHRU:
2083 passthru = (TW_Passthru *)ioctl->data;
2084 /* Don't return data for non-data ATA cmds */
2085 if ((passthru->param != 0) && (passthru->param != 0x8))
2086 memcpy(buff, tw_dev->alignment_virtual_address[request_id], passthru->sector_count * 512);
2088 /* For non-data cmds, return cmd pkt */
2089 if (tw_dev->srb[request_id]->request_bufflen >= sizeof(TW_Command))
2090 memcpy(buff, tw_dev->command_packet_virtual_address[request_id], sizeof(TW_Command));
2093 case TW_CMD_PACKET_WITH_DATA:
2094 dprintk(KERN_WARNING "3w-xxxx: tw_ioctl_complete(): caught TW_CMD_PACKET_WITH_DATA.\n");
2095 clear_bit(TW_IN_IOCTL, &tw_dev->flags);
2096 return TW_ISR_DONT_COMPLETE; /* Special case for isr to not complete io */
2098 memset(buff, 0, tw_dev->srb[request_id]->request_bufflen);
2099 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
2100 if (param == NULL) {
2101 printk(KERN_WARNING "3w-xxxx: tw_ioctl_complete(): Bad alignment virtual address.\n");
2104 param_data = &(param->data[0]);
2105 memcpy(buff, param_data, tw_dev->ioctl_size[request_id]);
2108 } /* End tw_ioctl_complete() */
2110 static int tw_map_scsi_sg_data(struct pci_dev *pdev, Scsi_Cmnd *cmd)
2113 int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
2115 dprintk(KERN_WARNING "3w-xxxx: tw_map_scsi_sg_data()\n");
2117 if (cmd->use_sg == 0)
2120 use_sg = pci_map_sg(pdev, cmd->buffer, cmd->use_sg, dma_dir);
2123 printk(KERN_WARNING "3w-xxxx: tw_map_scsi_sg_data(): pci_map_sg() failed.\n");
2128 cmd->SCp.have_data_in = use_sg;
2131 } /* End tw_map_scsi_sg_data() */
2133 static u32 tw_map_scsi_single_data(struct pci_dev *pdev, Scsi_Cmnd *cmd)
2136 int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
2138 dprintk(KERN_WARNING "3w-xxxx: tw_map_scsi_single_data()\n");
2140 if (cmd->request_bufflen == 0)
2143 mapping = pci_map_page(pdev, virt_to_page(cmd->request_buffer), offset_in_page(cmd->request_buffer), cmd->request_bufflen, dma_dir);
2146 printk(KERN_WARNING "3w-xxxx: tw_map_scsi_single_data(): pci_map_page() failed.\n");
2151 cmd->SCp.have_data_in = mapping;
2154 } /* End tw_map_scsi_single_data() */
2156 /* This function will mask the command interrupt */
2157 void tw_mask_command_interrupt(TW_Device_Extension *tw_dev)
2159 u32 control_reg_addr, control_reg_value;
2161 control_reg_addr = tw_dev->registers.control_reg_addr;
2162 control_reg_value = TW_CONTROL_MASK_COMMAND_INTERRUPT;
2163 outl(control_reg_value, control_reg_addr);
2164 } /* End tw_mask_command_interrupt() */
2166 /* This function will poll the status register for a flag */
2167 int tw_poll_status(TW_Device_Extension *tw_dev, u32 flag, int seconds)
2169 u32 status_reg_addr, status_reg_value;
2170 struct timeval before, timeout;
2172 status_reg_addr = tw_dev->registers.status_reg_addr;
2173 do_gettimeofday(&before);
2174 status_reg_value = inl(status_reg_addr);
2176 if (tw_check_bits(status_reg_value)) {
2177 dprintk(KERN_WARNING "3w-xxxx: tw_poll_status(): Unexpected bits.\n");
2178 tw_decode_bits(tw_dev, status_reg_value, 0);
2181 while ((status_reg_value & flag) != flag) {
2182 status_reg_value = inl(status_reg_addr);
2184 if (tw_check_bits(status_reg_value)) {
2185 dprintk(KERN_WARNING "3w-xxxx: tw_poll_status(): Unexpected bits.\n");
2186 tw_decode_bits(tw_dev, status_reg_value, 0);
2189 do_gettimeofday(&timeout);
2190 if (before.tv_sec + seconds < timeout.tv_sec) {
2191 dprintk(KERN_WARNING "3w-xxxx: tw_poll_status(): Flag 0x%x not found.\n", flag);
2197 } /* End tw_poll_status() */
2199 /* This function will poll the status register for disappearance of a flag */
2200 int tw_poll_status_gone(TW_Device_Extension *tw_dev, u32 flag, int seconds)
2202 u32 status_reg_addr, status_reg_value;
2203 struct timeval before, timeout;
2205 status_reg_addr = tw_dev->registers.status_reg_addr;
2206 do_gettimeofday(&before);
2207 status_reg_value = inl(status_reg_addr);
2209 if (tw_check_bits(status_reg_value)) {
2210 dprintk(KERN_WARNING "3w-xxxx: tw_poll_status_gone(): Unexpected bits.\n");
2211 tw_decode_bits(tw_dev, status_reg_value, 0);
2214 while ((status_reg_value & flag) != 0) {
2215 status_reg_value = inl(status_reg_addr);
2217 if (tw_check_bits(status_reg_value)) {
2218 dprintk(KERN_WARNING "3w-xxxx: tw_poll_status_gone(): Unexpected bits.\n");
2219 tw_decode_bits(tw_dev, status_reg_value, 0);
2222 do_gettimeofday(&timeout);
2223 if (before.tv_sec + seconds < timeout.tv_sec) {
2224 dprintk(KERN_WARNING "3w-xxxx: tw_poll_status_gone(): Flag 0x%x never disappeared.\n", flag);
2230 } /* End tw_poll_status_gone() */
2232 /* This function will attempt to post a command packet to the board */
2233 int tw_post_command_packet(TW_Device_Extension *tw_dev, int request_id)
2235 u32 status_reg_addr, status_reg_value;
2236 unsigned long command_que_value;
2237 u32 command_que_addr;
2239 dprintk(KERN_NOTICE "3w-xxxx: tw_post_command_packet()\n");
2240 command_que_addr = tw_dev->registers.command_que_addr;
2241 command_que_value = tw_dev->command_packet_physical_address[request_id];
2242 status_reg_addr = tw_dev->registers.status_reg_addr;
2243 status_reg_value = inl(status_reg_addr);
2245 if (tw_check_bits(status_reg_value)) {
2246 dprintk(KERN_WARNING "3w-xxxx: tw_post_command_packet(): Unexpected bits.\n");
2247 tw_decode_bits(tw_dev, status_reg_value, 1);
2250 if ((status_reg_value & TW_STATUS_COMMAND_QUEUE_FULL) == 0) {
2251 /* We successfully posted the command packet */
2252 outl(command_que_value, command_que_addr);
2253 tw_dev->state[request_id] = TW_S_POSTED;
2254 tw_dev->posted_request_count++;
2255 if (tw_dev->posted_request_count > tw_dev->max_posted_request_count) {
2256 tw_dev->max_posted_request_count = tw_dev->posted_request_count;
2259 /* Couldn't post the command packet, so we do it in the isr */
2260 if (tw_dev->state[request_id] != TW_S_PENDING) {
2261 tw_dev->state[request_id] = TW_S_PENDING;
2262 tw_dev->pending_request_count++;
2263 if (tw_dev->pending_request_count > tw_dev->max_pending_request_count) {
2264 tw_dev->max_pending_request_count = tw_dev->pending_request_count;
2266 tw_dev->pending_queue[tw_dev->pending_tail] = request_id;
2267 if (tw_dev->pending_tail == TW_Q_LENGTH-1) {
2268 tw_dev->pending_tail = TW_Q_START;
2270 tw_dev->pending_tail = tw_dev->pending_tail + 1;
2273 tw_unmask_command_interrupt(tw_dev);
2277 } /* End tw_post_command_packet() */
2279 /* This function will reset a device extension */
2280 int tw_reset_device_extension(TW_Device_Extension *tw_dev)
2286 dprintk(KERN_NOTICE "3w-xxxx: tw_reset_device_extension()\n");
2289 if (tw_reset_sequence(tw_dev)) {
2290 printk(KERN_WARNING "3w-xxxx: scsi%d: Reset sequence failed.\n", tw_dev->host->host_no);
2294 /* Abort all requests that are in progress */
2295 for (i=0;i<imax;i++) {
2296 if ((tw_dev->state[i] != TW_S_FINISHED) &&
2297 (tw_dev->state[i] != TW_S_INITIAL) &&
2298 (tw_dev->state[i] != TW_S_COMPLETED)) {
2299 srb = tw_dev->srb[i];
2301 srb->result = (DID_RESET << 16);
2302 tw_dev->srb[i]->scsi_done(tw_dev->srb[i]);
2303 tw_unmap_scsi_data(tw_dev->tw_pci_dev, tw_dev->srb[i]);
2308 /* Reset queues and counts */
2309 for (i=0;i<imax;i++) {
2310 tw_dev->free_queue[i] = i;
2311 tw_dev->state[i] = TW_S_INITIAL;
2313 tw_dev->free_head = TW_Q_START;
2314 tw_dev->free_tail = TW_Q_START;
2315 tw_dev->posted_request_count = 0;
2316 tw_dev->pending_request_count = 0;
2317 tw_dev->pending_head = TW_Q_START;
2318 tw_dev->pending_tail = TW_Q_START;
2319 tw_dev->reset_print = 0;
2320 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
2323 } /* End tw_reset_device_extension() */
2325 /* This function will reset a controller */
2326 int tw_reset_sequence(TW_Device_Extension *tw_dev)
2331 /* Disable interrupts */
2332 tw_disable_interrupts(tw_dev);
2334 /* Reset the board */
2335 while (tries < TW_MAX_RESET_TRIES) {
2336 tw_soft_reset(tw_dev);
2338 error = tw_aen_drain_queue(tw_dev);
2340 printk(KERN_WARNING "3w-xxxx: scsi%d: AEN drain failed, retrying.\n", tw_dev->host->host_no);
2345 /* Check for controller errors */
2346 if (tw_check_errors(tw_dev)) {
2347 printk(KERN_WARNING "3w-xxxx: scsi%d: Controller errors found, retrying.\n", tw_dev->host->host_no);
2352 /* Now the controller is in a good state */
2356 if (tries >= TW_MAX_RESET_TRIES) {
2357 printk(KERN_WARNING "3w-xxxx: scsi%d: Controller errors, card not responding, check all cabling.\n", tw_dev->host->host_no);
2361 error = tw_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS);
2363 printk(KERN_WARNING "3w-xxxx: scsi%d: Connection initialization failed.\n", tw_dev->host->host_no);
2367 /* Re-enable interrupts */
2368 tw_enable_and_clear_interrupts(tw_dev);
2371 } /* End tw_reset_sequence() */
2373 /* This funciton returns unit geometry in cylinders/heads/sectors */
2374 int tw_scsi_biosparam(struct scsi_device *sdev, struct block_device *bdev,
2375 sector_t capacity, int geom[])
2377 int heads, sectors, cylinders;
2378 TW_Device_Extension *tw_dev;
2380 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_biosparam()\n");
2381 tw_dev = (TW_Device_Extension *)sdev->host->hostdata;
2385 cylinders = (unsigned long)capacity / (heads * sectors);
2387 if (capacity >= 0x200000) {
2390 cylinders = (unsigned long)capacity / (heads * sectors);
2393 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_biosparam(): heads = %d, sectors = %d, cylinders = %d\n", heads, sectors, cylinders);
2396 geom[2] = cylinders;
2399 } /* End tw_scsi_biosparam() */
2401 /* This function will find and initialize any cards */
2402 int tw_scsi_detect(Scsi_Host_Template *tw_host)
2406 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_detect()\n");
2408 printk(KERN_WARNING "3ware Storage Controller device driver for Linux v%s.\n", tw_driver_version);
2410 ret = tw_findcards(tw_host);
2413 } /* End tw_scsi_detect() */
2415 /* This is the new scsi eh abort function */
2416 int tw_scsi_eh_abort(Scsi_Cmnd *SCpnt)
2418 TW_Device_Extension *tw_dev=NULL;
2421 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_eh_abort()\n");
2424 printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Invalid Scsi_Cmnd.\n");
2428 tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
2429 if (tw_dev == NULL) {
2430 printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Invalid device extension.\n");
2434 spin_lock(&tw_dev->tw_lock);
2435 tw_dev->num_aborts++;
2437 /* If the command hasn't been posted yet, we can do the abort */
2438 for (i=0;i<TW_Q_LENGTH;i++) {
2439 if (tw_dev->srb[i] == SCpnt) {
2440 if (tw_dev->state[i] == TW_S_STARTED) {
2441 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);
2442 tw_dev->state[i] = TW_S_COMPLETED;
2443 tw_state_request_finish(tw_dev, i);
2444 spin_unlock(&tw_dev->tw_lock);
2447 if (tw_dev->state[i] == TW_S_PENDING) {
2448 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);
2449 if (tw_dev->pending_head == TW_Q_LENGTH-1) {
2450 tw_dev->pending_head = TW_Q_START;
2452 tw_dev->pending_head = tw_dev->pending_head + 1;
2454 tw_dev->pending_request_count--;
2455 tw_dev->state[i] = TW_S_COMPLETED;
2456 tw_state_request_finish(tw_dev, i);
2457 spin_unlock(&tw_dev->tw_lock);
2460 if (tw_dev->state[i] == TW_S_POSTED) {
2461 /* If the command has already been posted, we have to reset the card */
2462 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);
2463 /* We have to let AEN requests through before the reset */
2464 spin_unlock(&tw_dev->tw_lock);
2465 spin_unlock_irq(tw_dev->host->host_lock);
2466 mdelay(TW_AEN_WAIT_TIME);
2467 spin_lock_irq(tw_dev->host->host_lock);
2468 spin_lock(&tw_dev->tw_lock);
2470 if (tw_reset_device_extension(tw_dev)) {
2471 dprintk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Reset failed for card %d.\n", tw_dev->host->host_no);
2472 spin_unlock(&tw_dev->tw_lock);
2479 spin_unlock(&tw_dev->tw_lock);
2481 } /* End tw_scsi_eh_abort() */
2483 /* This is the new scsi eh reset function */
2484 int tw_scsi_eh_reset(Scsi_Cmnd *SCpnt)
2486 TW_Device_Extension *tw_dev=NULL;
2488 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_eh_reset()\n");
2491 printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_reset(): Invalid Scsi_Cmnd.\n");
2495 tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
2496 if (tw_dev == NULL) {
2497 printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_reset(): Invalid device extension.\n");
2501 /* We have to let AEN requests through before the reset */
2502 spin_unlock_irq(tw_dev->host->host_lock);
2503 mdelay(TW_AEN_WAIT_TIME);
2504 spin_lock_irq(tw_dev->host->host_lock);
2506 spin_lock(&tw_dev->tw_lock);
2507 tw_dev->num_resets++;
2509 /* Now reset the card and some of the device extension data */
2510 if (tw_reset_device_extension(tw_dev)) {
2511 printk(KERN_WARNING "3w-xxxx: scsi%d: Reset failed.\n", tw_dev->host->host_no);
2512 spin_unlock(&tw_dev->tw_lock);
2515 printk(KERN_WARNING "3w-xxxx: scsi%d: Reset succeeded.\n", tw_dev->host->host_no);
2516 spin_unlock(&tw_dev->tw_lock);
2519 } /* End tw_scsi_eh_reset() */
2521 /* This function handles input and output from /proc/scsi/3w-xxxx/x */
2522 int tw_scsi_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
2523 off_t offset, int length, int inout)
2525 TW_Device_Extension *tw_dev = NULL;
2530 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_proc_info()\n");
2532 /* Find the correct device extension */
2533 for (i=0;i<tw_device_extension_count;i++)
2534 if (tw_device_extension_list[i]->host->host_no == shost->host_no)
2535 tw_dev = tw_device_extension_list[i];
2536 if (tw_dev == NULL) {
2537 printk(KERN_WARNING "3w-xxxx: tw_scsi_proc_info(): Couldn't locate device extension.\n");
2541 info.buffer = buffer;
2542 info.length = length;
2543 info.offset = offset;
2548 if (strncmp(buffer, "debug", 5) == 0) {
2549 printk(KERN_INFO "3w-xxxx: Posted commands:\n");
2550 for (j=0;j<TW_Q_LENGTH;j++) {
2551 if (tw_dev->state[j] == TW_S_POSTED) {
2552 TW_Command *command = (TW_Command *)tw_dev->command_packet_virtual_address[j];
2553 printk(KERN_INFO "3w-xxxx: Request_id: %d\n", j);
2554 printk(KERN_INFO "Opcode: 0x%x\n", command->byte0.opcode);
2555 printk(KERN_INFO "Block_count: 0x%x\n", command->byte6.block_count);
2556 printk(KERN_INFO "LBA: 0x%x\n", command->byte8.io.lba);
2557 printk(KERN_INFO "Physical command packet addr: 0x%lx\n", tw_dev->command_packet_physical_address[j]);
2558 printk(KERN_INFO "Scsi_Cmnd: %p\n", tw_dev->srb[j]);
2561 printk(KERN_INFO "3w-xxxx: Free_head: %3d\n", tw_dev->free_head);
2562 printk(KERN_INFO "3w-xxxx: Free_tail: %3d\n", tw_dev->free_tail);
2570 tw_copy_info(&info, "scsi%d: 3ware Storage Controller\n", shost->host_no);
2571 tw_copy_info(&info, "Driver version: %s\n", tw_driver_version);
2572 tw_copy_info(&info, "Current commands posted: %3d\n", tw_dev->posted_request_count);
2573 tw_copy_info(&info, "Max commands posted: %3d\n", tw_dev->max_posted_request_count);
2574 tw_copy_info(&info, "Current pending commands: %3d\n", tw_dev->pending_request_count);
2575 tw_copy_info(&info, "Max pending commands: %3d\n", tw_dev->max_pending_request_count);
2576 tw_copy_info(&info, "Last sgl length: %3d\n", tw_dev->sgl_entries);
2577 tw_copy_info(&info, "Max sgl length: %3d\n", tw_dev->max_sgl_entries);
2578 tw_copy_info(&info, "Last sector count: %3d\n", tw_dev->sector_count);
2579 tw_copy_info(&info, "Max sector count: %3d\n", tw_dev->max_sector_count);
2580 tw_copy_info(&info, "Resets: %3d\n", tw_dev->num_resets);
2581 tw_copy_info(&info, "Aborts: %3d\n", tw_dev->num_aborts);
2582 tw_copy_info(&info, "AEN's: %3d\n", tw_dev->aen_count);
2584 if (info.position > info.offset) {
2585 return (info.position - info.offset);
2589 } /* End tw_scsi_proc_info() */
2591 /* This is the main scsi queue function to handle scsi opcodes */
2592 int tw_scsi_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
2594 unsigned char *command = SCpnt->cmnd;
2597 TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
2599 if (tw_dev == NULL) {
2600 printk(KERN_WARNING "3w-xxxx: tw_scsi_queue(): Invalid device extension.\n");
2601 SCpnt->result = (DID_ERROR << 16);
2606 spin_lock(&tw_dev->tw_lock);
2607 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue()\n");
2609 /* Skip scsi command if it isn't for us */
2610 if ((SCpnt->device->channel != 0) || (SCpnt->device->lun != 0)) {
2611 SCpnt->result = (DID_BAD_TARGET << 16);
2613 spin_unlock(&tw_dev->tw_lock);
2617 /* Save done function into Scsi_Cmnd struct */
2618 SCpnt->scsi_done = done;
2620 /* Queue the command and get a request id */
2621 tw_state_request_start(tw_dev, &request_id);
2623 /* Save the scsi command for use by the ISR */
2624 tw_dev->srb[request_id] = SCpnt;
2626 /* Initialize phase to zero */
2627 SCpnt->SCp.phase = 0;
2634 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught READ/WRITE.\n");
2635 error = tw_scsiop_read_write(tw_dev, request_id);
2637 case TEST_UNIT_READY:
2638 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught TEST_UNIT_READY.\n");
2639 error = tw_scsiop_test_unit_ready(tw_dev, request_id);
2642 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught INQUIRY.\n");
2643 error = tw_scsiop_inquiry(tw_dev, request_id);
2646 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught READ_CAPACITY.\n");
2647 error = tw_scsiop_read_capacity(tw_dev, request_id);
2650 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught REQUEST_SENSE.\n");
2651 error = tw_scsiop_request_sense(tw_dev, request_id);
2654 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught MODE_SENSE.\n");
2655 error = tw_scsiop_mode_sense(tw_dev, request_id);
2657 case SYNCHRONIZE_CACHE:
2658 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught SYNCHRONIZE_CACHE.\n");
2659 error = tw_scsiop_synchronize_cache(tw_dev, request_id);
2662 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught TW_SCSI_IOCTL.\n");
2663 error = tw_ioctl(tw_dev, request_id);
2666 printk(KERN_NOTICE "3w-xxxx: scsi%d: Unknown scsi opcode: 0x%x\n", tw_dev->host->host_no, *command);
2667 tw_dev->state[request_id] = TW_S_COMPLETED;
2668 tw_state_request_finish(tw_dev, request_id);
2669 SCpnt->result = (DID_BAD_TARGET << 16);
2673 tw_dev->state[request_id] = TW_S_COMPLETED;
2674 tw_state_request_finish(tw_dev, request_id);
2675 SCpnt->result = (DID_ERROR << 16);
2678 spin_unlock(&tw_dev->tw_lock);
2681 } /* End tw_scsi_queue() */
2683 /* This function will release the resources on an rmmod call */
2684 int tw_scsi_release(struct Scsi_Host *tw_host)
2686 TW_Device_Extension *tw_dev;
2687 tw_dev = (TW_Device_Extension *)tw_host->hostdata;
2689 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_release()\n");
2691 /* Fake like we just shut down, so notify the card that
2692 * we "shut down cleanly".
2694 tw_halt(0, 0, 0); // parameters aren't actually used
2696 /* Free up the IO region */
2697 release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
2699 /* Free up the IRQ */
2700 free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
2702 /* Unregister character device */
2703 if (twe_major >= 0) {
2704 unregister_chrdev(twe_major, "twe");
2708 /* Free up device extension resources */
2709 tw_free_device_extension(tw_dev);
2711 /* Tell kernel scsi-layer we are gone */
2712 scsi_unregister(tw_host);
2715 } /* End tw_scsi_release() */
2717 /* This function handles scsi inquiry commands */
2718 int tw_scsiop_inquiry(TW_Device_Extension *tw_dev, int request_id)
2721 TW_Command *command_packet;
2722 unsigned long command_que_value;
2723 u32 command_que_addr;
2724 unsigned long param_value;
2726 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry()\n");
2728 /* Initialize command packet */
2729 command_que_addr = tw_dev->registers.command_que_addr;
2730 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
2731 if (command_packet == NULL) {
2732 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad command packet virtual address.\n");
2735 memset(command_packet, 0, sizeof(TW_Sector));
2736 command_packet->byte0.opcode = TW_OP_GET_PARAM;
2737 command_packet->byte0.sgl_offset = 2;
2738 command_packet->size = 4;
2739 command_packet->request_id = request_id;
2740 command_packet->byte3.unit = 0;
2741 command_packet->byte3.host_id = 0;
2742 command_packet->status = 0;
2743 command_packet->flags = 0;
2744 command_packet->byte6.parameter_count = 1;
2746 /* Now setup the param */
2747 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
2748 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad alignment virtual address.\n");
2751 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
2752 memset(param, 0, sizeof(TW_Sector));
2753 param->table_id = 3; /* unit summary table */
2754 param->parameter_id = 3; /* unitsstatus parameter */
2755 param->parameter_size_bytes = TW_MAX_UNITS;
2756 param_value = tw_dev->alignment_physical_address[request_id];
2757 if (param_value == 0) {
2758 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad alignment physical address.\n");
2762 command_packet->byte8.param.sgl[0].address = param_value;
2763 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
2764 command_que_value = tw_dev->command_packet_physical_address[request_id];
2765 if (command_que_value == 0) {
2766 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad command packet physical address.\n");
2770 /* Now try to post the command packet */
2771 tw_post_command_packet(tw_dev, request_id);
2774 } /* End tw_scsiop_inquiry() */
2776 /* This function is called by the isr to complete an inquiry command */
2777 int tw_scsiop_inquiry_complete(TW_Device_Extension *tw_dev, int request_id)
2779 unsigned char *is_unit_present;
2780 unsigned char *request_buffer;
2783 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry_complete()\n");
2785 /* Fill request buffer */
2786 if (tw_dev->srb[request_id]->request_buffer == NULL) {
2787 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry_complete(): Request buffer NULL.\n");
2790 request_buffer = tw_dev->srb[request_id]->request_buffer;
2791 memset(request_buffer, 0, tw_dev->srb[request_id]->request_bufflen);
2792 request_buffer[0] = TYPE_DISK; /* Peripheral device type */
2793 request_buffer[1] = 0; /* Device type modifier */
2794 request_buffer[2] = 0; /* No ansi/iso compliance */
2795 request_buffer[4] = 31; /* Additional length */
2796 memcpy(&request_buffer[8], "3ware ", 8); /* Vendor ID */
2797 sprintf(&request_buffer[16], "Logical Disk %-2d ", tw_dev->srb[request_id]->device->id);
2798 memcpy(&request_buffer[32], tw_driver_version, 3);
2800 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
2801 if (param == NULL) {
2802 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry_complete(): Bad alignment virtual address.\n");
2805 is_unit_present = &(param->data[0]);
2807 if (is_unit_present[tw_dev->srb[request_id]->device->id] & TW_UNIT_ONLINE) {
2808 tw_dev->is_unit_present[tw_dev->srb[request_id]->device->id] = TRUE;
2810 tw_dev->is_unit_present[tw_dev->srb[request_id]->device->id] = FALSE;
2811 tw_dev->srb[request_id]->result = (DID_BAD_TARGET << 16);
2812 return TW_ISR_DONT_RESULT;
2816 } /* End tw_scsiop_inquiry_complete() */
2818 /* This function handles scsi mode_sense commands */
2819 int tw_scsiop_mode_sense(TW_Device_Extension *tw_dev, int request_id)
2822 TW_Command *command_packet;
2823 unsigned long command_que_value;
2824 unsigned long param_value;
2826 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_mode_sense()\n");
2828 /* Only page control = 0, page code = 0x8 (cache page) supported */
2829 if (tw_dev->srb[request_id]->cmnd[2] != 0x8) {
2830 tw_dev->state[request_id] = TW_S_COMPLETED;
2831 tw_state_request_finish(tw_dev, request_id);
2832 tw_dev->srb[request_id]->result = (DID_OK << 16);
2833 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
2837 /* Now read firmware cache setting for this unit */
2838 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
2839 if (command_packet == NULL) {
2840 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad command packet virtual address.\n");
2844 /* Setup the command packet */
2845 memset(command_packet, 0, sizeof(TW_Sector));
2846 command_packet->byte0.opcode = TW_OP_GET_PARAM;
2847 command_packet->byte0.sgl_offset = 2;
2848 command_packet->size = 4;
2849 command_packet->request_id = request_id;
2850 command_packet->byte3.unit = 0;
2851 command_packet->byte3.host_id = 0;
2852 command_packet->status = 0;
2853 command_packet->flags = 0;
2854 command_packet->byte6.parameter_count = 1;
2856 /* Setup the param */
2857 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
2858 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad alignment virtual address.\n");
2862 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
2863 memset(param, 0, sizeof(TW_Sector));
2864 param->table_id = TW_UNIT_INFORMATION_TABLE_BASE + tw_dev->srb[request_id]->device->id;
2865 param->parameter_id = 7; /* unit flags */
2866 param->parameter_size_bytes = 1;
2867 param_value = tw_dev->alignment_physical_address[request_id];
2868 if (param_value == 0) {
2869 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad alignment physical address.\n");
2873 command_packet->byte8.param.sgl[0].address = param_value;
2874 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
2875 command_que_value = tw_dev->command_packet_physical_address[request_id];
2876 if (command_que_value == 0) {
2877 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad command packet physical address.\n");
2881 /* Now try to post the command packet */
2882 tw_post_command_packet(tw_dev, request_id);
2885 } /* End tw_scsiop_mode_sense() */
2887 /* This function is called by the isr to complete a mode sense command */
2888 int tw_scsiop_mode_sense_complete(TW_Device_Extension *tw_dev, int request_id)
2891 unsigned char *flags;
2892 unsigned char *request_buffer;
2894 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_mode_sense_complete()\n");
2896 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
2897 if (param == NULL) {
2898 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense_complete(): Bad alignment virtual address.\n");
2901 flags = (char *)&(param->data[0]);
2902 request_buffer = tw_dev->srb[request_id]->buffer;
2903 memset(request_buffer, 0, tw_dev->srb[request_id]->request_bufflen);
2905 request_buffer[0] = 0xf; /* mode data length */
2906 request_buffer[1] = 0; /* default medium type */
2907 request_buffer[2] = 0x10; /* dpo/fua support on */
2908 request_buffer[3] = 0; /* no block descriptors */
2909 request_buffer[4] = 0x8; /* caching page */
2910 request_buffer[5] = 0xa; /* page length */
2912 request_buffer[6] = 0x4; /* WCE on */
2914 request_buffer[6] = 0x0; /* WCE off */
2917 } /* End tw_scsiop_mode_sense_complete() */
2919 /* This function handles scsi read_capacity commands */
2920 int tw_scsiop_read_capacity(TW_Device_Extension *tw_dev, int request_id)
2923 TW_Command *command_packet;
2924 unsigned long command_que_value;
2925 u32 command_que_addr;
2926 unsigned long param_value;
2928 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity()\n");
2930 /* Initialize command packet */
2931 command_que_addr = tw_dev->registers.command_que_addr;
2932 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
2934 if (command_packet == NULL) {
2935 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad command packet virtual address.\n");
2938 memset(command_packet, 0, sizeof(TW_Sector));
2939 command_packet->byte0.opcode = TW_OP_GET_PARAM;
2940 command_packet->byte0.sgl_offset = 2;
2941 command_packet->size = 4;
2942 command_packet->request_id = request_id;
2943 command_packet->byte3.unit = tw_dev->srb[request_id]->device->id;
2944 command_packet->byte3.host_id = 0;
2945 command_packet->status = 0;
2946 command_packet->flags = 0;
2947 command_packet->byte6.block_count = 1;
2949 /* Now setup the param */
2950 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
2951 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad alignment virtual address.\n");
2954 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
2955 memset(param, 0, sizeof(TW_Sector));
2956 param->table_id = TW_UNIT_INFORMATION_TABLE_BASE +
2957 tw_dev->srb[request_id]->device->id;
2958 param->parameter_id = 4; /* unitcapacity parameter */
2959 param->parameter_size_bytes = 4;
2960 param_value = tw_dev->alignment_physical_address[request_id];
2961 if (param_value == 0) {
2962 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad alignment physical address.\n");
2966 command_packet->byte8.param.sgl[0].address = param_value;
2967 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
2968 command_que_value = tw_dev->command_packet_physical_address[request_id];
2969 if (command_que_value == 0) {
2970 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad command packet physical address.\n");
2974 /* Now try to post the command to the board */
2975 tw_post_command_packet(tw_dev, request_id);
2978 } /* End tw_scsiop_read_capacity() */
2980 /* This function is called by the isr to complete a readcapacity command */
2981 int tw_scsiop_read_capacity_complete(TW_Device_Extension *tw_dev, int request_id)
2983 unsigned char *param_data;
2988 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity_complete()\n");
2990 buff = tw_dev->srb[request_id]->request_buffer;
2992 printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_capacity_complete(): Request buffer NULL.\n");
2995 memset(buff, 0, tw_dev->srb[request_id]->request_bufflen);
2996 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
2997 if (param == NULL) {
2998 printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_capacity_complete(): Bad alignment virtual address.\n");
3001 param_data = &(param->data[0]);
3003 capacity = (param_data[3] << 24) | (param_data[2] << 16) |
3004 (param_data[1] << 8) | param_data[0];
3006 /* Subtract one sector to fix get last sector ioctl */
3009 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity_complete(): Capacity = 0x%x.\n", capacity);
3011 /* Number of LBA's */
3012 buff[0] = (capacity >> 24);
3013 buff[1] = (capacity >> 16) & 0xff;
3014 buff[2] = (capacity >> 8) & 0xff;
3015 buff[3] = capacity & 0xff;
3017 /* Block size in bytes (512) */
3018 buff[4] = (TW_BLOCK_SIZE >> 24);
3019 buff[5] = (TW_BLOCK_SIZE >> 16) & 0xff;
3020 buff[6] = (TW_BLOCK_SIZE >> 8) & 0xff;
3021 buff[7] = TW_BLOCK_SIZE & 0xff;
3024 } /* End tw_scsiop_read_capacity_complete() */
3026 /* This function handles scsi read or write commands */
3027 int tw_scsiop_read_write(TW_Device_Extension *tw_dev, int request_id)
3029 TW_Command *command_packet;
3030 unsigned long command_que_value;
3031 u32 command_que_addr = 0x0;
3032 u32 lba = 0x0, num_sectors = 0x0, buffaddr = 0x0;
3035 struct scatterlist *sglist;
3037 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write()\n");
3039 if (tw_dev->srb[request_id]->request_buffer == NULL) {
3040 printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_write(): Request buffer NULL.\n");
3043 sglist = (struct scatterlist *)tw_dev->srb[request_id]->request_buffer;
3044 srb = tw_dev->srb[request_id];
3046 /* Initialize command packet */
3047 command_que_addr = tw_dev->registers.command_que_addr;
3048 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
3049 if (command_packet == NULL) {
3050 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): Bad command packet virtual address.\n");
3054 if (srb->cmnd[0] == READ_6 || srb->cmnd[0] == READ_10) {
3055 command_packet->byte0.opcode = TW_OP_READ;
3057 command_packet->byte0.opcode = TW_OP_WRITE;
3060 command_packet->byte0.sgl_offset = 3;
3061 command_packet->size = 3;
3062 command_packet->request_id = request_id;
3063 command_packet->byte3.unit = srb->device->id;
3064 command_packet->byte3.host_id = 0;
3065 command_packet->status = 0;
3066 command_packet->flags = 0;
3068 if (srb->cmnd[0] == WRITE_10) {
3069 if ((srb->cmnd[1] & 0x8) || (srb->cmnd[1] & 0x10))
3070 command_packet->flags = 1;
3073 if (srb->cmnd[0] == READ_6 || srb->cmnd[0] == WRITE_6) {
3074 lba = ((u32)srb->cmnd[1] << 16) | ((u32)srb->cmnd[2] << 8) | (u32)srb->cmnd[3];
3075 num_sectors = (u32)srb->cmnd[4];
3077 lba = ((u32)srb->cmnd[2] << 24) | ((u32)srb->cmnd[3] << 16) | ((u32)srb->cmnd[4] << 8) | (u32)srb->cmnd[5];
3078 num_sectors = (u32)srb->cmnd[8] | ((u32)srb->cmnd[7] << 8);
3081 /* Update sector statistic */
3082 tw_dev->sector_count = num_sectors;
3083 if (tw_dev->sector_count > tw_dev->max_sector_count)
3084 tw_dev->max_sector_count = tw_dev->sector_count;
3086 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): lba = 0x%x num_sectors = 0x%x\n", lba, num_sectors);
3087 command_packet->byte8.io.lba = lba;
3088 command_packet->byte6.block_count = num_sectors;
3090 /* Do this if there are no sg list entries */
3091 if (tw_dev->srb[request_id]->use_sg == 0) {
3092 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): SG = 0\n");
3093 buffaddr = tw_map_scsi_single_data(tw_dev->tw_pci_dev, tw_dev->srb[request_id]);
3097 command_packet->byte8.io.sgl[0].address = buffaddr;
3098 command_packet->byte8.io.sgl[0].length = tw_dev->srb[request_id]->request_bufflen;
3099 command_packet->size+=2;
3102 /* Do this if we have multiple sg list entries */
3103 if (tw_dev->srb[request_id]->use_sg > 0) {
3104 use_sg = tw_map_scsi_sg_data(tw_dev->tw_pci_dev, tw_dev->srb[request_id]);
3108 for (i=0;i<use_sg; i++) {
3109 command_packet->byte8.io.sgl[i].address = sg_dma_address(&sglist[i]);
3110 command_packet->byte8.io.sgl[i].length = sg_dma_len(&sglist[i]);
3111 command_packet->size+=2;
3115 /* Update SG statistics */
3116 tw_dev->sgl_entries = tw_dev->srb[request_id]->use_sg;
3117 if (tw_dev->sgl_entries > tw_dev->max_sgl_entries)
3118 tw_dev->max_sgl_entries = tw_dev->sgl_entries;
3120 command_que_value = tw_dev->command_packet_physical_address[request_id];
3121 if (command_que_value == 0) {
3122 dprintk(KERN_WARNING "3w-xxxx: tw_scsiop_read_write(): Bad command packet physical address.\n");
3126 /* Now try to post the command to the board */
3127 tw_post_command_packet(tw_dev, request_id);
3130 } /* End tw_scsiop_read_write() */
3132 /* This function will handle the request sense scsi command */
3133 int tw_scsiop_request_sense(TW_Device_Extension *tw_dev, int request_id)
3135 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_request_sense()\n");
3137 /* For now we just zero the request buffer */
3138 memset(tw_dev->srb[request_id]->request_buffer, 0, tw_dev->srb[request_id]->request_bufflen);
3139 tw_dev->state[request_id] = TW_S_COMPLETED;
3140 tw_state_request_finish(tw_dev, request_id);
3142 /* If we got a request_sense, we probably want a reset, return error */
3143 tw_dev->srb[request_id]->result = (DID_ERROR << 16);
3144 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
3147 } /* End tw_scsiop_request_sense() */
3149 /* This function will handle synchronize cache scsi command */
3150 int tw_scsiop_synchronize_cache(TW_Device_Extension *tw_dev, int request_id)
3152 TW_Command *command_packet;
3153 unsigned long command_que_value;
3155 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_synchronize_cache()\n");
3157 /* Send firmware flush command for this unit */
3158 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
3159 if (command_packet == NULL) {
3160 printk(KERN_WARNING "3w-xxxx: tw_scsiop_synchronize_cache(): Bad command packet virtual address.\n");
3164 /* Setup the command packet */
3165 memset(command_packet, 0, sizeof(TW_Sector));
3166 command_packet->byte0.opcode = TW_OP_FLUSH_CACHE;
3167 command_packet->byte0.sgl_offset = 0;
3168 command_packet->size = 2;
3169 command_packet->request_id = request_id;
3170 command_packet->byte3.unit = tw_dev->srb[request_id]->device->id;
3171 command_packet->byte3.host_id = 0;
3172 command_packet->status = 0;
3173 command_packet->flags = 0;
3174 command_packet->byte6.parameter_count = 1;
3175 command_que_value = tw_dev->command_packet_physical_address[request_id];
3176 if (command_que_value == 0) {
3177 printk(KERN_WARNING "3w-xxxx: tw_scsiop_synchronize_cache(): Bad command packet physical address.\n");
3181 /* Now try to post the command packet */
3182 tw_post_command_packet(tw_dev, request_id);
3185 } /* End tw_scsiop_synchronize_cache() */
3187 /* This function will handle test unit ready scsi command */
3188 int tw_scsiop_test_unit_ready(TW_Device_Extension *tw_dev, int request_id)
3191 TW_Command *command_packet;
3192 unsigned long command_que_value;
3193 u32 command_que_addr;
3194 unsigned long param_value;
3196 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_test_unit_ready()\n");
3198 /* Initialize command packet */
3199 command_que_addr = tw_dev->registers.command_que_addr;
3200 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
3201 if (command_packet == NULL) {
3202 printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready(): Bad command packet virtual address.\n");
3205 memset(command_packet, 0, sizeof(TW_Sector));
3206 command_packet->byte0.opcode = TW_OP_GET_PARAM;
3207 command_packet->byte0.sgl_offset = 2;
3208 command_packet->size = 4;
3209 command_packet->request_id = request_id;
3210 command_packet->byte3.unit = 0;
3211 command_packet->byte3.host_id = 0;
3212 command_packet->status = 0;
3213 command_packet->flags = 0;
3214 command_packet->byte6.parameter_count = 1;
3216 /* Now setup the param */
3217 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
3218 printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready(): Bad alignment virtual address.\n");
3221 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
3222 memset(param, 0, sizeof(TW_Sector));
3223 param->table_id = 3; /* unit summary table */
3224 param->parameter_id = 3; /* unitsstatus parameter */
3225 param->parameter_size_bytes = TW_MAX_UNITS;
3226 param_value = tw_dev->alignment_physical_address[request_id];
3227 if (param_value == 0) {
3228 printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready(): Bad alignment physical address.\n");
3232 command_packet->byte8.param.sgl[0].address = param_value;
3233 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
3234 command_que_value = tw_dev->command_packet_physical_address[request_id];
3235 if (command_que_value == 0) {
3236 printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready(): Bad command packet physical address.\n");
3240 /* Now try to post the command packet */
3241 tw_post_command_packet(tw_dev, request_id);
3244 } /* End tw_scsiop_test_unit_ready() */
3246 /* This function is called by the isr to complete a testunitready command */
3247 int tw_scsiop_test_unit_ready_complete(TW_Device_Extension *tw_dev, int request_id)
3249 unsigned char *is_unit_present;
3252 dprintk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready_complete()\n");
3254 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
3255 if (param == NULL) {
3256 printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready_complete(): Bad alignment virtual address.\n");
3259 is_unit_present = &(param->data[0]);
3261 if (is_unit_present[tw_dev->srb[request_id]->device->id] & TW_UNIT_ONLINE) {
3262 tw_dev->is_unit_present[tw_dev->srb[request_id]->device->id] = TRUE;
3264 tw_dev->is_unit_present[tw_dev->srb[request_id]->device->id] = FALSE;
3265 tw_dev->srb[request_id]->result = (DID_BAD_TARGET << 16);
3266 return TW_ISR_DONT_RESULT;
3270 } /* End tw_scsiop_test_unit_ready_complete() */
3272 /* Set a value in the features table */
3273 int tw_setfeature(TW_Device_Extension *tw_dev, int parm, int param_size,
3277 TW_Command *command_packet;
3278 TW_Response_Queue response_queue;
3280 unsigned long command_que_value;
3281 u32 command_que_addr;
3282 u32 response_que_addr;
3283 unsigned long param_value;
3285 /* Initialize SetParam command packet */
3286 if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
3287 printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad command packet virtual address.\n");
3290 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
3291 memset(command_packet, 0, sizeof(TW_Sector));
3292 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
3294 command_packet->byte0.opcode = TW_OP_SET_PARAM;
3295 command_packet->byte0.sgl_offset = 2;
3296 param->table_id = 0x404; /* Features table */
3297 param->parameter_id = parm;
3298 param->parameter_size_bytes = param_size;
3299 memcpy(param->data, val, param_size);
3301 param_value = tw_dev->alignment_physical_address[request_id];
3302 if (param_value == 0) {
3303 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Bad alignment physical address.\n");
3304 tw_dev->state[request_id] = TW_S_COMPLETED;
3305 tw_state_request_finish(tw_dev, request_id);
3306 tw_dev->srb[request_id]->result = (DID_OK << 16);
3307 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
3309 command_packet->byte8.param.sgl[0].address = param_value;
3310 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
3312 command_packet->size = 4;
3313 command_packet->request_id = request_id;
3314 command_packet->byte6.parameter_count = 1;
3316 command_que_value = tw_dev->command_packet_physical_address[request_id];
3317 if (command_que_value == 0) {
3318 printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad command packet physical address.\n");
3321 command_que_addr = tw_dev->registers.command_que_addr;
3322 response_que_addr = tw_dev->registers.response_que_addr;
3324 /* Send command packet to the board */
3325 outl(command_que_value, command_que_addr);
3327 /* Poll for completion */
3328 if (tw_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, 30) == 0) {
3329 response_queue.value = inl(response_que_addr);
3330 request_id = (unsigned char)response_queue.u.response_id;
3331 if (request_id != 0) {
3332 /* unexpected request id */
3333 printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Unexpected request id.\n");
3336 if (command_packet->status != 0) {
3338 tw_decode_sense(tw_dev, request_id, 0);
3344 } /* End tw_setfeature() */
3346 /* This function will setup the interrupt handler */
3347 int tw_setup_irq(TW_Device_Extension *tw_dev)
3349 char *device = TW_DEVICE_NAME;
3352 dprintk(KERN_NOTICE "3w-xxxx: tw_setup_irq()\n");
3353 error = request_irq(tw_dev->tw_pci_dev->irq, tw_interrupt, SA_SHIRQ, device, tw_dev);
3356 printk(KERN_WARNING "3w-xxxx: scsi%d: Error requesting IRQ: %d.\n", tw_dev->host->host_no, tw_dev->tw_pci_dev->irq);
3360 } /* End tw_setup_irq() */
3362 /* This function will tell the controller we're shutting down by sending
3363 initconnection with a 1 */
3364 int tw_shutdown_device(TW_Device_Extension *tw_dev)
3368 /* Disable interrupts */
3369 tw_disable_interrupts(tw_dev);
3371 /* poke the board */
3372 error = tw_initconnection(tw_dev, 1);
3374 printk(KERN_WARNING "3w-xxxx: scsi%d: Connection shutdown failed.\n", tw_dev->host->host_no);
3376 printk(KERN_NOTICE "3w-xxxx: Shutdown complete.\n");
3379 /* Re-enable interrupts */
3380 tw_enable_and_clear_interrupts(tw_dev);
3383 } /* End tw_shutdown_device() */
3385 /* This function will configure individual target parameters */
3386 int tw_slave_configure(Scsi_Device *SDptr)
3390 dprintk(KERN_WARNING "3w-xxxx: tw_slave_configure()\n");
3393 max_cmds = cmds_per_lun;
3394 if (max_cmds > TW_MAX_CMDS_PER_LUN)
3395 max_cmds = TW_MAX_CMDS_PER_LUN;
3397 max_cmds = TW_MAX_CMDS_PER_LUN;
3399 scsi_adjust_queue_depth(SDptr, MSG_ORDERED_TAG, max_cmds);
3402 } /* End tw_slave_configure() */
3404 /* This function will soft reset the controller */
3405 void tw_soft_reset(TW_Device_Extension *tw_dev)
3407 u32 control_reg_addr, control_reg_value;
3409 control_reg_addr = tw_dev->registers.control_reg_addr;
3410 control_reg_value = ( TW_CONTROL_ISSUE_SOFT_RESET |
3411 TW_CONTROL_CLEAR_HOST_INTERRUPT |
3412 TW_CONTROL_CLEAR_ATTENTION_INTERRUPT |
3413 TW_CONTROL_MASK_COMMAND_INTERRUPT |
3414 TW_CONTROL_MASK_RESPONSE_INTERRUPT |
3415 TW_CONTROL_CLEAR_ERROR_STATUS |
3416 TW_CONTROL_DISABLE_INTERRUPTS);
3417 outl(control_reg_value, control_reg_addr);
3418 } /* End tw_soft_reset() */
3420 /* This function will free a request_id */
3421 int tw_state_request_finish(TW_Device_Extension *tw_dev, int request_id)
3423 dprintk(KERN_NOTICE "3w-xxxx: tw_state_request_finish()\n");
3425 tw_dev->free_queue[tw_dev->free_tail] = request_id;
3426 tw_dev->state[request_id] = TW_S_FINISHED;
3427 if (tw_dev->free_tail == tw_dev->free_wrap)
3428 tw_dev->free_tail = TW_Q_START;
3430 tw_dev->free_tail++;
3432 dprintk(KERN_NOTICE "3w-xxxx: tw_state_request_finish(): Freeing request_id %d\n", request_id);
3435 } /* End tw_state_request_finish() */
3437 /* This function will assign an available request_id */
3438 int tw_state_request_start(TW_Device_Extension *tw_dev, int *request_id)
3442 dprintk(KERN_NOTICE "3w-xxxx: tw_state_request_start()\n");
3444 /* Obtain next free request_id */
3445 id = tw_dev->free_queue[tw_dev->free_head];
3446 if (tw_dev->free_head == tw_dev->free_wrap)
3447 tw_dev->free_head = TW_Q_START;
3449 tw_dev->free_head++;
3452 tw_dev->state[id] = TW_S_STARTED;
3454 dprintk(KERN_NOTICE "3w-xxxx: tw_state_request_start(): id = %d.\n", id);
3456 } /* End tw_state_request_start() */
3458 static void tw_unmap_scsi_data(struct pci_dev *pdev, Scsi_Cmnd *cmd)
3460 int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
3462 dprintk(KERN_WARNING "3w-xxxx: tw_unmap_scsi_data()\n");
3464 switch(cmd->SCp.phase) {
3466 pci_unmap_page(pdev, cmd->SCp.have_data_in, cmd->request_bufflen, dma_dir);
3469 pci_unmap_sg(pdev, cmd->request_buffer, cmd->use_sg, dma_dir);
3472 } /* End tw_unmap_scsi_data() */
3474 /* This function will unmask the command interrupt on the controller */
3475 void tw_unmask_command_interrupt(TW_Device_Extension *tw_dev)
3477 u32 control_reg_addr, control_reg_value;
3479 control_reg_addr = tw_dev->registers.control_reg_addr;
3480 control_reg_value = TW_CONTROL_UNMASK_COMMAND_INTERRUPT;
3481 outl(control_reg_value, control_reg_addr);
3482 } /* End tw_unmask_command_interrupt() */
3484 static Scsi_Host_Template driver_template = {
3485 .proc_name = "3w-xxxx",
3486 .proc_info = tw_scsi_proc_info,
3487 .name = "3ware Storage Controller",
3488 .detect = tw_scsi_detect,
3489 .release = tw_scsi_release,
3490 .queuecommand = tw_scsi_queue,
3491 .eh_abort_handler = tw_scsi_eh_abort,
3492 .eh_host_reset_handler = tw_scsi_eh_reset,
3493 .bios_param = tw_scsi_biosparam,
3494 .slave_configure = tw_slave_configure,
3495 .can_queue = TW_Q_LENGTH-2,
3497 .sg_tablesize = TW_MAX_SGL_LENGTH,
3498 .max_sectors = TW_MAX_SECTORS,
3499 .cmd_per_lun = TW_MAX_CMDS_PER_LUN,
3500 .use_clustering = ENABLE_CLUSTERING,
3503 #include "scsi_module.c"