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