MOXA linux-2.6.x / linux-2.6.9-uc0 from sdlinux-moxaart.tgz
[linux-2.6.9-moxart.git] / drivers / scsi / 3w-9xxx.c
blob2bac40c0e836c26dfc4248679a383e8344998169
1 /*
2 3w-9xxx.c -- 3ware 9000 Storage Controller device driver for Linux.
4 Written By: Adam Radford <linuxraid@amcc.com>
6 Copyright (C) 2004 Applied Micro Circuits Corporation.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; version 2 of the License.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 NO WARRANTY
18 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
19 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
20 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
21 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
22 solely responsible for determining the appropriateness of using and
23 distributing the Program and assumes all risks associated with its
24 exercise of rights under this Agreement, including but not limited to
25 the risks and costs of program errors, damage to or loss of data,
26 programs or equipment, and unavailability or interruption of operations.
28 DISCLAIMER OF LIABILITY
29 NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
30 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
32 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
33 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
34 USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
35 HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
37 You should have received a copy of the GNU General Public License
38 along with this program; if not, write to the Free Software
39 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
41 Bugs/Comments/Suggestions should be mailed to:
42 linuxraid@amcc.com
44 For more information, goto:
45 http://www.amcc.com
47 Note: This version of the driver does not contain a bundled firmware
48 image.
50 History
51 -------
52 2.26.02.000 - Driver cleanup for kernel submission.
53 2.26.02.001 - Replace schedule_timeout() calls with msleep().
56 #include <linux/module.h>
57 #include <linux/reboot.h>
58 #include <linux/spinlock.h>
59 #include <linux/interrupt.h>
60 #include <linux/moduleparam.h>
61 #include <linux/errno.h>
62 #include <linux/types.h>
63 #include <linux/delay.h>
64 #include <linux/pci.h>
65 #include <linux/time.h>
66 #include <asm/io.h>
67 #include <asm/irq.h>
68 #include <asm/uaccess.h>
69 #include <scsi/scsi.h>
70 #include <scsi/scsi_host.h>
71 #include <scsi/scsi_tcq.h>
72 #include <scsi/scsi_cmnd.h>
73 #include "3w-9xxx.h"
75 /* Globals */
76 static const char *twa_driver_version="2.26.02.001";
77 static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT];
78 static unsigned int twa_device_extension_count;
79 static int twa_major = -1;
80 extern struct timezone sys_tz;
82 /* Module parameters */
83 MODULE_AUTHOR ("AMCC");
84 MODULE_DESCRIPTION ("3ware 9000 Storage Controller Linux Driver");
85 MODULE_LICENSE("GPL");
87 /* Function prototypes */
88 static void twa_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_Header *header);
89 static int twa_aen_read_queue(TW_Device_Extension *tw_dev, int request_id);
90 static char *twa_aen_severity_lookup(unsigned char severity_code);
91 static void twa_aen_sync_time(TW_Device_Extension *tw_dev, int request_id);
92 static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
93 static int twa_chrdev_open(struct inode *inode, struct file *file);
94 static int twa_fill_sense(TW_Device_Extension *tw_dev, int request_id, int copy_sense, int print_host);
95 static void twa_free_request_id(TW_Device_Extension *tw_dev,int request_id);
96 static void twa_get_request_id(TW_Device_Extension *tw_dev, int *request_id);
97 static int twa_initconnection(TW_Device_Extension *tw_dev, int message_credits,
98 u32 set_features, unsigned short current_fw_srl,
99 unsigned short current_fw_arch_id,
100 unsigned short current_fw_branch,
101 unsigned short current_fw_build,
102 unsigned short *fw_on_ctlr_srl,
103 unsigned short *fw_on_ctlr_arch_id,
104 unsigned short *fw_on_ctlr_branch,
105 unsigned short *fw_on_ctlr_build,
106 u32 *init_connect_result);
107 static void twa_load_sgl(TW_Command_Full *full_command_packet, int request_id, dma_addr_t dma_handle, int length);
108 static int twa_poll_response(TW_Device_Extension *tw_dev, int request_id, int seconds);
109 static int twa_poll_status_gone(TW_Device_Extension *tw_dev, u32 flag, int seconds);
110 static int twa_post_command_packet(TW_Device_Extension *tw_dev, int request_id, char internal);
111 static int twa_reset_device_extension(TW_Device_Extension *tw_dev);
112 static int twa_reset_sequence(TW_Device_Extension *tw_dev, int soft_reset);
113 static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, char *cdb, int use_sg, TW_SG_Apache *sglistarg);
114 static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int request_id);
115 static char *twa_string_lookup(twa_message_type *table, unsigned int aen_code);
116 static void twa_unmap_scsi_data(TW_Device_Extension *tw_dev, int request_id);
118 /* Functions */
120 /* Show some statistics about the card */
121 static ssize_t twa_show_stats(struct class_device *class_dev, char *buf)
123 struct Scsi_Host *host = class_to_shost(class_dev);
124 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
125 unsigned long flags = 0;
126 ssize_t len;
128 spin_lock_irqsave(tw_dev->host->host_lock, flags);
129 len = snprintf(buf, PAGE_SIZE, "Driver version: %s\n"
130 "Current commands posted: %4d\n"
131 "Max commands posted: %4d\n"
132 "Current pending commands: %4d\n"
133 "Max pending commands: %4d\n"
134 "Last sgl length: %4d\n"
135 "Max sgl length: %4d\n"
136 "Last sector count: %4d\n"
137 "Max sector count: %4d\n"
138 "SCSI Host Resets: %4d\n"
139 "SCSI Aborts/Timeouts: %4d\n"
140 "AEN's: %4d\n",
141 twa_driver_version,
142 tw_dev->posted_request_count,
143 tw_dev->max_posted_request_count,
144 tw_dev->pending_request_count,
145 tw_dev->max_pending_request_count,
146 tw_dev->sgl_entries,
147 tw_dev->max_sgl_entries,
148 tw_dev->sector_count,
149 tw_dev->max_sector_count,
150 tw_dev->num_resets,
151 tw_dev->num_aborts,
152 tw_dev->aen_count);
153 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
154 return len;
155 } /* End twa_show_stats() */
157 /* This function will set a devices queue depth */
158 static ssize_t twa_store_queue_depth(struct device *dev, const char *buf, size_t count)
160 int queue_depth;
161 struct scsi_device *sdev = to_scsi_device(dev);
163 queue_depth = simple_strtoul(buf, NULL, 0);
164 if (queue_depth > TW_Q_LENGTH-2)
165 return -EINVAL;
166 scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, queue_depth);
168 return count;
169 } /* End twa_store_queue_depth() */
171 /* Create sysfs 'queue_depth' entry */
172 static struct device_attribute twa_queue_depth_attr = {
173 .attr = {
174 .name = "queue_depth",
175 .mode = S_IRUSR | S_IWUSR,
177 .store = twa_store_queue_depth
180 /* Device attributes initializer */
181 static struct device_attribute *twa_dev_attrs[] = {
182 &twa_queue_depth_attr,
183 NULL,
186 /* Create sysfs 'stats' entry */
187 static struct class_device_attribute twa_host_stats_attr = {
188 .attr = {
189 .name = "stats",
190 .mode = S_IRUGO,
192 .show = twa_show_stats
195 /* Host attributes initializer */
196 static struct class_device_attribute *twa_host_attrs[] = {
197 &twa_host_stats_attr,
198 NULL,
201 /* File operations struct for character device */
202 static struct file_operations twa_fops = {
203 .owner = THIS_MODULE,
204 .ioctl = twa_chrdev_ioctl,
205 .open = twa_chrdev_open,
206 .release = NULL
209 /* This function will complete an aen request from the isr */
210 static int twa_aen_complete(TW_Device_Extension *tw_dev, int request_id)
212 TW_Command_Full *full_command_packet;
213 TW_Command *command_packet;
214 TW_Command_Apache_Header *header;
215 unsigned short aen;
216 int retval = 1;
218 header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id];
219 tw_dev->posted_request_count--;
220 aen = header->status_block.error;
221 full_command_packet = tw_dev->command_packet_virt[request_id];
222 command_packet = &full_command_packet->command.oldcommand;
224 /* First check for internal completion of set param for time sync */
225 if (TW_OP_OUT(command_packet->opcode__sgloffset) == TW_OP_SET_PARAM) {
226 /* Keep reading the queue in case there are more aen's */
227 if (twa_aen_read_queue(tw_dev, request_id))
228 goto out2;
229 else {
230 retval = 0;
231 goto out;
235 switch (aen) {
236 case TW_AEN_QUEUE_EMPTY:
237 /* Quit reading the queue if this is the last one */
238 break;
239 case TW_AEN_SYNC_TIME_WITH_HOST:
240 twa_aen_sync_time(tw_dev, request_id);
241 retval = 0;
242 goto out;
243 default:
244 twa_aen_queue_event(tw_dev, header);
246 /* If there are more aen's, keep reading the queue */
247 if (twa_aen_read_queue(tw_dev, request_id))
248 goto out2;
249 else {
250 retval = 0;
251 goto out;
254 retval = 0;
255 out2:
256 tw_dev->state[request_id] = TW_S_COMPLETED;
257 twa_free_request_id(tw_dev, request_id);
258 clear_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags);
259 out:
260 return retval;
261 } /* End twa_aen_complete() */
263 /* This function will drain aen queue */
264 static int twa_aen_drain_queue(TW_Device_Extension *tw_dev, int no_check_reset)
266 int request_id = 0;
267 char cdb[TW_MAX_CDB_LEN];
268 TW_SG_Apache sglist[1];
269 int finished = 0, count = 0;
270 TW_Command_Full *full_command_packet;
271 TW_Command_Apache_Header *header;
272 unsigned short aen;
273 int first_reset = 0, queue = 0, retval = 1;
275 if (no_check_reset)
276 first_reset = 0;
277 else
278 first_reset = 1;
280 full_command_packet = tw_dev->command_packet_virt[request_id];
281 memset(full_command_packet, 0, sizeof(TW_Command_Full));
283 /* Initialize cdb */
284 memset(&cdb, 0, TW_MAX_CDB_LEN);
285 cdb[0] = REQUEST_SENSE; /* opcode */
286 cdb[4] = TW_ALLOCATION_LENGTH; /* allocation length */
288 /* Initialize sglist */
289 memset(&sglist, 0, sizeof(TW_SG_Apache));
290 sglist[0].length = TW_SECTOR_SIZE;
291 sglist[0].address = tw_dev->generic_buffer_phys[request_id];
293 if (sglist[0].address & TW_ALIGNMENT_9000_SGL) {
294 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1, "Found unaligned address during AEN drain");
295 goto out;
298 /* Mark internal command */
299 tw_dev->srb[request_id] = NULL;
301 do {
302 /* Send command to the board */
303 if (twa_scsiop_execute_scsi(tw_dev, request_id, cdb, 1, sglist)) {
304 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2, "Error posting request sense");
305 goto out;
308 /* Now poll for completion */
309 if (twa_poll_response(tw_dev, request_id, 30)) {
310 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x3, "No valid response while draining AEN queue");
311 tw_dev->posted_request_count--;
312 goto out;
315 tw_dev->posted_request_count--;
316 header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id];
317 aen = header->status_block.error;
318 queue = 0;
319 count++;
321 switch (aen) {
322 case TW_AEN_QUEUE_EMPTY:
323 if (first_reset != 1)
324 goto out;
325 else
326 finished = 1;
327 break;
328 case TW_AEN_SOFT_RESET:
329 if (first_reset == 0)
330 first_reset = 1;
331 else
332 queue = 1;
333 break;
334 case TW_AEN_SYNC_TIME_WITH_HOST:
335 break;
336 default:
337 queue = 1;
340 /* Now queue an event info */
341 if (queue)
342 twa_aen_queue_event(tw_dev, header);
343 } while ((finished == 0) && (count < TW_MAX_AEN_DRAIN));
345 if (count == TW_MAX_AEN_DRAIN)
346 goto out;
348 retval = 0;
349 out:
350 tw_dev->state[request_id] = TW_S_INITIAL;
351 return retval;
352 } /* End twa_aen_drain_queue() */
354 /* This function will queue an event */
355 static void twa_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_Header *header)
357 u32 local_time;
358 struct timeval time;
359 TW_Event *event;
360 unsigned short aen;
361 char host[16];
363 tw_dev->aen_count++;
365 /* Fill out event info */
366 event = tw_dev->event_queue[tw_dev->error_index];
368 /* Check for clobber */
369 host[0] = '\0';
370 if (tw_dev->host) {
371 sprintf(host, " scsi%d:", tw_dev->host->host_no);
372 if (event->retrieved == TW_AEN_NOT_RETRIEVED)
373 tw_dev->aen_clobber = 1;
376 aen = header->status_block.error;
377 memset(event, 0, sizeof(TW_Event));
379 event->severity = TW_SEV_OUT(header->status_block.severity__reserved);
380 do_gettimeofday(&time);
381 local_time = (u32)(time.tv_sec - (sys_tz.tz_minuteswest * 60));
382 event->time_stamp_sec = local_time;
383 event->aen_code = aen;
384 event->retrieved = TW_AEN_NOT_RETRIEVED;
385 event->sequence_id = tw_dev->error_sequence_id;
386 tw_dev->error_sequence_id++;
388 header->err_specific_desc[sizeof(header->err_specific_desc) - 1] = '\0';
389 event->parameter_len = strlen(header->err_specific_desc);
390 memcpy(event->parameter_data, header->err_specific_desc, event->parameter_len);
391 if (event->severity != TW_AEN_SEVERITY_DEBUG)
392 printk(KERN_WARNING "3w-9xxx:%s AEN: %s (0x%02X:0x%04X): %s:%s.\n",
393 host,
394 twa_aen_severity_lookup(TW_SEV_OUT(header->status_block.severity__reserved)),
395 TW_MESSAGE_SOURCE_CONTROLLER_EVENT, aen,
396 twa_string_lookup(twa_aen_table, aen),
397 header->err_specific_desc);
398 else
399 tw_dev->aen_count--;
401 if ((tw_dev->error_index + 1) == TW_Q_LENGTH)
402 tw_dev->event_queue_wrapped = 1;
403 tw_dev->error_index = (tw_dev->error_index + 1 ) % TW_Q_LENGTH;
404 } /* End twa_aen_queue_event() */
406 /* This function will read the aen queue from the isr */
407 static int twa_aen_read_queue(TW_Device_Extension *tw_dev, int request_id)
409 char cdb[TW_MAX_CDB_LEN];
410 TW_SG_Apache sglist[1];
411 TW_Command_Full *full_command_packet;
412 int retval = 1;
414 full_command_packet = tw_dev->command_packet_virt[request_id];
415 memset(full_command_packet, 0, sizeof(TW_Command_Full));
417 /* Initialize cdb */
418 memset(&cdb, 0, TW_MAX_CDB_LEN);
419 cdb[0] = REQUEST_SENSE; /* opcode */
420 cdb[4] = TW_ALLOCATION_LENGTH; /* allocation length */
422 /* Initialize sglist */
423 memset(&sglist, 0, sizeof(TW_SG_Apache));
424 sglist[0].length = TW_SECTOR_SIZE;
425 sglist[0].address = tw_dev->generic_buffer_phys[request_id];
427 /* Mark internal command */
428 tw_dev->srb[request_id] = NULL;
430 /* Now post the command packet */
431 if (twa_scsiop_execute_scsi(tw_dev, request_id, cdb, 1, sglist)) {
432 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x4, "Post failed while reading AEN queue");
433 goto out;
435 retval = 0;
436 out:
437 return retval;
438 } /* End twa_aen_read_queue() */
440 /* This function will look up an AEN severity string */
441 static char *twa_aen_severity_lookup(unsigned char severity_code)
443 char *retval = NULL;
445 if ((severity_code < (unsigned char) TW_AEN_SEVERITY_ERROR) ||
446 (severity_code > (unsigned char) TW_AEN_SEVERITY_DEBUG))
447 goto out;
449 retval = twa_aen_severity_table[severity_code];
450 out:
451 return retval;
452 } /* End twa_aen_severity_lookup() */
454 /* This function will sync firmware time with the host time */
455 static void twa_aen_sync_time(TW_Device_Extension *tw_dev, int request_id)
457 u32 schedulertime;
458 struct timeval utc;
459 TW_Command_Full *full_command_packet;
460 TW_Command *command_packet;
461 TW_Param_Apache *param;
462 u32 local_time;
464 /* Fill out the command packet */
465 full_command_packet = tw_dev->command_packet_virt[request_id];
466 memset(full_command_packet, 0, sizeof(TW_Command_Full));
467 command_packet = &full_command_packet->command.oldcommand;
468 command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_SET_PARAM);
469 command_packet->request_id = request_id;
470 command_packet->byte8_offset.param.sgl[0].address = tw_dev->generic_buffer_phys[request_id];
471 command_packet->byte8_offset.param.sgl[0].length = TW_SECTOR_SIZE;
472 command_packet->size = TW_COMMAND_SIZE;
473 command_packet->byte6_offset.parameter_count = 1;
475 /* Setup the param */
476 param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id];
477 memset(param, 0, TW_SECTOR_SIZE);
478 param->table_id = TW_TIMEKEEP_TABLE | 0x8000; /* Controller time keep table */
479 param->parameter_id = 0x3; /* SchedulerTime */
480 param->parameter_size_bytes = 4;
482 /* Convert system time in UTC to local time seconds since last
483 Sunday 12:00AM */
484 do_gettimeofday(&utc);
485 local_time = (u32)(utc.tv_sec - (sys_tz.tz_minuteswest * 60));
486 schedulertime = local_time - (3 * 86400);
487 schedulertime = schedulertime % 604800;
489 memcpy(param->data, &schedulertime, sizeof(u32));
491 /* Mark internal command */
492 tw_dev->srb[request_id] = NULL;
494 /* Now post the command */
495 twa_post_command_packet(tw_dev, request_id, 1);
496 } /* End twa_aen_sync_time() */
498 /* This function will allocate memory and check if it is correctly aligned */
499 static int twa_allocate_memory(TW_Device_Extension *tw_dev, int size, int which)
501 int i;
502 dma_addr_t dma_handle;
503 unsigned long *cpu_addr;
504 int retval = 1;
506 cpu_addr = pci_alloc_consistent(tw_dev->tw_pci_dev, size*TW_Q_LENGTH, &dma_handle);
507 if (!cpu_addr) {
508 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x5, "Memory allocation failed");
509 goto out;
512 if ((unsigned long)cpu_addr % (TW_ALIGNMENT_9000)) {
513 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x6, "Failed to allocate correctly aligned memory");
514 pci_free_consistent(tw_dev->tw_pci_dev, size*TW_Q_LENGTH, cpu_addr, dma_handle);
515 goto out;
518 memset(cpu_addr, 0, size*TW_Q_LENGTH);
520 for (i = 0; i < TW_Q_LENGTH; i++) {
521 switch(which) {
522 case 0:
523 tw_dev->command_packet_phys[i] = dma_handle+(i*size);
524 tw_dev->command_packet_virt[i] = (TW_Command_Full *)((unsigned char *)cpu_addr + (i*size));
525 break;
526 case 1:
527 tw_dev->generic_buffer_phys[i] = dma_handle+(i*size);
528 tw_dev->generic_buffer_virt[i] = (unsigned long *)((unsigned char *)cpu_addr + (i*size));
529 break;
532 retval = 0;
533 out:
534 return retval;
535 } /* End twa_allocate_memory() */
537 /* This function will check the status register for unexpected bits */
538 static int twa_check_bits(u32 status_reg_value)
540 int retval = 1;
542 if ((status_reg_value & TW_STATUS_EXPECTED_BITS) != TW_STATUS_EXPECTED_BITS)
543 goto out;
544 if ((status_reg_value & TW_STATUS_UNEXPECTED_BITS) != 0)
545 goto out;
547 retval = 0;
548 out:
549 return retval;
550 } /* End twa_check_bits() */
552 /* This function will check the srl and decide if we are compatible */
553 static int twa_check_srl(TW_Device_Extension *tw_dev, int *flashed)
555 int retval = 1;
556 unsigned short fw_on_ctlr_srl = 0, fw_on_ctlr_arch_id = 0;
557 unsigned short fw_on_ctlr_branch = 0, fw_on_ctlr_build = 0;
558 u32 init_connect_result = 0;
560 if (twa_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS,
561 TW_EXTENDED_INIT_CONNECT, TW_CURRENT_FW_SRL,
562 TW_9000_ARCH_ID, TW_CURRENT_FW_BRANCH,
563 TW_CURRENT_FW_BUILD, &fw_on_ctlr_srl,
564 &fw_on_ctlr_arch_id, &fw_on_ctlr_branch,
565 &fw_on_ctlr_build, &init_connect_result)) {
566 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x7, "Initconnection failed while checking SRL");
567 goto out;
570 tw_dev->working_srl = TW_CURRENT_FW_SRL;
571 tw_dev->working_branch = TW_CURRENT_FW_BRANCH;
572 tw_dev->working_build = TW_CURRENT_FW_BUILD;
574 /* Try base mode compatibility */
575 if (!(init_connect_result & TW_CTLR_FW_COMPATIBLE)) {
576 if (twa_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS,
577 TW_EXTENDED_INIT_CONNECT,
578 TW_BASE_FW_SRL, TW_9000_ARCH_ID,
579 TW_BASE_FW_BRANCH, TW_BASE_FW_BUILD,
580 &fw_on_ctlr_srl, &fw_on_ctlr_arch_id,
581 &fw_on_ctlr_branch, &fw_on_ctlr_build,
582 &init_connect_result)) {
583 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xa, "Initconnection (base mode) failed while checking SRL");
584 goto out;
586 if (!(init_connect_result & TW_CTLR_FW_COMPATIBLE)) {
587 if (TW_CURRENT_FW_SRL > fw_on_ctlr_srl) {
588 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x32, "Firmware and driver incompatibility: please upgrade firmware");
589 } else {
590 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x33, "Firmware and driver incompatibility: please upgrade driver");
592 goto out;
594 tw_dev->working_srl = TW_BASE_FW_SRL;
595 tw_dev->working_branch = TW_BASE_FW_BRANCH;
596 tw_dev->working_build = TW_BASE_FW_BUILD;
598 retval = 0;
599 out:
600 return retval;
601 } /* End twa_check_srl() */
603 /* This function handles ioctl for the character device */
604 static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
606 long timeout;
607 unsigned long *cpu_addr, data_buffer_length_adjusted = 0, flags = 0;
608 dma_addr_t dma_handle;
609 int request_id = 0;
610 unsigned int sequence_id = 0;
611 unsigned char event_index, start_index;
612 TW_Ioctl_Driver_Command driver_command;
613 TW_Ioctl_Buf_Apache *tw_ioctl;
614 TW_Lock *tw_lock;
615 TW_Command_Full *full_command_packet;
616 TW_Compatibility_Info *tw_compat_info;
617 TW_Event *event;
618 struct timeval current_time;
619 u32 current_time_ms;
620 TW_Device_Extension *tw_dev = twa_device_extension_list[iminor(inode)];
621 int retval = TW_IOCTL_ERROR_OS_EFAULT;
622 void __user *argp = (void __user *)arg;
624 /* Only let one of these through at a time */
625 if (down_interruptible(&tw_dev->ioctl_sem)) {
626 retval = TW_IOCTL_ERROR_OS_EINTR;
627 goto out;
630 /* First copy down the driver command */
631 if (copy_from_user(&driver_command, argp, sizeof(TW_Ioctl_Driver_Command)))
632 goto out2;
634 /* Check data buffer size */
635 if (driver_command.buffer_length > TW_MAX_SECTORS * 512) {
636 retval = TW_IOCTL_ERROR_OS_EINVAL;
637 goto out2;
640 /* Hardware can only do multiple of 512 byte transfers */
641 data_buffer_length_adjusted = (driver_command.buffer_length + 511) & ~511;
643 /* Now allocate ioctl buf memory */
644 cpu_addr = pci_alloc_consistent(tw_dev->tw_pci_dev, data_buffer_length_adjusted+sizeof(TW_Ioctl_Buf_Apache) - 1, &dma_handle);
645 if (!cpu_addr) {
646 retval = TW_IOCTL_ERROR_OS_ENOMEM;
647 goto out2;
650 tw_ioctl = (TW_Ioctl_Buf_Apache *)cpu_addr;
652 /* Now copy down the entire ioctl */
653 if (copy_from_user(tw_ioctl, argp, driver_command.buffer_length + sizeof(TW_Ioctl_Buf_Apache) - 1))
654 goto out3;
656 /* See which ioctl we are doing */
657 switch (cmd) {
658 case TW_IOCTL_FIRMWARE_PASS_THROUGH:
659 spin_lock_irqsave(tw_dev->host->host_lock, flags);
660 twa_get_request_id(tw_dev, &request_id);
662 /* Flag internal command */
663 tw_dev->srb[request_id] = NULL;
665 /* Flag chrdev ioctl */
666 tw_dev->chrdev_request_id = request_id;
668 full_command_packet = &tw_ioctl->firmware_command;
670 /* Load request id and sglist for both command types */
671 twa_load_sgl(full_command_packet, request_id, dma_handle, data_buffer_length_adjusted);
673 memcpy(tw_dev->command_packet_virt[request_id], &(tw_ioctl->firmware_command), sizeof(TW_Command_Full));
675 /* Now post the command packet to the controller */
676 twa_post_command_packet(tw_dev, request_id, 1);
677 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
679 timeout = TW_IOCTL_CHRDEV_TIMEOUT*HZ;
681 /* Now wait for command to complete */
682 timeout = wait_event_interruptible_timeout(tw_dev->ioctl_wqueue, tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE, timeout);
684 /* Check if we timed out, got a signal, or didn't get
685 an interrupt */
686 if ((timeout <= 0) && (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE)) {
687 /* Now we need to reset the board */
688 if (timeout == TW_IOCTL_ERROR_OS_ERESTARTSYS) {
689 retval = timeout;
690 } else {
691 printk(KERN_WARNING "3w-9xxx: scsi%d: WARNING: (0x%02X:0x%04X): Character ioctl (0x%x) timed out, resetting card.\n",
692 tw_dev->host->host_no, TW_DRIVER, 0xc,
693 cmd);
694 retval = TW_IOCTL_ERROR_OS_EIO;
696 spin_lock_irqsave(tw_dev->host->host_lock, flags);
697 tw_dev->state[request_id] = TW_S_COMPLETED;
698 twa_free_request_id(tw_dev, request_id);
699 tw_dev->posted_request_count--;
700 twa_reset_device_extension(tw_dev);
701 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
702 goto out3;
705 /* Now copy in the command packet response */
706 memcpy(&(tw_ioctl->firmware_command), tw_dev->command_packet_virt[request_id], sizeof(TW_Command_Full));
708 /* Now complete the io */
709 spin_lock_irqsave(tw_dev->host->host_lock, flags);
710 tw_dev->posted_request_count--;
711 tw_dev->state[request_id] = TW_S_COMPLETED;
712 twa_free_request_id(tw_dev, request_id);
713 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
714 break;
715 case TW_IOCTL_GET_COMPATIBILITY_INFO:
716 tw_ioctl->driver_command.status = 0;
717 /* Copy compatiblity struct into ioctl data buffer */
718 tw_compat_info = (TW_Compatibility_Info *)tw_ioctl->data_buffer;
719 strncpy(tw_compat_info->driver_version, twa_driver_version, strlen(twa_driver_version));
720 tw_compat_info->working_srl = tw_dev->working_srl;
721 tw_compat_info->working_branch = tw_dev->working_branch;
722 tw_compat_info->working_build = tw_dev->working_build;
723 break;
724 case TW_IOCTL_GET_LAST_EVENT:
725 if (tw_dev->event_queue_wrapped) {
726 if (tw_dev->aen_clobber) {
727 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_AEN_CLOBBER;
728 tw_dev->aen_clobber = 0;
729 } else
730 tw_ioctl->driver_command.status = 0;
731 } else {
732 if (!tw_dev->error_index) {
733 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS;
734 break;
736 tw_ioctl->driver_command.status = 0;
738 event_index = (tw_dev->error_index - 1 + TW_Q_LENGTH) % TW_Q_LENGTH;
739 memcpy(tw_ioctl->data_buffer, tw_dev->event_queue[event_index], sizeof(TW_Event));
740 tw_dev->event_queue[event_index]->retrieved = TW_AEN_RETRIEVED;
741 break;
742 case TW_IOCTL_GET_FIRST_EVENT:
743 if (tw_dev->event_queue_wrapped) {
744 if (tw_dev->aen_clobber) {
745 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_AEN_CLOBBER;
746 tw_dev->aen_clobber = 0;
747 } else
748 tw_ioctl->driver_command.status = 0;
749 event_index = tw_dev->error_index;
750 } else {
751 if (!tw_dev->error_index) {
752 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS;
753 break;
755 tw_ioctl->driver_command.status = 0;
756 event_index = 0;
758 memcpy(tw_ioctl->data_buffer, tw_dev->event_queue[event_index], sizeof(TW_Event));
759 tw_dev->event_queue[event_index]->retrieved = TW_AEN_RETRIEVED;
760 break;
761 case TW_IOCTL_GET_NEXT_EVENT:
762 event = (TW_Event *)tw_ioctl->data_buffer;
763 sequence_id = event->sequence_id;
764 tw_ioctl->driver_command.status = 0;
766 if (tw_dev->event_queue_wrapped) {
767 if (tw_dev->aen_clobber) {
768 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_AEN_CLOBBER;
769 tw_dev->aen_clobber = 0;
771 start_index = tw_dev->error_index;
772 } else {
773 if (!tw_dev->error_index) {
774 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS;
775 break;
777 start_index = 0;
779 event_index = (start_index + sequence_id - tw_dev->event_queue[start_index]->sequence_id + 1) % TW_Q_LENGTH;
781 if (!(tw_dev->event_queue[event_index]->sequence_id > sequence_id)) {
782 if (tw_ioctl->driver_command.status == TW_IOCTL_ERROR_STATUS_AEN_CLOBBER)
783 tw_dev->aen_clobber = 1;
784 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS;
785 break;
787 memcpy(tw_ioctl->data_buffer, tw_dev->event_queue[event_index], sizeof(TW_Event));
788 tw_dev->event_queue[event_index]->retrieved = TW_AEN_RETRIEVED;
789 break;
790 case TW_IOCTL_GET_PREVIOUS_EVENT:
791 event = (TW_Event *)tw_ioctl->data_buffer;
792 sequence_id = event->sequence_id;
793 tw_ioctl->driver_command.status = 0;
795 if (tw_dev->event_queue_wrapped) {
796 if (tw_dev->aen_clobber) {
797 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_AEN_CLOBBER;
798 tw_dev->aen_clobber = 0;
800 start_index = tw_dev->error_index;
801 } else {
802 if (!tw_dev->error_index) {
803 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS;
804 break;
806 start_index = 0;
808 event_index = (start_index + sequence_id - tw_dev->event_queue[start_index]->sequence_id - 1) % TW_Q_LENGTH;
810 if (!(tw_dev->event_queue[event_index]->sequence_id < sequence_id)) {
811 if (tw_ioctl->driver_command.status == TW_IOCTL_ERROR_STATUS_AEN_CLOBBER)
812 tw_dev->aen_clobber = 1;
813 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS;
814 break;
816 memcpy(tw_ioctl->data_buffer, tw_dev->event_queue[event_index], sizeof(TW_Event));
817 tw_dev->event_queue[event_index]->retrieved = TW_AEN_RETRIEVED;
818 break;
819 case TW_IOCTL_GET_LOCK:
820 tw_lock = (TW_Lock *)tw_ioctl->data_buffer;
821 do_gettimeofday(&current_time);
822 current_time_ms = (current_time.tv_sec * 1000) + (current_time.tv_usec / 1000);
824 if ((tw_lock->force_flag == 1) || (tw_dev->ioctl_sem_lock == 0) || (current_time_ms >= tw_dev->ioctl_msec)) {
825 tw_dev->ioctl_sem_lock = 1;
826 tw_dev->ioctl_msec = current_time_ms + tw_lock->timeout_msec;
827 tw_ioctl->driver_command.status = 0;
828 tw_lock->time_remaining_msec = tw_lock->timeout_msec;
829 } else {
830 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_LOCKED;
831 tw_lock->time_remaining_msec = tw_dev->ioctl_msec - current_time_ms;
833 break;
834 case TW_IOCTL_RELEASE_LOCK:
835 if (tw_dev->ioctl_sem_lock == 1) {
836 tw_dev->ioctl_sem_lock = 0;
837 tw_ioctl->driver_command.status = 0;
838 } else {
839 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NOT_LOCKED;
841 break;
842 default:
843 retval = TW_IOCTL_ERROR_OS_ENOTTY;
844 goto out3;
847 /* Now copy the entire response to userspace */
848 if (copy_to_user(argp, tw_ioctl, sizeof(TW_Ioctl_Buf_Apache) + driver_command.buffer_length - 1) == 0)
849 retval = 0;
850 out3:
851 /* Now free ioctl buf memory */
852 pci_free_consistent(tw_dev->tw_pci_dev, data_buffer_length_adjusted+sizeof(TW_Ioctl_Buf_Apache) - 1, cpu_addr, dma_handle);
853 out2:
854 up(&tw_dev->ioctl_sem);
855 out:
856 return retval;
857 } /* End twa_chrdev_ioctl() */
859 /* This function handles open for the character device */
860 static int twa_chrdev_open(struct inode *inode, struct file *file)
862 unsigned int minor_number;
863 int retval = TW_IOCTL_ERROR_OS_ENODEV;
865 minor_number = iminor(inode);
866 if (minor_number >= twa_device_extension_count)
867 goto out;
868 retval = 0;
869 out:
870 return retval;
871 } /* End twa_chrdev_open() */
873 /* This function will print readable messages from status register errors */
874 static int twa_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value)
876 int retval = 1;
878 /* Check for various error conditions and handle them appropriately */
879 if (status_reg_value & TW_STATUS_PCI_PARITY_ERROR) {
880 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xc, "PCI Parity Error: clearing");
881 writel(TW_CONTROL_CLEAR_PARITY_ERROR, TW_CONTROL_REG_ADDR(tw_dev));
884 if (status_reg_value & TW_STATUS_PCI_ABORT) {
885 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xd, "PCI Abort: clearing");
886 writel(TW_CONTROL_CLEAR_PCI_ABORT, TW_CONTROL_REG_ADDR(tw_dev));
887 pci_write_config_word(tw_dev->tw_pci_dev, PCI_STATUS, TW_PCI_CLEAR_PCI_ABORT);
890 if (status_reg_value & TW_STATUS_QUEUE_ERROR) {
891 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xe, "Controller Queue Error: clearing");
892 writel(TW_CONTROL_CLEAR_QUEUE_ERROR, TW_CONTROL_REG_ADDR(tw_dev));
895 if (status_reg_value & TW_STATUS_SBUF_WRITE_ERROR) {
896 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xf, "SBUF Write Error: clearing");
897 writel(TW_CONTROL_CLEAR_SBUF_WRITE_ERROR, TW_CONTROL_REG_ADDR(tw_dev));
900 if (status_reg_value & TW_STATUS_MICROCONTROLLER_ERROR) {
901 if (tw_dev->reset_print == 0) {
902 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x10, "Microcontroller Error: clearing");
903 tw_dev->reset_print = 1;
905 goto out;
907 retval = 0;
908 out:
909 return retval;
910 } /* End twa_decode_bits() */
912 /* This function will empty the response queue */
913 static int twa_empty_response_queue(TW_Device_Extension *tw_dev)
915 u32 status_reg_value, response_que_value;
916 int count = 0, retval = 1;
918 status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
920 while (((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) && (count < TW_MAX_RESPONSE_DRAIN)) {
921 response_que_value = readl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
922 status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
923 count++;
925 if (count == TW_MAX_RESPONSE_DRAIN)
926 goto out;
928 retval = 0;
929 out:
930 return retval;
931 } /* End twa_empty_response_queue() */
933 /* This function passes sense keys from firmware to scsi layer */
934 static int twa_fill_sense(TW_Device_Extension *tw_dev, int request_id, int copy_sense, int print_host)
936 TW_Command_Full *full_command_packet;
937 unsigned short error;
938 int retval = 1;
940 full_command_packet = tw_dev->command_packet_virt[request_id];
941 /* Don't print error for Logical unit not supported during rollcall */
942 error = full_command_packet->header.status_block.error;
943 if ((error != TW_ERROR_LOGICAL_UNIT_NOT_SUPPORTED) && (error != TW_ERROR_UNIT_OFFLINE)) {
944 if (print_host)
945 printk(KERN_WARNING "3w-9xxx: scsi%d: ERROR: (0x%02X:0x%04X): %s:%s.\n",
946 tw_dev->host->host_no,
947 TW_MESSAGE_SOURCE_CONTROLLER_ERROR,
948 full_command_packet->header.status_block.error,
949 twa_string_lookup(twa_error_table,
950 full_command_packet->header.status_block.error),
951 full_command_packet->header.err_specific_desc);
952 else
953 printk(KERN_WARNING "3w-9xxx: ERROR: (0x%02X:0x%04X): %s:%s.\n",
954 TW_MESSAGE_SOURCE_CONTROLLER_ERROR,
955 full_command_packet->header.status_block.error,
956 twa_string_lookup(twa_error_table,
957 full_command_packet->header.status_block.error),
958 full_command_packet->header.err_specific_desc);
961 if (copy_sense) {
962 memcpy(tw_dev->srb[request_id]->sense_buffer, full_command_packet->header.sense_data, TW_SENSE_DATA_LENGTH);
963 tw_dev->srb[request_id]->result = (full_command_packet->command.newcommand.status << 1);
964 retval = TW_ISR_DONT_RESULT;
965 goto out;
967 retval = 0;
968 out:
969 return retval;
970 } /* End twa_fill_sense() */
972 /* This function will free up device extension resources */
973 static void twa_free_device_extension(TW_Device_Extension *tw_dev)
975 if (tw_dev->command_packet_virt[0])
976 pci_free_consistent(tw_dev->tw_pci_dev,
977 sizeof(TW_Command_Full)*TW_Q_LENGTH,
978 tw_dev->command_packet_virt[0],
979 tw_dev->command_packet_phys[0]);
981 if (tw_dev->generic_buffer_virt[0])
982 pci_free_consistent(tw_dev->tw_pci_dev,
983 TW_SECTOR_SIZE*TW_Q_LENGTH,
984 tw_dev->generic_buffer_virt[0],
985 tw_dev->generic_buffer_phys[0]);
987 if (tw_dev->event_queue[0])
988 kfree(tw_dev->event_queue[0]);
989 } /* End twa_free_device_extension() */
991 /* This function will free a request id */
992 static void twa_free_request_id(TW_Device_Extension *tw_dev, int request_id)
994 tw_dev->free_queue[tw_dev->free_tail] = request_id;
995 tw_dev->state[request_id] = TW_S_FINISHED;
996 tw_dev->free_tail = (tw_dev->free_tail + 1) % TW_Q_LENGTH;
997 } /* End twa_free_request_id() */
999 /* This function will get parameter table entires from the firmware */
1000 static void *twa_get_param(TW_Device_Extension *tw_dev, int request_id, int table_id, int parameter_id, int parameter_size_bytes)
1002 TW_Command_Full *full_command_packet;
1003 TW_Command *command_packet;
1004 TW_Param_Apache *param;
1005 unsigned long param_value;
1006 void *retval = NULL;
1008 /* Setup the command packet */
1009 full_command_packet = tw_dev->command_packet_virt[request_id];
1010 memset(full_command_packet, 0, sizeof(TW_Command_Full));
1011 command_packet = &full_command_packet->command.oldcommand;
1013 command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
1014 command_packet->size = TW_COMMAND_SIZE;
1015 command_packet->request_id = request_id;
1016 command_packet->byte6_offset.block_count = 1;
1018 /* Now setup the param */
1019 param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id];
1020 memset(param, 0, TW_SECTOR_SIZE);
1021 param->table_id = table_id | 0x8000;
1022 param->parameter_id = parameter_id;
1023 param->parameter_size_bytes = parameter_size_bytes;
1024 param_value = tw_dev->generic_buffer_phys[request_id];
1026 command_packet->byte8_offset.param.sgl[0].address = param_value;
1027 command_packet->byte8_offset.param.sgl[0].length = TW_SECTOR_SIZE;
1029 /* Post the command packet to the board */
1030 twa_post_command_packet(tw_dev, request_id, 1);
1032 /* Poll for completion */
1033 if (twa_poll_response(tw_dev, request_id, 30))
1034 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x13, "No valid response during get param")
1035 else
1036 retval = (void *)&(param->data[0]);
1038 tw_dev->posted_request_count--;
1039 tw_dev->state[request_id] = TW_S_INITIAL;
1041 return retval;
1042 } /* End twa_get_param() */
1044 /* This function will assign an available request id */
1045 static void twa_get_request_id(TW_Device_Extension *tw_dev, int *request_id)
1047 *request_id = tw_dev->free_queue[tw_dev->free_head];
1048 tw_dev->free_head = (tw_dev->free_head + 1) % TW_Q_LENGTH;
1049 tw_dev->state[*request_id] = TW_S_STARTED;
1050 } /* End twa_get_request_id() */
1052 /* This function will send an initconnection command to controller */
1053 static int twa_initconnection(TW_Device_Extension *tw_dev, int message_credits,
1054 u32 set_features, unsigned short current_fw_srl,
1055 unsigned short current_fw_arch_id,
1056 unsigned short current_fw_branch,
1057 unsigned short current_fw_build,
1058 unsigned short *fw_on_ctlr_srl,
1059 unsigned short *fw_on_ctlr_arch_id,
1060 unsigned short *fw_on_ctlr_branch,
1061 unsigned short *fw_on_ctlr_build,
1062 u32 *init_connect_result)
1064 TW_Command_Full *full_command_packet;
1065 TW_Initconnect *tw_initconnect;
1066 int request_id = 0, retval = 1;
1068 /* Initialize InitConnection command packet */
1069 full_command_packet = tw_dev->command_packet_virt[request_id];
1070 memset(full_command_packet, 0, sizeof(TW_Command_Full));
1071 full_command_packet->header.header_desc.size_header = 128;
1073 tw_initconnect = (TW_Initconnect *)&full_command_packet->command.oldcommand;
1074 tw_initconnect->opcode__reserved = TW_OPRES_IN(0, TW_OP_INIT_CONNECTION);
1075 tw_initconnect->request_id = request_id;
1076 tw_initconnect->message_credits = message_credits;
1077 tw_initconnect->features = set_features;
1078 #if BITS_PER_LONG > 32
1079 /* Turn on 64-bit sgl support */
1080 tw_initconnect->features |= 1;
1081 #endif
1083 if (set_features & TW_EXTENDED_INIT_CONNECT) {
1084 tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE_EXTENDED;
1085 tw_initconnect->fw_srl = current_fw_srl;
1086 tw_initconnect->fw_arch_id = current_fw_arch_id;
1087 tw_initconnect->fw_branch = current_fw_branch;
1088 tw_initconnect->fw_build = current_fw_build;
1089 } else
1090 tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE;
1092 /* Send command packet to the board */
1093 twa_post_command_packet(tw_dev, request_id, 1);
1095 /* Poll for completion */
1096 if (twa_poll_response(tw_dev, request_id, 30)) {
1097 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x15, "No valid response during init connection");
1098 } else {
1099 if (set_features & TW_EXTENDED_INIT_CONNECT) {
1100 *fw_on_ctlr_srl = tw_initconnect->fw_srl;
1101 *fw_on_ctlr_arch_id = tw_initconnect->fw_arch_id;
1102 *fw_on_ctlr_branch = tw_initconnect->fw_branch;
1103 *fw_on_ctlr_build = tw_initconnect->fw_build;
1104 *init_connect_result = tw_initconnect->result;
1106 retval = 0;
1109 tw_dev->posted_request_count--;
1110 tw_dev->state[request_id] = TW_S_INITIAL;
1112 return retval;
1113 } /* End twa_initconnection() */
1115 /* This function will initialize the fields of a device extension */
1116 static int twa_initialize_device_extension(TW_Device_Extension *tw_dev)
1118 int i, retval = 1;
1120 /* Initialize command packet buffers */
1121 if (twa_allocate_memory(tw_dev, sizeof(TW_Command_Full), 0)) {
1122 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x16, "Command packet memory allocation failed");
1123 goto out;
1126 /* Initialize generic buffer */
1127 if (twa_allocate_memory(tw_dev, TW_SECTOR_SIZE, 1)) {
1128 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x17, "Generic memory allocation failed");
1129 goto out;
1132 /* Allocate event info space */
1133 tw_dev->event_queue[0] = kmalloc(sizeof(TW_Event) * TW_Q_LENGTH, GFP_KERNEL);
1134 if (!tw_dev->event_queue[0]) {
1135 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x18, "Event info memory allocation failed");
1136 goto out;
1139 memset(tw_dev->event_queue[0], 0, sizeof(TW_Event) * TW_Q_LENGTH);
1141 for (i = 0; i < TW_Q_LENGTH; i++) {
1142 tw_dev->event_queue[i] = (TW_Event *)((unsigned char *)tw_dev->event_queue[0] + (i * sizeof(TW_Event)));
1143 tw_dev->free_queue[i] = i;
1144 tw_dev->state[i] = TW_S_INITIAL;
1147 tw_dev->pending_head = TW_Q_START;
1148 tw_dev->pending_tail = TW_Q_START;
1149 tw_dev->free_head = TW_Q_START;
1150 tw_dev->free_tail = TW_Q_START;
1151 tw_dev->error_sequence_id = 1;
1152 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1154 init_MUTEX(&tw_dev->ioctl_sem);
1155 init_waitqueue_head(&tw_dev->ioctl_wqueue);
1157 retval = 0;
1158 out:
1159 return retval;
1160 } /* End twa_initialize_device_extension() */
1162 /* This function is the interrupt service routine */
1163 static irqreturn_t twa_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
1165 int request_id, error = 0;
1166 u32 status_reg_value;
1167 TW_Response_Queue response_que;
1168 TW_Command_Full *full_command_packet;
1169 TW_Command *command_packet;
1170 TW_Device_Extension *tw_dev = (TW_Device_Extension *)dev_instance;
1171 int handled = 0;
1173 /* Get the per adapter lock */
1174 spin_lock(tw_dev->host->host_lock);
1176 /* See if the interrupt matches this instance */
1177 if (tw_dev->tw_pci_dev->irq == (unsigned int)irq) {
1179 handled = 1;
1181 /* Read the registers */
1182 status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
1184 /* Check if this is our interrupt, otherwise bail */
1185 if (!(status_reg_value & TW_STATUS_VALID_INTERRUPT))
1186 goto twa_interrupt_bail;
1188 /* Check controller for errors */
1189 if (twa_check_bits(status_reg_value)) {
1190 if (twa_decode_bits(tw_dev, status_reg_value)) {
1191 TW_CLEAR_ALL_INTERRUPTS(tw_dev);
1192 goto twa_interrupt_bail;
1196 /* Handle host interrupt */
1197 if (status_reg_value & TW_STATUS_HOST_INTERRUPT)
1198 TW_CLEAR_HOST_INTERRUPT(tw_dev);
1200 /* Handle attention interrupt */
1201 if (status_reg_value & TW_STATUS_ATTENTION_INTERRUPT) {
1202 TW_CLEAR_ATTENTION_INTERRUPT(tw_dev);
1203 if (!(test_and_set_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags))) {
1204 twa_get_request_id(tw_dev, &request_id);
1206 error = twa_aen_read_queue(tw_dev, request_id);
1207 if (error) {
1208 tw_dev->state[request_id] = TW_S_COMPLETED;
1209 twa_free_request_id(tw_dev, request_id);
1210 clear_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags);
1215 /* Handle command interrupt */
1216 if (status_reg_value & TW_STATUS_COMMAND_INTERRUPT) {
1217 TW_MASK_COMMAND_INTERRUPT(tw_dev);
1218 /* Drain as many pending commands as we can */
1219 while (tw_dev->pending_request_count > 0) {
1220 request_id = tw_dev->pending_queue[tw_dev->pending_head];
1221 if (tw_dev->state[request_id] != TW_S_PENDING) {
1222 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x19, "Found request id that wasn't pending");
1223 TW_CLEAR_ALL_INTERRUPTS(tw_dev);
1224 goto twa_interrupt_bail;
1226 if (twa_post_command_packet(tw_dev, request_id, 1)==0) {
1227 tw_dev->pending_head = (tw_dev->pending_head + 1) % TW_Q_LENGTH;
1228 tw_dev->pending_request_count--;
1229 } else {
1230 /* If we get here, we will continue re-posting on the next command interrupt */
1231 break;
1236 /* Handle response interrupt */
1237 if (status_reg_value & TW_STATUS_RESPONSE_INTERRUPT) {
1239 /* Drain the response queue from the board */
1240 while ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
1241 /* Complete the response */
1242 response_que.value = readl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
1243 request_id = TW_RESID_OUT(response_que.response_id);
1244 full_command_packet = tw_dev->command_packet_virt[request_id];
1245 error = 0;
1246 command_packet = &full_command_packet->command.oldcommand;
1247 /* Check for command packet errors */
1248 if (full_command_packet->command.newcommand.status != 0) {
1249 if (tw_dev->srb[request_id] != 0) {
1250 error = twa_fill_sense(tw_dev, request_id, 1, 1);
1251 } else {
1252 /* Skip ioctl error prints */
1253 if (request_id != tw_dev->chrdev_request_id) {
1254 error = twa_fill_sense(tw_dev, request_id, 0, 1);
1259 /* Check for correct state */
1260 if (tw_dev->state[request_id] != TW_S_POSTED) {
1261 if (tw_dev->srb[request_id] != 0) {
1262 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1a, "Received a request id that wasn't posted");
1263 TW_CLEAR_ALL_INTERRUPTS(tw_dev);
1264 goto twa_interrupt_bail;
1268 /* Check for internal command completion */
1269 if (tw_dev->srb[request_id] == 0) {
1270 if (request_id != tw_dev->chrdev_request_id) {
1271 if (twa_aen_complete(tw_dev, request_id))
1272 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1b, "Error completing AEN during attention interrupt");
1273 } else {
1274 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1275 wake_up(&tw_dev->ioctl_wqueue);
1277 } else {
1278 twa_scsiop_execute_scsi_complete(tw_dev, request_id);
1279 /* If no error command was a success */
1280 if (error == 0) {
1281 tw_dev->srb[request_id]->result = (DID_OK << 16);
1284 /* If error, command failed */
1285 if (error == 1) {
1286 /* Ask for a host reset */
1287 tw_dev->srb[request_id]->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
1290 /* Now complete the io */
1291 tw_dev->state[request_id] = TW_S_COMPLETED;
1292 twa_free_request_id(tw_dev, request_id);
1293 tw_dev->posted_request_count--;
1294 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1295 twa_unmap_scsi_data(tw_dev, request_id);
1298 /* Check for valid status after each drain */
1299 status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
1300 if (twa_check_bits(status_reg_value)) {
1301 if (twa_decode_bits(tw_dev, status_reg_value)) {
1302 TW_CLEAR_ALL_INTERRUPTS(tw_dev);
1303 goto twa_interrupt_bail;
1309 twa_interrupt_bail:
1310 spin_unlock(tw_dev->host->host_lock);
1311 return IRQ_RETVAL(handled);
1312 } /* End twa_interrupt() */
1314 /* This function will load the request id and various sgls for ioctls */
1315 static void twa_load_sgl(TW_Command_Full *full_command_packet, int request_id, dma_addr_t dma_handle, int length)
1317 TW_Command *oldcommand;
1318 TW_Command_Apache *newcommand;
1319 TW_SG_Entry *sgl;
1321 if (TW_OP_OUT(full_command_packet->command.newcommand.opcode__reserved) == TW_OP_EXECUTE_SCSI) {
1322 newcommand = &full_command_packet->command.newcommand;
1323 newcommand->request_id = request_id;
1324 newcommand->sg_list[0].address = dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1;
1325 newcommand->sg_list[0].length = length;
1326 } else {
1327 oldcommand = &full_command_packet->command.oldcommand;
1328 oldcommand->request_id = request_id;
1330 if (TW_SGL_OUT(oldcommand->opcode__sgloffset)) {
1331 /* Load the sg list */
1332 sgl = (TW_SG_Entry *)((u32 *)oldcommand+TW_SGL_OUT(oldcommand->opcode__sgloffset));
1333 sgl->address = dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1;
1334 sgl->length = length;
1337 } /* End twa_load_sgl() */
1339 /* This function will perform a pci-dma mapping for a scatter gather list */
1340 static int twa_map_scsi_sg_data(TW_Device_Extension *tw_dev, int request_id)
1342 int use_sg;
1343 struct scsi_cmnd *cmd = tw_dev->srb[request_id];
1344 struct pci_dev *pdev = tw_dev->tw_pci_dev;
1345 int retval = 0;
1347 if (cmd->use_sg == 0)
1348 goto out;
1350 use_sg = pci_map_sg(pdev, cmd->buffer, cmd->use_sg, DMA_BIDIRECTIONAL);
1352 if (use_sg == 0) {
1353 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1c, "Failed to map scatter gather list");
1354 goto out;
1357 cmd->SCp.phase = TW_PHASE_SGLIST;
1358 cmd->SCp.have_data_in = use_sg;
1359 retval = use_sg;
1360 out:
1361 return retval;
1362 } /* End twa_map_scsi_sg_data() */
1364 /* This function will perform a pci-dma map for a single buffer */
1365 static dma_addr_t twa_map_scsi_single_data(TW_Device_Extension *tw_dev, int request_id)
1367 dma_addr_t mapping;
1368 struct scsi_cmnd *cmd = tw_dev->srb[request_id];
1369 struct pci_dev *pdev = tw_dev->tw_pci_dev;
1370 int retval = 0;
1372 if (cmd->request_bufflen == 0) {
1373 retval = 0;
1374 goto out;
1377 mapping = pci_map_single(pdev, cmd->request_buffer, cmd->request_bufflen, DMA_BIDIRECTIONAL);
1379 if (mapping == 0) {
1380 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1d, "Failed to map page");
1381 goto out;
1384 cmd->SCp.phase = TW_PHASE_SINGLE;
1385 cmd->SCp.have_data_in = mapping;
1386 retval = mapping;
1387 out:
1388 return retval;
1389 } /* End twa_map_scsi_single_data() */
1391 /* This function will poll for a response interrupt of a request */
1392 static int twa_poll_response(TW_Device_Extension *tw_dev, int request_id, int seconds)
1394 int retval = 1, found = 0, response_request_id;
1395 TW_Response_Queue response_queue;
1396 TW_Command_Full *full_command_packet = tw_dev->command_packet_virt[request_id];
1398 if (twa_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, seconds) == 0) {
1399 response_queue.value = readl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
1400 response_request_id = TW_RESID_OUT(response_queue.response_id);
1401 if (request_id != response_request_id) {
1402 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1e, "Found unexpected request id while polling for response");
1403 goto out;
1405 if (TW_OP_OUT(full_command_packet->command.newcommand.opcode__reserved) == TW_OP_EXECUTE_SCSI) {
1406 if (full_command_packet->command.newcommand.status != 0) {
1407 /* bad response */
1408 twa_fill_sense(tw_dev, request_id, 0, 0);
1409 goto out;
1411 found = 1;
1412 } else {
1413 if (full_command_packet->command.oldcommand.status != 0) {
1414 /* bad response */
1415 twa_fill_sense(tw_dev, request_id, 0, 0);
1416 goto out;
1418 found = 1;
1422 if (found)
1423 retval = 0;
1424 out:
1425 return retval;
1426 } /* End twa_poll_response() */
1428 /* This function will poll the status register for a flag */
1429 static int twa_poll_status(TW_Device_Extension *tw_dev, u32 flag, int seconds)
1431 u32 status_reg_value;
1432 unsigned long before;
1433 int retval = 1;
1435 status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
1436 before = jiffies;
1438 if (twa_check_bits(status_reg_value))
1439 twa_decode_bits(tw_dev, status_reg_value);
1441 while ((status_reg_value & flag) != flag) {
1442 status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
1444 if (twa_check_bits(status_reg_value))
1445 twa_decode_bits(tw_dev, status_reg_value);
1447 if (time_after(jiffies, before + HZ * seconds))
1448 goto out;
1450 msleep(50);
1452 retval = 0;
1453 out:
1454 return retval;
1455 } /* End twa_poll_status() */
1457 /* This function will poll the status register for disappearance of a flag */
1458 static int twa_poll_status_gone(TW_Device_Extension *tw_dev, u32 flag, int seconds)
1460 u32 status_reg_value;
1461 unsigned long before;
1462 int retval = 1;
1464 status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
1465 before = jiffies;
1467 if (twa_check_bits(status_reg_value))
1468 twa_decode_bits(tw_dev, status_reg_value);
1470 while ((status_reg_value & flag) != 0) {
1471 status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
1472 if (twa_check_bits(status_reg_value))
1473 twa_decode_bits(tw_dev, status_reg_value);
1475 if (time_after(jiffies, before + HZ * seconds))
1476 goto out;
1478 msleep(50);
1480 retval = 0;
1481 out:
1482 return retval;
1483 } /* End twa_poll_status_gone() */
1485 /* This function will attempt to post a command packet to the board */
1486 static int twa_post_command_packet(TW_Device_Extension *tw_dev, int request_id, char internal)
1488 u32 status_reg_value;
1489 unsigned long command_que_value;
1490 int retval = 1;
1492 command_que_value = tw_dev->command_packet_phys[request_id];
1493 status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
1495 if (twa_check_bits(status_reg_value))
1496 twa_decode_bits(tw_dev, status_reg_value);
1498 if (((tw_dev->pending_request_count > 0) && (tw_dev->state[request_id] != TW_S_PENDING)) || (status_reg_value & TW_STATUS_COMMAND_QUEUE_FULL)) {
1500 /* Only pend internal driver commands */
1501 if (!internal) {
1502 retval = SCSI_MLQUEUE_HOST_BUSY;
1503 goto out;
1506 /* Couldn't post the command packet, so we do it later */
1507 if (tw_dev->state[request_id] != TW_S_PENDING) {
1508 tw_dev->state[request_id] = TW_S_PENDING;
1509 tw_dev->pending_request_count++;
1510 if (tw_dev->pending_request_count > tw_dev->max_pending_request_count) {
1511 tw_dev->max_pending_request_count = tw_dev->pending_request_count;
1513 tw_dev->pending_queue[tw_dev->pending_tail] = request_id;
1514 tw_dev->pending_tail = (tw_dev->pending_tail + 1) % TW_Q_LENGTH;
1516 TW_UNMASK_COMMAND_INTERRUPT(tw_dev);
1517 goto out;
1518 } else {
1519 /* We successfully posted the command packet */
1520 #if BITS_PER_LONG > 32
1521 writeq(TW_COMMAND_OFFSET + command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
1522 #else
1523 writel(TW_COMMAND_OFFSET + command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
1524 #endif
1525 tw_dev->state[request_id] = TW_S_POSTED;
1526 tw_dev->posted_request_count++;
1527 if (tw_dev->posted_request_count > tw_dev->max_posted_request_count) {
1528 tw_dev->max_posted_request_count = tw_dev->posted_request_count;
1531 retval = 0;
1532 out:
1533 return retval;
1534 } /* End twa_post_command_packet() */
1536 /* This function will reset a device extension */
1537 static int twa_reset_device_extension(TW_Device_Extension *tw_dev)
1539 int i = 0;
1540 int retval = 1;
1542 /* Abort all requests that are in progress */
1543 for (i = 0; i < TW_Q_LENGTH; i++) {
1544 if ((tw_dev->state[i] != TW_S_FINISHED) &&
1545 (tw_dev->state[i] != TW_S_INITIAL) &&
1546 (tw_dev->state[i] != TW_S_COMPLETED)) {
1547 if (tw_dev->srb[i]) {
1548 tw_dev->srb[i]->result = (DID_RESET << 16);
1549 tw_dev->srb[i]->scsi_done(tw_dev->srb[i]);
1550 twa_unmap_scsi_data(tw_dev, i);
1555 /* Reset queues and counts */
1556 for (i = 0; i < TW_Q_LENGTH; i++) {
1557 tw_dev->free_queue[i] = i;
1558 tw_dev->state[i] = TW_S_INITIAL;
1560 tw_dev->free_head = TW_Q_START;
1561 tw_dev->free_tail = TW_Q_START;
1562 tw_dev->posted_request_count = 0;
1563 tw_dev->pending_request_count = 0;
1564 tw_dev->pending_head = TW_Q_START;
1565 tw_dev->pending_tail = TW_Q_START;
1566 tw_dev->reset_print = 0;
1567 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1568 tw_dev->flags = 0;
1570 TW_DISABLE_INTERRUPTS(tw_dev);
1572 if (twa_reset_sequence(tw_dev, 1))
1573 goto out;
1575 TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
1577 retval = 0;
1578 out:
1579 return retval;
1580 } /* End twa_reset_device_extension() */
1582 /* This function will reset a controller */
1583 static int twa_reset_sequence(TW_Device_Extension *tw_dev, int soft_reset)
1585 int tries = 0, retval = 1, flashed = 0, do_soft_reset = soft_reset;
1587 while (tries < TW_MAX_RESET_TRIES) {
1588 if (do_soft_reset)
1589 TW_SOFT_RESET(tw_dev);
1591 /* Make sure controller is in a good state */
1592 if (twa_poll_status(tw_dev, TW_STATUS_MICROCONTROLLER_READY | (do_soft_reset == 1 ? TW_STATUS_ATTENTION_INTERRUPT : 0), 30)) {
1593 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1f, "Microcontroller not ready during reset sequence");
1594 do_soft_reset = 1;
1595 tries++;
1596 continue;
1599 /* Empty response queue */
1600 if (twa_empty_response_queue(tw_dev)) {
1601 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x20, "Response queue empty failed during reset sequence");
1602 do_soft_reset = 1;
1603 tries++;
1604 continue;
1607 flashed = 0;
1609 /* Check for compatibility/flash */
1610 if (twa_check_srl(tw_dev, &flashed)) {
1611 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x21, "Compatibility check failed during reset sequence");
1612 do_soft_reset = 1;
1613 tries++;
1614 continue;
1615 } else {
1616 if (flashed) {
1617 tries++;
1618 continue;
1622 /* Drain the AEN queue */
1623 if (twa_aen_drain_queue(tw_dev, soft_reset)) {
1624 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x22, "AEN drain failed during reset sequence");
1625 do_soft_reset = 1;
1626 tries++;
1627 continue;
1630 /* If we got here, controller is in a good state */
1631 retval = 0;
1632 goto out;
1634 out:
1635 return retval;
1636 } /* End twa_reset_sequence() */
1638 /* This funciton returns unit geometry in cylinders/heads/sectors */
1639 static int twa_scsi_biosparam(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int geom[])
1641 int heads, sectors, cylinders;
1642 TW_Device_Extension *tw_dev;
1644 tw_dev = (TW_Device_Extension *)sdev->host->hostdata;
1646 if (capacity >= 0x200000) {
1647 heads = 255;
1648 sectors = 63;
1649 cylinders = sector_div(capacity, heads * sectors);
1650 } else {
1651 heads = 64;
1652 sectors = 32;
1653 cylinders = sector_div(capacity, heads * sectors);
1656 geom[0] = heads;
1657 geom[1] = sectors;
1658 geom[2] = cylinders;
1660 return 0;
1661 } /* End twa_scsi_biosparam() */
1663 /* This is the new scsi eh abort function */
1664 static int twa_scsi_eh_abort(struct scsi_cmnd *SCpnt)
1666 int i;
1667 TW_Device_Extension *tw_dev = NULL;
1668 int retval = FAILED;
1670 tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
1672 spin_unlock_irq(tw_dev->host->host_lock);
1674 tw_dev->num_aborts++;
1676 /* If we find any IO's in process, we have to reset the card */
1677 for (i = 0; i < TW_Q_LENGTH; i++) {
1678 if ((tw_dev->state[i] != TW_S_FINISHED) && (tw_dev->state[i] != TW_S_INITIAL)) {
1679 printk(KERN_WARNING "3w-9xxx: scsi%d: WARNING: (0x%02X:0x%04X): Unit #%d: Command (0x%x) timed out, resetting card.\n",
1680 tw_dev->host->host_no, TW_DRIVER, 0x2c,
1681 SCpnt->device->id, SCpnt->cmnd[0]);
1682 if (twa_reset_device_extension(tw_dev)) {
1683 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2a, "Controller reset failed during scsi abort");
1684 goto out;
1686 break;
1689 retval = SUCCESS;
1690 out:
1691 spin_lock_irq(tw_dev->host->host_lock);
1692 return retval;
1693 } /* End twa_scsi_eh_abort() */
1695 /* This is the new scsi eh reset function */
1696 static int twa_scsi_eh_reset(struct scsi_cmnd *SCpnt)
1698 TW_Device_Extension *tw_dev = NULL;
1699 int retval = FAILED;
1701 tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
1703 spin_unlock_irq(tw_dev->host->host_lock);
1705 tw_dev->num_resets++;
1707 printk(KERN_WARNING "3w-9xxx: scsi%d: SCSI host reset started.\n", tw_dev->host->host_no);
1709 /* Now reset the card and some of the device extension data */
1710 if (twa_reset_device_extension(tw_dev)) {
1711 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2b, "Controller reset failed during scsi host reset");
1712 goto out;
1714 printk(KERN_WARNING "3w-9xxx: scsi%d: SCSI host reset succeeded.\n", tw_dev->host->host_no);
1715 retval = SUCCESS;
1716 out:
1717 spin_lock_irq(tw_dev->host->host_lock);
1718 return retval;
1719 } /* End twa_scsi_eh_reset() */
1721 /* This is the main scsi queue function to handle scsi opcodes */
1722 static int twa_scsi_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1724 int request_id, retval;
1725 TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
1727 /* Save done function into scsi_cmnd struct */
1728 SCpnt->scsi_done = done;
1730 /* Get a free request id */
1731 twa_get_request_id(tw_dev, &request_id);
1733 /* Save the scsi command for use by the ISR */
1734 tw_dev->srb[request_id] = SCpnt;
1736 /* Initialize phase to zero */
1737 SCpnt->SCp.phase = TW_PHASE_INITIAL;
1739 retval = twa_scsiop_execute_scsi(tw_dev, request_id, NULL, 0, NULL);
1740 switch (retval) {
1741 case SCSI_MLQUEUE_HOST_BUSY:
1742 twa_free_request_id(tw_dev, request_id);
1743 break;
1744 case 1:
1745 tw_dev->state[request_id] = TW_S_COMPLETED;
1746 twa_free_request_id(tw_dev, request_id);
1747 SCpnt->result = (DID_ERROR << 16);
1748 done(SCpnt);
1751 return retval;
1752 } /* End twa_scsi_queue() */
1754 /* This function hands scsi cdb's to the firmware */
1755 static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, char *cdb, int use_sg, TW_SG_Apache *sglistarg)
1757 TW_Command_Full *full_command_packet;
1758 TW_Command_Apache *command_packet;
1759 u32 num_sectors = 0x0;
1760 int i, sg_count;
1761 struct scsi_cmnd *srb = NULL;
1762 struct scatterlist *sglist = NULL;
1763 u32 buffaddr = 0x0;
1764 int retval = 1;
1766 if (tw_dev->srb[request_id]) {
1767 if (tw_dev->srb[request_id]->request_buffer) {
1768 sglist = (struct scatterlist *)tw_dev->srb[request_id]->request_buffer;
1770 srb = tw_dev->srb[request_id];
1773 /* Initialize command packet */
1774 full_command_packet = tw_dev->command_packet_virt[request_id];
1775 full_command_packet->header.header_desc.size_header = 128;
1776 full_command_packet->header.status_block.error = 0;
1777 full_command_packet->header.status_block.severity__reserved = 0;
1779 command_packet = &full_command_packet->command.newcommand;
1780 command_packet->status = 0;
1781 command_packet->opcode__reserved = TW_OPRES_IN(0, TW_OP_EXECUTE_SCSI);
1783 /* We forced 16 byte cdb use earlier */
1784 if (!cdb)
1785 memcpy(command_packet->cdb, srb->cmnd, TW_MAX_CDB_LEN);
1786 else
1787 memcpy(command_packet->cdb, cdb, TW_MAX_CDB_LEN);
1789 if (srb)
1790 command_packet->unit = srb->device->id;
1791 else
1792 command_packet->unit = 0;
1794 command_packet->request_id = request_id;
1795 command_packet->sgl_offset = 16;
1797 if (!sglistarg) {
1798 /* Map sglist from scsi layer to cmd packet */
1799 if (tw_dev->srb[request_id]->use_sg == 0) {
1800 if (tw_dev->srb[request_id]->request_bufflen < TW_MIN_SGL_LENGTH) {
1801 command_packet->sg_list[0].address = tw_dev->generic_buffer_phys[request_id];
1802 command_packet->sg_list[0].length = TW_MIN_SGL_LENGTH;
1803 } else {
1804 buffaddr = twa_map_scsi_single_data(tw_dev, request_id);
1805 if (buffaddr == 0)
1806 goto out;
1808 command_packet->sg_list[0].address = buffaddr;
1809 command_packet->sg_list[0].length = tw_dev->srb[request_id]->request_bufflen;
1811 command_packet->sgl_entries = 1;
1813 if (command_packet->sg_list[0].address & TW_ALIGNMENT_9000_SGL) {
1814 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2d, "Found unaligned address during execute scsi");
1815 goto out;
1819 if (tw_dev->srb[request_id]->use_sg > 0) {
1820 sg_count = twa_map_scsi_sg_data(tw_dev, request_id);
1821 if (sg_count == 0)
1822 goto out;
1824 for (i = 0; i < sg_count; i++) {
1825 command_packet->sg_list[i].address = sg_dma_address(&sglist[i]);
1826 command_packet->sg_list[i].length = sg_dma_len(&sglist[i]);
1827 if (command_packet->sg_list[i].address & TW_ALIGNMENT_9000_SGL) {
1828 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2e, "Found unaligned sgl address during execute scsi");
1829 goto out;
1832 command_packet->sgl_entries = tw_dev->srb[request_id]->use_sg;
1834 } else {
1835 /* Internal cdb post */
1836 for (i = 0; i < use_sg; i++) {
1837 command_packet->sg_list[i].address = sglistarg[i].address;
1838 command_packet->sg_list[i].length = sglistarg[i].length;
1839 if (command_packet->sg_list[i].address & TW_ALIGNMENT_9000_SGL) {
1840 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2f, "Found unaligned sgl address during internal post");
1841 goto out;
1844 command_packet->sgl_entries = use_sg;
1847 if (srb) {
1848 if (srb->cmnd[0] == READ_6 || srb->cmnd[0] == WRITE_6)
1849 num_sectors = (u32)srb->cmnd[4];
1851 if (srb->cmnd[0] == READ_10 || srb->cmnd[0] == WRITE_10)
1852 num_sectors = (u32)srb->cmnd[8] | ((u32)srb->cmnd[7] << 8);
1855 /* Update sector statistic */
1856 tw_dev->sector_count = num_sectors;
1857 if (tw_dev->sector_count > tw_dev->max_sector_count)
1858 tw_dev->max_sector_count = tw_dev->sector_count;
1860 /* Update SG statistics */
1861 if (srb) {
1862 tw_dev->sgl_entries = tw_dev->srb[request_id]->use_sg;
1863 if (tw_dev->sgl_entries > tw_dev->max_sgl_entries)
1864 tw_dev->max_sgl_entries = tw_dev->sgl_entries;
1867 /* Now post the command to the board */
1868 if (srb) {
1869 retval = twa_post_command_packet(tw_dev, request_id, 0);
1870 } else {
1871 twa_post_command_packet(tw_dev, request_id, 1);
1872 retval = 0;
1874 out:
1875 return retval;
1876 } /* End twa_scsiop_execute_scsi() */
1878 /* This function completes an execute scsi operation */
1879 static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int request_id)
1881 /* Copy the response if too small */
1882 if ((tw_dev->srb[request_id]->request_buffer) && (tw_dev->srb[request_id]->request_bufflen < TW_MIN_SGL_LENGTH)) {
1883 memcpy(tw_dev->srb[request_id]->request_buffer,
1884 tw_dev->generic_buffer_virt[request_id],
1885 tw_dev->srb[request_id]->request_bufflen);
1887 } /* End twa_scsiop_execute_scsi_complete() */
1889 /* This function tells the controller to shut down */
1890 static void __twa_shutdown(TW_Device_Extension *tw_dev)
1892 /* Disable interrupts */
1893 TW_DISABLE_INTERRUPTS(tw_dev);
1895 printk(KERN_WARNING "3w-9xxx: Shutting down host %d.\n", tw_dev->host->host_no);
1897 /* Tell the card we are shutting down */
1898 if (twa_initconnection(tw_dev, 1, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL)) {
1899 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x31, "Connection shutdown failed");
1900 } else {
1901 printk(KERN_WARNING "3w-9xxx: Shutdown complete.\n");
1904 /* Clear all interrupts just before exit */
1905 TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
1906 } /* End __twa_shutdown() */
1908 /* Wrapper for __twa_shutdown */
1909 static void twa_shutdown(struct device *dev)
1911 struct Scsi_Host *host = pci_get_drvdata(to_pci_dev(dev));
1912 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
1914 __twa_shutdown(tw_dev);
1915 } /* End twa_shutdown() */
1917 /* This function will look up a string */
1918 static char *twa_string_lookup(twa_message_type *table, unsigned int code)
1920 int index;
1922 for (index = 0; ((code != table[index].code) &&
1923 (table[index].text != (char *)0)); index++);
1924 return(table[index].text);
1925 } /* End twa_string_lookup() */
1927 /* This function will perform a pci-dma unmap */
1928 static void twa_unmap_scsi_data(TW_Device_Extension *tw_dev, int request_id)
1930 struct scsi_cmnd *cmd = tw_dev->srb[request_id];
1931 struct pci_dev *pdev = tw_dev->tw_pci_dev;
1933 switch(cmd->SCp.phase) {
1934 case TW_PHASE_SINGLE:
1935 pci_unmap_single(pdev, cmd->SCp.have_data_in, cmd->request_bufflen, DMA_BIDIRECTIONAL);
1936 break;
1937 case TW_PHASE_SGLIST:
1938 pci_unmap_sg(pdev, cmd->request_buffer, cmd->use_sg, DMA_BIDIRECTIONAL);
1939 break;
1941 } /* End twa_unmap_scsi_data() */
1943 /* scsi_host_template initializer */
1944 static struct scsi_host_template driver_template = {
1945 .module = THIS_MODULE,
1946 .name = "3ware 9000 Storage Controller",
1947 .queuecommand = twa_scsi_queue,
1948 .eh_abort_handler = twa_scsi_eh_abort,
1949 .eh_host_reset_handler = twa_scsi_eh_reset,
1950 .bios_param = twa_scsi_biosparam,
1951 .can_queue = TW_Q_LENGTH-2,
1952 .this_id = -1,
1953 .sg_tablesize = TW_APACHE_MAX_SGL_LENGTH,
1954 .max_sectors = TW_MAX_SECTORS,
1955 .cmd_per_lun = TW_MAX_CMDS_PER_LUN,
1956 .use_clustering = ENABLE_CLUSTERING,
1957 .shost_attrs = twa_host_attrs,
1958 .sdev_attrs = twa_dev_attrs,
1959 .emulated = 1
1962 /* This function will probe and initialize a card */
1963 static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id *dev_id)
1965 struct Scsi_Host *host = NULL;
1966 TW_Device_Extension *tw_dev;
1967 u32 mem_addr;
1968 int retval = -ENODEV;
1970 retval = pci_enable_device(pdev);
1971 if (retval) {
1972 TW_PRINTK(host, TW_DRIVER, 0x34, "Failed to enable pci device");
1973 goto out_disable_device;
1976 pci_set_master(pdev);
1978 retval = pci_set_dma_mask(pdev, TW_DMA_MASK);
1979 if (retval) {
1980 TW_PRINTK(host, TW_DRIVER, 0x23, "Failed to set dma mask");
1981 goto out_disable_device;
1984 host = scsi_host_alloc(&driver_template, sizeof(TW_Device_Extension));
1985 if (!host) {
1986 TW_PRINTK(host, TW_DRIVER, 0x24, "Failed to allocate memory for device extension");
1987 retval = -ENOMEM;
1988 goto out_disable_device;
1990 tw_dev = (TW_Device_Extension *)host->hostdata;
1992 memset(tw_dev, 0, sizeof(TW_Device_Extension));
1994 /* Save values to device extension */
1995 tw_dev->host = host;
1996 tw_dev->tw_pci_dev = pdev;
1998 if (twa_initialize_device_extension(tw_dev)) {
1999 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x25, "Failed to initialize device extension");
2000 goto out_free_device_extension;
2003 /* Request IO regions */
2004 retval = pci_request_regions(pdev, "3w-9xxx");
2005 if (retval) {
2006 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x26, "Failed to get mem region");
2007 goto out_free_device_extension;
2010 mem_addr = pci_resource_start(pdev, 1);
2012 /* Save base address */
2013 tw_dev->base_addr = ioremap(mem_addr, PAGE_SIZE);
2014 if (!tw_dev->base_addr) {
2015 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x35, "Failed to ioremap");
2016 goto out_release_mem_region;
2019 /* Disable interrupts on the card */
2020 TW_DISABLE_INTERRUPTS(tw_dev);
2022 /* Initialize the card */
2023 if (twa_reset_sequence(tw_dev, 0))
2024 goto out_release_mem_region;
2026 /* Set host specific parameters */
2027 host->max_id = TW_MAX_UNITS;
2028 host->max_cmd_len = TW_MAX_CDB_LEN;
2030 /* Luns and channels aren't supported by adapter */
2031 host->max_lun = 0;
2032 host->max_channel = 0;
2034 /* Register the card with the kernel SCSI layer */
2035 retval = scsi_add_host(host, &pdev->dev);
2036 if (retval) {
2037 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x27, "scsi add host failed");
2038 goto out_release_mem_region;
2041 pci_set_drvdata(pdev, host);
2043 printk(KERN_WARNING "3w-9xxx: scsi%d: Found a 3ware 9000 Storage Controller at 0x%x, IRQ: %d.\n",
2044 host->host_no, mem_addr, pdev->irq);
2045 printk(KERN_WARNING "3w-9xxx: scsi%d: Firmware %s, BIOS %s, Ports: %d.\n",
2046 host->host_no,
2047 (char *)twa_get_param(tw_dev, 0, TW_VERSION_TABLE,
2048 TW_PARAM_FWVER, TW_PARAM_FWVER_LENGTH),
2049 (char *)twa_get_param(tw_dev, 1, TW_VERSION_TABLE,
2050 TW_PARAM_BIOSVER, TW_PARAM_BIOSVER_LENGTH),
2051 *(int *)twa_get_param(tw_dev, 2, TW_INFORMATION_TABLE,
2052 TW_PARAM_PORTCOUNT, TW_PARAM_PORTCOUNT_LENGTH));
2054 /* Now setup the interrupt handler */
2055 retval = request_irq(pdev->irq, twa_interrupt, SA_SHIRQ, "3w-9xxx", tw_dev);
2056 if (retval) {
2057 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x30, "Error requesting IRQ");
2058 goto out_remove_host;
2061 twa_device_extension_list[twa_device_extension_count] = tw_dev;
2062 twa_device_extension_count++;
2064 /* Re-enable interrupts on the card */
2065 TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
2067 /* Finally, scan the host */
2068 scsi_scan_host(host);
2070 if (twa_major == -1) {
2071 if ((twa_major = register_chrdev (0, "twa", &twa_fops)) < 0)
2072 TW_PRINTK(host, TW_DRIVER, 0x29, "Failed to register character device");
2074 return 0;
2076 out_remove_host:
2077 scsi_remove_host(host);
2078 out_release_mem_region:
2079 pci_release_regions(pdev);
2080 out_free_device_extension:
2081 twa_free_device_extension(tw_dev);
2082 scsi_host_put(host);
2083 out_disable_device:
2084 pci_disable_device(pdev);
2086 return retval;
2087 } /* End twa_probe() */
2089 /* This function is called to remove a device */
2090 static void twa_remove(struct pci_dev *pdev)
2092 struct Scsi_Host *host = pci_get_drvdata(pdev);
2093 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
2095 scsi_remove_host(tw_dev->host);
2097 __twa_shutdown(tw_dev);
2099 /* Free up the IRQ */
2100 free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
2102 /* Free up the mem region */
2103 pci_release_regions(pdev);
2105 /* Free up device extension resources */
2106 twa_free_device_extension(tw_dev);
2108 /* Unregister character device */
2109 if (twa_major >= 0) {
2110 unregister_chrdev(twa_major, "twa");
2111 twa_major = -1;
2114 scsi_host_put(tw_dev->host);
2115 pci_disable_device(pdev);
2116 twa_device_extension_count--;
2117 } /* End twa_remove() */
2119 /* PCI Devices supported by this driver */
2120 static struct pci_device_id twa_pci_tbl[] __devinitdata = {
2121 { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9000,
2122 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2125 MODULE_DEVICE_TABLE(pci, twa_pci_tbl);
2127 /* pci_driver initializer */
2128 static struct pci_driver twa_driver = {
2129 .name = "3w-9xxx",
2130 .id_table = twa_pci_tbl,
2131 .probe = twa_probe,
2132 .remove = twa_remove,
2133 .driver = {
2134 .shutdown = twa_shutdown
2138 /* This function is called on driver initialization */
2139 static int __init twa_init(void)
2141 printk(KERN_WARNING "3ware 9000 Storage Controller device driver for Linux v%s.\n", twa_driver_version);
2143 return pci_module_init(&twa_driver);
2144 } /* End twa_init() */
2146 /* This function is called on driver exit */
2147 static void __exit twa_exit(void)
2149 pci_unregister_driver(&twa_driver);
2150 } /* End twa_exit() */
2152 module_init(twa_init);
2153 module_exit(twa_exit);