aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/3w-9xxx.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/scsi/3w-9xxx.c
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'drivers/scsi/3w-9xxx.c')
-rw-r--r--drivers/scsi/3w-9xxx.c2167
1 files changed, 2167 insertions, 0 deletions
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
new file mode 100644
index 000000000000..a2b18f5a4f93
--- /dev/null
+++ b/drivers/scsi/3w-9xxx.c
@@ -0,0 +1,2167 @@
1/*
2 3w-9xxx.c -- 3ware 9000 Storage Controller device driver for Linux.
3
4 Written By: Adam Radford <linuxraid@amcc.com>
5
6 Copyright (C) 2004-2005 Applied Micro Circuits Corporation.
7
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.
11
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.
16
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.
27
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
36
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
40
41 Bugs/Comments/Suggestions should be mailed to:
42 linuxraid@amcc.com
43
44 For more information, goto:
45 http://www.amcc.com
46
47 Note: This version of the driver does not contain a bundled firmware
48 image.
49
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.
62*/
63
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"
82
83/* Globals */
84#define TW_DRIVER_VERSION "2.26.02.002"
85static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT];
86static unsigned int twa_device_extension_count;
87static int twa_major = -1;
88extern struct timezone sys_tz;
89
90/* Module parameters */
91MODULE_AUTHOR ("AMCC");
92MODULE_DESCRIPTION ("3ware 9000 Storage Controller Linux Driver");
93MODULE_LICENSE("GPL");
94MODULE_VERSION(TW_DRIVER_VERSION);
95
96/* Function prototypes */
97static void twa_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_Header *header);
98static int twa_aen_read_queue(TW_Device_Extension *tw_dev, int request_id);
99static char *twa_aen_severity_lookup(unsigned char severity_code);
100static void twa_aen_sync_time(TW_Device_Extension *tw_dev, int request_id);
101static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
102static int twa_chrdev_open(struct inode *inode, struct file *file);
103static int twa_fill_sense(TW_Device_Extension *tw_dev, int request_id, int copy_sense, int print_host);
104static void twa_free_request_id(TW_Device_Extension *tw_dev,int request_id);
105static void twa_get_request_id(TW_Device_Extension *tw_dev, int *request_id);
106static 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);
116static void twa_load_sgl(TW_Command_Full *full_command_packet, int request_id, dma_addr_t dma_handle, int length);
117static int twa_poll_response(TW_Device_Extension *tw_dev, int request_id, int seconds);
118static int twa_poll_status_gone(TW_Device_Extension *tw_dev, u32 flag, int seconds);
119static int twa_post_command_packet(TW_Device_Extension *tw_dev, int request_id, char internal);
120static int twa_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_reset);
121static int twa_reset_sequence(TW_Device_Extension *tw_dev, int soft_reset);
122static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, char *cdb, int use_sg, TW_SG_Entry *sglistarg);
123static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int request_id);
124static char *twa_string_lookup(twa_message_type *table, unsigned int aen_code);
125static void twa_unmap_scsi_data(TW_Device_Extension *tw_dev, int request_id);
126
127/* Functions */
128
129/* Show some statistics about the card */
130static ssize_t twa_show_stats(struct class_device *class_dev, char *buf)
131{
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;
136
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() */
163
164/* This function will set a devices queue depth */
165static int twa_change_queue_depth(struct scsi_device *sdev, int queue_depth)
166{
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() */
172
173/* Create sysfs 'stats' entry */
174static struct class_device_attribute twa_host_stats_attr = {
175 .attr = {
176 .name = "stats",
177 .mode = S_IRUGO,
178 },
179 .show = twa_show_stats
180};
181
182/* Host attributes initializer */
183static struct class_device_attribute *twa_host_attrs[] = {
184 &twa_host_stats_attr,
185 NULL,
186};
187
188/* File operations struct for character device */
189static struct file_operations twa_fops = {
190 .owner = THIS_MODULE,
191 .ioctl = twa_chrdev_ioctl,
192 .open = twa_chrdev_open,
193 .release = NULL
194};
195
196/* This function will complete an aen request from the isr */
197static int twa_aen_complete(TW_Device_Extension *tw_dev, int request_id)
198{
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;
204
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;
210
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;
219 }
220 }
221
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);
232
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;
239 }
240 }
241 retval = 0;
242out2:
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);
246out:
247 return retval;
248} /* End twa_aen_complete() */
249
250/* This function will drain aen queue */
251static int twa_aen_drain_queue(TW_Device_Extension *tw_dev, int no_check_reset)
252{
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;
261
262 if (no_check_reset)
263 first_reset = 0;
264 else
265 first_reset = 1;
266
267 full_command_packet = tw_dev->command_packet_virt[request_id];
268 memset(full_command_packet, 0, sizeof(TW_Command_Full));
269
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 */
274
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];
279
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;
283 }
284
285 /* Mark internal command */
286 tw_dev->srb[request_id] = NULL;
287
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;
293 }
294
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;
300 }
301
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++;
307
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;
325 }
326
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));
331
332 if (count == TW_MAX_AEN_DRAIN)
333 goto out;
334
335 retval = 0;
336out:
337 tw_dev->state[request_id] = TW_S_INITIAL;
338 return retval;
339} /* End twa_aen_drain_queue() */
340
341/* This function will queue an event */
342static void twa_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_Header *header)
343{
344 u32 local_time;
345 struct timeval time;
346 TW_Event *event;
347 unsigned short aen;
348 char host[16];
349 char *error_str;
350
351 tw_dev->aen_count++;
352
353 /* Fill out event info */
354 event = tw_dev->event_queue[tw_dev->error_index];
355
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;
362 }
363
364 aen = header->status_block.error;
365 memset(event, 0, sizeof(TW_Event));
366
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++;
375
376 /* Check for embedded error string */
377 error_str = &(header->err_specific_desc[strlen(header->err_specific_desc)+1]);
378
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--;
391
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() */
396
397/* This function will read the aen queue from the isr */
398static int twa_aen_read_queue(TW_Device_Extension *tw_dev, int request_id)
399{
400 char cdb[TW_MAX_CDB_LEN];
401 TW_SG_Entry sglist[1];
402 TW_Command_Full *full_command_packet;
403 int retval = 1;
404
405 full_command_packet = tw_dev->command_packet_virt[request_id];
406 memset(full_command_packet, 0, sizeof(TW_Command_Full));
407
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 */
412
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];
417
418 /* Mark internal command */
419 tw_dev->srb[request_id] = NULL;
420
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;
425 }
426 retval = 0;
427out:
428 return retval;
429} /* End twa_aen_read_queue() */
430
431/* This function will look up an AEN severity string */
432static char *twa_aen_severity_lookup(unsigned char severity_code)
433{
434 char *retval = NULL;
435
436 if ((severity_code < (unsigned char) TW_AEN_SEVERITY_ERROR) ||
437 (severity_code > (unsigned char) TW_AEN_SEVERITY_DEBUG))
438 goto out;
439
440 retval = twa_aen_severity_table[severity_code];
441out:
442 return retval;
443} /* End twa_aen_severity_lookup() */
444
445/* This function will sync firmware time with the host time */
446static void twa_aen_sync_time(TW_Device_Extension *tw_dev, int request_id)
447{
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;
454
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;
465
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;
472
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;
479
480 memcpy(param->data, &schedulertime, sizeof(u32));
481
482 /* Mark internal command */
483 tw_dev->srb[request_id] = NULL;
484
485 /* Now post the command */
486 twa_post_command_packet(tw_dev, request_id, 1);
487} /* End twa_aen_sync_time() */
488
489/* This function will allocate memory and check if it is correctly aligned */
490static int twa_allocate_memory(TW_Device_Extension *tw_dev, int size, int which)
491{
492 int i;
493 dma_addr_t dma_handle;
494 unsigned long *cpu_addr;
495 int retval = 1;
496
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;
501 }
502
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;
507 }
508
509 memset(cpu_addr, 0, size*TW_Q_LENGTH);
510
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;
521 }
522 }
523 retval = 0;
524out:
525 return retval;
526} /* End twa_allocate_memory() */
527
528/* This function will check the status register for unexpected bits */
529static int twa_check_bits(u32 status_reg_value)
530{
531 int retval = 1;
532
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;
537
538 retval = 0;
539out:
540 return retval;
541} /* End twa_check_bits() */
542
543/* This function will check the srl and decide if we are compatible */
544static int twa_check_srl(TW_Device_Extension *tw_dev, int *flashed)
545{
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;
550
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;
559 }
560
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;
564
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;
576 }
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");
582 }
583 goto out;
584 }
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;
588 }
589 retval = 0;
590out:
591 return retval;
592} /* End twa_check_srl() */
593
594/* This function handles ioctl for the character device */
595static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
596{
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;
614
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;
619 }
620
621 /* First copy down the driver command */
622 if (copy_from_user(&driver_command, argp, sizeof(TW_Ioctl_Driver_Command)))
623 goto out2;
624
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;
629 }
630
631 /* Hardware can only do multiple of 512 byte transfers */
632 data_buffer_length_adjusted = (driver_command.buffer_length + 511) & ~511;
633
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;
639 }
640
641 tw_ioctl = (TW_Ioctl_Buf_Apache *)cpu_addr;
642
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;
646
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);
652
653 /* Flag internal command */
654 tw_dev->srb[request_id] = NULL;
655
656 /* Flag chrdev ioctl */
657 tw_dev->chrdev_request_id = request_id;
658
659 full_command_packet = &tw_ioctl->firmware_command;
660
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);
663
664 memcpy(tw_dev->command_packet_virt[request_id], &(tw_ioctl->firmware_command), sizeof(TW_Command_Full));
665
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);
669
670 timeout = TW_IOCTL_CHRDEV_TIMEOUT*HZ;
671
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);
674
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;
680 }
681
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;
696 }
697
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));
700
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;
734 }
735 tw_ioctl->driver_command.status = 0;
736 }
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;
753 }
754 tw_ioctl->driver_command.status = 0;
755 event_index = 0;
756 }
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;
764
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;
769 }
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;
775 }
776 start_index = 0;
777 }
778 event_index = (start_index + sequence_id - tw_dev->event_queue[start_index]->sequence_id + 1) % TW_Q_LENGTH;
779
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;
785 }
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;
793
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;
798 }
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;
804 }
805 start_index = 0;
806 }
807 event_index = (start_index + sequence_id - tw_dev->event_queue[start_index]->sequence_id - 1) % TW_Q_LENGTH;
808
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;
814 }
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);
822
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;
831 }
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;
839 }
840 break;
841 default:
842 retval = TW_IOCTL_ERROR_OS_ENOTTY;
843 goto out3;
844 }
845
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;
849out3:
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);
852out2:
853 up(&tw_dev->ioctl_sem);
854out:
855 return retval;
856} /* End twa_chrdev_ioctl() */
857
858/* This function handles open for the character device */
859static int twa_chrdev_open(struct inode *inode, struct file *file)
860{
861 unsigned int minor_number;
862 int retval = TW_IOCTL_ERROR_OS_ENODEV;
863
864 minor_number = iminor(inode);
865 if (minor_number >= twa_device_extension_count)
866 goto out;
867 retval = 0;
868out:
869 return retval;
870} /* End twa_chrdev_open() */
871
872/* This function will print readable messages from status register errors */
873static int twa_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value)
874{
875 int retval = 1;
876
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));
881 }
882
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);
887 }
888
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));
892 }
893
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));
897 }
898
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;
903 }
904 goto out;
905 }
906 retval = 0;
907out:
908 return retval;
909} /* End twa_decode_bits() */
910
911/* This function will empty the response queue */
912static int twa_empty_response_queue(TW_Device_Extension *tw_dev)
913{
914 u32 status_reg_value, response_que_value;
915 int count = 0, retval = 1;
916
917 status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
918
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++;
923 }
924 if (count == TW_MAX_RESPONSE_DRAIN)
925 goto out;
926
927 retval = 0;
928out:
929 return retval;
930} /* End twa_empty_response_queue() */
931
932/* This function passes sense keys from firmware to scsi layer */
933static int twa_fill_sense(TW_Device_Extension *tw_dev, int request_id, int copy_sense, int print_host)
934{
935 TW_Command_Full *full_command_packet;
936 unsigned short error;
937 int retval = 1;
938 char *error_str;
939
940 full_command_packet = tw_dev->command_packet_virt[request_id];
941
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]);
944
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);
965 }
966
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;
972 }
973 retval = 0;
974out:
975 return retval;
976} /* End twa_fill_sense() */
977
978/* This function will free up device extension resources */
979static void twa_free_device_extension(TW_Device_Extension *tw_dev)
980{
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]);
986
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]);
992
993 if (tw_dev->event_queue[0])
994 kfree(tw_dev->event_queue[0]);
995} /* End twa_free_device_extension() */
996
997/* This function will free a request id */
998static void twa_free_request_id(TW_Device_Extension *tw_dev, int request_id)
999{
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() */
1004
1005/* This function will get parameter table entires from the firmware */
1006static void *twa_get_param(TW_Device_Extension *tw_dev, int request_id, int table_id, int parameter_id, int parameter_size_bytes)
1007{
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;
1013
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;
1018
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;
1023
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];
1031
1032 command_packet->byte8_offset.param.sgl[0].address = param_value;
1033 command_packet->byte8_offset.param.sgl[0].length = TW_SECTOR_SIZE;
1034
1035 /* Post the command packet to the board */
1036 twa_post_command_packet(tw_dev, request_id, 1);
1037
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]);
1043
1044 tw_dev->posted_request_count--;
1045 tw_dev->state[request_id] = TW_S_INITIAL;
1046
1047 return retval;
1048} /* End twa_get_param() */
1049
1050/* This function will assign an available request id */
1051static void twa_get_request_id(TW_Device_Extension *tw_dev, int *request_id)
1052{
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() */
1057
1058/* This function will send an initconnection command to controller */
1059static 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)
1069{
1070 TW_Command_Full *full_command_packet;
1071 TW_Initconnect *tw_initconnect;
1072 int request_id = 0, retval = 1;
1073
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;
1078
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;
1084
1085 /* Turn on 64-bit sgl support if we need to */
1086 tw_initconnect->features |= sizeof(dma_addr_t) > 4 ? 1 : 0;
1087
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;
1096
1097 /* Send command packet to the board */
1098 twa_post_command_packet(tw_dev, request_id, 1);
1099
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;
1110 }
1111 retval = 0;
1112 }
1113
1114 tw_dev->posted_request_count--;
1115 tw_dev->state[request_id] = TW_S_INITIAL;
1116
1117 return retval;
1118} /* End twa_initconnection() */
1119
1120/* This function will initialize the fields of a device extension */
1121static int twa_initialize_device_extension(TW_Device_Extension *tw_dev)
1122{
1123 int i, retval = 1;
1124
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;
1129 }
1130
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;
1135 }
1136
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;
1142 }
1143
1144 memset(tw_dev->event_queue[0], 0, sizeof(TW_Event) * TW_Q_LENGTH);
1145
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;
1150 }
1151
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;
1158
1159 init_MUTEX(&tw_dev->ioctl_sem);
1160 init_waitqueue_head(&tw_dev->ioctl_wqueue);
1161
1162 retval = 0;
1163out:
1164 return retval;
1165} /* End twa_initialize_device_extension() */
1166
1167/* This function is the interrupt service routine */
1168static irqreturn_t twa_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
1169{
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;
1177
1178 /* Get the per adapter lock */
1179 spin_lock(tw_dev->host->host_lock);
1180
1181 /* Read the registers */
1182 status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
1183
1184 /* Check if this is our interrupt, otherwise bail */
1185 if (!(status_reg_value & TW_STATUS_VALID_INTERRUPT))
1186 goto twa_interrupt_bail;
1187
1188 handled = 1;
1189
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;
1195 }
1196 }
1197
1198 /* Handle host interrupt */
1199 if (status_reg_value & TW_STATUS_HOST_INTERRUPT)
1200 TW_CLEAR_HOST_INTERRUPT(tw_dev);
1201
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);
1207
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);
1213 }
1214 }
1215 }
1216
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;
1227 }
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;
1234 }
1235 }
1236 }
1237
1238 /* Handle response interrupt */
1239 if (status_reg_value & TW_STATUS_RESPONSE_INTERRUPT) {
1240
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);
1257 }
1258 }
1259 }
1260
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;
1267 }
1268 }
1269
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);
1278 }
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);
1284 }
1285
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);
1290 }
1291
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;
1296 }
1297
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);
1304 }
1305
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;
1312 }
1313 }
1314 }
1315 }
1316
1317twa_interrupt_bail:
1318 spin_unlock(tw_dev->host->host_lock);
1319 return IRQ_RETVAL(handled);
1320} /* End twa_interrupt() */
1321
1322/* This function will load the request id and various sgls for ioctls */
1323static void twa_load_sgl(TW_Command_Full *full_command_packet, int request_id, dma_addr_t dma_handle, int length)
1324{
1325 TW_Command *oldcommand;
1326 TW_Command_Apache *newcommand;
1327 TW_SG_Entry *sgl;
1328
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;
1340
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;
1346
1347 if ((sizeof(long) < 8) && (sizeof(dma_addr_t) > 4))
1348 oldcommand->size += 1;
1349 }
1350 }
1351} /* End twa_load_sgl() */
1352
1353/* This function will perform a pci-dma mapping for a scatter gather list */
1354static int twa_map_scsi_sg_data(TW_Device_Extension *tw_dev, int request_id)
1355{
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;
1360
1361 if (cmd->use_sg == 0)
1362 goto out;
1363
1364 use_sg = pci_map_sg(pdev, cmd->buffer, cmd->use_sg, DMA_BIDIRECTIONAL);
1365
1366 if (use_sg == 0) {
1367 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1c, "Failed to map scatter gather list");
1368 goto out;
1369 }
1370
1371 cmd->SCp.phase = TW_PHASE_SGLIST;
1372 cmd->SCp.have_data_in = use_sg;
1373 retval = use_sg;
1374out:
1375 return retval;
1376} /* End twa_map_scsi_sg_data() */
1377
1378/* This function will perform a pci-dma map for a single buffer */
1379static dma_addr_t twa_map_scsi_single_data(TW_Device_Extension *tw_dev, int request_id)
1380{
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;
1385
1386 if (cmd->request_bufflen == 0) {
1387 retval = 0;
1388 goto out;
1389 }
1390
1391 mapping = pci_map_single(pdev, cmd->request_buffer, cmd->request_bufflen, DMA_BIDIRECTIONAL);
1392
1393 if (mapping == 0) {
1394 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1d, "Failed to map page");
1395 goto out;
1396 }
1397
1398 cmd->SCp.phase = TW_PHASE_SINGLE;
1399 cmd->SCp.have_data_in = mapping;
1400 retval = mapping;
1401out:
1402 return retval;
1403} /* End twa_map_scsi_single_data() */
1404
1405/* This function will poll for a response interrupt of a request */
1406static int twa_poll_response(TW_Device_Extension *tw_dev, int request_id, int seconds)
1407{
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];
1411
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;
1418 }
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;
1424 }
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;
1431 }
1432 found = 1;
1433 }
1434 }
1435
1436 if (found)
1437 retval = 0;
1438out:
1439 return retval;
1440} /* End twa_poll_response() */
1441
1442/* This function will poll the status register for a flag */
1443static int twa_poll_status(TW_Device_Extension *tw_dev, u32 flag, int seconds)
1444{
1445 u32 status_reg_value;
1446 unsigned long before;
1447 int retval = 1;
1448
1449 status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
1450 before = jiffies;
1451
1452 if (twa_check_bits(status_reg_value))
1453 twa_decode_bits(tw_dev, status_reg_value);
1454
1455 while ((status_reg_value & flag) != flag) {
1456 status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
1457
1458 if (twa_check_bits(status_reg_value))
1459 twa_decode_bits(tw_dev, status_reg_value);
1460
1461 if (time_after(jiffies, before + HZ * seconds))
1462 goto out;
1463
1464 msleep(50);
1465 }
1466 retval = 0;
1467out:
1468 return retval;
1469} /* End twa_poll_status() */
1470
1471/* This function will poll the status register for disappearance of a flag */
1472static int twa_poll_status_gone(TW_Device_Extension *tw_dev, u32 flag, int seconds)
1473{
1474 u32 status_reg_value;
1475 unsigned long before;
1476 int retval = 1;
1477
1478 status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
1479 before = jiffies;
1480
1481 if (twa_check_bits(status_reg_value))
1482 twa_decode_bits(tw_dev, status_reg_value);
1483
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);
1488
1489 if (time_after(jiffies, before + HZ * seconds))
1490 goto out;
1491
1492 msleep(50);
1493 }
1494 retval = 0;
1495out:
1496 return retval;
1497} /* End twa_poll_status_gone() */
1498
1499/* This function will attempt to post a command packet to the board */
1500static int twa_post_command_packet(TW_Device_Extension *tw_dev, int request_id, char internal)
1501{
1502 u32 status_reg_value;
1503 dma_addr_t command_que_value;
1504 int retval = 1;
1505
1506 command_que_value = tw_dev->command_packet_phys[request_id];
1507 status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
1508
1509 if (twa_check_bits(status_reg_value))
1510 twa_decode_bits(tw_dev, status_reg_value);
1511
1512 if (((tw_dev->pending_request_count > 0) && (tw_dev->state[request_id] != TW_S_PENDING)) || (status_reg_value & TW_STATUS_COMMAND_QUEUE_FULL)) {
1513
1514 /* Only pend internal driver commands */
1515 if (!internal) {
1516 retval = SCSI_MLQUEUE_HOST_BUSY;
1517 goto out;
1518 }
1519
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;
1526 }
1527 tw_dev->pending_queue[tw_dev->pending_tail] = request_id;
1528 tw_dev->pending_tail = (tw_dev->pending_tail + 1) % TW_Q_LENGTH;
1529 }
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));
1540 }
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;
1545 }
1546 }
1547 retval = 0;
1548out:
1549 return retval;
1550} /* End twa_post_command_packet() */
1551
1552/* This function will reset a device extension */
1553static int twa_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_reset)
1554{
1555 int i = 0;
1556 int retval = 1;
1557 unsigned long flags = 0;
1558
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);
1563
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);
1573 }
1574 }
1575 }
1576
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;
1581 }
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;
1589
1590 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
1591
1592 if (twa_reset_sequence(tw_dev, 1))
1593 goto out;
1594
1595 TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
1596
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);
1603 }
1604 retval = 0;
1605out:
1606 return retval;
1607} /* End twa_reset_device_extension() */
1608
1609/* This function will reset a controller */
1610static int twa_reset_sequence(TW_Device_Extension *tw_dev, int soft_reset)
1611{
1612 int tries = 0, retval = 1, flashed = 0, do_soft_reset = soft_reset;
1613
1614 while (tries < TW_MAX_RESET_TRIES) {
1615 if (do_soft_reset)
1616 TW_SOFT_RESET(tw_dev);
1617
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;
1624 }
1625
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;
1632 }
1633
1634 flashed = 0;
1635
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;
1646 }
1647 }
1648
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;
1655 }
1656
1657 /* If we got here, controller is in a good state */
1658 retval = 0;
1659 goto out;
1660 }
1661out:
1662 return retval;
1663} /* End twa_reset_sequence() */
1664
1665/* This funciton returns unit geometry in cylinders/heads/sectors */
1666static int twa_scsi_biosparam(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int geom[])
1667{
1668 int heads, sectors, cylinders;
1669 TW_Device_Extension *tw_dev;
1670
1671 tw_dev = (TW_Device_Extension *)sdev->host->hostdata;
1672
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);
1681 }
1682
1683 geom[0] = heads;
1684 geom[1] = sectors;
1685 geom[2] = cylinders;
1686
1687 return 0;
1688} /* End twa_scsi_biosparam() */
1689
1690/* This is the new scsi eh reset function */
1691static int twa_scsi_eh_reset(struct scsi_cmnd *SCpnt)
1692{
1693 TW_Device_Extension *tw_dev = NULL;
1694 int retval = FAILED;
1695
1696 tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
1697
1698 spin_unlock_irq(tw_dev->host->host_lock);
1699
1700 tw_dev->num_resets++;
1701
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]);
1703
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;
1708 }
1709
1710 retval = SUCCESS;
1711out:
1712 spin_lock_irq(tw_dev->host->host_lock);
1713 return retval;
1714} /* End twa_scsi_eh_reset() */
1715
1716/* This is the main scsi queue function to handle scsi opcodes */
1717static int twa_scsi_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1718{
1719 int request_id, retval;
1720 TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
1721
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;
1728 }
1729
1730 /* Save done function into scsi_cmnd struct */
1731 SCpnt->scsi_done = done;
1732
1733 /* Get a free request id */
1734 twa_get_request_id(tw_dev, &request_id);
1735
1736 /* Save the scsi command for use by the ISR */
1737 tw_dev->srb[request_id] = SCpnt;
1738
1739 /* Initialize phase to zero */
1740 SCpnt->SCp.phase = TW_PHASE_INITIAL;
1741
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;
1753 }
1754out:
1755 return retval;
1756} /* End twa_scsi_queue() */
1757
1758/* This function hands scsi cdb's to the firmware */
1759static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, char *cdb, int use_sg, TW_SG_Entry *sglistarg)
1760{
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;
1769
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;
1773 }
1774 srb = tw_dev->srb[request_id];
1775 }
1776
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;
1782
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);
1786
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);
1792
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;
1801 }
1802
1803 command_packet->sgl_offset = 16;
1804
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;
1815
1816 command_packet->sg_list[0].address = buffaddr;
1817 command_packet->sg_list[0].length = tw_dev->srb[request_id]->request_bufflen;
1818 }
1819 command_packet->sgl_entries__lunh = TW_REQ_LUN_IN((srb->device->lun >> 4), 1);
1820
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;
1824 }
1825 }
1826
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;
1835
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;
1842 }
1843 }
1844 }
1845 command_packet->sgl_entries__lunh = TW_REQ_LUN_IN((srb->device->lun >> 4), tw_dev->srb[request_id]->use_sg);
1846 }
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;
1855 }
1856 }
1857 command_packet->sgl_entries__lunh = TW_REQ_LUN_IN(0, use_sg);
1858 }
1859
1860 if (srb) {
1861 if (srb->cmnd[0] == READ_6 || srb->cmnd[0] == WRITE_6)
1862 num_sectors = (u32)srb->cmnd[4];
1863
1864 if (srb->cmnd[0] == READ_10 || srb->cmnd[0] == WRITE_10)
1865 num_sectors = (u32)srb->cmnd[8] | ((u32)srb->cmnd[7] << 8);
1866 }
1867
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;
1872
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;
1878 }
1879
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;
1886 }
1887out:
1888 return retval;
1889} /* End twa_scsiop_execute_scsi() */
1890
1891/* This function completes an execute scsi operation */
1892static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int request_id)
1893{
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);
1899 }
1900} /* End twa_scsiop_execute_scsi_complete() */
1901
1902/* This function tells the controller to shut down */
1903static void __twa_shutdown(TW_Device_Extension *tw_dev)
1904{
1905 /* Disable interrupts */
1906 TW_DISABLE_INTERRUPTS(tw_dev);
1907
1908 printk(KERN_WARNING "3w-9xxx: Shutting down host %d.\n", tw_dev->host->host_no);
1909
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");
1915 }
1916
1917 /* Clear all interrupts just before exit */
1918 TW_CLEAR_ALL_INTERRUPTS(tw_dev);
1919} /* End __twa_shutdown() */
1920
1921/* Wrapper for __twa_shutdown */
1922static void twa_shutdown(struct device *dev)
1923{
1924 struct Scsi_Host *host = pci_get_drvdata(to_pci_dev(dev));
1925 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
1926
1927 __twa_shutdown(tw_dev);
1928} /* End twa_shutdown() */
1929
1930/* This function will look up a string */
1931static char *twa_string_lookup(twa_message_type *table, unsigned int code)
1932{
1933 int index;
1934
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() */
1939
1940/* This function will perform a pci-dma unmap */
1941static void twa_unmap_scsi_data(TW_Device_Extension *tw_dev, int request_id)
1942{
1943 struct scsi_cmnd *cmd = tw_dev->srb[request_id];
1944 struct pci_dev *pdev = tw_dev->tw_pci_dev;
1945
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;
1953 }
1954} /* End twa_unmap_scsi_data() */
1955
1956/* scsi_host_template initializer */
1957static 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
1972};
1973
1974/* This function will probe and initialize a card */
1975static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id *dev_id)
1976{
1977 struct Scsi_Host *host = NULL;
1978 TW_Device_Extension *tw_dev;
1979 u32 mem_addr;
1980 int retval = -ENODEV;
1981
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;
1986 }
1987
1988 pci_set_master(pdev);
1989
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;
1994 }
1995
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;
2001 }
2002 tw_dev = (TW_Device_Extension *)host->hostdata;
2003
2004 memset(tw_dev, 0, sizeof(TW_Device_Extension));
2005
2006 /* Save values to device extension */
2007 tw_dev->host = host;
2008 tw_dev->tw_pci_dev = pdev;
2009
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;
2013 }
2014
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;
2020 }
2021
2022 mem_addr = pci_resource_start(pdev, 1);
2023
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;
2029 }
2030
2031 /* Disable interrupts on the card */
2032 TW_DISABLE_INTERRUPTS(tw_dev);
2033
2034 /* Initialize the card */
2035 if (twa_reset_sequence(tw_dev, 0))
2036 goto out_release_mem_region;
2037
2038 /* Set host specific parameters */
2039 host->max_id = TW_MAX_UNITS;
2040 host->max_cmd_len = TW_MAX_CDB_LEN;
2041
2042 /* Channels aren't supported by adapter */
2043 host->max_lun = TW_MAX_LUNS(tw_dev->working_srl);
2044 host->max_channel = 0;
2045
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;
2051 }
2052
2053 pci_set_drvdata(pdev, host);
2054
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));
2065
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;
2071 }
2072
2073 twa_device_extension_list[twa_device_extension_count] = tw_dev;
2074 twa_device_extension_count++;
2075
2076 /* Re-enable interrupts on the card */
2077 TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
2078
2079 /* Finally, scan the host */
2080 scsi_scan_host(host);
2081
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");
2085 }
2086 return 0;
2087
2088out_remove_host:
2089 scsi_remove_host(host);
2090out_release_mem_region:
2091 pci_release_regions(pdev);
2092out_free_device_extension:
2093 twa_free_device_extension(tw_dev);
2094 scsi_host_put(host);
2095out_disable_device:
2096 pci_disable_device(pdev);
2097
2098 return retval;
2099} /* End twa_probe() */
2100
2101/* This function is called to remove a device */
2102static void twa_remove(struct pci_dev *pdev)
2103{
2104 struct Scsi_Host *host = pci_get_drvdata(pdev);
2105 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
2106
2107 scsi_remove_host(tw_dev->host);
2108
2109 /* Unregister character device */
2110 if (twa_major >= 0) {
2111 unregister_chrdev(twa_major, "twa");
2112 twa_major = -1;
2113 }
2114
2115 /* Free up the IRQ */
2116 free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
2117
2118 /* Shutdown the card */
2119 __twa_shutdown(tw_dev);
2120
2121 /* Free up the mem region */
2122 pci_release_regions(pdev);
2123
2124 /* Free up device extension resources */
2125 twa_free_device_extension(tw_dev);
2126
2127 scsi_host_put(tw_dev->host);
2128 pci_disable_device(pdev);
2129 twa_device_extension_count--;
2130} /* End twa_remove() */
2131
2132/* PCI Devices supported by this driver */
2133static 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},
2136 { }
2137};
2138MODULE_DEVICE_TABLE(pci, twa_pci_tbl);
2139
2140/* pci_driver initializer */
2141static 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
2148 }
2149};
2150
2151/* This function is called on driver initialization */
2152static int __init twa_init(void)
2153{
2154 printk(KERN_WARNING "3ware 9000 Storage Controller device driver for Linux v%s.\n", TW_DRIVER_VERSION);
2155
2156 return pci_module_init(&twa_driver);
2157} /* End twa_init() */
2158
2159/* This function is called on driver exit */
2160static void __exit twa_exit(void)
2161{
2162 pci_unregister_driver(&twa_driver);
2163} /* End twa_exit() */
2164
2165module_init(twa_init);
2166module_exit(twa_exit);
2167