[PATCH] fix semaphore handling in __unregister_chrdev_region
[linux/fpc-iii.git] / drivers / scsi / 3w-9xxx.c
bloba2b18f5a4f9305af289e0eb750ad457f2152169f
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-2005 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().
54 2.26.02.002 - Add support for PAE mode.
55 Add lun support.
56 Fix twa_remove() to free irq handler/unregister_chrdev()
57 before shutting down card.
58 Change to new 'change_queue_depth' api.
59 Fix 'handled=1' ISR usage, remove bogus IRQ check.
60 Remove un-needed eh_abort handler.
61 Add support for embedded firmware error strings.
64 #include <linux/module.h>
65 #include <linux/reboot.h>
66 #include <linux/spinlock.h>
67 #include <linux/interrupt.h>
68 #include <linux/moduleparam.h>
69 #include <linux/errno.h>
70 #include <linux/types.h>
71 #include <linux/delay.h>
72 #include <linux/pci.h>
73 #include <linux/time.h>
74 #include <asm/io.h>
75 #include <asm/irq.h>
76 #include <asm/uaccess.h>
77 #include <scsi/scsi.h>
78 #include <scsi/scsi_host.h>
79 #include <scsi/scsi_tcq.h>
80 #include <scsi/scsi_cmnd.h>
81 #include "3w-9xxx.h"
83 /* Globals */
84 #define TW_DRIVER_VERSION "2.26.02.002"
85 static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT];
86 static unsigned int twa_device_extension_count;
87 static int twa_major = -1;
88 extern struct timezone sys_tz;
90 /* Module parameters */
91 MODULE_AUTHOR ("AMCC");
92 MODULE_DESCRIPTION ("3ware 9000 Storage Controller Linux Driver");
93 MODULE_LICENSE("GPL");
94 MODULE_VERSION(TW_DRIVER_VERSION);
96 /* Function prototypes */
97 static void twa_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_Header *header);
98 static int twa_aen_read_queue(TW_Device_Extension *tw_dev, int request_id);
99 static char *twa_aen_severity_lookup(unsigned char severity_code);
100 static void twa_aen_sync_time(TW_Device_Extension *tw_dev, int request_id);
101 static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
102 static int twa_chrdev_open(struct inode *inode, struct file *file);
103 static int twa_fill_sense(TW_Device_Extension *tw_dev, int request_id, int copy_sense, int print_host);
104 static void twa_free_request_id(TW_Device_Extension *tw_dev,int request_id);
105 static void twa_get_request_id(TW_Device_Extension *tw_dev, int *request_id);
106 static int twa_initconnection(TW_Device_Extension *tw_dev, int message_credits,
107 u32 set_features, unsigned short current_fw_srl,
108 unsigned short current_fw_arch_id,
109 unsigned short current_fw_branch,
110 unsigned short current_fw_build,
111 unsigned short *fw_on_ctlr_srl,
112 unsigned short *fw_on_ctlr_arch_id,
113 unsigned short *fw_on_ctlr_branch,
114 unsigned short *fw_on_ctlr_build,
115 u32 *init_connect_result);
116 static void twa_load_sgl(TW_Command_Full *full_command_packet, int request_id, dma_addr_t dma_handle, int length);
117 static int twa_poll_response(TW_Device_Extension *tw_dev, int request_id, int seconds);
118 static int twa_poll_status_gone(TW_Device_Extension *tw_dev, u32 flag, int seconds);
119 static int twa_post_command_packet(TW_Device_Extension *tw_dev, int request_id, char internal);
120 static int twa_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_reset);
121 static int twa_reset_sequence(TW_Device_Extension *tw_dev, int soft_reset);
122 static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, char *cdb, int use_sg, TW_SG_Entry *sglistarg);
123 static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int request_id);
124 static char *twa_string_lookup(twa_message_type *table, unsigned int aen_code);
125 static void twa_unmap_scsi_data(TW_Device_Extension *tw_dev, int request_id);
127 /* Functions */
129 /* Show some statistics about the card */
130 static ssize_t twa_show_stats(struct class_device *class_dev, char *buf)
132 struct Scsi_Host *host = class_to_shost(class_dev);
133 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
134 unsigned long flags = 0;
135 ssize_t len;
137 spin_lock_irqsave(tw_dev->host->host_lock, flags);
138 len = snprintf(buf, PAGE_SIZE, "3w-9xxx Driver version: %s\n"
139 "Current commands posted: %4d\n"
140 "Max commands posted: %4d\n"
141 "Current pending commands: %4d\n"
142 "Max pending commands: %4d\n"
143 "Last sgl length: %4d\n"
144 "Max sgl length: %4d\n"
145 "Last sector count: %4d\n"
146 "Max sector count: %4d\n"
147 "SCSI Host Resets: %4d\n"
148 "AEN's: %4d\n",
149 TW_DRIVER_VERSION,
150 tw_dev->posted_request_count,
151 tw_dev->max_posted_request_count,
152 tw_dev->pending_request_count,
153 tw_dev->max_pending_request_count,
154 tw_dev->sgl_entries,
155 tw_dev->max_sgl_entries,
156 tw_dev->sector_count,
157 tw_dev->max_sector_count,
158 tw_dev->num_resets,
159 tw_dev->aen_count);
160 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
161 return len;
162 } /* End twa_show_stats() */
164 /* This function will set a devices queue depth */
165 static int twa_change_queue_depth(struct scsi_device *sdev, int queue_depth)
167 if (queue_depth > TW_Q_LENGTH-2)
168 queue_depth = TW_Q_LENGTH-2;
169 scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, queue_depth);
170 return queue_depth;
171 } /* End twa_change_queue_depth() */
173 /* Create sysfs 'stats' entry */
174 static struct class_device_attribute twa_host_stats_attr = {
175 .attr = {
176 .name = "stats",
177 .mode = S_IRUGO,
179 .show = twa_show_stats
182 /* Host attributes initializer */
183 static struct class_device_attribute *twa_host_attrs[] = {
184 &twa_host_stats_attr,
185 NULL,
188 /* File operations struct for character device */
189 static struct file_operations twa_fops = {
190 .owner = THIS_MODULE,
191 .ioctl = twa_chrdev_ioctl,
192 .open = twa_chrdev_open,
193 .release = NULL
196 /* This function will complete an aen request from the isr */
197 static int twa_aen_complete(TW_Device_Extension *tw_dev, int request_id)
199 TW_Command_Full *full_command_packet;
200 TW_Command *command_packet;
201 TW_Command_Apache_Header *header;
202 unsigned short aen;
203 int retval = 1;
205 header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id];
206 tw_dev->posted_request_count--;
207 aen = header->status_block.error;
208 full_command_packet = tw_dev->command_packet_virt[request_id];
209 command_packet = &full_command_packet->command.oldcommand;
211 /* First check for internal completion of set param for time sync */
212 if (TW_OP_OUT(command_packet->opcode__sgloffset) == TW_OP_SET_PARAM) {
213 /* Keep reading the queue in case there are more aen's */
214 if (twa_aen_read_queue(tw_dev, request_id))
215 goto out2;
216 else {
217 retval = 0;
218 goto out;
222 switch (aen) {
223 case TW_AEN_QUEUE_EMPTY:
224 /* Quit reading the queue if this is the last one */
225 break;
226 case TW_AEN_SYNC_TIME_WITH_HOST:
227 twa_aen_sync_time(tw_dev, request_id);
228 retval = 0;
229 goto out;
230 default:
231 twa_aen_queue_event(tw_dev, header);
233 /* If there are more aen's, keep reading the queue */
234 if (twa_aen_read_queue(tw_dev, request_id))
235 goto out2;
236 else {
237 retval = 0;
238 goto out;
241 retval = 0;
242 out2:
243 tw_dev->state[request_id] = TW_S_COMPLETED;
244 twa_free_request_id(tw_dev, request_id);
245 clear_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags);
246 out:
247 return retval;
248 } /* End twa_aen_complete() */
250 /* This function will drain aen queue */
251 static int twa_aen_drain_queue(TW_Device_Extension *tw_dev, int no_check_reset)
253 int request_id = 0;
254 char cdb[TW_MAX_CDB_LEN];
255 TW_SG_Entry sglist[1];
256 int finished = 0, count = 0;
257 TW_Command_Full *full_command_packet;
258 TW_Command_Apache_Header *header;
259 unsigned short aen;
260 int first_reset = 0, queue = 0, retval = 1;
262 if (no_check_reset)
263 first_reset = 0;
264 else
265 first_reset = 1;
267 full_command_packet = tw_dev->command_packet_virt[request_id];
268 memset(full_command_packet, 0, sizeof(TW_Command_Full));
270 /* Initialize cdb */
271 memset(&cdb, 0, TW_MAX_CDB_LEN);
272 cdb[0] = REQUEST_SENSE; /* opcode */
273 cdb[4] = TW_ALLOCATION_LENGTH; /* allocation length */
275 /* Initialize sglist */
276 memset(&sglist, 0, sizeof(TW_SG_Entry));
277 sglist[0].length = TW_SECTOR_SIZE;
278 sglist[0].address = tw_dev->generic_buffer_phys[request_id];
280 if (sglist[0].address & TW_ALIGNMENT_9000_SGL) {
281 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1, "Found unaligned address during AEN drain");
282 goto out;
285 /* Mark internal command */
286 tw_dev->srb[request_id] = NULL;
288 do {
289 /* Send command to the board */
290 if (twa_scsiop_execute_scsi(tw_dev, request_id, cdb, 1, sglist)) {
291 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2, "Error posting request sense");
292 goto out;
295 /* Now poll for completion */
296 if (twa_poll_response(tw_dev, request_id, 30)) {
297 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x3, "No valid response while draining AEN queue");
298 tw_dev->posted_request_count--;
299 goto out;
302 tw_dev->posted_request_count--;
303 header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id];
304 aen = header->status_block.error;
305 queue = 0;
306 count++;
308 switch (aen) {
309 case TW_AEN_QUEUE_EMPTY:
310 if (first_reset != 1)
311 goto out;
312 else
313 finished = 1;
314 break;
315 case TW_AEN_SOFT_RESET:
316 if (first_reset == 0)
317 first_reset = 1;
318 else
319 queue = 1;
320 break;
321 case TW_AEN_SYNC_TIME_WITH_HOST:
322 break;
323 default:
324 queue = 1;
327 /* Now queue an event info */
328 if (queue)
329 twa_aen_queue_event(tw_dev, header);
330 } while ((finished == 0) && (count < TW_MAX_AEN_DRAIN));
332 if (count == TW_MAX_AEN_DRAIN)
333 goto out;
335 retval = 0;
336 out:
337 tw_dev->state[request_id] = TW_S_INITIAL;
338 return retval;
339 } /* End twa_aen_drain_queue() */
341 /* This function will queue an event */
342 static void twa_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_Header *header)
344 u32 local_time;
345 struct timeval time;
346 TW_Event *event;
347 unsigned short aen;
348 char host[16];
349 char *error_str;
351 tw_dev->aen_count++;
353 /* Fill out event info */
354 event = tw_dev->event_queue[tw_dev->error_index];
356 /* Check for clobber */
357 host[0] = '\0';
358 if (tw_dev->host) {
359 sprintf(host, " scsi%d:", tw_dev->host->host_no);
360 if (event->retrieved == TW_AEN_NOT_RETRIEVED)
361 tw_dev->aen_clobber = 1;
364 aen = header->status_block.error;
365 memset(event, 0, sizeof(TW_Event));
367 event->severity = TW_SEV_OUT(header->status_block.severity__reserved);
368 do_gettimeofday(&time);
369 local_time = (u32)(time.tv_sec - (sys_tz.tz_minuteswest * 60));
370 event->time_stamp_sec = local_time;
371 event->aen_code = aen;
372 event->retrieved = TW_AEN_NOT_RETRIEVED;
373 event->sequence_id = tw_dev->error_sequence_id;
374 tw_dev->error_sequence_id++;
376 /* Check for embedded error string */
377 error_str = &(header->err_specific_desc[strlen(header->err_specific_desc)+1]);
379 header->err_specific_desc[sizeof(header->err_specific_desc) - 1] = '\0';
380 event->parameter_len = strlen(header->err_specific_desc);
381 memcpy(event->parameter_data, header->err_specific_desc, event->parameter_len);
382 if (event->severity != TW_AEN_SEVERITY_DEBUG)
383 printk(KERN_WARNING "3w-9xxx:%s AEN: %s (0x%02X:0x%04X): %s:%s.\n",
384 host,
385 twa_aen_severity_lookup(TW_SEV_OUT(header->status_block.severity__reserved)),
386 TW_MESSAGE_SOURCE_CONTROLLER_EVENT, aen,
387 error_str[0] == '\0' ? twa_string_lookup(twa_aen_table, aen) : error_str,
388 header->err_specific_desc);
389 else
390 tw_dev->aen_count--;
392 if ((tw_dev->error_index + 1) == TW_Q_LENGTH)
393 tw_dev->event_queue_wrapped = 1;
394 tw_dev->error_index = (tw_dev->error_index + 1 ) % TW_Q_LENGTH;
395 } /* End twa_aen_queue_event() */
397 /* This function will read the aen queue from the isr */
398 static int twa_aen_read_queue(TW_Device_Extension *tw_dev, int request_id)
400 char cdb[TW_MAX_CDB_LEN];
401 TW_SG_Entry sglist[1];
402 TW_Command_Full *full_command_packet;
403 int retval = 1;
405 full_command_packet = tw_dev->command_packet_virt[request_id];
406 memset(full_command_packet, 0, sizeof(TW_Command_Full));
408 /* Initialize cdb */
409 memset(&cdb, 0, TW_MAX_CDB_LEN);
410 cdb[0] = REQUEST_SENSE; /* opcode */
411 cdb[4] = TW_ALLOCATION_LENGTH; /* allocation length */
413 /* Initialize sglist */
414 memset(&sglist, 0, sizeof(TW_SG_Entry));
415 sglist[0].length = TW_SECTOR_SIZE;
416 sglist[0].address = tw_dev->generic_buffer_phys[request_id];
418 /* Mark internal command */
419 tw_dev->srb[request_id] = NULL;
421 /* Now post the command packet */
422 if (twa_scsiop_execute_scsi(tw_dev, request_id, cdb, 1, sglist)) {
423 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x4, "Post failed while reading AEN queue");
424 goto out;
426 retval = 0;
427 out:
428 return retval;
429 } /* End twa_aen_read_queue() */
431 /* This function will look up an AEN severity string */
432 static char *twa_aen_severity_lookup(unsigned char severity_code)
434 char *retval = NULL;
436 if ((severity_code < (unsigned char) TW_AEN_SEVERITY_ERROR) ||
437 (severity_code > (unsigned char) TW_AEN_SEVERITY_DEBUG))
438 goto out;
440 retval = twa_aen_severity_table[severity_code];
441 out:
442 return retval;
443 } /* End twa_aen_severity_lookup() */
445 /* This function will sync firmware time with the host time */
446 static void twa_aen_sync_time(TW_Device_Extension *tw_dev, int request_id)
448 u32 schedulertime;
449 struct timeval utc;
450 TW_Command_Full *full_command_packet;
451 TW_Command *command_packet;
452 TW_Param_Apache *param;
453 u32 local_time;
455 /* Fill out the command packet */
456 full_command_packet = tw_dev->command_packet_virt[request_id];
457 memset(full_command_packet, 0, sizeof(TW_Command_Full));
458 command_packet = &full_command_packet->command.oldcommand;
459 command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_SET_PARAM);
460 command_packet->request_id = request_id;
461 command_packet->byte8_offset.param.sgl[0].address = tw_dev->generic_buffer_phys[request_id];
462 command_packet->byte8_offset.param.sgl[0].length = TW_SECTOR_SIZE;
463 command_packet->size = TW_COMMAND_SIZE;
464 command_packet->byte6_offset.parameter_count = 1;
466 /* Setup the param */
467 param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id];
468 memset(param, 0, TW_SECTOR_SIZE);
469 param->table_id = TW_TIMEKEEP_TABLE | 0x8000; /* Controller time keep table */
470 param->parameter_id = 0x3; /* SchedulerTime */
471 param->parameter_size_bytes = 4;
473 /* Convert system time in UTC to local time seconds since last
474 Sunday 12:00AM */
475 do_gettimeofday(&utc);
476 local_time = (u32)(utc.tv_sec - (sys_tz.tz_minuteswest * 60));
477 schedulertime = local_time - (3 * 86400);
478 schedulertime = schedulertime % 604800;
480 memcpy(param->data, &schedulertime, sizeof(u32));
482 /* Mark internal command */
483 tw_dev->srb[request_id] = NULL;
485 /* Now post the command */
486 twa_post_command_packet(tw_dev, request_id, 1);
487 } /* End twa_aen_sync_time() */
489 /* This function will allocate memory and check if it is correctly aligned */
490 static int twa_allocate_memory(TW_Device_Extension *tw_dev, int size, int which)
492 int i;
493 dma_addr_t dma_handle;
494 unsigned long *cpu_addr;
495 int retval = 1;
497 cpu_addr = pci_alloc_consistent(tw_dev->tw_pci_dev, size*TW_Q_LENGTH, &dma_handle);
498 if (!cpu_addr) {
499 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x5, "Memory allocation failed");
500 goto out;
503 if ((unsigned long)cpu_addr % (TW_ALIGNMENT_9000)) {
504 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x6, "Failed to allocate correctly aligned memory");
505 pci_free_consistent(tw_dev->tw_pci_dev, size*TW_Q_LENGTH, cpu_addr, dma_handle);
506 goto out;
509 memset(cpu_addr, 0, size*TW_Q_LENGTH);
511 for (i = 0; i < TW_Q_LENGTH; i++) {
512 switch(which) {
513 case 0:
514 tw_dev->command_packet_phys[i] = dma_handle+(i*size);
515 tw_dev->command_packet_virt[i] = (TW_Command_Full *)((unsigned char *)cpu_addr + (i*size));
516 break;
517 case 1:
518 tw_dev->generic_buffer_phys[i] = dma_handle+(i*size);
519 tw_dev->generic_buffer_virt[i] = (unsigned long *)((unsigned char *)cpu_addr + (i*size));
520 break;
523 retval = 0;
524 out:
525 return retval;
526 } /* End twa_allocate_memory() */
528 /* This function will check the status register for unexpected bits */
529 static int twa_check_bits(u32 status_reg_value)
531 int retval = 1;
533 if ((status_reg_value & TW_STATUS_EXPECTED_BITS) != TW_STATUS_EXPECTED_BITS)
534 goto out;
535 if ((status_reg_value & TW_STATUS_UNEXPECTED_BITS) != 0)
536 goto out;
538 retval = 0;
539 out:
540 return retval;
541 } /* End twa_check_bits() */
543 /* This function will check the srl and decide if we are compatible */
544 static int twa_check_srl(TW_Device_Extension *tw_dev, int *flashed)
546 int retval = 1;
547 unsigned short fw_on_ctlr_srl = 0, fw_on_ctlr_arch_id = 0;
548 unsigned short fw_on_ctlr_branch = 0, fw_on_ctlr_build = 0;
549 u32 init_connect_result = 0;
551 if (twa_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS,
552 TW_EXTENDED_INIT_CONNECT, TW_CURRENT_DRIVER_SRL,
553 TW_9000_ARCH_ID, TW_CURRENT_DRIVER_BRANCH,
554 TW_CURRENT_DRIVER_BUILD, &fw_on_ctlr_srl,
555 &fw_on_ctlr_arch_id, &fw_on_ctlr_branch,
556 &fw_on_ctlr_build, &init_connect_result)) {
557 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x7, "Initconnection failed while checking SRL");
558 goto out;
561 tw_dev->working_srl = fw_on_ctlr_srl;
562 tw_dev->working_branch = fw_on_ctlr_branch;
563 tw_dev->working_build = fw_on_ctlr_build;
565 /* Try base mode compatibility */
566 if (!(init_connect_result & TW_CTLR_FW_COMPATIBLE)) {
567 if (twa_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS,
568 TW_EXTENDED_INIT_CONNECT,
569 TW_BASE_FW_SRL, TW_9000_ARCH_ID,
570 TW_BASE_FW_BRANCH, TW_BASE_FW_BUILD,
571 &fw_on_ctlr_srl, &fw_on_ctlr_arch_id,
572 &fw_on_ctlr_branch, &fw_on_ctlr_build,
573 &init_connect_result)) {
574 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xa, "Initconnection (base mode) failed while checking SRL");
575 goto out;
577 if (!(init_connect_result & TW_CTLR_FW_COMPATIBLE)) {
578 if (TW_CURRENT_DRIVER_SRL > fw_on_ctlr_srl) {
579 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x32, "Firmware and driver incompatibility: please upgrade firmware");
580 } else {
581 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x33, "Firmware and driver incompatibility: please upgrade driver");
583 goto out;
585 tw_dev->working_srl = TW_BASE_FW_SRL;
586 tw_dev->working_branch = TW_BASE_FW_BRANCH;
587 tw_dev->working_build = TW_BASE_FW_BUILD;
589 retval = 0;
590 out:
591 return retval;
592 } /* End twa_check_srl() */
594 /* This function handles ioctl for the character device */
595 static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
597 long timeout;
598 unsigned long *cpu_addr, data_buffer_length_adjusted = 0, flags = 0;
599 dma_addr_t dma_handle;
600 int request_id = 0;
601 unsigned int sequence_id = 0;
602 unsigned char event_index, start_index;
603 TW_Ioctl_Driver_Command driver_command;
604 TW_Ioctl_Buf_Apache *tw_ioctl;
605 TW_Lock *tw_lock;
606 TW_Command_Full *full_command_packet;
607 TW_Compatibility_Info *tw_compat_info;
608 TW_Event *event;
609 struct timeval current_time;
610 u32 current_time_ms;
611 TW_Device_Extension *tw_dev = twa_device_extension_list[iminor(inode)];
612 int retval = TW_IOCTL_ERROR_OS_EFAULT;
613 void __user *argp = (void __user *)arg;
615 /* Only let one of these through at a time */
616 if (down_interruptible(&tw_dev->ioctl_sem)) {
617 retval = TW_IOCTL_ERROR_OS_EINTR;
618 goto out;
621 /* First copy down the driver command */
622 if (copy_from_user(&driver_command, argp, sizeof(TW_Ioctl_Driver_Command)))
623 goto out2;
625 /* Check data buffer size */
626 if (driver_command.buffer_length > TW_MAX_SECTORS * 512) {
627 retval = TW_IOCTL_ERROR_OS_EINVAL;
628 goto out2;
631 /* Hardware can only do multiple of 512 byte transfers */
632 data_buffer_length_adjusted = (driver_command.buffer_length + 511) & ~511;
634 /* Now allocate ioctl buf memory */
635 cpu_addr = dma_alloc_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_Ioctl_Buf_Apache) - 1, &dma_handle, GFP_KERNEL);
636 if (!cpu_addr) {
637 retval = TW_IOCTL_ERROR_OS_ENOMEM;
638 goto out2;
641 tw_ioctl = (TW_Ioctl_Buf_Apache *)cpu_addr;
643 /* Now copy down the entire ioctl */
644 if (copy_from_user(tw_ioctl, argp, driver_command.buffer_length + sizeof(TW_Ioctl_Buf_Apache) - 1))
645 goto out3;
647 /* See which ioctl we are doing */
648 switch (cmd) {
649 case TW_IOCTL_FIRMWARE_PASS_THROUGH:
650 spin_lock_irqsave(tw_dev->host->host_lock, flags);
651 twa_get_request_id(tw_dev, &request_id);
653 /* Flag internal command */
654 tw_dev->srb[request_id] = NULL;
656 /* Flag chrdev ioctl */
657 tw_dev->chrdev_request_id = request_id;
659 full_command_packet = &tw_ioctl->firmware_command;
661 /* Load request id and sglist for both command types */
662 twa_load_sgl(full_command_packet, request_id, dma_handle, data_buffer_length_adjusted);
664 memcpy(tw_dev->command_packet_virt[request_id], &(tw_ioctl->firmware_command), sizeof(TW_Command_Full));
666 /* Now post the command packet to the controller */
667 twa_post_command_packet(tw_dev, request_id, 1);
668 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
670 timeout = TW_IOCTL_CHRDEV_TIMEOUT*HZ;
672 /* Now wait for command to complete */
673 timeout = wait_event_timeout(tw_dev->ioctl_wqueue, tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE, timeout);
675 /* See if we reset while waiting for the ioctl to complete */
676 if (test_bit(TW_IN_RESET, &tw_dev->flags)) {
677 clear_bit(TW_IN_RESET, &tw_dev->flags);
678 retval = TW_IOCTL_ERROR_OS_ERESTARTSYS;
679 goto out3;
682 /* We timed out, and didn't get an interrupt */
683 if (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE) {
684 /* Now we need to reset the board */
685 printk(KERN_WARNING "3w-9xxx: scsi%d: WARNING: (0x%02X:0x%04X): Character ioctl (0x%x) timed out, resetting card.\n",
686 tw_dev->host->host_no, TW_DRIVER, 0xc,
687 cmd);
688 retval = TW_IOCTL_ERROR_OS_EIO;
689 spin_lock_irqsave(tw_dev->host->host_lock, flags);
690 tw_dev->state[request_id] = TW_S_COMPLETED;
691 twa_free_request_id(tw_dev, request_id);
692 tw_dev->posted_request_count--;
693 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
694 twa_reset_device_extension(tw_dev, 1);
695 goto out3;
698 /* Now copy in the command packet response */
699 memcpy(&(tw_ioctl->firmware_command), tw_dev->command_packet_virt[request_id], sizeof(TW_Command_Full));
701 /* Now complete the io */
702 spin_lock_irqsave(tw_dev->host->host_lock, flags);
703 tw_dev->posted_request_count--;
704 tw_dev->state[request_id] = TW_S_COMPLETED;
705 twa_free_request_id(tw_dev, request_id);
706 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
707 break;
708 case TW_IOCTL_GET_COMPATIBILITY_INFO:
709 tw_ioctl->driver_command.status = 0;
710 /* Copy compatiblity struct into ioctl data buffer */
711 tw_compat_info = (TW_Compatibility_Info *)tw_ioctl->data_buffer;
712 strncpy(tw_compat_info->driver_version, TW_DRIVER_VERSION, strlen(TW_DRIVER_VERSION));
713 tw_compat_info->working_srl = tw_dev->working_srl;
714 tw_compat_info->working_branch = tw_dev->working_branch;
715 tw_compat_info->working_build = tw_dev->working_build;
716 tw_compat_info->driver_srl_high = TW_CURRENT_DRIVER_SRL;
717 tw_compat_info->driver_branch_high = TW_CURRENT_DRIVER_BRANCH;
718 tw_compat_info->driver_build_high = TW_CURRENT_DRIVER_BUILD;
719 tw_compat_info->driver_srl_low = TW_BASE_FW_SRL;
720 tw_compat_info->driver_branch_low = TW_BASE_FW_BRANCH;
721 tw_compat_info->driver_build_low = TW_BASE_FW_BUILD;
722 break;
723 case TW_IOCTL_GET_LAST_EVENT:
724 if (tw_dev->event_queue_wrapped) {
725 if (tw_dev->aen_clobber) {
726 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_AEN_CLOBBER;
727 tw_dev->aen_clobber = 0;
728 } else
729 tw_ioctl->driver_command.status = 0;
730 } else {
731 if (!tw_dev->error_index) {
732 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS;
733 break;
735 tw_ioctl->driver_command.status = 0;
737 event_index = (tw_dev->error_index - 1 + TW_Q_LENGTH) % TW_Q_LENGTH;
738 memcpy(tw_ioctl->data_buffer, tw_dev->event_queue[event_index], sizeof(TW_Event));
739 tw_dev->event_queue[event_index]->retrieved = TW_AEN_RETRIEVED;
740 break;
741 case TW_IOCTL_GET_FIRST_EVENT:
742 if (tw_dev->event_queue_wrapped) {
743 if (tw_dev->aen_clobber) {
744 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_AEN_CLOBBER;
745 tw_dev->aen_clobber = 0;
746 } else
747 tw_ioctl->driver_command.status = 0;
748 event_index = tw_dev->error_index;
749 } else {
750 if (!tw_dev->error_index) {
751 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS;
752 break;
754 tw_ioctl->driver_command.status = 0;
755 event_index = 0;
757 memcpy(tw_ioctl->data_buffer, tw_dev->event_queue[event_index], sizeof(TW_Event));
758 tw_dev->event_queue[event_index]->retrieved = TW_AEN_RETRIEVED;
759 break;
760 case TW_IOCTL_GET_NEXT_EVENT:
761 event = (TW_Event *)tw_ioctl->data_buffer;
762 sequence_id = event->sequence_id;
763 tw_ioctl->driver_command.status = 0;
765 if (tw_dev->event_queue_wrapped) {
766 if (tw_dev->aen_clobber) {
767 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_AEN_CLOBBER;
768 tw_dev->aen_clobber = 0;
770 start_index = tw_dev->error_index;
771 } else {
772 if (!tw_dev->error_index) {
773 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS;
774 break;
776 start_index = 0;
778 event_index = (start_index + sequence_id - tw_dev->event_queue[start_index]->sequence_id + 1) % TW_Q_LENGTH;
780 if (!(tw_dev->event_queue[event_index]->sequence_id > sequence_id)) {
781 if (tw_ioctl->driver_command.status == TW_IOCTL_ERROR_STATUS_AEN_CLOBBER)
782 tw_dev->aen_clobber = 1;
783 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS;
784 break;
786 memcpy(tw_ioctl->data_buffer, tw_dev->event_queue[event_index], sizeof(TW_Event));
787 tw_dev->event_queue[event_index]->retrieved = TW_AEN_RETRIEVED;
788 break;
789 case TW_IOCTL_GET_PREVIOUS_EVENT:
790 event = (TW_Event *)tw_ioctl->data_buffer;
791 sequence_id = event->sequence_id;
792 tw_ioctl->driver_command.status = 0;
794 if (tw_dev->event_queue_wrapped) {
795 if (tw_dev->aen_clobber) {
796 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_AEN_CLOBBER;
797 tw_dev->aen_clobber = 0;
799 start_index = tw_dev->error_index;
800 } else {
801 if (!tw_dev->error_index) {
802 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS;
803 break;
805 start_index = 0;
807 event_index = (start_index + sequence_id - tw_dev->event_queue[start_index]->sequence_id - 1) % TW_Q_LENGTH;
809 if (!(tw_dev->event_queue[event_index]->sequence_id < sequence_id)) {
810 if (tw_ioctl->driver_command.status == TW_IOCTL_ERROR_STATUS_AEN_CLOBBER)
811 tw_dev->aen_clobber = 1;
812 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS;
813 break;
815 memcpy(tw_ioctl->data_buffer, tw_dev->event_queue[event_index], sizeof(TW_Event));
816 tw_dev->event_queue[event_index]->retrieved = TW_AEN_RETRIEVED;
817 break;
818 case TW_IOCTL_GET_LOCK:
819 tw_lock = (TW_Lock *)tw_ioctl->data_buffer;
820 do_gettimeofday(&current_time);
821 current_time_ms = (current_time.tv_sec * 1000) + (current_time.tv_usec / 1000);
823 if ((tw_lock->force_flag == 1) || (tw_dev->ioctl_sem_lock == 0) || (current_time_ms >= tw_dev->ioctl_msec)) {
824 tw_dev->ioctl_sem_lock = 1;
825 tw_dev->ioctl_msec = current_time_ms + tw_lock->timeout_msec;
826 tw_ioctl->driver_command.status = 0;
827 tw_lock->time_remaining_msec = tw_lock->timeout_msec;
828 } else {
829 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_LOCKED;
830 tw_lock->time_remaining_msec = tw_dev->ioctl_msec - current_time_ms;
832 break;
833 case TW_IOCTL_RELEASE_LOCK:
834 if (tw_dev->ioctl_sem_lock == 1) {
835 tw_dev->ioctl_sem_lock = 0;
836 tw_ioctl->driver_command.status = 0;
837 } else {
838 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NOT_LOCKED;
840 break;
841 default:
842 retval = TW_IOCTL_ERROR_OS_ENOTTY;
843 goto out3;
846 /* Now copy the entire response to userspace */
847 if (copy_to_user(argp, tw_ioctl, sizeof(TW_Ioctl_Buf_Apache) + driver_command.buffer_length - 1) == 0)
848 retval = 0;
849 out3:
850 /* Now free ioctl buf memory */
851 dma_free_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_Ioctl_Buf_Apache) - 1, cpu_addr, dma_handle);
852 out2:
853 up(&tw_dev->ioctl_sem);
854 out:
855 return retval;
856 } /* End twa_chrdev_ioctl() */
858 /* This function handles open for the character device */
859 static int twa_chrdev_open(struct inode *inode, struct file *file)
861 unsigned int minor_number;
862 int retval = TW_IOCTL_ERROR_OS_ENODEV;
864 minor_number = iminor(inode);
865 if (minor_number >= twa_device_extension_count)
866 goto out;
867 retval = 0;
868 out:
869 return retval;
870 } /* End twa_chrdev_open() */
872 /* This function will print readable messages from status register errors */
873 static int twa_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value)
875 int retval = 1;
877 /* Check for various error conditions and handle them appropriately */
878 if (status_reg_value & TW_STATUS_PCI_PARITY_ERROR) {
879 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xc, "PCI Parity Error: clearing");
880 writel(TW_CONTROL_CLEAR_PARITY_ERROR, TW_CONTROL_REG_ADDR(tw_dev));
883 if (status_reg_value & TW_STATUS_PCI_ABORT) {
884 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xd, "PCI Abort: clearing");
885 writel(TW_CONTROL_CLEAR_PCI_ABORT, TW_CONTROL_REG_ADDR(tw_dev));
886 pci_write_config_word(tw_dev->tw_pci_dev, PCI_STATUS, TW_PCI_CLEAR_PCI_ABORT);
889 if (status_reg_value & TW_STATUS_QUEUE_ERROR) {
890 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xe, "Controller Queue Error: clearing");
891 writel(TW_CONTROL_CLEAR_QUEUE_ERROR, TW_CONTROL_REG_ADDR(tw_dev));
894 if (status_reg_value & TW_STATUS_SBUF_WRITE_ERROR) {
895 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xf, "SBUF Write Error: clearing");
896 writel(TW_CONTROL_CLEAR_SBUF_WRITE_ERROR, TW_CONTROL_REG_ADDR(tw_dev));
899 if (status_reg_value & TW_STATUS_MICROCONTROLLER_ERROR) {
900 if (tw_dev->reset_print == 0) {
901 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x10, "Microcontroller Error: clearing");
902 tw_dev->reset_print = 1;
904 goto out;
906 retval = 0;
907 out:
908 return retval;
909 } /* End twa_decode_bits() */
911 /* This function will empty the response queue */
912 static int twa_empty_response_queue(TW_Device_Extension *tw_dev)
914 u32 status_reg_value, response_que_value;
915 int count = 0, retval = 1;
917 status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
919 while (((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) && (count < TW_MAX_RESPONSE_DRAIN)) {
920 response_que_value = readl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
921 status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
922 count++;
924 if (count == TW_MAX_RESPONSE_DRAIN)
925 goto out;
927 retval = 0;
928 out:
929 return retval;
930 } /* End twa_empty_response_queue() */
932 /* This function passes sense keys from firmware to scsi layer */
933 static int twa_fill_sense(TW_Device_Extension *tw_dev, int request_id, int copy_sense, int print_host)
935 TW_Command_Full *full_command_packet;
936 unsigned short error;
937 int retval = 1;
938 char *error_str;
940 full_command_packet = tw_dev->command_packet_virt[request_id];
942 /* Check for embedded error string */
943 error_str = &(full_command_packet->header.err_specific_desc[strlen(full_command_packet->header.err_specific_desc) + 1]);
945 /* Don't print error for Logical unit not supported during rollcall */
946 error = full_command_packet->header.status_block.error;
947 if ((error != TW_ERROR_LOGICAL_UNIT_NOT_SUPPORTED) && (error != TW_ERROR_UNIT_OFFLINE)) {
948 if (print_host)
949 printk(KERN_WARNING "3w-9xxx: scsi%d: ERROR: (0x%02X:0x%04X): %s:%s.\n",
950 tw_dev->host->host_no,
951 TW_MESSAGE_SOURCE_CONTROLLER_ERROR,
952 full_command_packet->header.status_block.error,
953 error_str[0] == '\0' ?
954 twa_string_lookup(twa_error_table,
955 full_command_packet->header.status_block.error) : error_str,
956 full_command_packet->header.err_specific_desc);
957 else
958 printk(KERN_WARNING "3w-9xxx: ERROR: (0x%02X:0x%04X): %s:%s.\n",
959 TW_MESSAGE_SOURCE_CONTROLLER_ERROR,
960 full_command_packet->header.status_block.error,
961 error_str[0] == '\0' ?
962 twa_string_lookup(twa_error_table,
963 full_command_packet->header.status_block.error) : error_str,
964 full_command_packet->header.err_specific_desc);
967 if (copy_sense) {
968 memcpy(tw_dev->srb[request_id]->sense_buffer, full_command_packet->header.sense_data, TW_SENSE_DATA_LENGTH);
969 tw_dev->srb[request_id]->result = (full_command_packet->command.newcommand.status << 1);
970 retval = TW_ISR_DONT_RESULT;
971 goto out;
973 retval = 0;
974 out:
975 return retval;
976 } /* End twa_fill_sense() */
978 /* This function will free up device extension resources */
979 static void twa_free_device_extension(TW_Device_Extension *tw_dev)
981 if (tw_dev->command_packet_virt[0])
982 pci_free_consistent(tw_dev->tw_pci_dev,
983 sizeof(TW_Command_Full)*TW_Q_LENGTH,
984 tw_dev->command_packet_virt[0],
985 tw_dev->command_packet_phys[0]);
987 if (tw_dev->generic_buffer_virt[0])
988 pci_free_consistent(tw_dev->tw_pci_dev,
989 TW_SECTOR_SIZE*TW_Q_LENGTH,
990 tw_dev->generic_buffer_virt[0],
991 tw_dev->generic_buffer_phys[0]);
993 if (tw_dev->event_queue[0])
994 kfree(tw_dev->event_queue[0]);
995 } /* End twa_free_device_extension() */
997 /* This function will free a request id */
998 static void twa_free_request_id(TW_Device_Extension *tw_dev, int request_id)
1000 tw_dev->free_queue[tw_dev->free_tail] = request_id;
1001 tw_dev->state[request_id] = TW_S_FINISHED;
1002 tw_dev->free_tail = (tw_dev->free_tail + 1) % TW_Q_LENGTH;
1003 } /* End twa_free_request_id() */
1005 /* This function will get parameter table entires from the firmware */
1006 static void *twa_get_param(TW_Device_Extension *tw_dev, int request_id, int table_id, int parameter_id, int parameter_size_bytes)
1008 TW_Command_Full *full_command_packet;
1009 TW_Command *command_packet;
1010 TW_Param_Apache *param;
1011 unsigned long param_value;
1012 void *retval = NULL;
1014 /* Setup the command packet */
1015 full_command_packet = tw_dev->command_packet_virt[request_id];
1016 memset(full_command_packet, 0, sizeof(TW_Command_Full));
1017 command_packet = &full_command_packet->command.oldcommand;
1019 command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
1020 command_packet->size = TW_COMMAND_SIZE;
1021 command_packet->request_id = request_id;
1022 command_packet->byte6_offset.block_count = 1;
1024 /* Now setup the param */
1025 param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id];
1026 memset(param, 0, TW_SECTOR_SIZE);
1027 param->table_id = table_id | 0x8000;
1028 param->parameter_id = parameter_id;
1029 param->parameter_size_bytes = parameter_size_bytes;
1030 param_value = tw_dev->generic_buffer_phys[request_id];
1032 command_packet->byte8_offset.param.sgl[0].address = param_value;
1033 command_packet->byte8_offset.param.sgl[0].length = TW_SECTOR_SIZE;
1035 /* Post the command packet to the board */
1036 twa_post_command_packet(tw_dev, request_id, 1);
1038 /* Poll for completion */
1039 if (twa_poll_response(tw_dev, request_id, 30))
1040 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x13, "No valid response during get param")
1041 else
1042 retval = (void *)&(param->data[0]);
1044 tw_dev->posted_request_count--;
1045 tw_dev->state[request_id] = TW_S_INITIAL;
1047 return retval;
1048 } /* End twa_get_param() */
1050 /* This function will assign an available request id */
1051 static void twa_get_request_id(TW_Device_Extension *tw_dev, int *request_id)
1053 *request_id = tw_dev->free_queue[tw_dev->free_head];
1054 tw_dev->free_head = (tw_dev->free_head + 1) % TW_Q_LENGTH;
1055 tw_dev->state[*request_id] = TW_S_STARTED;
1056 } /* End twa_get_request_id() */
1058 /* This function will send an initconnection command to controller */
1059 static int twa_initconnection(TW_Device_Extension *tw_dev, int message_credits,
1060 u32 set_features, unsigned short current_fw_srl,
1061 unsigned short current_fw_arch_id,
1062 unsigned short current_fw_branch,
1063 unsigned short current_fw_build,
1064 unsigned short *fw_on_ctlr_srl,
1065 unsigned short *fw_on_ctlr_arch_id,
1066 unsigned short *fw_on_ctlr_branch,
1067 unsigned short *fw_on_ctlr_build,
1068 u32 *init_connect_result)
1070 TW_Command_Full *full_command_packet;
1071 TW_Initconnect *tw_initconnect;
1072 int request_id = 0, retval = 1;
1074 /* Initialize InitConnection command packet */
1075 full_command_packet = tw_dev->command_packet_virt[request_id];
1076 memset(full_command_packet, 0, sizeof(TW_Command_Full));
1077 full_command_packet->header.header_desc.size_header = 128;
1079 tw_initconnect = (TW_Initconnect *)&full_command_packet->command.oldcommand;
1080 tw_initconnect->opcode__reserved = TW_OPRES_IN(0, TW_OP_INIT_CONNECTION);
1081 tw_initconnect->request_id = request_id;
1082 tw_initconnect->message_credits = message_credits;
1083 tw_initconnect->features = set_features;
1085 /* Turn on 64-bit sgl support if we need to */
1086 tw_initconnect->features |= sizeof(dma_addr_t) > 4 ? 1 : 0;
1088 if (set_features & TW_EXTENDED_INIT_CONNECT) {
1089 tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE_EXTENDED;
1090 tw_initconnect->fw_srl = current_fw_srl;
1091 tw_initconnect->fw_arch_id = current_fw_arch_id;
1092 tw_initconnect->fw_branch = current_fw_branch;
1093 tw_initconnect->fw_build = current_fw_build;
1094 } else
1095 tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE;
1097 /* Send command packet to the board */
1098 twa_post_command_packet(tw_dev, request_id, 1);
1100 /* Poll for completion */
1101 if (twa_poll_response(tw_dev, request_id, 30)) {
1102 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x15, "No valid response during init connection");
1103 } else {
1104 if (set_features & TW_EXTENDED_INIT_CONNECT) {
1105 *fw_on_ctlr_srl = tw_initconnect->fw_srl;
1106 *fw_on_ctlr_arch_id = tw_initconnect->fw_arch_id;
1107 *fw_on_ctlr_branch = tw_initconnect->fw_branch;
1108 *fw_on_ctlr_build = tw_initconnect->fw_build;
1109 *init_connect_result = tw_initconnect->result;
1111 retval = 0;
1114 tw_dev->posted_request_count--;
1115 tw_dev->state[request_id] = TW_S_INITIAL;
1117 return retval;
1118 } /* End twa_initconnection() */
1120 /* This function will initialize the fields of a device extension */
1121 static int twa_initialize_device_extension(TW_Device_Extension *tw_dev)
1123 int i, retval = 1;
1125 /* Initialize command packet buffers */
1126 if (twa_allocate_memory(tw_dev, sizeof(TW_Command_Full), 0)) {
1127 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x16, "Command packet memory allocation failed");
1128 goto out;
1131 /* Initialize generic buffer */
1132 if (twa_allocate_memory(tw_dev, TW_SECTOR_SIZE, 1)) {
1133 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x17, "Generic memory allocation failed");
1134 goto out;
1137 /* Allocate event info space */
1138 tw_dev->event_queue[0] = kmalloc(sizeof(TW_Event) * TW_Q_LENGTH, GFP_KERNEL);
1139 if (!tw_dev->event_queue[0]) {
1140 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x18, "Event info memory allocation failed");
1141 goto out;
1144 memset(tw_dev->event_queue[0], 0, sizeof(TW_Event) * TW_Q_LENGTH);
1146 for (i = 0; i < TW_Q_LENGTH; i++) {
1147 tw_dev->event_queue[i] = (TW_Event *)((unsigned char *)tw_dev->event_queue[0] + (i * sizeof(TW_Event)));
1148 tw_dev->free_queue[i] = i;
1149 tw_dev->state[i] = TW_S_INITIAL;
1152 tw_dev->pending_head = TW_Q_START;
1153 tw_dev->pending_tail = TW_Q_START;
1154 tw_dev->free_head = TW_Q_START;
1155 tw_dev->free_tail = TW_Q_START;
1156 tw_dev->error_sequence_id = 1;
1157 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1159 init_MUTEX(&tw_dev->ioctl_sem);
1160 init_waitqueue_head(&tw_dev->ioctl_wqueue);
1162 retval = 0;
1163 out:
1164 return retval;
1165 } /* End twa_initialize_device_extension() */
1167 /* This function is the interrupt service routine */
1168 static irqreturn_t twa_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
1170 int request_id, error = 0;
1171 u32 status_reg_value;
1172 TW_Response_Queue response_que;
1173 TW_Command_Full *full_command_packet;
1174 TW_Command *command_packet;
1175 TW_Device_Extension *tw_dev = (TW_Device_Extension *)dev_instance;
1176 int handled = 0;
1178 /* Get the per adapter lock */
1179 spin_lock(tw_dev->host->host_lock);
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 handled = 1;
1190 /* Check controller for errors */
1191 if (twa_check_bits(status_reg_value)) {
1192 if (twa_decode_bits(tw_dev, status_reg_value)) {
1193 TW_CLEAR_ALL_INTERRUPTS(tw_dev);
1194 goto twa_interrupt_bail;
1198 /* Handle host interrupt */
1199 if (status_reg_value & TW_STATUS_HOST_INTERRUPT)
1200 TW_CLEAR_HOST_INTERRUPT(tw_dev);
1202 /* Handle attention interrupt */
1203 if (status_reg_value & TW_STATUS_ATTENTION_INTERRUPT) {
1204 TW_CLEAR_ATTENTION_INTERRUPT(tw_dev);
1205 if (!(test_and_set_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags))) {
1206 twa_get_request_id(tw_dev, &request_id);
1208 error = twa_aen_read_queue(tw_dev, request_id);
1209 if (error) {
1210 tw_dev->state[request_id] = TW_S_COMPLETED;
1211 twa_free_request_id(tw_dev, request_id);
1212 clear_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags);
1217 /* Handle command interrupt */
1218 if (status_reg_value & TW_STATUS_COMMAND_INTERRUPT) {
1219 TW_MASK_COMMAND_INTERRUPT(tw_dev);
1220 /* Drain as many pending commands as we can */
1221 while (tw_dev->pending_request_count > 0) {
1222 request_id = tw_dev->pending_queue[tw_dev->pending_head];
1223 if (tw_dev->state[request_id] != TW_S_PENDING) {
1224 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x19, "Found request id that wasn't pending");
1225 TW_CLEAR_ALL_INTERRUPTS(tw_dev);
1226 goto twa_interrupt_bail;
1228 if (twa_post_command_packet(tw_dev, request_id, 1)==0) {
1229 tw_dev->pending_head = (tw_dev->pending_head + 1) % TW_Q_LENGTH;
1230 tw_dev->pending_request_count--;
1231 } else {
1232 /* If we get here, we will continue re-posting on the next command interrupt */
1233 break;
1238 /* Handle response interrupt */
1239 if (status_reg_value & TW_STATUS_RESPONSE_INTERRUPT) {
1241 /* Drain the response queue from the board */
1242 while ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
1243 /* Complete the response */
1244 response_que.value = readl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
1245 request_id = TW_RESID_OUT(response_que.response_id);
1246 full_command_packet = tw_dev->command_packet_virt[request_id];
1247 error = 0;
1248 command_packet = &full_command_packet->command.oldcommand;
1249 /* Check for command packet errors */
1250 if (full_command_packet->command.newcommand.status != 0) {
1251 if (tw_dev->srb[request_id] != 0) {
1252 error = twa_fill_sense(tw_dev, request_id, 1, 1);
1253 } else {
1254 /* Skip ioctl error prints */
1255 if (request_id != tw_dev->chrdev_request_id) {
1256 error = twa_fill_sense(tw_dev, request_id, 0, 1);
1261 /* Check for correct state */
1262 if (tw_dev->state[request_id] != TW_S_POSTED) {
1263 if (tw_dev->srb[request_id] != 0) {
1264 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1a, "Received a request id that wasn't posted");
1265 TW_CLEAR_ALL_INTERRUPTS(tw_dev);
1266 goto twa_interrupt_bail;
1270 /* Check for internal command completion */
1271 if (tw_dev->srb[request_id] == 0) {
1272 if (request_id != tw_dev->chrdev_request_id) {
1273 if (twa_aen_complete(tw_dev, request_id))
1274 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1b, "Error completing AEN during attention interrupt");
1275 } else {
1276 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1277 wake_up(&tw_dev->ioctl_wqueue);
1279 } else {
1280 twa_scsiop_execute_scsi_complete(tw_dev, request_id);
1281 /* If no error command was a success */
1282 if (error == 0) {
1283 tw_dev->srb[request_id]->result = (DID_OK << 16);
1286 /* If error, command failed */
1287 if (error == 1) {
1288 /* Ask for a host reset */
1289 tw_dev->srb[request_id]->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
1292 /* Report residual bytes for single sgl */
1293 if ((tw_dev->srb[request_id]->use_sg <= 1) && (full_command_packet->command.newcommand.status == 0)) {
1294 if (full_command_packet->command.newcommand.sg_list[0].length < tw_dev->srb[request_id]->request_bufflen)
1295 tw_dev->srb[request_id]->resid = tw_dev->srb[request_id]->request_bufflen - full_command_packet->command.newcommand.sg_list[0].length;
1298 /* Now complete the io */
1299 tw_dev->state[request_id] = TW_S_COMPLETED;
1300 twa_free_request_id(tw_dev, request_id);
1301 tw_dev->posted_request_count--;
1302 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1303 twa_unmap_scsi_data(tw_dev, request_id);
1306 /* Check for valid status after each drain */
1307 status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
1308 if (twa_check_bits(status_reg_value)) {
1309 if (twa_decode_bits(tw_dev, status_reg_value)) {
1310 TW_CLEAR_ALL_INTERRUPTS(tw_dev);
1311 goto twa_interrupt_bail;
1317 twa_interrupt_bail:
1318 spin_unlock(tw_dev->host->host_lock);
1319 return IRQ_RETVAL(handled);
1320 } /* End twa_interrupt() */
1322 /* This function will load the request id and various sgls for ioctls */
1323 static void twa_load_sgl(TW_Command_Full *full_command_packet, int request_id, dma_addr_t dma_handle, int length)
1325 TW_Command *oldcommand;
1326 TW_Command_Apache *newcommand;
1327 TW_SG_Entry *sgl;
1329 if (TW_OP_OUT(full_command_packet->command.newcommand.opcode__reserved) == TW_OP_EXECUTE_SCSI) {
1330 newcommand = &full_command_packet->command.newcommand;
1331 newcommand->request_id__lunl =
1332 TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->request_id__lunl), request_id);
1333 newcommand->sg_list[0].address = dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1;
1334 newcommand->sg_list[0].length = length;
1335 newcommand->sgl_entries__lunh =
1336 TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->sgl_entries__lunh), 1);
1337 } else {
1338 oldcommand = &full_command_packet->command.oldcommand;
1339 oldcommand->request_id = request_id;
1341 if (TW_SGL_OUT(oldcommand->opcode__sgloffset)) {
1342 /* Load the sg list */
1343 sgl = (TW_SG_Entry *)((u32 *)oldcommand+TW_SGL_OUT(oldcommand->opcode__sgloffset));
1344 sgl->address = dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1;
1345 sgl->length = length;
1347 if ((sizeof(long) < 8) && (sizeof(dma_addr_t) > 4))
1348 oldcommand->size += 1;
1351 } /* End twa_load_sgl() */
1353 /* This function will perform a pci-dma mapping for a scatter gather list */
1354 static int twa_map_scsi_sg_data(TW_Device_Extension *tw_dev, int request_id)
1356 int use_sg;
1357 struct scsi_cmnd *cmd = tw_dev->srb[request_id];
1358 struct pci_dev *pdev = tw_dev->tw_pci_dev;
1359 int retval = 0;
1361 if (cmd->use_sg == 0)
1362 goto out;
1364 use_sg = pci_map_sg(pdev, cmd->buffer, cmd->use_sg, DMA_BIDIRECTIONAL);
1366 if (use_sg == 0) {
1367 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1c, "Failed to map scatter gather list");
1368 goto out;
1371 cmd->SCp.phase = TW_PHASE_SGLIST;
1372 cmd->SCp.have_data_in = use_sg;
1373 retval = use_sg;
1374 out:
1375 return retval;
1376 } /* End twa_map_scsi_sg_data() */
1378 /* This function will perform a pci-dma map for a single buffer */
1379 static dma_addr_t twa_map_scsi_single_data(TW_Device_Extension *tw_dev, int request_id)
1381 dma_addr_t mapping;
1382 struct scsi_cmnd *cmd = tw_dev->srb[request_id];
1383 struct pci_dev *pdev = tw_dev->tw_pci_dev;
1384 int retval = 0;
1386 if (cmd->request_bufflen == 0) {
1387 retval = 0;
1388 goto out;
1391 mapping = pci_map_single(pdev, cmd->request_buffer, cmd->request_bufflen, DMA_BIDIRECTIONAL);
1393 if (mapping == 0) {
1394 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1d, "Failed to map page");
1395 goto out;
1398 cmd->SCp.phase = TW_PHASE_SINGLE;
1399 cmd->SCp.have_data_in = mapping;
1400 retval = mapping;
1401 out:
1402 return retval;
1403 } /* End twa_map_scsi_single_data() */
1405 /* This function will poll for a response interrupt of a request */
1406 static int twa_poll_response(TW_Device_Extension *tw_dev, int request_id, int seconds)
1408 int retval = 1, found = 0, response_request_id;
1409 TW_Response_Queue response_queue;
1410 TW_Command_Full *full_command_packet = tw_dev->command_packet_virt[request_id];
1412 if (twa_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, seconds) == 0) {
1413 response_queue.value = readl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
1414 response_request_id = TW_RESID_OUT(response_queue.response_id);
1415 if (request_id != response_request_id) {
1416 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1e, "Found unexpected request id while polling for response");
1417 goto out;
1419 if (TW_OP_OUT(full_command_packet->command.newcommand.opcode__reserved) == TW_OP_EXECUTE_SCSI) {
1420 if (full_command_packet->command.newcommand.status != 0) {
1421 /* bad response */
1422 twa_fill_sense(tw_dev, request_id, 0, 0);
1423 goto out;
1425 found = 1;
1426 } else {
1427 if (full_command_packet->command.oldcommand.status != 0) {
1428 /* bad response */
1429 twa_fill_sense(tw_dev, request_id, 0, 0);
1430 goto out;
1432 found = 1;
1436 if (found)
1437 retval = 0;
1438 out:
1439 return retval;
1440 } /* End twa_poll_response() */
1442 /* This function will poll the status register for a flag */
1443 static int twa_poll_status(TW_Device_Extension *tw_dev, u32 flag, int seconds)
1445 u32 status_reg_value;
1446 unsigned long before;
1447 int retval = 1;
1449 status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
1450 before = jiffies;
1452 if (twa_check_bits(status_reg_value))
1453 twa_decode_bits(tw_dev, status_reg_value);
1455 while ((status_reg_value & flag) != flag) {
1456 status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
1458 if (twa_check_bits(status_reg_value))
1459 twa_decode_bits(tw_dev, status_reg_value);
1461 if (time_after(jiffies, before + HZ * seconds))
1462 goto out;
1464 msleep(50);
1466 retval = 0;
1467 out:
1468 return retval;
1469 } /* End twa_poll_status() */
1471 /* This function will poll the status register for disappearance of a flag */
1472 static int twa_poll_status_gone(TW_Device_Extension *tw_dev, u32 flag, int seconds)
1474 u32 status_reg_value;
1475 unsigned long before;
1476 int retval = 1;
1478 status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
1479 before = jiffies;
1481 if (twa_check_bits(status_reg_value))
1482 twa_decode_bits(tw_dev, status_reg_value);
1484 while ((status_reg_value & flag) != 0) {
1485 status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
1486 if (twa_check_bits(status_reg_value))
1487 twa_decode_bits(tw_dev, status_reg_value);
1489 if (time_after(jiffies, before + HZ * seconds))
1490 goto out;
1492 msleep(50);
1494 retval = 0;
1495 out:
1496 return retval;
1497 } /* End twa_poll_status_gone() */
1499 /* This function will attempt to post a command packet to the board */
1500 static int twa_post_command_packet(TW_Device_Extension *tw_dev, int request_id, char internal)
1502 u32 status_reg_value;
1503 dma_addr_t command_que_value;
1504 int retval = 1;
1506 command_que_value = tw_dev->command_packet_phys[request_id];
1507 status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
1509 if (twa_check_bits(status_reg_value))
1510 twa_decode_bits(tw_dev, status_reg_value);
1512 if (((tw_dev->pending_request_count > 0) && (tw_dev->state[request_id] != TW_S_PENDING)) || (status_reg_value & TW_STATUS_COMMAND_QUEUE_FULL)) {
1514 /* Only pend internal driver commands */
1515 if (!internal) {
1516 retval = SCSI_MLQUEUE_HOST_BUSY;
1517 goto out;
1520 /* Couldn't post the command packet, so we do it later */
1521 if (tw_dev->state[request_id] != TW_S_PENDING) {
1522 tw_dev->state[request_id] = TW_S_PENDING;
1523 tw_dev->pending_request_count++;
1524 if (tw_dev->pending_request_count > tw_dev->max_pending_request_count) {
1525 tw_dev->max_pending_request_count = tw_dev->pending_request_count;
1527 tw_dev->pending_queue[tw_dev->pending_tail] = request_id;
1528 tw_dev->pending_tail = (tw_dev->pending_tail + 1) % TW_Q_LENGTH;
1530 TW_UNMASK_COMMAND_INTERRUPT(tw_dev);
1531 goto out;
1532 } else {
1533 /* We successfully posted the command packet */
1534 if (sizeof(dma_addr_t) > 4) {
1535 command_que_value += TW_COMMAND_OFFSET;
1536 writel((u32)command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
1537 writel((u32)((u64)command_que_value >> 32), TW_COMMAND_QUEUE_REG_ADDR(tw_dev) + 0x4);
1538 } else {
1539 writel(TW_COMMAND_OFFSET + command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
1541 tw_dev->state[request_id] = TW_S_POSTED;
1542 tw_dev->posted_request_count++;
1543 if (tw_dev->posted_request_count > tw_dev->max_posted_request_count) {
1544 tw_dev->max_posted_request_count = tw_dev->posted_request_count;
1547 retval = 0;
1548 out:
1549 return retval;
1550 } /* End twa_post_command_packet() */
1552 /* This function will reset a device extension */
1553 static int twa_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_reset)
1555 int i = 0;
1556 int retval = 1;
1557 unsigned long flags = 0;
1559 set_bit(TW_IN_RESET, &tw_dev->flags);
1560 TW_DISABLE_INTERRUPTS(tw_dev);
1561 TW_MASK_COMMAND_INTERRUPT(tw_dev);
1562 spin_lock_irqsave(tw_dev->host->host_lock, flags);
1564 /* Abort all requests that are in progress */
1565 for (i = 0; i < TW_Q_LENGTH; i++) {
1566 if ((tw_dev->state[i] != TW_S_FINISHED) &&
1567 (tw_dev->state[i] != TW_S_INITIAL) &&
1568 (tw_dev->state[i] != TW_S_COMPLETED)) {
1569 if (tw_dev->srb[i]) {
1570 tw_dev->srb[i]->result = (DID_RESET << 16);
1571 tw_dev->srb[i]->scsi_done(tw_dev->srb[i]);
1572 twa_unmap_scsi_data(tw_dev, i);
1577 /* Reset queues and counts */
1578 for (i = 0; i < TW_Q_LENGTH; i++) {
1579 tw_dev->free_queue[i] = i;
1580 tw_dev->state[i] = TW_S_INITIAL;
1582 tw_dev->free_head = TW_Q_START;
1583 tw_dev->free_tail = TW_Q_START;
1584 tw_dev->posted_request_count = 0;
1585 tw_dev->pending_request_count = 0;
1586 tw_dev->pending_head = TW_Q_START;
1587 tw_dev->pending_tail = TW_Q_START;
1588 tw_dev->reset_print = 0;
1590 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
1592 if (twa_reset_sequence(tw_dev, 1))
1593 goto out;
1595 TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
1597 /* Wake up any ioctl that was pending before the reset */
1598 if ((tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE) || (ioctl_reset)) {
1599 clear_bit(TW_IN_RESET, &tw_dev->flags);
1600 } else {
1601 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1602 wake_up(&tw_dev->ioctl_wqueue);
1604 retval = 0;
1605 out:
1606 return retval;
1607 } /* End twa_reset_device_extension() */
1609 /* This function will reset a controller */
1610 static int twa_reset_sequence(TW_Device_Extension *tw_dev, int soft_reset)
1612 int tries = 0, retval = 1, flashed = 0, do_soft_reset = soft_reset;
1614 while (tries < TW_MAX_RESET_TRIES) {
1615 if (do_soft_reset)
1616 TW_SOFT_RESET(tw_dev);
1618 /* Make sure controller is in a good state */
1619 if (twa_poll_status(tw_dev, TW_STATUS_MICROCONTROLLER_READY | (do_soft_reset == 1 ? TW_STATUS_ATTENTION_INTERRUPT : 0), 60)) {
1620 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1f, "Microcontroller not ready during reset sequence");
1621 do_soft_reset = 1;
1622 tries++;
1623 continue;
1626 /* Empty response queue */
1627 if (twa_empty_response_queue(tw_dev)) {
1628 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x20, "Response queue empty failed during reset sequence");
1629 do_soft_reset = 1;
1630 tries++;
1631 continue;
1634 flashed = 0;
1636 /* Check for compatibility/flash */
1637 if (twa_check_srl(tw_dev, &flashed)) {
1638 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x21, "Compatibility check failed during reset sequence");
1639 do_soft_reset = 1;
1640 tries++;
1641 continue;
1642 } else {
1643 if (flashed) {
1644 tries++;
1645 continue;
1649 /* Drain the AEN queue */
1650 if (twa_aen_drain_queue(tw_dev, soft_reset)) {
1651 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x22, "AEN drain failed during reset sequence");
1652 do_soft_reset = 1;
1653 tries++;
1654 continue;
1657 /* If we got here, controller is in a good state */
1658 retval = 0;
1659 goto out;
1661 out:
1662 return retval;
1663 } /* End twa_reset_sequence() */
1665 /* This funciton returns unit geometry in cylinders/heads/sectors */
1666 static int twa_scsi_biosparam(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int geom[])
1668 int heads, sectors, cylinders;
1669 TW_Device_Extension *tw_dev;
1671 tw_dev = (TW_Device_Extension *)sdev->host->hostdata;
1673 if (capacity >= 0x200000) {
1674 heads = 255;
1675 sectors = 63;
1676 cylinders = sector_div(capacity, heads * sectors);
1677 } else {
1678 heads = 64;
1679 sectors = 32;
1680 cylinders = sector_div(capacity, heads * sectors);
1683 geom[0] = heads;
1684 geom[1] = sectors;
1685 geom[2] = cylinders;
1687 return 0;
1688 } /* End twa_scsi_biosparam() */
1690 /* This is the new scsi eh reset function */
1691 static int twa_scsi_eh_reset(struct scsi_cmnd *SCpnt)
1693 TW_Device_Extension *tw_dev = NULL;
1694 int retval = FAILED;
1696 tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
1698 spin_unlock_irq(tw_dev->host->host_lock);
1700 tw_dev->num_resets++;
1702 printk(KERN_WARNING "3w-9xxx: scsi%d: WARNING: (0x%02X:0x%04X): Unit #%d: Command (0x%x) timed out, resetting card.\n", tw_dev->host->host_no, TW_DRIVER, 0x2c, SCpnt->device->id, SCpnt->cmnd[0]);
1704 /* Now reset the card and some of the device extension data */
1705 if (twa_reset_device_extension(tw_dev, 0)) {
1706 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2b, "Controller reset failed during scsi host reset");
1707 goto out;
1710 retval = SUCCESS;
1711 out:
1712 spin_lock_irq(tw_dev->host->host_lock);
1713 return retval;
1714 } /* End twa_scsi_eh_reset() */
1716 /* This is the main scsi queue function to handle scsi opcodes */
1717 static int twa_scsi_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1719 int request_id, retval;
1720 TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
1722 /* Check if this FW supports luns */
1723 if ((SCpnt->device->lun != 0) && (tw_dev->working_srl < TW_FW_SRL_LUNS_SUPPORTED)) {
1724 SCpnt->result = (DID_BAD_TARGET << 16);
1725 done(SCpnt);
1726 retval = 0;
1727 goto out;
1730 /* Save done function into scsi_cmnd struct */
1731 SCpnt->scsi_done = done;
1733 /* Get a free request id */
1734 twa_get_request_id(tw_dev, &request_id);
1736 /* Save the scsi command for use by the ISR */
1737 tw_dev->srb[request_id] = SCpnt;
1739 /* Initialize phase to zero */
1740 SCpnt->SCp.phase = TW_PHASE_INITIAL;
1742 retval = twa_scsiop_execute_scsi(tw_dev, request_id, NULL, 0, NULL);
1743 switch (retval) {
1744 case SCSI_MLQUEUE_HOST_BUSY:
1745 twa_free_request_id(tw_dev, request_id);
1746 break;
1747 case 1:
1748 tw_dev->state[request_id] = TW_S_COMPLETED;
1749 twa_free_request_id(tw_dev, request_id);
1750 SCpnt->result = (DID_ERROR << 16);
1751 done(SCpnt);
1752 retval = 0;
1754 out:
1755 return retval;
1756 } /* End twa_scsi_queue() */
1758 /* This function hands scsi cdb's to the firmware */
1759 static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, char *cdb, int use_sg, TW_SG_Entry *sglistarg)
1761 TW_Command_Full *full_command_packet;
1762 TW_Command_Apache *command_packet;
1763 u32 num_sectors = 0x0;
1764 int i, sg_count;
1765 struct scsi_cmnd *srb = NULL;
1766 struct scatterlist *sglist = NULL;
1767 u32 buffaddr = 0x0;
1768 int retval = 1;
1770 if (tw_dev->srb[request_id]) {
1771 if (tw_dev->srb[request_id]->request_buffer) {
1772 sglist = (struct scatterlist *)tw_dev->srb[request_id]->request_buffer;
1774 srb = tw_dev->srb[request_id];
1777 /* Initialize command packet */
1778 full_command_packet = tw_dev->command_packet_virt[request_id];
1779 full_command_packet->header.header_desc.size_header = 128;
1780 full_command_packet->header.status_block.error = 0;
1781 full_command_packet->header.status_block.severity__reserved = 0;
1783 command_packet = &full_command_packet->command.newcommand;
1784 command_packet->status = 0;
1785 command_packet->opcode__reserved = TW_OPRES_IN(0, TW_OP_EXECUTE_SCSI);
1787 /* We forced 16 byte cdb use earlier */
1788 if (!cdb)
1789 memcpy(command_packet->cdb, srb->cmnd, TW_MAX_CDB_LEN);
1790 else
1791 memcpy(command_packet->cdb, cdb, TW_MAX_CDB_LEN);
1793 if (srb) {
1794 command_packet->unit = srb->device->id;
1795 command_packet->request_id__lunl =
1796 TW_REQ_LUN_IN(srb->device->lun, request_id);
1797 } else {
1798 command_packet->request_id__lunl =
1799 TW_REQ_LUN_IN(0, request_id);
1800 command_packet->unit = 0;
1803 command_packet->sgl_offset = 16;
1805 if (!sglistarg) {
1806 /* Map sglist from scsi layer to cmd packet */
1807 if (tw_dev->srb[request_id]->use_sg == 0) {
1808 if (tw_dev->srb[request_id]->request_bufflen < TW_MIN_SGL_LENGTH) {
1809 command_packet->sg_list[0].address = tw_dev->generic_buffer_phys[request_id];
1810 command_packet->sg_list[0].length = TW_MIN_SGL_LENGTH;
1811 } else {
1812 buffaddr = twa_map_scsi_single_data(tw_dev, request_id);
1813 if (buffaddr == 0)
1814 goto out;
1816 command_packet->sg_list[0].address = buffaddr;
1817 command_packet->sg_list[0].length = tw_dev->srb[request_id]->request_bufflen;
1819 command_packet->sgl_entries__lunh = TW_REQ_LUN_IN((srb->device->lun >> 4), 1);
1821 if (command_packet->sg_list[0].address & TW_ALIGNMENT_9000_SGL) {
1822 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2d, "Found unaligned address during execute scsi");
1823 goto out;
1827 if (tw_dev->srb[request_id]->use_sg > 0) {
1828 if ((tw_dev->srb[request_id]->use_sg == 1) && (tw_dev->srb[request_id]->request_bufflen < TW_MIN_SGL_LENGTH)) {
1829 command_packet->sg_list[0].address = tw_dev->generic_buffer_phys[request_id];
1830 command_packet->sg_list[0].length = TW_MIN_SGL_LENGTH;
1831 } else {
1832 sg_count = twa_map_scsi_sg_data(tw_dev, request_id);
1833 if (sg_count == 0)
1834 goto out;
1836 for (i = 0; i < sg_count; i++) {
1837 command_packet->sg_list[i].address = sg_dma_address(&sglist[i]);
1838 command_packet->sg_list[i].length = sg_dma_len(&sglist[i]);
1839 if (command_packet->sg_list[i].address & TW_ALIGNMENT_9000_SGL) {
1840 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2e, "Found unaligned sgl address during execute scsi");
1841 goto out;
1845 command_packet->sgl_entries__lunh = TW_REQ_LUN_IN((srb->device->lun >> 4), tw_dev->srb[request_id]->use_sg);
1847 } else {
1848 /* Internal cdb post */
1849 for (i = 0; i < use_sg; i++) {
1850 command_packet->sg_list[i].address = sglistarg[i].address;
1851 command_packet->sg_list[i].length = sglistarg[i].length;
1852 if (command_packet->sg_list[i].address & TW_ALIGNMENT_9000_SGL) {
1853 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2f, "Found unaligned sgl address during internal post");
1854 goto out;
1857 command_packet->sgl_entries__lunh = TW_REQ_LUN_IN(0, use_sg);
1860 if (srb) {
1861 if (srb->cmnd[0] == READ_6 || srb->cmnd[0] == WRITE_6)
1862 num_sectors = (u32)srb->cmnd[4];
1864 if (srb->cmnd[0] == READ_10 || srb->cmnd[0] == WRITE_10)
1865 num_sectors = (u32)srb->cmnd[8] | ((u32)srb->cmnd[7] << 8);
1868 /* Update sector statistic */
1869 tw_dev->sector_count = num_sectors;
1870 if (tw_dev->sector_count > tw_dev->max_sector_count)
1871 tw_dev->max_sector_count = tw_dev->sector_count;
1873 /* Update SG statistics */
1874 if (srb) {
1875 tw_dev->sgl_entries = tw_dev->srb[request_id]->use_sg;
1876 if (tw_dev->sgl_entries > tw_dev->max_sgl_entries)
1877 tw_dev->max_sgl_entries = tw_dev->sgl_entries;
1880 /* Now post the command to the board */
1881 if (srb) {
1882 retval = twa_post_command_packet(tw_dev, request_id, 0);
1883 } else {
1884 twa_post_command_packet(tw_dev, request_id, 1);
1885 retval = 0;
1887 out:
1888 return retval;
1889 } /* End twa_scsiop_execute_scsi() */
1891 /* This function completes an execute scsi operation */
1892 static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int request_id)
1894 /* Copy the response if too small */
1895 if ((tw_dev->srb[request_id]->request_buffer) && (tw_dev->srb[request_id]->request_bufflen < TW_MIN_SGL_LENGTH)) {
1896 memcpy(tw_dev->srb[request_id]->request_buffer,
1897 tw_dev->generic_buffer_virt[request_id],
1898 tw_dev->srb[request_id]->request_bufflen);
1900 } /* End twa_scsiop_execute_scsi_complete() */
1902 /* This function tells the controller to shut down */
1903 static void __twa_shutdown(TW_Device_Extension *tw_dev)
1905 /* Disable interrupts */
1906 TW_DISABLE_INTERRUPTS(tw_dev);
1908 printk(KERN_WARNING "3w-9xxx: Shutting down host %d.\n", tw_dev->host->host_no);
1910 /* Tell the card we are shutting down */
1911 if (twa_initconnection(tw_dev, 1, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL)) {
1912 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x31, "Connection shutdown failed");
1913 } else {
1914 printk(KERN_WARNING "3w-9xxx: Shutdown complete.\n");
1917 /* Clear all interrupts just before exit */
1918 TW_CLEAR_ALL_INTERRUPTS(tw_dev);
1919 } /* End __twa_shutdown() */
1921 /* Wrapper for __twa_shutdown */
1922 static void twa_shutdown(struct device *dev)
1924 struct Scsi_Host *host = pci_get_drvdata(to_pci_dev(dev));
1925 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
1927 __twa_shutdown(tw_dev);
1928 } /* End twa_shutdown() */
1930 /* This function will look up a string */
1931 static char *twa_string_lookup(twa_message_type *table, unsigned int code)
1933 int index;
1935 for (index = 0; ((code != table[index].code) &&
1936 (table[index].text != (char *)0)); index++);
1937 return(table[index].text);
1938 } /* End twa_string_lookup() */
1940 /* This function will perform a pci-dma unmap */
1941 static void twa_unmap_scsi_data(TW_Device_Extension *tw_dev, int request_id)
1943 struct scsi_cmnd *cmd = tw_dev->srb[request_id];
1944 struct pci_dev *pdev = tw_dev->tw_pci_dev;
1946 switch(cmd->SCp.phase) {
1947 case TW_PHASE_SINGLE:
1948 pci_unmap_single(pdev, cmd->SCp.have_data_in, cmd->request_bufflen, DMA_BIDIRECTIONAL);
1949 break;
1950 case TW_PHASE_SGLIST:
1951 pci_unmap_sg(pdev, cmd->request_buffer, cmd->use_sg, DMA_BIDIRECTIONAL);
1952 break;
1954 } /* End twa_unmap_scsi_data() */
1956 /* scsi_host_template initializer */
1957 static struct scsi_host_template driver_template = {
1958 .module = THIS_MODULE,
1959 .name = "3ware 9000 Storage Controller",
1960 .queuecommand = twa_scsi_queue,
1961 .eh_host_reset_handler = twa_scsi_eh_reset,
1962 .bios_param = twa_scsi_biosparam,
1963 .change_queue_depth = twa_change_queue_depth,
1964 .can_queue = TW_Q_LENGTH-2,
1965 .this_id = -1,
1966 .sg_tablesize = TW_APACHE_MAX_SGL_LENGTH,
1967 .max_sectors = TW_MAX_SECTORS,
1968 .cmd_per_lun = TW_MAX_CMDS_PER_LUN,
1969 .use_clustering = ENABLE_CLUSTERING,
1970 .shost_attrs = twa_host_attrs,
1971 .emulated = 1
1974 /* This function will probe and initialize a card */
1975 static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id *dev_id)
1977 struct Scsi_Host *host = NULL;
1978 TW_Device_Extension *tw_dev;
1979 u32 mem_addr;
1980 int retval = -ENODEV;
1982 retval = pci_enable_device(pdev);
1983 if (retval) {
1984 TW_PRINTK(host, TW_DRIVER, 0x34, "Failed to enable pci device");
1985 goto out_disable_device;
1988 pci_set_master(pdev);
1990 retval = pci_set_dma_mask(pdev, sizeof(dma_addr_t) > 4 ? DMA_64BIT_MASK : DMA_32BIT_MASK);
1991 if (retval) {
1992 TW_PRINTK(host, TW_DRIVER, 0x23, "Failed to set dma mask");
1993 goto out_disable_device;
1996 host = scsi_host_alloc(&driver_template, sizeof(TW_Device_Extension));
1997 if (!host) {
1998 TW_PRINTK(host, TW_DRIVER, 0x24, "Failed to allocate memory for device extension");
1999 retval = -ENOMEM;
2000 goto out_disable_device;
2002 tw_dev = (TW_Device_Extension *)host->hostdata;
2004 memset(tw_dev, 0, sizeof(TW_Device_Extension));
2006 /* Save values to device extension */
2007 tw_dev->host = host;
2008 tw_dev->tw_pci_dev = pdev;
2010 if (twa_initialize_device_extension(tw_dev)) {
2011 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x25, "Failed to initialize device extension");
2012 goto out_free_device_extension;
2015 /* Request IO regions */
2016 retval = pci_request_regions(pdev, "3w-9xxx");
2017 if (retval) {
2018 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x26, "Failed to get mem region");
2019 goto out_free_device_extension;
2022 mem_addr = pci_resource_start(pdev, 1);
2024 /* Save base address */
2025 tw_dev->base_addr = ioremap(mem_addr, PAGE_SIZE);
2026 if (!tw_dev->base_addr) {
2027 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x35, "Failed to ioremap");
2028 goto out_release_mem_region;
2031 /* Disable interrupts on the card */
2032 TW_DISABLE_INTERRUPTS(tw_dev);
2034 /* Initialize the card */
2035 if (twa_reset_sequence(tw_dev, 0))
2036 goto out_release_mem_region;
2038 /* Set host specific parameters */
2039 host->max_id = TW_MAX_UNITS;
2040 host->max_cmd_len = TW_MAX_CDB_LEN;
2042 /* Channels aren't supported by adapter */
2043 host->max_lun = TW_MAX_LUNS(tw_dev->working_srl);
2044 host->max_channel = 0;
2046 /* Register the card with the kernel SCSI layer */
2047 retval = scsi_add_host(host, &pdev->dev);
2048 if (retval) {
2049 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x27, "scsi add host failed");
2050 goto out_release_mem_region;
2053 pci_set_drvdata(pdev, host);
2055 printk(KERN_WARNING "3w-9xxx: scsi%d: Found a 3ware 9000 Storage Controller at 0x%x, IRQ: %d.\n",
2056 host->host_no, mem_addr, pdev->irq);
2057 printk(KERN_WARNING "3w-9xxx: scsi%d: Firmware %s, BIOS %s, Ports: %d.\n",
2058 host->host_no,
2059 (char *)twa_get_param(tw_dev, 0, TW_VERSION_TABLE,
2060 TW_PARAM_FWVER, TW_PARAM_FWVER_LENGTH),
2061 (char *)twa_get_param(tw_dev, 1, TW_VERSION_TABLE,
2062 TW_PARAM_BIOSVER, TW_PARAM_BIOSVER_LENGTH),
2063 *(int *)twa_get_param(tw_dev, 2, TW_INFORMATION_TABLE,
2064 TW_PARAM_PORTCOUNT, TW_PARAM_PORTCOUNT_LENGTH));
2066 /* Now setup the interrupt handler */
2067 retval = request_irq(pdev->irq, twa_interrupt, SA_SHIRQ, "3w-9xxx", tw_dev);
2068 if (retval) {
2069 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x30, "Error requesting IRQ");
2070 goto out_remove_host;
2073 twa_device_extension_list[twa_device_extension_count] = tw_dev;
2074 twa_device_extension_count++;
2076 /* Re-enable interrupts on the card */
2077 TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
2079 /* Finally, scan the host */
2080 scsi_scan_host(host);
2082 if (twa_major == -1) {
2083 if ((twa_major = register_chrdev (0, "twa", &twa_fops)) < 0)
2084 TW_PRINTK(host, TW_DRIVER, 0x29, "Failed to register character device");
2086 return 0;
2088 out_remove_host:
2089 scsi_remove_host(host);
2090 out_release_mem_region:
2091 pci_release_regions(pdev);
2092 out_free_device_extension:
2093 twa_free_device_extension(tw_dev);
2094 scsi_host_put(host);
2095 out_disable_device:
2096 pci_disable_device(pdev);
2098 return retval;
2099 } /* End twa_probe() */
2101 /* This function is called to remove a device */
2102 static void twa_remove(struct pci_dev *pdev)
2104 struct Scsi_Host *host = pci_get_drvdata(pdev);
2105 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
2107 scsi_remove_host(tw_dev->host);
2109 /* Unregister character device */
2110 if (twa_major >= 0) {
2111 unregister_chrdev(twa_major, "twa");
2112 twa_major = -1;
2115 /* Free up the IRQ */
2116 free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
2118 /* Shutdown the card */
2119 __twa_shutdown(tw_dev);
2121 /* Free up the mem region */
2122 pci_release_regions(pdev);
2124 /* Free up device extension resources */
2125 twa_free_device_extension(tw_dev);
2127 scsi_host_put(tw_dev->host);
2128 pci_disable_device(pdev);
2129 twa_device_extension_count--;
2130 } /* End twa_remove() */
2132 /* PCI Devices supported by this driver */
2133 static struct pci_device_id twa_pci_tbl[] __devinitdata = {
2134 { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9000,
2135 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2138 MODULE_DEVICE_TABLE(pci, twa_pci_tbl);
2140 /* pci_driver initializer */
2141 static struct pci_driver twa_driver = {
2142 .name = "3w-9xxx",
2143 .id_table = twa_pci_tbl,
2144 .probe = twa_probe,
2145 .remove = twa_remove,
2146 .driver = {
2147 .shutdown = twa_shutdown
2151 /* This function is called on driver initialization */
2152 static int __init twa_init(void)
2154 printk(KERN_WARNING "3ware 9000 Storage Controller device driver for Linux v%s.\n", TW_DRIVER_VERSION);
2156 return pci_module_init(&twa_driver);
2157 } /* End twa_init() */
2159 /* This function is called on driver exit */
2160 static void __exit twa_exit(void)
2162 pci_unregister_driver(&twa_driver);
2163 } /* End twa_exit() */
2165 module_init(twa_init);
2166 module_exit(twa_exit);