Linux Audio

Check our new training course

Loading...
v3.1
   1/*
   2   3w-sas.c -- LSI 3ware SAS/SATA-RAID Controller device driver for Linux.
   3
   4   Written By: Adam Radford <linuxraid@lsi.com>
   5
   6   Copyright (C) 2009 LSI 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   Controllers supported by this driver:
  42
  43   LSI 3ware 9750 6Gb/s SAS/SATA-RAID
  44
  45   Bugs/Comments/Suggestions should be mailed to:
  46   linuxraid@lsi.com
  47
  48   For more information, goto:
  49   http://www.lsi.com
  50
  51   History
  52   -------
  53   3.26.02.000 - Initial driver release.
  54*/
  55
  56#include <linux/module.h>
  57#include <linux/reboot.h>
  58#include <linux/spinlock.h>
  59#include <linux/interrupt.h>
  60#include <linux/moduleparam.h>
  61#include <linux/errno.h>
  62#include <linux/types.h>
  63#include <linux/delay.h>
  64#include <linux/pci.h>
  65#include <linux/time.h>
  66#include <linux/mutex.h>
  67#include <linux/slab.h>
  68#include <asm/io.h>
  69#include <asm/irq.h>
  70#include <asm/uaccess.h>
  71#include <scsi/scsi.h>
  72#include <scsi/scsi_host.h>
  73#include <scsi/scsi_tcq.h>
  74#include <scsi/scsi_cmnd.h>
  75#include "3w-sas.h"
  76
  77/* Globals */
  78#define TW_DRIVER_VERSION "3.26.02.000"
  79static DEFINE_MUTEX(twl_chrdev_mutex);
  80static TW_Device_Extension *twl_device_extension_list[TW_MAX_SLOT];
  81static unsigned int twl_device_extension_count;
  82static int twl_major = -1;
  83extern struct timezone sys_tz;
  84
  85/* Module parameters */
  86MODULE_AUTHOR ("LSI");
  87MODULE_DESCRIPTION ("LSI 3ware SAS/SATA-RAID Linux Driver");
  88MODULE_LICENSE("GPL");
  89MODULE_VERSION(TW_DRIVER_VERSION);
  90
  91static int use_msi;
  92module_param(use_msi, int, S_IRUGO);
  93MODULE_PARM_DESC(use_msi, "Use Message Signaled Interrupts. Default: 0");
  94
  95/* Function prototypes */
  96static int twl_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_reset);
  97
  98/* Functions */
  99
 100/* This function returns AENs through sysfs */
 101static ssize_t twl_sysfs_aen_read(struct file *filp, struct kobject *kobj,
 102				  struct bin_attribute *bin_attr,
 103				  char *outbuf, loff_t offset, size_t count)
 104{
 105	struct device *dev = container_of(kobj, struct device, kobj);
 106	struct Scsi_Host *shost = class_to_shost(dev);
 107	TW_Device_Extension *tw_dev = (TW_Device_Extension *)shost->hostdata;
 108	unsigned long flags = 0;
 109	ssize_t ret;
 110
 111	if (!capable(CAP_SYS_ADMIN))
 112		return -EACCES;
 113
 114	spin_lock_irqsave(tw_dev->host->host_lock, flags);
 115	ret = memory_read_from_buffer(outbuf, count, &offset, tw_dev->event_queue[0], sizeof(TW_Event) * TW_Q_LENGTH);
 116	spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
 117
 118	return ret;
 119} /* End twl_sysfs_aen_read() */
 120
 121/* aen_read sysfs attribute initializer */
 122static struct bin_attribute twl_sysfs_aen_read_attr = {
 123	.attr = {
 124		.name = "3ware_aen_read",
 125		.mode = S_IRUSR,
 126	}, 
 127	.size = 0,
 128	.read = twl_sysfs_aen_read
 129};
 130
 131/* This function returns driver compatibility info through sysfs */
 132static ssize_t twl_sysfs_compat_info(struct file *filp, struct kobject *kobj,
 133				     struct bin_attribute *bin_attr,
 134				     char *outbuf, loff_t offset, size_t count)
 135{
 136	struct device *dev = container_of(kobj, struct device, kobj);
 137	struct Scsi_Host *shost = class_to_shost(dev);
 138	TW_Device_Extension *tw_dev = (TW_Device_Extension *)shost->hostdata;
 139	unsigned long flags = 0;
 140	ssize_t ret;
 141
 142	if (!capable(CAP_SYS_ADMIN))
 143		return -EACCES;
 144
 145	spin_lock_irqsave(tw_dev->host->host_lock, flags);
 146	ret = memory_read_from_buffer(outbuf, count, &offset, &tw_dev->tw_compat_info, sizeof(TW_Compatibility_Info));
 147	spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
 148
 149	return ret;
 150} /* End twl_sysfs_compat_info() */
 151
 152/* compat_info sysfs attribute initializer */
 153static struct bin_attribute twl_sysfs_compat_info_attr = {
 154	.attr = {
 155		.name = "3ware_compat_info",
 156		.mode = S_IRUSR,
 157	}, 
 158	.size = 0,
 159	.read = twl_sysfs_compat_info
 160};
 161
 162/* Show some statistics about the card */
 163static ssize_t twl_show_stats(struct device *dev,
 164			      struct device_attribute *attr, char *buf)
 165{
 166	struct Scsi_Host *host = class_to_shost(dev);
 167	TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
 168	unsigned long flags = 0;
 169	ssize_t len;
 170
 171	spin_lock_irqsave(tw_dev->host->host_lock, flags);
 172	len = snprintf(buf, PAGE_SIZE, "3w-sas Driver version: %s\n"
 173		       "Current commands posted:   %4d\n"
 174		       "Max commands posted:       %4d\n"
 175		       "Last sgl length:           %4d\n"
 176		       "Max sgl length:            %4d\n"
 177		       "Last sector count:         %4d\n"
 178		       "Max sector count:          %4d\n"
 179		       "SCSI Host Resets:          %4d\n"
 180		       "AEN's:                     %4d\n", 
 181		       TW_DRIVER_VERSION,
 182		       tw_dev->posted_request_count,
 183		       tw_dev->max_posted_request_count,
 184		       tw_dev->sgl_entries,
 185		       tw_dev->max_sgl_entries,
 186		       tw_dev->sector_count,
 187		       tw_dev->max_sector_count,
 188		       tw_dev->num_resets,
 189		       tw_dev->aen_count);
 190	spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
 191	return len;
 192} /* End twl_show_stats() */
 193
 194/* This function will set a devices queue depth */
 195static int twl_change_queue_depth(struct scsi_device *sdev, int queue_depth,
 196				  int reason)
 197{
 198	if (reason != SCSI_QDEPTH_DEFAULT)
 199		return -EOPNOTSUPP;
 200
 201	if (queue_depth > TW_Q_LENGTH-2)
 202		queue_depth = TW_Q_LENGTH-2;
 203	scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, queue_depth);
 204	return queue_depth;
 205} /* End twl_change_queue_depth() */
 206
 207/* stats sysfs attribute initializer */
 208static struct device_attribute twl_host_stats_attr = {
 209	.attr = {
 210		.name = 	"3ware_stats",
 211		.mode =		S_IRUGO,
 212	},
 213	.show = twl_show_stats
 214};
 215
 216/* Host attributes initializer */
 217static struct device_attribute *twl_host_attrs[] = {
 218	&twl_host_stats_attr,
 219	NULL,
 220};
 221
 222/* This function will look up an AEN severity string */
 223static char *twl_aen_severity_lookup(unsigned char severity_code)
 224{
 225	char *retval = NULL;
 226
 227	if ((severity_code < (unsigned char) TW_AEN_SEVERITY_ERROR) ||
 228	    (severity_code > (unsigned char) TW_AEN_SEVERITY_DEBUG))
 229		goto out;
 230
 231	retval = twl_aen_severity_table[severity_code];
 232out:
 233	return retval;
 234} /* End twl_aen_severity_lookup() */
 235
 236/* This function will queue an event */
 237static void twl_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_Header *header)
 238{
 239	u32 local_time;
 240	struct timeval time;
 241	TW_Event *event;
 242	unsigned short aen;
 243	char host[16];
 244	char *error_str;
 245
 246	tw_dev->aen_count++;
 247
 248	/* Fill out event info */
 249	event = tw_dev->event_queue[tw_dev->error_index];
 250
 251	host[0] = '\0';
 252	if (tw_dev->host)
 253		sprintf(host, " scsi%d:", tw_dev->host->host_no);
 254
 255	aen = le16_to_cpu(header->status_block.error);
 256	memset(event, 0, sizeof(TW_Event));
 257
 258	event->severity = TW_SEV_OUT(header->status_block.severity__reserved);
 259	do_gettimeofday(&time);
 260	local_time = (u32)(time.tv_sec - (sys_tz.tz_minuteswest * 60));
 261	event->time_stamp_sec = local_time;
 262	event->aen_code = aen;
 263	event->retrieved = TW_AEN_NOT_RETRIEVED;
 264	event->sequence_id = tw_dev->error_sequence_id;
 265	tw_dev->error_sequence_id++;
 266
 267	/* Check for embedded error string */
 268	error_str = &(header->err_specific_desc[strlen(header->err_specific_desc)+1]);
 269
 270	header->err_specific_desc[sizeof(header->err_specific_desc) - 1] = '\0';
 271	event->parameter_len = strlen(header->err_specific_desc);
 272	memcpy(event->parameter_data, header->err_specific_desc, event->parameter_len + 1 + strlen(error_str));
 273	if (event->severity != TW_AEN_SEVERITY_DEBUG)
 274		printk(KERN_WARNING "3w-sas:%s AEN: %s (0x%02X:0x%04X): %s:%s.\n",
 275		       host,
 276		       twl_aen_severity_lookup(TW_SEV_OUT(header->status_block.severity__reserved)),
 277		       TW_MESSAGE_SOURCE_CONTROLLER_EVENT, aen, error_str,
 278		       header->err_specific_desc);
 279	else
 280		tw_dev->aen_count--;
 281
 282	tw_dev->error_index = (tw_dev->error_index + 1 ) % TW_Q_LENGTH;
 283} /* End twl_aen_queue_event() */
 284
 285/* This function will attempt to post a command packet to the board */
 286static int twl_post_command_packet(TW_Device_Extension *tw_dev, int request_id)
 287{
 288	dma_addr_t command_que_value;
 289
 290	command_que_value = tw_dev->command_packet_phys[request_id];
 291	command_que_value += TW_COMMAND_OFFSET;
 292
 293	/* First write upper 4 bytes */
 294	writel((u32)((u64)command_que_value >> 32), TWL_HIBQPH_REG_ADDR(tw_dev));
 295	/* Then the lower 4 bytes */
 296	writel((u32)(command_que_value | TWL_PULL_MODE), TWL_HIBQPL_REG_ADDR(tw_dev));
 297
 298	tw_dev->state[request_id] = TW_S_POSTED;
 299	tw_dev->posted_request_count++;
 300	if (tw_dev->posted_request_count > tw_dev->max_posted_request_count)
 301		tw_dev->max_posted_request_count = tw_dev->posted_request_count;
 302
 303	return 0;
 304} /* End twl_post_command_packet() */
 305
 306/* This function will perform a pci-dma mapping for a scatter gather list */
 307static int twl_map_scsi_sg_data(TW_Device_Extension *tw_dev, int request_id)
 308{
 309	int use_sg;
 310	struct scsi_cmnd *cmd = tw_dev->srb[request_id];
 311
 312	use_sg = scsi_dma_map(cmd);
 313	if (!use_sg)
 314		return 0;
 315	else if (use_sg < 0) {
 316		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1, "Failed to map scatter gather list");
 317		return 0;
 318	}
 319
 320	cmd->SCp.phase = TW_PHASE_SGLIST;
 321	cmd->SCp.have_data_in = use_sg;
 322
 323	return use_sg;
 324} /* End twl_map_scsi_sg_data() */
 325
 326/* This function hands scsi cdb's to the firmware */
 327static int twl_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, char *cdb, int use_sg, TW_SG_Entry_ISO *sglistarg)
 328{
 329	TW_Command_Full *full_command_packet;
 330	TW_Command_Apache *command_packet;
 331	int i, sg_count;
 332	struct scsi_cmnd *srb = NULL;
 333	struct scatterlist *sglist = NULL, *sg;
 334	int retval = 1;
 335
 336	if (tw_dev->srb[request_id]) {
 337		srb = tw_dev->srb[request_id];
 338		if (scsi_sglist(srb))
 339			sglist = scsi_sglist(srb);
 340	}
 341
 342	/* Initialize command packet */
 343	full_command_packet = tw_dev->command_packet_virt[request_id];
 344	full_command_packet->header.header_desc.size_header = 128;
 345	full_command_packet->header.status_block.error = 0;
 346	full_command_packet->header.status_block.severity__reserved = 0;
 347
 348	command_packet = &full_command_packet->command.newcommand;
 349	command_packet->status = 0;
 350	command_packet->opcode__reserved = TW_OPRES_IN(0, TW_OP_EXECUTE_SCSI);
 351
 352	/* We forced 16 byte cdb use earlier */
 353	if (!cdb)
 354		memcpy(command_packet->cdb, srb->cmnd, TW_MAX_CDB_LEN);
 355	else
 356		memcpy(command_packet->cdb, cdb, TW_MAX_CDB_LEN);
 357
 358	if (srb) {
 359		command_packet->unit = srb->device->id;
 360		command_packet->request_id__lunl =
 361			cpu_to_le16(TW_REQ_LUN_IN(srb->device->lun, request_id));
 362	} else {
 363		command_packet->request_id__lunl =
 364			cpu_to_le16(TW_REQ_LUN_IN(0, request_id));
 365		command_packet->unit = 0;
 366	}
 367
 368	command_packet->sgl_offset = 16;
 369
 370	if (!sglistarg) {
 371		/* Map sglist from scsi layer to cmd packet */
 372		if (scsi_sg_count(srb)) {
 373			sg_count = twl_map_scsi_sg_data(tw_dev, request_id);
 374			if (sg_count == 0)
 375				goto out;
 376
 377			scsi_for_each_sg(srb, sg, sg_count, i) {
 378				command_packet->sg_list[i].address = TW_CPU_TO_SGL(sg_dma_address(sg));
 379				command_packet->sg_list[i].length = TW_CPU_TO_SGL(sg_dma_len(sg));
 380			}
 381			command_packet->sgl_entries__lunh = cpu_to_le16(TW_REQ_LUN_IN((srb->device->lun >> 4), scsi_sg_count(tw_dev->srb[request_id])));
 382		}
 383	} else {
 384		/* Internal cdb post */
 385		for (i = 0; i < use_sg; i++) {
 386			command_packet->sg_list[i].address = TW_CPU_TO_SGL(sglistarg[i].address);
 387			command_packet->sg_list[i].length = TW_CPU_TO_SGL(sglistarg[i].length);
 388		}
 389		command_packet->sgl_entries__lunh = cpu_to_le16(TW_REQ_LUN_IN(0, use_sg));
 390	}
 391
 392	/* Update some stats */
 393	if (srb) {
 394		tw_dev->sector_count = scsi_bufflen(srb) / 512;
 395		if (tw_dev->sector_count > tw_dev->max_sector_count)
 396			tw_dev->max_sector_count = tw_dev->sector_count;
 397		tw_dev->sgl_entries = scsi_sg_count(srb);
 398		if (tw_dev->sgl_entries > tw_dev->max_sgl_entries)
 399			tw_dev->max_sgl_entries = tw_dev->sgl_entries;
 400	}
 401
 402	/* Now post the command to the board */
 403	retval = twl_post_command_packet(tw_dev, request_id);
 404
 405out:
 406	return retval;
 407} /* End twl_scsiop_execute_scsi() */
 408
 409/* This function will read the aen queue from the isr */
 410static int twl_aen_read_queue(TW_Device_Extension *tw_dev, int request_id)
 411{
 412	char cdb[TW_MAX_CDB_LEN];
 413	TW_SG_Entry_ISO sglist[1];
 414	TW_Command_Full *full_command_packet;
 415	int retval = 1;
 416
 417	full_command_packet = tw_dev->command_packet_virt[request_id];
 418	memset(full_command_packet, 0, sizeof(TW_Command_Full));
 419
 420	/* Initialize cdb */
 421	memset(&cdb, 0, TW_MAX_CDB_LEN);
 422	cdb[0] = REQUEST_SENSE; /* opcode */
 423	cdb[4] = TW_ALLOCATION_LENGTH; /* allocation length */
 424
 425	/* Initialize sglist */
 426	memset(&sglist, 0, sizeof(TW_SG_Entry_ISO));
 427	sglist[0].length = TW_SECTOR_SIZE;
 428	sglist[0].address = tw_dev->generic_buffer_phys[request_id];
 429
 430	/* Mark internal command */
 431	tw_dev->srb[request_id] = NULL;
 432
 433	/* Now post the command packet */
 434	if (twl_scsiop_execute_scsi(tw_dev, request_id, cdb, 1, sglist)) {
 435		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2, "Post failed while reading AEN queue");
 436		goto out;
 437	}
 438	retval = 0;
 439out:
 440	return retval;
 441} /* End twl_aen_read_queue() */
 442
 443/* This function will sync firmware time with the host time */
 444static void twl_aen_sync_time(TW_Device_Extension *tw_dev, int request_id)
 445{
 446	u32 schedulertime;
 447	struct timeval utc;
 448	TW_Command_Full *full_command_packet;
 449	TW_Command *command_packet;
 450	TW_Param_Apache *param;
 451	u32 local_time;
 452
 453	/* Fill out the command packet */
 454	full_command_packet = tw_dev->command_packet_virt[request_id];
 455	memset(full_command_packet, 0, sizeof(TW_Command_Full));
 456	command_packet = &full_command_packet->command.oldcommand;
 457	command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_SET_PARAM);
 458	command_packet->request_id = request_id;
 459	command_packet->byte8_offset.param.sgl[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]);
 460	command_packet->byte8_offset.param.sgl[0].length = TW_CPU_TO_SGL(TW_SECTOR_SIZE);
 461	command_packet->size = TW_COMMAND_SIZE;
 462	command_packet->byte6_offset.parameter_count = cpu_to_le16(1);
 463
 464	/* Setup the param */
 465	param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id];
 466	memset(param, 0, TW_SECTOR_SIZE);
 467	param->table_id = cpu_to_le16(TW_TIMEKEEP_TABLE | 0x8000); /* Controller time keep table */
 468	param->parameter_id = cpu_to_le16(0x3); /* SchedulerTime */
 469	param->parameter_size_bytes = cpu_to_le16(4);
 470
 471	/* Convert system time in UTC to local time seconds since last 
 472           Sunday 12:00AM */
 473	do_gettimeofday(&utc);
 474	local_time = (u32)(utc.tv_sec - (sys_tz.tz_minuteswest * 60));
 475	schedulertime = local_time - (3 * 86400);
 476	schedulertime = cpu_to_le32(schedulertime % 604800);
 477
 478	memcpy(param->data, &schedulertime, sizeof(u32));
 479
 480	/* Mark internal command */
 481	tw_dev->srb[request_id] = NULL;
 482
 483	/* Now post the command */
 484	twl_post_command_packet(tw_dev, request_id);
 485} /* End twl_aen_sync_time() */
 486
 487/* This function will assign an available request id */
 488static void twl_get_request_id(TW_Device_Extension *tw_dev, int *request_id)
 489{
 490	*request_id = tw_dev->free_queue[tw_dev->free_head];
 491	tw_dev->free_head = (tw_dev->free_head + 1) % TW_Q_LENGTH;
 492	tw_dev->state[*request_id] = TW_S_STARTED;
 493} /* End twl_get_request_id() */
 494
 495/* This function will free a request id */
 496static void twl_free_request_id(TW_Device_Extension *tw_dev, int request_id)
 497{
 498	tw_dev->free_queue[tw_dev->free_tail] = request_id;
 499	tw_dev->state[request_id] = TW_S_FINISHED;
 500	tw_dev->free_tail = (tw_dev->free_tail + 1) % TW_Q_LENGTH;
 501} /* End twl_free_request_id() */
 502
 503/* This function will complete an aen request from the isr */
 504static int twl_aen_complete(TW_Device_Extension *tw_dev, int request_id)
 505{
 506	TW_Command_Full *full_command_packet;
 507	TW_Command *command_packet;
 508	TW_Command_Apache_Header *header;
 509	unsigned short aen;
 510	int retval = 1;
 511
 512	header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id];
 513	tw_dev->posted_request_count--;
 514	aen = le16_to_cpu(header->status_block.error);
 515	full_command_packet = tw_dev->command_packet_virt[request_id];
 516	command_packet = &full_command_packet->command.oldcommand;
 517
 518	/* First check for internal completion of set param for time sync */
 519	if (TW_OP_OUT(command_packet->opcode__sgloffset) == TW_OP_SET_PARAM) {
 520		/* Keep reading the queue in case there are more aen's */
 521		if (twl_aen_read_queue(tw_dev, request_id))
 522			goto out2;
 523	        else {
 524			retval = 0;
 525			goto out;
 526		}
 527	}
 528
 529	switch (aen) {
 530	case TW_AEN_QUEUE_EMPTY:
 531		/* Quit reading the queue if this is the last one */
 532		break;
 533	case TW_AEN_SYNC_TIME_WITH_HOST:
 534		twl_aen_sync_time(tw_dev, request_id);
 535		retval = 0;
 536		goto out;
 537	default:
 538		twl_aen_queue_event(tw_dev, header);
 539
 540		/* If there are more aen's, keep reading the queue */
 541		if (twl_aen_read_queue(tw_dev, request_id))
 542			goto out2;
 543		else {
 544			retval = 0;
 545			goto out;
 546		}
 547	}
 548	retval = 0;
 549out2:
 550	tw_dev->state[request_id] = TW_S_COMPLETED;
 551	twl_free_request_id(tw_dev, request_id);
 552	clear_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags);
 553out:
 554	return retval;
 555} /* End twl_aen_complete() */
 556
 557/* This function will poll for a response */
 558static int twl_poll_response(TW_Device_Extension *tw_dev, int request_id, int seconds)
 559{
 560	unsigned long before;
 561	dma_addr_t mfa;
 562	u32 regh, regl;
 563	u32 response;
 564	int retval = 1;
 565	int found = 0;
 566
 567	before = jiffies;
 568
 569	while (!found) {
 570		if (sizeof(dma_addr_t) > 4) {
 571			regh = readl(TWL_HOBQPH_REG_ADDR(tw_dev));
 572			regl = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
 573			mfa = ((u64)regh << 32) | regl;
 574		} else
 575			mfa = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
 576
 577		response = (u32)mfa;
 578
 579		if (TW_RESID_OUT(response) == request_id)
 580			found = 1;
 581
 582		if (time_after(jiffies, before + HZ * seconds))
 583			goto out;
 584
 585		msleep(50);
 586	}
 587	retval = 0;
 588out: 
 589	return retval;
 590} /* End twl_poll_response() */
 591
 592/* This function will drain the aen queue */
 593static int twl_aen_drain_queue(TW_Device_Extension *tw_dev, int no_check_reset)
 594{
 595	int request_id = 0;
 596	char cdb[TW_MAX_CDB_LEN];
 597	TW_SG_Entry_ISO sglist[1];
 598	int finished = 0, count = 0;
 599	TW_Command_Full *full_command_packet;
 600	TW_Command_Apache_Header *header;
 601	unsigned short aen;
 602	int first_reset = 0, queue = 0, retval = 1;
 603
 604	if (no_check_reset)
 605		first_reset = 0;
 606	else
 607		first_reset = 1;
 608
 609	full_command_packet = tw_dev->command_packet_virt[request_id];
 610	memset(full_command_packet, 0, sizeof(TW_Command_Full));
 611
 612	/* Initialize cdb */
 613	memset(&cdb, 0, TW_MAX_CDB_LEN);
 614	cdb[0] = REQUEST_SENSE; /* opcode */
 615	cdb[4] = TW_ALLOCATION_LENGTH; /* allocation length */
 616
 617	/* Initialize sglist */
 618	memset(&sglist, 0, sizeof(TW_SG_Entry_ISO));
 619	sglist[0].length = TW_SECTOR_SIZE;
 620	sglist[0].address = tw_dev->generic_buffer_phys[request_id];
 621
 622	/* Mark internal command */
 623	tw_dev->srb[request_id] = NULL;
 624
 625	do {
 626		/* Send command to the board */
 627		if (twl_scsiop_execute_scsi(tw_dev, request_id, cdb, 1, sglist)) {
 628			TW_PRINTK(tw_dev->host, TW_DRIVER, 0x3, "Error posting request sense");
 629			goto out;
 630		}
 631
 632		/* Now poll for completion */
 633		if (twl_poll_response(tw_dev, request_id, 30)) {
 634			TW_PRINTK(tw_dev->host, TW_DRIVER, 0x4, "No valid response while draining AEN queue");
 635			tw_dev->posted_request_count--;
 636			goto out;
 637		}
 638
 639		tw_dev->posted_request_count--;
 640		header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id];
 641		aen = le16_to_cpu(header->status_block.error);
 642		queue = 0;
 643		count++;
 644
 645		switch (aen) {
 646		case TW_AEN_QUEUE_EMPTY:
 647			if (first_reset != 1)
 648				goto out;
 649			else
 650				finished = 1;
 651			break;
 652		case TW_AEN_SOFT_RESET:
 653			if (first_reset == 0)
 654				first_reset = 1;
 655			else
 656				queue = 1;
 657			break;
 658		case TW_AEN_SYNC_TIME_WITH_HOST:
 659			break;
 660		default:
 661			queue = 1;
 662		}
 663
 664		/* Now queue an event info */
 665		if (queue)
 666			twl_aen_queue_event(tw_dev, header);
 667	} while ((finished == 0) && (count < TW_MAX_AEN_DRAIN));
 668
 669	if (count == TW_MAX_AEN_DRAIN)
 670		goto out;
 671
 672	retval = 0;
 673out:
 674	tw_dev->state[request_id] = TW_S_INITIAL;
 675	return retval;
 676} /* End twl_aen_drain_queue() */
 677
 678/* This function will allocate memory and check if it is correctly aligned */
 679static int twl_allocate_memory(TW_Device_Extension *tw_dev, int size, int which)
 680{
 681	int i;
 682	dma_addr_t dma_handle;
 683	unsigned long *cpu_addr;
 684	int retval = 1;
 685
 686	cpu_addr = pci_alloc_consistent(tw_dev->tw_pci_dev, size*TW_Q_LENGTH, &dma_handle);
 
 687	if (!cpu_addr) {
 688		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x5, "Memory allocation failed");
 689		goto out;
 690	}
 691
 692	memset(cpu_addr, 0, size*TW_Q_LENGTH);
 693
 694	for (i = 0; i < TW_Q_LENGTH; i++) {
 695		switch(which) {
 696		case 0:
 697			tw_dev->command_packet_phys[i] = dma_handle+(i*size);
 698			tw_dev->command_packet_virt[i] = (TW_Command_Full *)((unsigned char *)cpu_addr + (i*size));
 699			break;
 700		case 1:
 701			tw_dev->generic_buffer_phys[i] = dma_handle+(i*size);
 702			tw_dev->generic_buffer_virt[i] = (unsigned long *)((unsigned char *)cpu_addr + (i*size));
 703			break;
 704		case 2:
 705			tw_dev->sense_buffer_phys[i] = dma_handle+(i*size);
 706			tw_dev->sense_buffer_virt[i] = (TW_Command_Apache_Header *)((unsigned char *)cpu_addr + (i*size));
 707			break;
 708		}
 709	}
 710	retval = 0;
 711out:
 712	return retval;
 713} /* End twl_allocate_memory() */
 714
 715/* This function will load the request id and various sgls for ioctls */
 716static void twl_load_sgl(TW_Device_Extension *tw_dev, TW_Command_Full *full_command_packet, int request_id, dma_addr_t dma_handle, int length)
 717{
 718	TW_Command *oldcommand;
 719	TW_Command_Apache *newcommand;
 720	TW_SG_Entry_ISO *sgl;
 721	unsigned int pae = 0;
 722
 723	if ((sizeof(long) < 8) && (sizeof(dma_addr_t) > 4))
 724		pae = 1;
 725
 726	if (TW_OP_OUT(full_command_packet->command.newcommand.opcode__reserved) == TW_OP_EXECUTE_SCSI) {
 727		newcommand = &full_command_packet->command.newcommand;
 728		newcommand->request_id__lunl =
 729			cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->request_id__lunl), request_id));
 730		if (length) {
 731			newcommand->sg_list[0].address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1);
 732			newcommand->sg_list[0].length = TW_CPU_TO_SGL(length);
 733		}
 734		newcommand->sgl_entries__lunh =
 735			cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->sgl_entries__lunh), length ? 1 : 0));
 736	} else {
 737		oldcommand = &full_command_packet->command.oldcommand;
 738		oldcommand->request_id = request_id;
 739
 740		if (TW_SGL_OUT(oldcommand->opcode__sgloffset)) {
 741			/* Load the sg list */
 742			sgl = (TW_SG_Entry_ISO *)((u32 *)oldcommand+oldcommand->size - (sizeof(TW_SG_Entry_ISO)/4) + pae + (sizeof(dma_addr_t) > 4 ? 1 : 0));
 743			sgl->address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1);
 744			sgl->length = TW_CPU_TO_SGL(length);
 745			oldcommand->size += pae;
 746			oldcommand->size += sizeof(dma_addr_t) > 4 ? 1 : 0;
 747		}
 748	}
 749} /* End twl_load_sgl() */
 750
 751/* This function handles ioctl for the character device
 752   This interface is used by smartmontools open source software */
 753static long twl_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 754{
 755	long timeout;
 756	unsigned long *cpu_addr, data_buffer_length_adjusted = 0, flags = 0;
 757	dma_addr_t dma_handle;
 758	int request_id = 0;
 759	TW_Ioctl_Driver_Command driver_command;
 760	struct inode *inode = file->f_dentry->d_inode;
 761	TW_Ioctl_Buf_Apache *tw_ioctl;
 762	TW_Command_Full *full_command_packet;
 763	TW_Device_Extension *tw_dev = twl_device_extension_list[iminor(inode)];
 764	int retval = -EFAULT;
 765	void __user *argp = (void __user *)arg;
 766
 767	mutex_lock(&twl_chrdev_mutex);
 768
 769	/* Only let one of these through at a time */
 770	if (mutex_lock_interruptible(&tw_dev->ioctl_lock)) {
 771		retval = -EINTR;
 772		goto out;
 773	}
 774
 775	/* First copy down the driver command */
 776	if (copy_from_user(&driver_command, argp, sizeof(TW_Ioctl_Driver_Command)))
 777		goto out2;
 778
 779	/* Check data buffer size */
 780	if (driver_command.buffer_length > TW_MAX_SECTORS * 2048) {
 781		retval = -EINVAL;
 782		goto out2;
 783	}
 784
 785	/* Hardware can only do multiple of 512 byte transfers */
 786	data_buffer_length_adjusted = (driver_command.buffer_length + 511) & ~511;
 787
 788	/* Now allocate ioctl buf memory */
 789	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);
 790	if (!cpu_addr) {
 791		retval = -ENOMEM;
 792		goto out2;
 793	}
 794
 795	tw_ioctl = (TW_Ioctl_Buf_Apache *)cpu_addr;
 796
 797	/* Now copy down the entire ioctl */
 798	if (copy_from_user(tw_ioctl, argp, driver_command.buffer_length + sizeof(TW_Ioctl_Buf_Apache) - 1))
 799		goto out3;
 800
 801	/* See which ioctl we are doing */
 802	switch (cmd) {
 803	case TW_IOCTL_FIRMWARE_PASS_THROUGH:
 804		spin_lock_irqsave(tw_dev->host->host_lock, flags);
 805		twl_get_request_id(tw_dev, &request_id);
 806
 807		/* Flag internal command */
 808		tw_dev->srb[request_id] = NULL;
 809
 810		/* Flag chrdev ioctl */
 811		tw_dev->chrdev_request_id = request_id;
 812
 813		full_command_packet = (TW_Command_Full *)&tw_ioctl->firmware_command;
 814
 815		/* Load request id and sglist for both command types */
 816		twl_load_sgl(tw_dev, full_command_packet, request_id, dma_handle, data_buffer_length_adjusted);
 817
 818		memcpy(tw_dev->command_packet_virt[request_id], &(tw_ioctl->firmware_command), sizeof(TW_Command_Full));
 819
 820		/* Now post the command packet to the controller */
 821		twl_post_command_packet(tw_dev, request_id);
 822		spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
 823
 824		timeout = TW_IOCTL_CHRDEV_TIMEOUT*HZ;
 825
 826		/* Now wait for command to complete */
 827		timeout = wait_event_timeout(tw_dev->ioctl_wqueue, tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE, timeout);
 828
 829		/* We timed out, and didn't get an interrupt */
 830		if (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE) {
 831			/* Now we need to reset the board */
 832			printk(KERN_WARNING "3w-sas: scsi%d: WARNING: (0x%02X:0x%04X): Character ioctl (0x%x) timed out, resetting card.\n",
 833			       tw_dev->host->host_no, TW_DRIVER, 0x6,
 834			       cmd);
 835			retval = -EIO;
 836			twl_reset_device_extension(tw_dev, 1);
 837			goto out3;
 838		}
 839
 840		/* Now copy in the command packet response */
 841		memcpy(&(tw_ioctl->firmware_command), tw_dev->command_packet_virt[request_id], sizeof(TW_Command_Full));
 842		
 843		/* Now complete the io */
 844		spin_lock_irqsave(tw_dev->host->host_lock, flags);
 845		tw_dev->posted_request_count--;
 846		tw_dev->state[request_id] = TW_S_COMPLETED;
 847		twl_free_request_id(tw_dev, request_id);
 848		spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
 849		break;
 850	default:
 851		retval = -ENOTTY;
 852		goto out3;
 853	}
 854
 855	/* Now copy the entire response to userspace */
 856	if (copy_to_user(argp, tw_ioctl, sizeof(TW_Ioctl_Buf_Apache) + driver_command.buffer_length - 1) == 0)
 857		retval = 0;
 858out3:
 859	/* Now free ioctl buf memory */
 860	dma_free_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_Ioctl_Buf_Apache) - 1, cpu_addr, dma_handle);
 861out2:
 862	mutex_unlock(&tw_dev->ioctl_lock);
 863out:
 864	mutex_unlock(&twl_chrdev_mutex);
 865	return retval;
 866} /* End twl_chrdev_ioctl() */
 867
 868/* This function handles open for the character device */
 869static int twl_chrdev_open(struct inode *inode, struct file *file)
 870{
 871	unsigned int minor_number;
 872	int retval = -ENODEV;
 873
 874	if (!capable(CAP_SYS_ADMIN)) {
 875		retval = -EACCES;
 876		goto out;
 877	}
 878
 879	minor_number = iminor(inode);
 880	if (minor_number >= twl_device_extension_count)
 881		goto out;
 882	retval = 0;
 883out:
 884	return retval;
 885} /* End twl_chrdev_open() */
 886
 887/* File operations struct for character device */
 888static const struct file_operations twl_fops = {
 889	.owner		= THIS_MODULE,
 890	.unlocked_ioctl	= twl_chrdev_ioctl,
 891	.open		= twl_chrdev_open,
 892	.release	= NULL,
 893	.llseek		= noop_llseek,
 894};
 895
 896/* This function passes sense data from firmware to scsi layer */
 897static int twl_fill_sense(TW_Device_Extension *tw_dev, int i, int request_id, int copy_sense, int print_host)
 898{
 899	TW_Command_Apache_Header *header;
 900	TW_Command_Full *full_command_packet;
 901	unsigned short error;
 902	char *error_str;
 903	int retval = 1;
 904
 905	header = tw_dev->sense_buffer_virt[i];
 906	full_command_packet = tw_dev->command_packet_virt[request_id];
 907
 908	/* Get embedded firmware error string */
 909	error_str = &(header->err_specific_desc[strlen(header->err_specific_desc) + 1]);
 910
 911	/* Don't print error for Logical unit not supported during rollcall */
 912	error = le16_to_cpu(header->status_block.error);
 913	if ((error != TW_ERROR_LOGICAL_UNIT_NOT_SUPPORTED) && (error != TW_ERROR_UNIT_OFFLINE) && (error != TW_ERROR_INVALID_FIELD_IN_CDB)) {
 914		if (print_host)
 915			printk(KERN_WARNING "3w-sas: scsi%d: ERROR: (0x%02X:0x%04X): %s:%s.\n",
 916			       tw_dev->host->host_no,
 917			       TW_MESSAGE_SOURCE_CONTROLLER_ERROR,
 918			       header->status_block.error,
 919			       error_str, 
 920			       header->err_specific_desc);
 921		else
 922			printk(KERN_WARNING "3w-sas: ERROR: (0x%02X:0x%04X): %s:%s.\n",
 923			       TW_MESSAGE_SOURCE_CONTROLLER_ERROR,
 924			       header->status_block.error,
 925			       error_str,
 926			       header->err_specific_desc);
 927	}
 928
 929	if (copy_sense) {
 930		memcpy(tw_dev->srb[request_id]->sense_buffer, header->sense_data, TW_SENSE_DATA_LENGTH);
 931		tw_dev->srb[request_id]->result = (full_command_packet->command.newcommand.status << 1);
 932		goto out;
 933	}
 934out:
 935	return retval;
 936} /* End twl_fill_sense() */
 937
 938/* This function will free up device extension resources */
 939static void twl_free_device_extension(TW_Device_Extension *tw_dev)
 940{
 941	if (tw_dev->command_packet_virt[0])
 942		pci_free_consistent(tw_dev->tw_pci_dev,
 943				    sizeof(TW_Command_Full)*TW_Q_LENGTH,
 944				    tw_dev->command_packet_virt[0],
 945				    tw_dev->command_packet_phys[0]);
 946
 947	if (tw_dev->generic_buffer_virt[0])
 948		pci_free_consistent(tw_dev->tw_pci_dev,
 949				    TW_SECTOR_SIZE*TW_Q_LENGTH,
 950				    tw_dev->generic_buffer_virt[0],
 951				    tw_dev->generic_buffer_phys[0]);
 952
 953	if (tw_dev->sense_buffer_virt[0])
 954		pci_free_consistent(tw_dev->tw_pci_dev,
 955				    sizeof(TW_Command_Apache_Header)*
 956				    TW_Q_LENGTH,
 957				    tw_dev->sense_buffer_virt[0],
 958				    tw_dev->sense_buffer_phys[0]);
 959
 960	kfree(tw_dev->event_queue[0]);
 961} /* End twl_free_device_extension() */
 962
 963/* This function will get parameter table entries from the firmware */
 964static void *twl_get_param(TW_Device_Extension *tw_dev, int request_id, int table_id, int parameter_id, int parameter_size_bytes)
 965{
 966	TW_Command_Full *full_command_packet;
 967	TW_Command *command_packet;
 968	TW_Param_Apache *param;
 969	void *retval = NULL;
 970
 971	/* Setup the command packet */
 972	full_command_packet = tw_dev->command_packet_virt[request_id];
 973	memset(full_command_packet, 0, sizeof(TW_Command_Full));
 974	command_packet = &full_command_packet->command.oldcommand;
 975
 976	command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
 977	command_packet->size              = TW_COMMAND_SIZE;
 978	command_packet->request_id        = request_id;
 979	command_packet->byte6_offset.block_count = cpu_to_le16(1);
 980
 981	/* Now setup the param */
 982	param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id];
 983	memset(param, 0, TW_SECTOR_SIZE);
 984	param->table_id = cpu_to_le16(table_id | 0x8000);
 985	param->parameter_id = cpu_to_le16(parameter_id);
 986	param->parameter_size_bytes = cpu_to_le16(parameter_size_bytes);
 987
 988	command_packet->byte8_offset.param.sgl[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]);
 989	command_packet->byte8_offset.param.sgl[0].length = TW_CPU_TO_SGL(TW_SECTOR_SIZE);
 990
 991	/* Post the command packet to the board */
 992	twl_post_command_packet(tw_dev, request_id);
 993
 994	/* Poll for completion */
 995	if (twl_poll_response(tw_dev, request_id, 30))
 996		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x7, "No valid response during get param")
 997	else
 998		retval = (void *)&(param->data[0]);
 999
1000	tw_dev->posted_request_count--;
1001	tw_dev->state[request_id] = TW_S_INITIAL;
1002
1003	return retval;
1004} /* End twl_get_param() */
1005
1006/* This function will send an initconnection command to controller */
1007static int twl_initconnection(TW_Device_Extension *tw_dev, int message_credits,
1008 			      u32 set_features, unsigned short current_fw_srl, 
1009			      unsigned short current_fw_arch_id, 
1010			      unsigned short current_fw_branch, 
1011			      unsigned short current_fw_build, 
1012			      unsigned short *fw_on_ctlr_srl, 
1013			      unsigned short *fw_on_ctlr_arch_id, 
1014			      unsigned short *fw_on_ctlr_branch, 
1015			      unsigned short *fw_on_ctlr_build, 
1016			      u32 *init_connect_result)
1017{
1018	TW_Command_Full *full_command_packet;
1019	TW_Initconnect *tw_initconnect;
1020	int request_id = 0, retval = 1;
1021
1022	/* Initialize InitConnection command packet */
1023	full_command_packet = tw_dev->command_packet_virt[request_id];
1024	memset(full_command_packet, 0, sizeof(TW_Command_Full));
1025	full_command_packet->header.header_desc.size_header = 128;
1026	
1027	tw_initconnect = (TW_Initconnect *)&full_command_packet->command.oldcommand;
1028	tw_initconnect->opcode__reserved = TW_OPRES_IN(0, TW_OP_INIT_CONNECTION);
1029	tw_initconnect->request_id = request_id;
1030	tw_initconnect->message_credits = cpu_to_le16(message_credits);
1031	tw_initconnect->features = set_features;
1032
1033	/* Turn on 64-bit sgl support if we need to */
1034	tw_initconnect->features |= sizeof(dma_addr_t) > 4 ? 1 : 0;
1035
1036	tw_initconnect->features = cpu_to_le32(tw_initconnect->features);
1037
1038	if (set_features & TW_EXTENDED_INIT_CONNECT) {
1039		tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE_EXTENDED;
1040		tw_initconnect->fw_srl = cpu_to_le16(current_fw_srl);
1041		tw_initconnect->fw_arch_id = cpu_to_le16(current_fw_arch_id);
1042		tw_initconnect->fw_branch = cpu_to_le16(current_fw_branch);
1043		tw_initconnect->fw_build = cpu_to_le16(current_fw_build);
1044	} else 
1045		tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE;
1046
1047	/* Send command packet to the board */
1048	twl_post_command_packet(tw_dev, request_id);
1049
1050	/* Poll for completion */
1051	if (twl_poll_response(tw_dev, request_id, 30)) {
1052		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x8, "No valid response during init connection");
1053	} else {
1054		if (set_features & TW_EXTENDED_INIT_CONNECT) {
1055			*fw_on_ctlr_srl = le16_to_cpu(tw_initconnect->fw_srl);
1056			*fw_on_ctlr_arch_id = le16_to_cpu(tw_initconnect->fw_arch_id);
1057			*fw_on_ctlr_branch = le16_to_cpu(tw_initconnect->fw_branch);
1058			*fw_on_ctlr_build = le16_to_cpu(tw_initconnect->fw_build);
1059			*init_connect_result = le32_to_cpu(tw_initconnect->result);
1060		}
1061		retval = 0;
1062	}
1063
1064	tw_dev->posted_request_count--;
1065	tw_dev->state[request_id] = TW_S_INITIAL;
1066
1067	return retval;
1068} /* End twl_initconnection() */
1069
1070/* This function will initialize the fields of a device extension */
1071static int twl_initialize_device_extension(TW_Device_Extension *tw_dev)
1072{
1073	int i, retval = 1;
1074
1075	/* Initialize command packet buffers */
1076	if (twl_allocate_memory(tw_dev, sizeof(TW_Command_Full), 0)) {
1077		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x9, "Command packet memory allocation failed");
1078		goto out;
1079	}
1080
1081	/* Initialize generic buffer */
1082	if (twl_allocate_memory(tw_dev, TW_SECTOR_SIZE, 1)) {
1083		TW_PRINTK(tw_dev->host, TW_DRIVER, 0xa, "Generic memory allocation failed");
1084		goto out;
1085	}
1086
1087	/* Allocate sense buffers */
1088	if (twl_allocate_memory(tw_dev, sizeof(TW_Command_Apache_Header), 2)) {
1089		TW_PRINTK(tw_dev->host, TW_DRIVER, 0xb, "Sense buffer allocation failed");
1090		goto out;
1091	}
1092
1093	/* Allocate event info space */
1094	tw_dev->event_queue[0] = kcalloc(TW_Q_LENGTH, sizeof(TW_Event), GFP_KERNEL);
1095	if (!tw_dev->event_queue[0]) {
1096		TW_PRINTK(tw_dev->host, TW_DRIVER, 0xc, "Event info memory allocation failed");
1097		goto out;
1098	}
1099
1100	for (i = 0; i < TW_Q_LENGTH; i++) {
1101		tw_dev->event_queue[i] = (TW_Event *)((unsigned char *)tw_dev->event_queue[0] + (i * sizeof(TW_Event)));
1102		tw_dev->free_queue[i] = i;
1103		tw_dev->state[i] = TW_S_INITIAL;
1104	}
1105
1106	tw_dev->free_head = TW_Q_START;
1107	tw_dev->free_tail = TW_Q_START;
1108	tw_dev->error_sequence_id = 1;
1109	tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1110
1111	mutex_init(&tw_dev->ioctl_lock);
1112	init_waitqueue_head(&tw_dev->ioctl_wqueue);
1113
1114	retval = 0;
1115out:
1116	return retval;
1117} /* End twl_initialize_device_extension() */
1118
1119/* This function will perform a pci-dma unmap */
1120static void twl_unmap_scsi_data(TW_Device_Extension *tw_dev, int request_id)
1121{
1122	struct scsi_cmnd *cmd = tw_dev->srb[request_id];
1123
1124	if (cmd->SCp.phase == TW_PHASE_SGLIST)
1125		scsi_dma_unmap(cmd);
1126} /* End twl_unmap_scsi_data() */
1127
1128/* This function will handle attention interrupts */
1129static int twl_handle_attention_interrupt(TW_Device_Extension *tw_dev)
1130{
1131	int retval = 1;
1132	u32 request_id, doorbell;
1133
1134	/* Read doorbell status */
1135	doorbell = readl(TWL_HOBDB_REG_ADDR(tw_dev));
1136
1137	/* Check for controller errors */
1138	if (doorbell & TWL_DOORBELL_CONTROLLER_ERROR) {
1139		TW_PRINTK(tw_dev->host, TW_DRIVER, 0xd, "Microcontroller Error: clearing");
1140		goto out;
1141	}
1142
1143	/* Check if we need to perform an AEN drain */
1144	if (doorbell & TWL_DOORBELL_ATTENTION_INTERRUPT) {
1145		if (!(test_and_set_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags))) {
1146			twl_get_request_id(tw_dev, &request_id);
1147			if (twl_aen_read_queue(tw_dev, request_id)) {
1148				tw_dev->state[request_id] = TW_S_COMPLETED;
1149				twl_free_request_id(tw_dev, request_id);
1150				clear_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags);
1151			}
1152		}
1153	}
1154
1155	retval = 0;
1156out:
1157	/* Clear doorbell interrupt */
1158	TWL_CLEAR_DB_INTERRUPT(tw_dev);
1159
1160	/* Make sure the clear was flushed by reading it back */
1161	readl(TWL_HOBDBC_REG_ADDR(tw_dev));
1162
1163	return retval;
1164} /* End twl_handle_attention_interrupt() */
1165
1166/* Interrupt service routine */
1167static irqreturn_t twl_interrupt(int irq, void *dev_instance)
1168{
1169	TW_Device_Extension *tw_dev = (TW_Device_Extension *)dev_instance;
1170	int i, handled = 0, error = 0;
1171	dma_addr_t mfa = 0;
1172	u32 reg, regl, regh, response, request_id = 0;
1173	struct scsi_cmnd *cmd;
1174	TW_Command_Full *full_command_packet;
1175
1176	spin_lock(tw_dev->host->host_lock);
1177
1178	/* Read host interrupt status */
1179	reg = readl(TWL_HISTAT_REG_ADDR(tw_dev));
1180
1181	/* Check if this is our interrupt, otherwise bail */
1182	if (!(reg & TWL_HISTATUS_VALID_INTERRUPT))
1183		goto twl_interrupt_bail;
1184
1185	handled = 1;
1186
1187	/* If we are resetting, bail */
1188	if (test_bit(TW_IN_RESET, &tw_dev->flags))
1189		goto twl_interrupt_bail;
1190
1191	/* Attention interrupt */
1192	if (reg & TWL_HISTATUS_ATTENTION_INTERRUPT) {
1193		if (twl_handle_attention_interrupt(tw_dev)) {
1194			TWL_MASK_INTERRUPTS(tw_dev);
1195			goto twl_interrupt_bail;
1196		}
1197	}
1198
1199	/* Response interrupt */
1200	while (reg & TWL_HISTATUS_RESPONSE_INTERRUPT) {
1201		if (sizeof(dma_addr_t) > 4) {
1202			regh = readl(TWL_HOBQPH_REG_ADDR(tw_dev));
1203			regl = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
1204			mfa = ((u64)regh << 32) | regl;
1205		} else
1206			mfa = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
1207
1208		error = 0;
1209		response = (u32)mfa;
1210
1211		/* Check for command packet error */
1212		if (!TW_NOTMFA_OUT(response)) {
1213			for (i=0;i<TW_Q_LENGTH;i++) {
1214				if (tw_dev->sense_buffer_phys[i] == mfa) {
1215					request_id = le16_to_cpu(tw_dev->sense_buffer_virt[i]->header_desc.request_id);
1216					if (tw_dev->srb[request_id] != NULL)
1217						error = twl_fill_sense(tw_dev, i, request_id, 1, 1);
1218					else {
1219						/* Skip ioctl error prints */
1220						if (request_id != tw_dev->chrdev_request_id)
1221							error = twl_fill_sense(tw_dev, i, request_id, 0, 1);
1222						else
1223							memcpy(tw_dev->command_packet_virt[request_id], tw_dev->sense_buffer_virt[i], sizeof(TW_Command_Apache_Header));
1224					}
1225
1226					/* Now re-post the sense buffer */
1227					writel((u32)((u64)tw_dev->sense_buffer_phys[i] >> 32), TWL_HOBQPH_REG_ADDR(tw_dev));
1228					writel((u32)tw_dev->sense_buffer_phys[i], TWL_HOBQPL_REG_ADDR(tw_dev));
1229					break;
1230				}
1231			}
1232		} else
1233			request_id = TW_RESID_OUT(response);
1234
1235		full_command_packet = tw_dev->command_packet_virt[request_id];
1236
1237		/* Check for correct state */
1238		if (tw_dev->state[request_id] != TW_S_POSTED) {
1239			if (tw_dev->srb[request_id] != NULL) {
1240				TW_PRINTK(tw_dev->host, TW_DRIVER, 0xe, "Received a request id that wasn't posted");
1241				TWL_MASK_INTERRUPTS(tw_dev);
1242				goto twl_interrupt_bail;
1243			}
1244		}
1245
1246		/* Check for internal command completion */
1247		if (tw_dev->srb[request_id] == NULL) {
1248			if (request_id != tw_dev->chrdev_request_id) {
1249				if (twl_aen_complete(tw_dev, request_id))
1250					TW_PRINTK(tw_dev->host, TW_DRIVER, 0xf, "Error completing AEN during attention interrupt");
1251			} else {
1252				tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1253				wake_up(&tw_dev->ioctl_wqueue);
1254			}
1255		} else {
1256			cmd = tw_dev->srb[request_id];
1257
1258			if (!error)
1259				cmd->result = (DID_OK << 16);
1260			
1261			/* Report residual bytes for single sgl */
1262			if ((scsi_sg_count(cmd) <= 1) && (full_command_packet->command.newcommand.status == 0)) {
1263				if (full_command_packet->command.newcommand.sg_list[0].length < scsi_bufflen(tw_dev->srb[request_id]))
1264					scsi_set_resid(cmd, scsi_bufflen(cmd) - full_command_packet->command.newcommand.sg_list[0].length);
1265			}
1266
1267			/* Now complete the io */
 
 
1268			tw_dev->state[request_id] = TW_S_COMPLETED;
1269			twl_free_request_id(tw_dev, request_id);
1270			tw_dev->posted_request_count--;
1271			tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1272			twl_unmap_scsi_data(tw_dev, request_id);
1273		}
1274
1275		/* Check for another response interrupt */
1276		reg = readl(TWL_HISTAT_REG_ADDR(tw_dev));
1277	}
1278
1279twl_interrupt_bail:
1280	spin_unlock(tw_dev->host->host_lock);
1281	return IRQ_RETVAL(handled);
1282} /* End twl_interrupt() */
1283
1284/* This function will poll for a register change */
1285static int twl_poll_register(TW_Device_Extension *tw_dev, void *reg, u32 value, u32 result, int seconds)
1286{
1287	unsigned long before;
1288	int retval = 1;
1289	u32 reg_value;
1290
1291	reg_value = readl(reg);
1292	before = jiffies;
1293
1294        while ((reg_value & value) != result) {
1295		reg_value = readl(reg);
1296		if (time_after(jiffies, before + HZ * seconds))
1297			goto out;
1298		msleep(50);
1299	}
1300	retval = 0;
1301out:
1302	return retval;
1303} /* End twl_poll_register() */
1304
1305/* This function will reset a controller */
1306static int twl_reset_sequence(TW_Device_Extension *tw_dev, int soft_reset)
1307{
1308	int retval = 1;
1309	int i = 0;
1310	u32 status = 0;
1311	unsigned short fw_on_ctlr_srl = 0, fw_on_ctlr_arch_id = 0;
1312	unsigned short fw_on_ctlr_branch = 0, fw_on_ctlr_build = 0;
1313	u32 init_connect_result = 0;
1314	int tries = 0;
1315	int do_soft_reset = soft_reset;
1316
1317	while (tries < TW_MAX_RESET_TRIES) {
1318		/* Do a soft reset if one is needed */
1319		if (do_soft_reset) {
1320			TWL_SOFT_RESET(tw_dev);
1321
1322			/* Make sure controller is in a good state */
1323			if (twl_poll_register(tw_dev, TWL_SCRPD3_REG_ADDR(tw_dev), TWL_CONTROLLER_READY, 0x0, 30)) {
1324				TW_PRINTK(tw_dev->host, TW_DRIVER, 0x10, "Controller never went non-ready during reset sequence");
1325				tries++;
1326				continue;
1327			}
1328			if (twl_poll_register(tw_dev, TWL_SCRPD3_REG_ADDR(tw_dev), TWL_CONTROLLER_READY, TWL_CONTROLLER_READY, 60)) {
1329				TW_PRINTK(tw_dev->host, TW_DRIVER, 0x11, "Controller not ready during reset sequence");
1330				tries++;
1331				continue;
1332			}
1333		}
1334
1335		/* Initconnect */
1336		if (twl_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS,
1337				       TW_EXTENDED_INIT_CONNECT, TW_CURRENT_DRIVER_SRL,
1338				       TW_9750_ARCH_ID, TW_CURRENT_DRIVER_BRANCH,
1339				       TW_CURRENT_DRIVER_BUILD, &fw_on_ctlr_srl,
1340				       &fw_on_ctlr_arch_id, &fw_on_ctlr_branch,
1341				       &fw_on_ctlr_build, &init_connect_result)) {
1342			TW_PRINTK(tw_dev->host, TW_DRIVER, 0x12, "Initconnection failed while checking SRL");
1343			do_soft_reset = 1;
1344			tries++;
1345			continue;
1346		}
1347
1348		/* Load sense buffers */
1349		while (i < TW_Q_LENGTH) {
1350			writel((u32)((u64)tw_dev->sense_buffer_phys[i] >> 32), TWL_HOBQPH_REG_ADDR(tw_dev));
1351			writel((u32)tw_dev->sense_buffer_phys[i], TWL_HOBQPL_REG_ADDR(tw_dev));
1352
1353			/* Check status for over-run after each write */
1354			status = readl(TWL_STATUS_REG_ADDR(tw_dev));
1355			if (!(status & TWL_STATUS_OVERRUN_SUBMIT))
1356			    i++;
1357		}
1358
1359		/* Now check status */
1360		status = readl(TWL_STATUS_REG_ADDR(tw_dev));
1361		if (status) {
1362			TW_PRINTK(tw_dev->host, TW_DRIVER, 0x13, "Bad controller status after loading sense buffers");
1363			do_soft_reset = 1;
1364			tries++;
1365			continue;
1366		}
1367
1368		/* Drain the AEN queue */
1369		if (twl_aen_drain_queue(tw_dev, soft_reset)) {
1370			TW_PRINTK(tw_dev->host, TW_DRIVER, 0x14, "AEN drain failed during reset sequence");
1371			do_soft_reset = 1;
1372			tries++;
1373			continue;
1374		}
1375
1376		/* Load rest of compatibility struct */
1377		strncpy(tw_dev->tw_compat_info.driver_version, TW_DRIVER_VERSION, strlen(TW_DRIVER_VERSION));
1378		tw_dev->tw_compat_info.driver_srl_high = TW_CURRENT_DRIVER_SRL;
1379		tw_dev->tw_compat_info.driver_branch_high = TW_CURRENT_DRIVER_BRANCH;
1380		tw_dev->tw_compat_info.driver_build_high = TW_CURRENT_DRIVER_BUILD;
1381		tw_dev->tw_compat_info.driver_srl_low = TW_BASE_FW_SRL;
1382		tw_dev->tw_compat_info.driver_branch_low = TW_BASE_FW_BRANCH;
1383		tw_dev->tw_compat_info.driver_build_low = TW_BASE_FW_BUILD;
1384		tw_dev->tw_compat_info.fw_on_ctlr_srl = fw_on_ctlr_srl;
1385		tw_dev->tw_compat_info.fw_on_ctlr_branch = fw_on_ctlr_branch;
1386		tw_dev->tw_compat_info.fw_on_ctlr_build = fw_on_ctlr_build;
1387
1388		/* If we got here, controller is in a good state */
1389		retval = 0;
1390		goto out;
1391	}
1392out:
1393	return retval;
1394} /* End twl_reset_sequence() */
1395
1396/* This function will reset a device extension */
1397static int twl_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_reset)
1398{
1399	int i = 0, retval = 1;
1400	unsigned long flags = 0;
1401
1402	/* Block SCSI requests while we are resetting */
1403	if (ioctl_reset)
1404		scsi_block_requests(tw_dev->host);
1405
1406	set_bit(TW_IN_RESET, &tw_dev->flags);
1407	TWL_MASK_INTERRUPTS(tw_dev);
1408	TWL_CLEAR_DB_INTERRUPT(tw_dev);
1409
1410	spin_lock_irqsave(tw_dev->host->host_lock, flags);
1411
1412	/* Abort all requests that are in progress */
1413	for (i = 0; i < TW_Q_LENGTH; i++) {
1414		if ((tw_dev->state[i] != TW_S_FINISHED) &&
1415		    (tw_dev->state[i] != TW_S_INITIAL) &&
1416		    (tw_dev->state[i] != TW_S_COMPLETED)) {
1417			if (tw_dev->srb[i]) {
1418				tw_dev->srb[i]->result = (DID_RESET << 16);
1419				tw_dev->srb[i]->scsi_done(tw_dev->srb[i]);
1420				twl_unmap_scsi_data(tw_dev, i);
 
 
1421			}
1422		}
1423	}
1424
1425	/* Reset queues and counts */
1426	for (i = 0; i < TW_Q_LENGTH; i++) {
1427		tw_dev->free_queue[i] = i;
1428		tw_dev->state[i] = TW_S_INITIAL;
1429	}
1430	tw_dev->free_head = TW_Q_START;
1431	tw_dev->free_tail = TW_Q_START;
1432	tw_dev->posted_request_count = 0;
1433
1434	spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
1435
1436	if (twl_reset_sequence(tw_dev, 1))
1437		goto out;
1438
1439	TWL_UNMASK_INTERRUPTS(tw_dev);
1440
1441	clear_bit(TW_IN_RESET, &tw_dev->flags);
1442	tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1443
1444	retval = 0;
1445out:
1446	if (ioctl_reset)
1447		scsi_unblock_requests(tw_dev->host);
1448	return retval;
1449} /* End twl_reset_device_extension() */
1450
1451/* This funciton returns unit geometry in cylinders/heads/sectors */
1452static int twl_scsi_biosparam(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int geom[])
1453{
1454	int heads, sectors;
1455	TW_Device_Extension *tw_dev;
1456
1457	tw_dev = (TW_Device_Extension *)sdev->host->hostdata;
1458
1459	if (capacity >= 0x200000) {
1460		heads = 255;
1461		sectors = 63;
1462	} else {
1463		heads = 64;
1464		sectors = 32;
1465	}
1466
1467	geom[0] = heads;
1468	geom[1] = sectors;
1469	geom[2] = sector_div(capacity, heads * sectors); /* cylinders */
1470
1471	return 0;
1472} /* End twl_scsi_biosparam() */
1473
1474/* This is the new scsi eh reset function */
1475static int twl_scsi_eh_reset(struct scsi_cmnd *SCpnt)
1476{
1477	TW_Device_Extension *tw_dev = NULL;
1478	int retval = FAILED;
1479
1480	tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
1481
1482	tw_dev->num_resets++;
1483
1484	sdev_printk(KERN_WARNING, SCpnt->device,
1485		"WARNING: (0x%02X:0x%04X): Command (0x%x) timed out, resetting card.\n",
1486		TW_DRIVER, 0x2c, SCpnt->cmnd[0]);
1487
1488	/* Make sure we are not issuing an ioctl or resetting from ioctl */
1489	mutex_lock(&tw_dev->ioctl_lock);
1490
1491	/* Now reset the card and some of the device extension data */
1492	if (twl_reset_device_extension(tw_dev, 0)) {
1493		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x15, "Controller reset failed during scsi host reset");
1494		goto out;
1495	}
1496
1497	retval = SUCCESS;
1498out:
1499	mutex_unlock(&tw_dev->ioctl_lock);
1500	return retval;
1501} /* End twl_scsi_eh_reset() */
1502
1503/* This is the main scsi queue function to handle scsi opcodes */
1504static int twl_scsi_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1505{
1506	int request_id, retval;
1507	TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
1508
1509	/* If we are resetting due to timed out ioctl, report as busy */
1510	if (test_bit(TW_IN_RESET, &tw_dev->flags)) {
1511		retval = SCSI_MLQUEUE_HOST_BUSY;
1512		goto out;
1513	}
1514
1515	/* Save done function into scsi_cmnd struct */
1516	SCpnt->scsi_done = done;
1517		
1518	/* Get a free request id */
1519	twl_get_request_id(tw_dev, &request_id);
1520
1521	/* Save the scsi command for use by the ISR */
1522	tw_dev->srb[request_id] = SCpnt;
1523
1524	/* Initialize phase to zero */
1525	SCpnt->SCp.phase = TW_PHASE_INITIAL;
1526
1527	retval = twl_scsiop_execute_scsi(tw_dev, request_id, NULL, 0, NULL);
1528	if (retval) {
1529		tw_dev->state[request_id] = TW_S_COMPLETED;
1530		twl_free_request_id(tw_dev, request_id);
1531		SCpnt->result = (DID_ERROR << 16);
1532		done(SCpnt);
1533		retval = 0;
1534	}
1535out:
1536	return retval;
1537} /* End twl_scsi_queue() */
1538
1539static DEF_SCSI_QCMD(twl_scsi_queue)
1540
1541/* This function tells the controller to shut down */
1542static void __twl_shutdown(TW_Device_Extension *tw_dev)
1543{
1544	/* Disable interrupts */
1545	TWL_MASK_INTERRUPTS(tw_dev);
1546
1547	/* Free up the IRQ */
1548	free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
1549
1550	printk(KERN_WARNING "3w-sas: Shutting down host %d.\n", tw_dev->host->host_no);
1551
1552	/* Tell the card we are shutting down */
1553	if (twl_initconnection(tw_dev, 1, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL)) {
1554		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x16, "Connection shutdown failed");
1555	} else {
1556		printk(KERN_WARNING "3w-sas: Shutdown complete.\n");
1557	}
1558
1559	/* Clear doorbell interrupt just before exit */
1560	TWL_CLEAR_DB_INTERRUPT(tw_dev);
1561} /* End __twl_shutdown() */
1562
1563/* Wrapper for __twl_shutdown */
1564static void twl_shutdown(struct pci_dev *pdev)
1565{
1566	struct Scsi_Host *host = pci_get_drvdata(pdev);
1567	TW_Device_Extension *tw_dev;
1568
1569	if (!host)
1570		return;
1571
1572	tw_dev = (TW_Device_Extension *)host->hostdata;
1573
1574	if (tw_dev->online) 
1575		__twl_shutdown(tw_dev);
1576} /* End twl_shutdown() */
1577
1578/* This function configures unit settings when a unit is coming on-line */
1579static int twl_slave_configure(struct scsi_device *sdev)
1580{
1581	/* Force 60 second timeout */
1582	blk_queue_rq_timeout(sdev->request_queue, 60 * HZ);
1583
1584	return 0;
1585} /* End twl_slave_configure() */
1586
1587/* scsi_host_template initializer */
1588static struct scsi_host_template driver_template = {
1589	.module			= THIS_MODULE,
1590	.name			= "3w-sas",
1591	.queuecommand		= twl_scsi_queue,
1592	.eh_host_reset_handler	= twl_scsi_eh_reset,
1593	.bios_param		= twl_scsi_biosparam,
1594	.change_queue_depth	= twl_change_queue_depth,
1595	.can_queue		= TW_Q_LENGTH-2,
1596	.slave_configure	= twl_slave_configure,
1597	.this_id		= -1,
1598	.sg_tablesize		= TW_LIBERATOR_MAX_SGL_LENGTH,
1599	.max_sectors		= TW_MAX_SECTORS,
1600	.cmd_per_lun		= TW_MAX_CMDS_PER_LUN,
1601	.use_clustering		= ENABLE_CLUSTERING,
1602	.shost_attrs		= twl_host_attrs,
1603	.emulated		= 1
 
1604};
1605
1606/* This function will probe and initialize a card */
1607static int __devinit twl_probe(struct pci_dev *pdev, const struct pci_device_id *dev_id)
1608{
1609	struct Scsi_Host *host = NULL;
1610	TW_Device_Extension *tw_dev;
1611	int retval = -ENODEV;
1612	int *ptr_phycount, phycount=0;
1613
1614	retval = pci_enable_device(pdev);
1615	if (retval) {
1616		TW_PRINTK(host, TW_DRIVER, 0x17, "Failed to enable pci device");
1617		goto out_disable_device;
1618	}
1619
1620	pci_set_master(pdev);
1621	pci_try_set_mwi(pdev);
1622
1623	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
1624	    || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)))
1625		if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1626		    || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
1627			TW_PRINTK(host, TW_DRIVER, 0x18, "Failed to set dma mask");
1628			retval = -ENODEV;
1629			goto out_disable_device;
1630		}
1631
1632	host = scsi_host_alloc(&driver_template, sizeof(TW_Device_Extension));
1633	if (!host) {
1634		TW_PRINTK(host, TW_DRIVER, 0x19, "Failed to allocate memory for device extension");
1635		retval = -ENOMEM;
1636		goto out_disable_device;
1637	}
1638	tw_dev = shost_priv(host);
1639
1640	/* Save values to device extension */
1641	tw_dev->host = host;
1642	tw_dev->tw_pci_dev = pdev;
1643
1644	if (twl_initialize_device_extension(tw_dev)) {
1645		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1a, "Failed to initialize device extension");
1646		goto out_free_device_extension;
1647	}
1648
1649	/* Request IO regions */
1650	retval = pci_request_regions(pdev, "3w-sas");
1651	if (retval) {
1652		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1b, "Failed to get mem region");
1653		goto out_free_device_extension;
1654	}
1655
1656	/* Save base address, use region 1 */
1657	tw_dev->base_addr = pci_iomap(pdev, 1, 0);
1658	if (!tw_dev->base_addr) {
1659		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1c, "Failed to ioremap");
1660		goto out_release_mem_region;
1661	}
1662
1663	/* Disable interrupts on the card */
1664	TWL_MASK_INTERRUPTS(tw_dev);
1665
1666	/* Initialize the card */
1667	if (twl_reset_sequence(tw_dev, 0)) {
1668		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1d, "Controller reset failed during probe");
1669		goto out_iounmap;
1670	}
1671
1672	/* Set host specific parameters */
1673	host->max_id = TW_MAX_UNITS;
1674	host->max_cmd_len = TW_MAX_CDB_LEN;
1675	host->max_lun = TW_MAX_LUNS;
1676	host->max_channel = 0;
1677
1678	/* Register the card with the kernel SCSI layer */
1679	retval = scsi_add_host(host, &pdev->dev);
1680	if (retval) {
1681		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1e, "scsi add host failed");
1682		goto out_iounmap;
1683	}
1684
1685	pci_set_drvdata(pdev, host);
1686
1687	printk(KERN_WARNING "3w-sas: scsi%d: Found an LSI 3ware %s Controller at 0x%llx, IRQ: %d.\n",
1688	       host->host_no,
1689	       (char *)twl_get_param(tw_dev, 1, TW_VERSION_TABLE,
1690				     TW_PARAM_MODEL, TW_PARAM_MODEL_LENGTH),
1691	       (u64)pci_resource_start(pdev, 1), pdev->irq);
1692
1693	ptr_phycount = twl_get_param(tw_dev, 2, TW_PARAM_PHY_SUMMARY_TABLE,
1694				     TW_PARAM_PHYCOUNT, TW_PARAM_PHYCOUNT_LENGTH);
1695	if (ptr_phycount)
1696		phycount = le32_to_cpu(*(int *)ptr_phycount);
1697
1698	printk(KERN_WARNING "3w-sas: scsi%d: Firmware %s, BIOS %s, Phys: %d.\n",
1699	       host->host_no,
1700	       (char *)twl_get_param(tw_dev, 1, TW_VERSION_TABLE,
1701				     TW_PARAM_FWVER, TW_PARAM_FWVER_LENGTH),
1702	       (char *)twl_get_param(tw_dev, 2, TW_VERSION_TABLE,
1703				     TW_PARAM_BIOSVER, TW_PARAM_BIOSVER_LENGTH),
1704	       phycount);
1705
1706	/* Try to enable MSI */
1707	if (use_msi && !pci_enable_msi(pdev))
1708		set_bit(TW_USING_MSI, &tw_dev->flags);
1709
1710	/* Now setup the interrupt handler */
1711	retval = request_irq(pdev->irq, twl_interrupt, IRQF_SHARED, "3w-sas", tw_dev);
1712	if (retval) {
1713		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1f, "Error requesting IRQ");
1714		goto out_remove_host;
1715	}
1716
1717	twl_device_extension_list[twl_device_extension_count] = tw_dev;
1718	twl_device_extension_count++;
1719
1720	/* Re-enable interrupts on the card */
1721	TWL_UNMASK_INTERRUPTS(tw_dev);
1722	
1723	/* Finally, scan the host */
1724	scsi_scan_host(host);
1725
1726	/* Add sysfs binary files */
1727	if (sysfs_create_bin_file(&host->shost_dev.kobj, &twl_sysfs_aen_read_attr))
1728		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x20, "Failed to create sysfs binary file: 3ware_aen_read");
1729	if (sysfs_create_bin_file(&host->shost_dev.kobj, &twl_sysfs_compat_info_attr))
1730		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x21, "Failed to create sysfs binary file: 3ware_compat_info");
1731
1732	if (twl_major == -1) {
1733		if ((twl_major = register_chrdev (0, "twl", &twl_fops)) < 0)
1734			TW_PRINTK(host, TW_DRIVER, 0x22, "Failed to register character device");
1735	}
1736	tw_dev->online = 1;
1737	return 0;
1738
1739out_remove_host:
1740	if (test_bit(TW_USING_MSI, &tw_dev->flags))
1741		pci_disable_msi(pdev);
1742	scsi_remove_host(host);
1743out_iounmap:
1744	iounmap(tw_dev->base_addr);
1745out_release_mem_region:
1746	pci_release_regions(pdev);
1747out_free_device_extension:
1748	twl_free_device_extension(tw_dev);
1749	scsi_host_put(host);
1750out_disable_device:
1751	pci_disable_device(pdev);
1752
1753	return retval;
1754} /* End twl_probe() */
1755
1756/* This function is called to remove a device */
1757static void twl_remove(struct pci_dev *pdev)
1758{
1759	struct Scsi_Host *host = pci_get_drvdata(pdev);
1760	TW_Device_Extension *tw_dev;
1761
1762	if (!host)
1763		return;
1764
1765	tw_dev = (TW_Device_Extension *)host->hostdata;
1766
1767	if (!tw_dev->online)
1768		return;
1769
1770	/* Remove sysfs binary files */
1771	sysfs_remove_bin_file(&host->shost_dev.kobj, &twl_sysfs_aen_read_attr);
1772	sysfs_remove_bin_file(&host->shost_dev.kobj, &twl_sysfs_compat_info_attr);
1773
1774	scsi_remove_host(tw_dev->host);
1775
1776	/* Unregister character device */
1777	if (twl_major >= 0) {
1778		unregister_chrdev(twl_major, "twl");
1779		twl_major = -1;
1780	}
1781
1782	/* Shutdown the card */
1783	__twl_shutdown(tw_dev);
1784
1785	/* Disable MSI if enabled */
1786	if (test_bit(TW_USING_MSI, &tw_dev->flags))
1787		pci_disable_msi(pdev);
1788
1789	/* Free IO remapping */
1790	iounmap(tw_dev->base_addr);
1791
1792	/* Free up the mem region */
1793	pci_release_regions(pdev);
1794
1795	/* Free up device extension resources */
1796	twl_free_device_extension(tw_dev);
1797
1798	scsi_host_put(tw_dev->host);
1799	pci_disable_device(pdev);
1800	twl_device_extension_count--;
1801} /* End twl_remove() */
1802
1803#ifdef CONFIG_PM
1804/* This function is called on PCI suspend */
1805static int twl_suspend(struct pci_dev *pdev, pm_message_t state)
1806{
1807	struct Scsi_Host *host = pci_get_drvdata(pdev);
1808	TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
1809
1810	printk(KERN_WARNING "3w-sas: Suspending host %d.\n", tw_dev->host->host_no);
1811	/* Disable interrupts */
1812	TWL_MASK_INTERRUPTS(tw_dev);
1813
1814	free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
1815
1816	/* Tell the card we are shutting down */
1817	if (twl_initconnection(tw_dev, 1, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL)) {
1818		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x23, "Connection shutdown failed during suspend");
1819	} else {
1820		printk(KERN_WARNING "3w-sas: Suspend complete.\n");
1821	}
1822
1823	/* Clear doorbell interrupt */
1824	TWL_CLEAR_DB_INTERRUPT(tw_dev);
1825
1826	pci_save_state(pdev);
1827	pci_disable_device(pdev);
1828	pci_set_power_state(pdev, pci_choose_state(pdev, state));
1829
1830	return 0;
1831} /* End twl_suspend() */
1832
1833/* This function is called on PCI resume */
1834static int twl_resume(struct pci_dev *pdev)
1835{
1836	int retval = 0;
1837	struct Scsi_Host *host = pci_get_drvdata(pdev);
1838	TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
1839
1840	printk(KERN_WARNING "3w-sas: Resuming host %d.\n", tw_dev->host->host_no);
1841	pci_set_power_state(pdev, PCI_D0);
1842	pci_enable_wake(pdev, PCI_D0, 0);
1843	pci_restore_state(pdev);
1844
1845	retval = pci_enable_device(pdev);
1846	if (retval) {
1847		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x24, "Enable device failed during resume");
1848		return retval;
1849	}
1850
1851	pci_set_master(pdev);
1852	pci_try_set_mwi(pdev);
1853
1854	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
1855	    || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)))
1856		if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1857		    || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
1858			TW_PRINTK(host, TW_DRIVER, 0x25, "Failed to set dma mask during resume");
1859			retval = -ENODEV;
1860			goto out_disable_device;
1861		}
1862
1863	/* Initialize the card */
1864	if (twl_reset_sequence(tw_dev, 0)) {
1865		retval = -ENODEV;
1866		goto out_disable_device;
1867	}
1868
1869	/* Now setup the interrupt handler */
1870	retval = request_irq(pdev->irq, twl_interrupt, IRQF_SHARED, "3w-sas", tw_dev);
1871	if (retval) {
1872		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x26, "Error requesting IRQ during resume");
1873		retval = -ENODEV;
1874		goto out_disable_device;
1875	}
1876
1877	/* Now enable MSI if enabled */
1878	if (test_bit(TW_USING_MSI, &tw_dev->flags))
1879		pci_enable_msi(pdev);
1880
1881	/* Re-enable interrupts on the card */
1882	TWL_UNMASK_INTERRUPTS(tw_dev);
1883
1884	printk(KERN_WARNING "3w-sas: Resume complete.\n");
1885	return 0;
1886
1887out_disable_device:
1888	scsi_remove_host(host);
1889	pci_disable_device(pdev);
1890
1891	return retval;
1892} /* End twl_resume() */
1893#endif
1894
1895/* PCI Devices supported by this driver */
1896static struct pci_device_id twl_pci_tbl[] __devinitdata = {
1897	{ PCI_VDEVICE(3WARE, PCI_DEVICE_ID_3WARE_9750) },
1898	{ }
1899};
1900MODULE_DEVICE_TABLE(pci, twl_pci_tbl);
1901
1902/* pci_driver initializer */
1903static struct pci_driver twl_driver = {
1904	.name		= "3w-sas",
1905	.id_table	= twl_pci_tbl,
1906	.probe		= twl_probe,
1907	.remove		= twl_remove,
1908#ifdef CONFIG_PM
1909	.suspend	= twl_suspend,
1910	.resume		= twl_resume,
1911#endif
1912	.shutdown	= twl_shutdown
1913};
1914
1915/* This function is called on driver initialization */
1916static int __init twl_init(void)
1917{
1918	printk(KERN_INFO "LSI 3ware SAS/SATA-RAID Controller device driver for Linux v%s.\n", TW_DRIVER_VERSION);
1919
1920	return pci_register_driver(&twl_driver);
1921} /* End twl_init() */
1922
1923/* This function is called on driver exit */
1924static void __exit twl_exit(void)
1925{
1926	pci_unregister_driver(&twl_driver);
1927} /* End twl_exit() */
1928
1929module_init(twl_init);
1930module_exit(twl_exit);
1931
v4.17
   1/*
   2   3w-sas.c -- LSI 3ware SAS/SATA-RAID Controller device driver for Linux.
   3
   4   Written By: Adam Radford <aradford@gmail.com>
   5
   6   Copyright (C) 2009 LSI 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   Controllers supported by this driver:
  42
  43   LSI 3ware 9750 6Gb/s SAS/SATA-RAID
  44
  45   Bugs/Comments/Suggestions should be mailed to:
  46   aradford@gmail.com
 
 
 
  47
  48   History
  49   -------
  50   3.26.02.000 - Initial driver release.
  51*/
  52
  53#include <linux/module.h>
  54#include <linux/reboot.h>
  55#include <linux/spinlock.h>
  56#include <linux/interrupt.h>
  57#include <linux/moduleparam.h>
  58#include <linux/errno.h>
  59#include <linux/types.h>
  60#include <linux/delay.h>
  61#include <linux/pci.h>
  62#include <linux/time.h>
  63#include <linux/mutex.h>
  64#include <linux/slab.h>
  65#include <asm/io.h>
  66#include <asm/irq.h>
  67#include <linux/uaccess.h>
  68#include <scsi/scsi.h>
  69#include <scsi/scsi_host.h>
  70#include <scsi/scsi_tcq.h>
  71#include <scsi/scsi_cmnd.h>
  72#include "3w-sas.h"
  73
  74/* Globals */
  75#define TW_DRIVER_VERSION "3.26.02.000"
  76static DEFINE_MUTEX(twl_chrdev_mutex);
  77static TW_Device_Extension *twl_device_extension_list[TW_MAX_SLOT];
  78static unsigned int twl_device_extension_count;
  79static int twl_major = -1;
  80extern struct timezone sys_tz;
  81
  82/* Module parameters */
  83MODULE_AUTHOR ("LSI");
  84MODULE_DESCRIPTION ("LSI 3ware SAS/SATA-RAID Linux Driver");
  85MODULE_LICENSE("GPL");
  86MODULE_VERSION(TW_DRIVER_VERSION);
  87
  88static int use_msi;
  89module_param(use_msi, int, S_IRUGO);
  90MODULE_PARM_DESC(use_msi, "Use Message Signaled Interrupts. Default: 0");
  91
  92/* Function prototypes */
  93static int twl_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_reset);
  94
  95/* Functions */
  96
  97/* This function returns AENs through sysfs */
  98static ssize_t twl_sysfs_aen_read(struct file *filp, struct kobject *kobj,
  99				  struct bin_attribute *bin_attr,
 100				  char *outbuf, loff_t offset, size_t count)
 101{
 102	struct device *dev = container_of(kobj, struct device, kobj);
 103	struct Scsi_Host *shost = class_to_shost(dev);
 104	TW_Device_Extension *tw_dev = (TW_Device_Extension *)shost->hostdata;
 105	unsigned long flags = 0;
 106	ssize_t ret;
 107
 108	if (!capable(CAP_SYS_ADMIN))
 109		return -EACCES;
 110
 111	spin_lock_irqsave(tw_dev->host->host_lock, flags);
 112	ret = memory_read_from_buffer(outbuf, count, &offset, tw_dev->event_queue[0], sizeof(TW_Event) * TW_Q_LENGTH);
 113	spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
 114
 115	return ret;
 116} /* End twl_sysfs_aen_read() */
 117
 118/* aen_read sysfs attribute initializer */
 119static struct bin_attribute twl_sysfs_aen_read_attr = {
 120	.attr = {
 121		.name = "3ware_aen_read",
 122		.mode = S_IRUSR,
 123	}, 
 124	.size = 0,
 125	.read = twl_sysfs_aen_read
 126};
 127
 128/* This function returns driver compatibility info through sysfs */
 129static ssize_t twl_sysfs_compat_info(struct file *filp, struct kobject *kobj,
 130				     struct bin_attribute *bin_attr,
 131				     char *outbuf, loff_t offset, size_t count)
 132{
 133	struct device *dev = container_of(kobj, struct device, kobj);
 134	struct Scsi_Host *shost = class_to_shost(dev);
 135	TW_Device_Extension *tw_dev = (TW_Device_Extension *)shost->hostdata;
 136	unsigned long flags = 0;
 137	ssize_t ret;
 138
 139	if (!capable(CAP_SYS_ADMIN))
 140		return -EACCES;
 141
 142	spin_lock_irqsave(tw_dev->host->host_lock, flags);
 143	ret = memory_read_from_buffer(outbuf, count, &offset, &tw_dev->tw_compat_info, sizeof(TW_Compatibility_Info));
 144	spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
 145
 146	return ret;
 147} /* End twl_sysfs_compat_info() */
 148
 149/* compat_info sysfs attribute initializer */
 150static struct bin_attribute twl_sysfs_compat_info_attr = {
 151	.attr = {
 152		.name = "3ware_compat_info",
 153		.mode = S_IRUSR,
 154	}, 
 155	.size = 0,
 156	.read = twl_sysfs_compat_info
 157};
 158
 159/* Show some statistics about the card */
 160static ssize_t twl_show_stats(struct device *dev,
 161			      struct device_attribute *attr, char *buf)
 162{
 163	struct Scsi_Host *host = class_to_shost(dev);
 164	TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
 165	unsigned long flags = 0;
 166	ssize_t len;
 167
 168	spin_lock_irqsave(tw_dev->host->host_lock, flags);
 169	len = snprintf(buf, PAGE_SIZE, "3w-sas Driver version: %s\n"
 170		       "Current commands posted:   %4d\n"
 171		       "Max commands posted:       %4d\n"
 172		       "Last sgl length:           %4d\n"
 173		       "Max sgl length:            %4d\n"
 174		       "Last sector count:         %4d\n"
 175		       "Max sector count:          %4d\n"
 176		       "SCSI Host Resets:          %4d\n"
 177		       "AEN's:                     %4d\n", 
 178		       TW_DRIVER_VERSION,
 179		       tw_dev->posted_request_count,
 180		       tw_dev->max_posted_request_count,
 181		       tw_dev->sgl_entries,
 182		       tw_dev->max_sgl_entries,
 183		       tw_dev->sector_count,
 184		       tw_dev->max_sector_count,
 185		       tw_dev->num_resets,
 186		       tw_dev->aen_count);
 187	spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
 188	return len;
 189} /* End twl_show_stats() */
 190
 
 
 
 
 
 
 
 
 
 
 
 
 
 191/* stats sysfs attribute initializer */
 192static struct device_attribute twl_host_stats_attr = {
 193	.attr = {
 194		.name = 	"3ware_stats",
 195		.mode =		S_IRUGO,
 196	},
 197	.show = twl_show_stats
 198};
 199
 200/* Host attributes initializer */
 201static struct device_attribute *twl_host_attrs[] = {
 202	&twl_host_stats_attr,
 203	NULL,
 204};
 205
 206/* This function will look up an AEN severity string */
 207static char *twl_aen_severity_lookup(unsigned char severity_code)
 208{
 209	char *retval = NULL;
 210
 211	if ((severity_code < (unsigned char) TW_AEN_SEVERITY_ERROR) ||
 212	    (severity_code > (unsigned char) TW_AEN_SEVERITY_DEBUG))
 213		goto out;
 214
 215	retval = twl_aen_severity_table[severity_code];
 216out:
 217	return retval;
 218} /* End twl_aen_severity_lookup() */
 219
 220/* This function will queue an event */
 221static void twl_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_Header *header)
 222{
 223	u32 local_time;
 
 224	TW_Event *event;
 225	unsigned short aen;
 226	char host[16];
 227	char *error_str;
 228
 229	tw_dev->aen_count++;
 230
 231	/* Fill out event info */
 232	event = tw_dev->event_queue[tw_dev->error_index];
 233
 234	host[0] = '\0';
 235	if (tw_dev->host)
 236		sprintf(host, " scsi%d:", tw_dev->host->host_no);
 237
 238	aen = le16_to_cpu(header->status_block.error);
 239	memset(event, 0, sizeof(TW_Event));
 240
 241	event->severity = TW_SEV_OUT(header->status_block.severity__reserved);
 242	/* event->time_stamp_sec overflows in y2106 */
 243	local_time = (u32)(ktime_get_real_seconds() - (sys_tz.tz_minuteswest * 60));
 244	event->time_stamp_sec = local_time;
 245	event->aen_code = aen;
 246	event->retrieved = TW_AEN_NOT_RETRIEVED;
 247	event->sequence_id = tw_dev->error_sequence_id;
 248	tw_dev->error_sequence_id++;
 249
 250	/* Check for embedded error string */
 251	error_str = &(header->err_specific_desc[strlen(header->err_specific_desc)+1]);
 252
 253	header->err_specific_desc[sizeof(header->err_specific_desc) - 1] = '\0';
 254	event->parameter_len = strlen(header->err_specific_desc);
 255	memcpy(event->parameter_data, header->err_specific_desc, event->parameter_len + 1 + strlen(error_str));
 256	if (event->severity != TW_AEN_SEVERITY_DEBUG)
 257		printk(KERN_WARNING "3w-sas:%s AEN: %s (0x%02X:0x%04X): %s:%s.\n",
 258		       host,
 259		       twl_aen_severity_lookup(TW_SEV_OUT(header->status_block.severity__reserved)),
 260		       TW_MESSAGE_SOURCE_CONTROLLER_EVENT, aen, error_str,
 261		       header->err_specific_desc);
 262	else
 263		tw_dev->aen_count--;
 264
 265	tw_dev->error_index = (tw_dev->error_index + 1 ) % TW_Q_LENGTH;
 266} /* End twl_aen_queue_event() */
 267
 268/* This function will attempt to post a command packet to the board */
 269static int twl_post_command_packet(TW_Device_Extension *tw_dev, int request_id)
 270{
 271	dma_addr_t command_que_value;
 272
 273	command_que_value = tw_dev->command_packet_phys[request_id];
 274	command_que_value += TW_COMMAND_OFFSET;
 275
 276	/* First write upper 4 bytes */
 277	writel((u32)((u64)command_que_value >> 32), TWL_HIBQPH_REG_ADDR(tw_dev));
 278	/* Then the lower 4 bytes */
 279	writel((u32)(command_que_value | TWL_PULL_MODE), TWL_HIBQPL_REG_ADDR(tw_dev));
 280
 281	tw_dev->state[request_id] = TW_S_POSTED;
 282	tw_dev->posted_request_count++;
 283	if (tw_dev->posted_request_count > tw_dev->max_posted_request_count)
 284		tw_dev->max_posted_request_count = tw_dev->posted_request_count;
 285
 286	return 0;
 287} /* End twl_post_command_packet() */
 288
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 289/* This function hands scsi cdb's to the firmware */
 290static int twl_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, char *cdb, int use_sg, TW_SG_Entry_ISO *sglistarg)
 291{
 292	TW_Command_Full *full_command_packet;
 293	TW_Command_Apache *command_packet;
 294	int i, sg_count;
 295	struct scsi_cmnd *srb = NULL;
 296	struct scatterlist *sglist = NULL, *sg;
 297	int retval = 1;
 298
 299	if (tw_dev->srb[request_id]) {
 300		srb = tw_dev->srb[request_id];
 301		if (scsi_sglist(srb))
 302			sglist = scsi_sglist(srb);
 303	}
 304
 305	/* Initialize command packet */
 306	full_command_packet = tw_dev->command_packet_virt[request_id];
 307	full_command_packet->header.header_desc.size_header = 128;
 308	full_command_packet->header.status_block.error = 0;
 309	full_command_packet->header.status_block.severity__reserved = 0;
 310
 311	command_packet = &full_command_packet->command.newcommand;
 312	command_packet->status = 0;
 313	command_packet->opcode__reserved = TW_OPRES_IN(0, TW_OP_EXECUTE_SCSI);
 314
 315	/* We forced 16 byte cdb use earlier */
 316	if (!cdb)
 317		memcpy(command_packet->cdb, srb->cmnd, TW_MAX_CDB_LEN);
 318	else
 319		memcpy(command_packet->cdb, cdb, TW_MAX_CDB_LEN);
 320
 321	if (srb) {
 322		command_packet->unit = srb->device->id;
 323		command_packet->request_id__lunl =
 324			cpu_to_le16(TW_REQ_LUN_IN(srb->device->lun, request_id));
 325	} else {
 326		command_packet->request_id__lunl =
 327			cpu_to_le16(TW_REQ_LUN_IN(0, request_id));
 328		command_packet->unit = 0;
 329	}
 330
 331	command_packet->sgl_offset = 16;
 332
 333	if (!sglistarg) {
 334		/* Map sglist from scsi layer to cmd packet */
 335		if (scsi_sg_count(srb)) {
 336			sg_count = scsi_dma_map(srb);
 337			if (sg_count <= 0)
 338				goto out;
 339
 340			scsi_for_each_sg(srb, sg, sg_count, i) {
 341				command_packet->sg_list[i].address = TW_CPU_TO_SGL(sg_dma_address(sg));
 342				command_packet->sg_list[i].length = TW_CPU_TO_SGL(sg_dma_len(sg));
 343			}
 344			command_packet->sgl_entries__lunh = cpu_to_le16(TW_REQ_LUN_IN((srb->device->lun >> 4), scsi_sg_count(tw_dev->srb[request_id])));
 345		}
 346	} else {
 347		/* Internal cdb post */
 348		for (i = 0; i < use_sg; i++) {
 349			command_packet->sg_list[i].address = TW_CPU_TO_SGL(sglistarg[i].address);
 350			command_packet->sg_list[i].length = TW_CPU_TO_SGL(sglistarg[i].length);
 351		}
 352		command_packet->sgl_entries__lunh = cpu_to_le16(TW_REQ_LUN_IN(0, use_sg));
 353	}
 354
 355	/* Update some stats */
 356	if (srb) {
 357		tw_dev->sector_count = scsi_bufflen(srb) / 512;
 358		if (tw_dev->sector_count > tw_dev->max_sector_count)
 359			tw_dev->max_sector_count = tw_dev->sector_count;
 360		tw_dev->sgl_entries = scsi_sg_count(srb);
 361		if (tw_dev->sgl_entries > tw_dev->max_sgl_entries)
 362			tw_dev->max_sgl_entries = tw_dev->sgl_entries;
 363	}
 364
 365	/* Now post the command to the board */
 366	retval = twl_post_command_packet(tw_dev, request_id);
 367
 368out:
 369	return retval;
 370} /* End twl_scsiop_execute_scsi() */
 371
 372/* This function will read the aen queue from the isr */
 373static int twl_aen_read_queue(TW_Device_Extension *tw_dev, int request_id)
 374{
 375	char cdb[TW_MAX_CDB_LEN];
 376	TW_SG_Entry_ISO sglist[1];
 377	TW_Command_Full *full_command_packet;
 378	int retval = 1;
 379
 380	full_command_packet = tw_dev->command_packet_virt[request_id];
 381	memset(full_command_packet, 0, sizeof(TW_Command_Full));
 382
 383	/* Initialize cdb */
 384	memset(&cdb, 0, TW_MAX_CDB_LEN);
 385	cdb[0] = REQUEST_SENSE; /* opcode */
 386	cdb[4] = TW_ALLOCATION_LENGTH; /* allocation length */
 387
 388	/* Initialize sglist */
 389	memset(&sglist, 0, sizeof(TW_SG_Entry_ISO));
 390	sglist[0].length = TW_SECTOR_SIZE;
 391	sglist[0].address = tw_dev->generic_buffer_phys[request_id];
 392
 393	/* Mark internal command */
 394	tw_dev->srb[request_id] = NULL;
 395
 396	/* Now post the command packet */
 397	if (twl_scsiop_execute_scsi(tw_dev, request_id, cdb, 1, sglist)) {
 398		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2, "Post failed while reading AEN queue");
 399		goto out;
 400	}
 401	retval = 0;
 402out:
 403	return retval;
 404} /* End twl_aen_read_queue() */
 405
 406/* This function will sync firmware time with the host time */
 407static void twl_aen_sync_time(TW_Device_Extension *tw_dev, int request_id)
 408{
 409	u32 schedulertime;
 
 410	TW_Command_Full *full_command_packet;
 411	TW_Command *command_packet;
 412	TW_Param_Apache *param;
 413	time64_t local_time;
 414
 415	/* Fill out the command packet */
 416	full_command_packet = tw_dev->command_packet_virt[request_id];
 417	memset(full_command_packet, 0, sizeof(TW_Command_Full));
 418	command_packet = &full_command_packet->command.oldcommand;
 419	command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_SET_PARAM);
 420	command_packet->request_id = request_id;
 421	command_packet->byte8_offset.param.sgl[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]);
 422	command_packet->byte8_offset.param.sgl[0].length = TW_CPU_TO_SGL(TW_SECTOR_SIZE);
 423	command_packet->size = TW_COMMAND_SIZE;
 424	command_packet->byte6_offset.parameter_count = cpu_to_le16(1);
 425
 426	/* Setup the param */
 427	param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id];
 428	memset(param, 0, TW_SECTOR_SIZE);
 429	param->table_id = cpu_to_le16(TW_TIMEKEEP_TABLE | 0x8000); /* Controller time keep table */
 430	param->parameter_id = cpu_to_le16(0x3); /* SchedulerTime */
 431	param->parameter_size_bytes = cpu_to_le16(4);
 432
 433	/* Convert system time in UTC to local time seconds since last 
 434           Sunday 12:00AM */
 435	local_time = (ktime_get_real_seconds() - (sys_tz.tz_minuteswest * 60));
 436	div_u64_rem(local_time - (3 * 86400), 604800, &schedulertime);
 437	schedulertime = cpu_to_le32(schedulertime);
 
 438
 439	memcpy(param->data, &schedulertime, sizeof(u32));
 440
 441	/* Mark internal command */
 442	tw_dev->srb[request_id] = NULL;
 443
 444	/* Now post the command */
 445	twl_post_command_packet(tw_dev, request_id);
 446} /* End twl_aen_sync_time() */
 447
 448/* This function will assign an available request id */
 449static void twl_get_request_id(TW_Device_Extension *tw_dev, int *request_id)
 450{
 451	*request_id = tw_dev->free_queue[tw_dev->free_head];
 452	tw_dev->free_head = (tw_dev->free_head + 1) % TW_Q_LENGTH;
 453	tw_dev->state[*request_id] = TW_S_STARTED;
 454} /* End twl_get_request_id() */
 455
 456/* This function will free a request id */
 457static void twl_free_request_id(TW_Device_Extension *tw_dev, int request_id)
 458{
 459	tw_dev->free_queue[tw_dev->free_tail] = request_id;
 460	tw_dev->state[request_id] = TW_S_FINISHED;
 461	tw_dev->free_tail = (tw_dev->free_tail + 1) % TW_Q_LENGTH;
 462} /* End twl_free_request_id() */
 463
 464/* This function will complete an aen request from the isr */
 465static int twl_aen_complete(TW_Device_Extension *tw_dev, int request_id)
 466{
 467	TW_Command_Full *full_command_packet;
 468	TW_Command *command_packet;
 469	TW_Command_Apache_Header *header;
 470	unsigned short aen;
 471	int retval = 1;
 472
 473	header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id];
 474	tw_dev->posted_request_count--;
 475	aen = le16_to_cpu(header->status_block.error);
 476	full_command_packet = tw_dev->command_packet_virt[request_id];
 477	command_packet = &full_command_packet->command.oldcommand;
 478
 479	/* First check for internal completion of set param for time sync */
 480	if (TW_OP_OUT(command_packet->opcode__sgloffset) == TW_OP_SET_PARAM) {
 481		/* Keep reading the queue in case there are more aen's */
 482		if (twl_aen_read_queue(tw_dev, request_id))
 483			goto out2;
 484	        else {
 485			retval = 0;
 486			goto out;
 487		}
 488	}
 489
 490	switch (aen) {
 491	case TW_AEN_QUEUE_EMPTY:
 492		/* Quit reading the queue if this is the last one */
 493		break;
 494	case TW_AEN_SYNC_TIME_WITH_HOST:
 495		twl_aen_sync_time(tw_dev, request_id);
 496		retval = 0;
 497		goto out;
 498	default:
 499		twl_aen_queue_event(tw_dev, header);
 500
 501		/* If there are more aen's, keep reading the queue */
 502		if (twl_aen_read_queue(tw_dev, request_id))
 503			goto out2;
 504		else {
 505			retval = 0;
 506			goto out;
 507		}
 508	}
 509	retval = 0;
 510out2:
 511	tw_dev->state[request_id] = TW_S_COMPLETED;
 512	twl_free_request_id(tw_dev, request_id);
 513	clear_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags);
 514out:
 515	return retval;
 516} /* End twl_aen_complete() */
 517
 518/* This function will poll for a response */
 519static int twl_poll_response(TW_Device_Extension *tw_dev, int request_id, int seconds)
 520{
 521	unsigned long before;
 522	dma_addr_t mfa;
 523	u32 regh, regl;
 524	u32 response;
 525	int retval = 1;
 526	int found = 0;
 527
 528	before = jiffies;
 529
 530	while (!found) {
 531		if (sizeof(dma_addr_t) > 4) {
 532			regh = readl(TWL_HOBQPH_REG_ADDR(tw_dev));
 533			regl = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
 534			mfa = ((u64)regh << 32) | regl;
 535		} else
 536			mfa = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
 537
 538		response = (u32)mfa;
 539
 540		if (TW_RESID_OUT(response) == request_id)
 541			found = 1;
 542
 543		if (time_after(jiffies, before + HZ * seconds))
 544			goto out;
 545
 546		msleep(50);
 547	}
 548	retval = 0;
 549out: 
 550	return retval;
 551} /* End twl_poll_response() */
 552
 553/* This function will drain the aen queue */
 554static int twl_aen_drain_queue(TW_Device_Extension *tw_dev, int no_check_reset)
 555{
 556	int request_id = 0;
 557	char cdb[TW_MAX_CDB_LEN];
 558	TW_SG_Entry_ISO sglist[1];
 559	int finished = 0, count = 0;
 560	TW_Command_Full *full_command_packet;
 561	TW_Command_Apache_Header *header;
 562	unsigned short aen;
 563	int first_reset = 0, queue = 0, retval = 1;
 564
 565	if (no_check_reset)
 566		first_reset = 0;
 567	else
 568		first_reset = 1;
 569
 570	full_command_packet = tw_dev->command_packet_virt[request_id];
 571	memset(full_command_packet, 0, sizeof(TW_Command_Full));
 572
 573	/* Initialize cdb */
 574	memset(&cdb, 0, TW_MAX_CDB_LEN);
 575	cdb[0] = REQUEST_SENSE; /* opcode */
 576	cdb[4] = TW_ALLOCATION_LENGTH; /* allocation length */
 577
 578	/* Initialize sglist */
 579	memset(&sglist, 0, sizeof(TW_SG_Entry_ISO));
 580	sglist[0].length = TW_SECTOR_SIZE;
 581	sglist[0].address = tw_dev->generic_buffer_phys[request_id];
 582
 583	/* Mark internal command */
 584	tw_dev->srb[request_id] = NULL;
 585
 586	do {
 587		/* Send command to the board */
 588		if (twl_scsiop_execute_scsi(tw_dev, request_id, cdb, 1, sglist)) {
 589			TW_PRINTK(tw_dev->host, TW_DRIVER, 0x3, "Error posting request sense");
 590			goto out;
 591		}
 592
 593		/* Now poll for completion */
 594		if (twl_poll_response(tw_dev, request_id, 30)) {
 595			TW_PRINTK(tw_dev->host, TW_DRIVER, 0x4, "No valid response while draining AEN queue");
 596			tw_dev->posted_request_count--;
 597			goto out;
 598		}
 599
 600		tw_dev->posted_request_count--;
 601		header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id];
 602		aen = le16_to_cpu(header->status_block.error);
 603		queue = 0;
 604		count++;
 605
 606		switch (aen) {
 607		case TW_AEN_QUEUE_EMPTY:
 608			if (first_reset != 1)
 609				goto out;
 610			else
 611				finished = 1;
 612			break;
 613		case TW_AEN_SOFT_RESET:
 614			if (first_reset == 0)
 615				first_reset = 1;
 616			else
 617				queue = 1;
 618			break;
 619		case TW_AEN_SYNC_TIME_WITH_HOST:
 620			break;
 621		default:
 622			queue = 1;
 623		}
 624
 625		/* Now queue an event info */
 626		if (queue)
 627			twl_aen_queue_event(tw_dev, header);
 628	} while ((finished == 0) && (count < TW_MAX_AEN_DRAIN));
 629
 630	if (count == TW_MAX_AEN_DRAIN)
 631		goto out;
 632
 633	retval = 0;
 634out:
 635	tw_dev->state[request_id] = TW_S_INITIAL;
 636	return retval;
 637} /* End twl_aen_drain_queue() */
 638
 639/* This function will allocate memory and check if it is correctly aligned */
 640static int twl_allocate_memory(TW_Device_Extension *tw_dev, int size, int which)
 641{
 642	int i;
 643	dma_addr_t dma_handle;
 644	unsigned long *cpu_addr;
 645	int retval = 1;
 646
 647	cpu_addr = pci_zalloc_consistent(tw_dev->tw_pci_dev, size * TW_Q_LENGTH,
 648					 &dma_handle);
 649	if (!cpu_addr) {
 650		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x5, "Memory allocation failed");
 651		goto out;
 652	}
 653
 
 
 654	for (i = 0; i < TW_Q_LENGTH; i++) {
 655		switch(which) {
 656		case 0:
 657			tw_dev->command_packet_phys[i] = dma_handle+(i*size);
 658			tw_dev->command_packet_virt[i] = (TW_Command_Full *)((unsigned char *)cpu_addr + (i*size));
 659			break;
 660		case 1:
 661			tw_dev->generic_buffer_phys[i] = dma_handle+(i*size);
 662			tw_dev->generic_buffer_virt[i] = (unsigned long *)((unsigned char *)cpu_addr + (i*size));
 663			break;
 664		case 2:
 665			tw_dev->sense_buffer_phys[i] = dma_handle+(i*size);
 666			tw_dev->sense_buffer_virt[i] = (TW_Command_Apache_Header *)((unsigned char *)cpu_addr + (i*size));
 667			break;
 668		}
 669	}
 670	retval = 0;
 671out:
 672	return retval;
 673} /* End twl_allocate_memory() */
 674
 675/* This function will load the request id and various sgls for ioctls */
 676static void twl_load_sgl(TW_Device_Extension *tw_dev, TW_Command_Full *full_command_packet, int request_id, dma_addr_t dma_handle, int length)
 677{
 678	TW_Command *oldcommand;
 679	TW_Command_Apache *newcommand;
 680	TW_SG_Entry_ISO *sgl;
 681	unsigned int pae = 0;
 682
 683	if ((sizeof(long) < 8) && (sizeof(dma_addr_t) > 4))
 684		pae = 1;
 685
 686	if (TW_OP_OUT(full_command_packet->command.newcommand.opcode__reserved) == TW_OP_EXECUTE_SCSI) {
 687		newcommand = &full_command_packet->command.newcommand;
 688		newcommand->request_id__lunl =
 689			cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->request_id__lunl), request_id));
 690		if (length) {
 691			newcommand->sg_list[0].address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1);
 692			newcommand->sg_list[0].length = TW_CPU_TO_SGL(length);
 693		}
 694		newcommand->sgl_entries__lunh =
 695			cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->sgl_entries__lunh), length ? 1 : 0));
 696	} else {
 697		oldcommand = &full_command_packet->command.oldcommand;
 698		oldcommand->request_id = request_id;
 699
 700		if (TW_SGL_OUT(oldcommand->opcode__sgloffset)) {
 701			/* Load the sg list */
 702			sgl = (TW_SG_Entry_ISO *)((u32 *)oldcommand+oldcommand->size - (sizeof(TW_SG_Entry_ISO)/4) + pae + (sizeof(dma_addr_t) > 4 ? 1 : 0));
 703			sgl->address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1);
 704			sgl->length = TW_CPU_TO_SGL(length);
 705			oldcommand->size += pae;
 706			oldcommand->size += sizeof(dma_addr_t) > 4 ? 1 : 0;
 707		}
 708	}
 709} /* End twl_load_sgl() */
 710
 711/* This function handles ioctl for the character device
 712   This interface is used by smartmontools open source software */
 713static long twl_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 714{
 715	long timeout;
 716	unsigned long *cpu_addr, data_buffer_length_adjusted = 0, flags = 0;
 717	dma_addr_t dma_handle;
 718	int request_id = 0;
 719	TW_Ioctl_Driver_Command driver_command;
 720	struct inode *inode = file_inode(file);
 721	TW_Ioctl_Buf_Apache *tw_ioctl;
 722	TW_Command_Full *full_command_packet;
 723	TW_Device_Extension *tw_dev = twl_device_extension_list[iminor(inode)];
 724	int retval = -EFAULT;
 725	void __user *argp = (void __user *)arg;
 726
 727	mutex_lock(&twl_chrdev_mutex);
 728
 729	/* Only let one of these through at a time */
 730	if (mutex_lock_interruptible(&tw_dev->ioctl_lock)) {
 731		retval = -EINTR;
 732		goto out;
 733	}
 734
 735	/* First copy down the driver command */
 736	if (copy_from_user(&driver_command, argp, sizeof(TW_Ioctl_Driver_Command)))
 737		goto out2;
 738
 739	/* Check data buffer size */
 740	if (driver_command.buffer_length > TW_MAX_SECTORS * 2048) {
 741		retval = -EINVAL;
 742		goto out2;
 743	}
 744
 745	/* Hardware can only do multiple of 512 byte transfers */
 746	data_buffer_length_adjusted = (driver_command.buffer_length + 511) & ~511;
 747
 748	/* Now allocate ioctl buf memory */
 749	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);
 750	if (!cpu_addr) {
 751		retval = -ENOMEM;
 752		goto out2;
 753	}
 754
 755	tw_ioctl = (TW_Ioctl_Buf_Apache *)cpu_addr;
 756
 757	/* Now copy down the entire ioctl */
 758	if (copy_from_user(tw_ioctl, argp, driver_command.buffer_length + sizeof(TW_Ioctl_Buf_Apache) - 1))
 759		goto out3;
 760
 761	/* See which ioctl we are doing */
 762	switch (cmd) {
 763	case TW_IOCTL_FIRMWARE_PASS_THROUGH:
 764		spin_lock_irqsave(tw_dev->host->host_lock, flags);
 765		twl_get_request_id(tw_dev, &request_id);
 766
 767		/* Flag internal command */
 768		tw_dev->srb[request_id] = NULL;
 769
 770		/* Flag chrdev ioctl */
 771		tw_dev->chrdev_request_id = request_id;
 772
 773		full_command_packet = (TW_Command_Full *)&tw_ioctl->firmware_command;
 774
 775		/* Load request id and sglist for both command types */
 776		twl_load_sgl(tw_dev, full_command_packet, request_id, dma_handle, data_buffer_length_adjusted);
 777
 778		memcpy(tw_dev->command_packet_virt[request_id], &(tw_ioctl->firmware_command), sizeof(TW_Command_Full));
 779
 780		/* Now post the command packet to the controller */
 781		twl_post_command_packet(tw_dev, request_id);
 782		spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
 783
 784		timeout = TW_IOCTL_CHRDEV_TIMEOUT*HZ;
 785
 786		/* Now wait for command to complete */
 787		timeout = wait_event_timeout(tw_dev->ioctl_wqueue, tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE, timeout);
 788
 789		/* We timed out, and didn't get an interrupt */
 790		if (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE) {
 791			/* Now we need to reset the board */
 792			printk(KERN_WARNING "3w-sas: scsi%d: WARNING: (0x%02X:0x%04X): Character ioctl (0x%x) timed out, resetting card.\n",
 793			       tw_dev->host->host_no, TW_DRIVER, 0x6,
 794			       cmd);
 795			retval = -EIO;
 796			twl_reset_device_extension(tw_dev, 1);
 797			goto out3;
 798		}
 799
 800		/* Now copy in the command packet response */
 801		memcpy(&(tw_ioctl->firmware_command), tw_dev->command_packet_virt[request_id], sizeof(TW_Command_Full));
 802		
 803		/* Now complete the io */
 804		spin_lock_irqsave(tw_dev->host->host_lock, flags);
 805		tw_dev->posted_request_count--;
 806		tw_dev->state[request_id] = TW_S_COMPLETED;
 807		twl_free_request_id(tw_dev, request_id);
 808		spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
 809		break;
 810	default:
 811		retval = -ENOTTY;
 812		goto out3;
 813	}
 814
 815	/* Now copy the entire response to userspace */
 816	if (copy_to_user(argp, tw_ioctl, sizeof(TW_Ioctl_Buf_Apache) + driver_command.buffer_length - 1) == 0)
 817		retval = 0;
 818out3:
 819	/* Now free ioctl buf memory */
 820	dma_free_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_Ioctl_Buf_Apache) - 1, cpu_addr, dma_handle);
 821out2:
 822	mutex_unlock(&tw_dev->ioctl_lock);
 823out:
 824	mutex_unlock(&twl_chrdev_mutex);
 825	return retval;
 826} /* End twl_chrdev_ioctl() */
 827
 828/* This function handles open for the character device */
 829static int twl_chrdev_open(struct inode *inode, struct file *file)
 830{
 831	unsigned int minor_number;
 832	int retval = -ENODEV;
 833
 834	if (!capable(CAP_SYS_ADMIN)) {
 835		retval = -EACCES;
 836		goto out;
 837	}
 838
 839	minor_number = iminor(inode);
 840	if (minor_number >= twl_device_extension_count)
 841		goto out;
 842	retval = 0;
 843out:
 844	return retval;
 845} /* End twl_chrdev_open() */
 846
 847/* File operations struct for character device */
 848static const struct file_operations twl_fops = {
 849	.owner		= THIS_MODULE,
 850	.unlocked_ioctl	= twl_chrdev_ioctl,
 851	.open		= twl_chrdev_open,
 852	.release	= NULL,
 853	.llseek		= noop_llseek,
 854};
 855
 856/* This function passes sense data from firmware to scsi layer */
 857static int twl_fill_sense(TW_Device_Extension *tw_dev, int i, int request_id, int copy_sense, int print_host)
 858{
 859	TW_Command_Apache_Header *header;
 860	TW_Command_Full *full_command_packet;
 861	unsigned short error;
 862	char *error_str;
 863	int retval = 1;
 864
 865	header = tw_dev->sense_buffer_virt[i];
 866	full_command_packet = tw_dev->command_packet_virt[request_id];
 867
 868	/* Get embedded firmware error string */
 869	error_str = &(header->err_specific_desc[strlen(header->err_specific_desc) + 1]);
 870
 871	/* Don't print error for Logical unit not supported during rollcall */
 872	error = le16_to_cpu(header->status_block.error);
 873	if ((error != TW_ERROR_LOGICAL_UNIT_NOT_SUPPORTED) && (error != TW_ERROR_UNIT_OFFLINE) && (error != TW_ERROR_INVALID_FIELD_IN_CDB)) {
 874		if (print_host)
 875			printk(KERN_WARNING "3w-sas: scsi%d: ERROR: (0x%02X:0x%04X): %s:%s.\n",
 876			       tw_dev->host->host_no,
 877			       TW_MESSAGE_SOURCE_CONTROLLER_ERROR,
 878			       header->status_block.error,
 879			       error_str, 
 880			       header->err_specific_desc);
 881		else
 882			printk(KERN_WARNING "3w-sas: ERROR: (0x%02X:0x%04X): %s:%s.\n",
 883			       TW_MESSAGE_SOURCE_CONTROLLER_ERROR,
 884			       header->status_block.error,
 885			       error_str,
 886			       header->err_specific_desc);
 887	}
 888
 889	if (copy_sense) {
 890		memcpy(tw_dev->srb[request_id]->sense_buffer, header->sense_data, TW_SENSE_DATA_LENGTH);
 891		tw_dev->srb[request_id]->result = (full_command_packet->command.newcommand.status << 1);
 892		goto out;
 893	}
 894out:
 895	return retval;
 896} /* End twl_fill_sense() */
 897
 898/* This function will free up device extension resources */
 899static void twl_free_device_extension(TW_Device_Extension *tw_dev)
 900{
 901	if (tw_dev->command_packet_virt[0])
 902		pci_free_consistent(tw_dev->tw_pci_dev,
 903				    sizeof(TW_Command_Full)*TW_Q_LENGTH,
 904				    tw_dev->command_packet_virt[0],
 905				    tw_dev->command_packet_phys[0]);
 906
 907	if (tw_dev->generic_buffer_virt[0])
 908		pci_free_consistent(tw_dev->tw_pci_dev,
 909				    TW_SECTOR_SIZE*TW_Q_LENGTH,
 910				    tw_dev->generic_buffer_virt[0],
 911				    tw_dev->generic_buffer_phys[0]);
 912
 913	if (tw_dev->sense_buffer_virt[0])
 914		pci_free_consistent(tw_dev->tw_pci_dev,
 915				    sizeof(TW_Command_Apache_Header)*
 916				    TW_Q_LENGTH,
 917				    tw_dev->sense_buffer_virt[0],
 918				    tw_dev->sense_buffer_phys[0]);
 919
 920	kfree(tw_dev->event_queue[0]);
 921} /* End twl_free_device_extension() */
 922
 923/* This function will get parameter table entries from the firmware */
 924static void *twl_get_param(TW_Device_Extension *tw_dev, int request_id, int table_id, int parameter_id, int parameter_size_bytes)
 925{
 926	TW_Command_Full *full_command_packet;
 927	TW_Command *command_packet;
 928	TW_Param_Apache *param;
 929	void *retval = NULL;
 930
 931	/* Setup the command packet */
 932	full_command_packet = tw_dev->command_packet_virt[request_id];
 933	memset(full_command_packet, 0, sizeof(TW_Command_Full));
 934	command_packet = &full_command_packet->command.oldcommand;
 935
 936	command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
 937	command_packet->size              = TW_COMMAND_SIZE;
 938	command_packet->request_id        = request_id;
 939	command_packet->byte6_offset.block_count = cpu_to_le16(1);
 940
 941	/* Now setup the param */
 942	param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id];
 943	memset(param, 0, TW_SECTOR_SIZE);
 944	param->table_id = cpu_to_le16(table_id | 0x8000);
 945	param->parameter_id = cpu_to_le16(parameter_id);
 946	param->parameter_size_bytes = cpu_to_le16(parameter_size_bytes);
 947
 948	command_packet->byte8_offset.param.sgl[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]);
 949	command_packet->byte8_offset.param.sgl[0].length = TW_CPU_TO_SGL(TW_SECTOR_SIZE);
 950
 951	/* Post the command packet to the board */
 952	twl_post_command_packet(tw_dev, request_id);
 953
 954	/* Poll for completion */
 955	if (twl_poll_response(tw_dev, request_id, 30))
 956		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x7, "No valid response during get param")
 957	else
 958		retval = (void *)&(param->data[0]);
 959
 960	tw_dev->posted_request_count--;
 961	tw_dev->state[request_id] = TW_S_INITIAL;
 962
 963	return retval;
 964} /* End twl_get_param() */
 965
 966/* This function will send an initconnection command to controller */
 967static int twl_initconnection(TW_Device_Extension *tw_dev, int message_credits,
 968 			      u32 set_features, unsigned short current_fw_srl, 
 969			      unsigned short current_fw_arch_id, 
 970			      unsigned short current_fw_branch, 
 971			      unsigned short current_fw_build, 
 972			      unsigned short *fw_on_ctlr_srl, 
 973			      unsigned short *fw_on_ctlr_arch_id, 
 974			      unsigned short *fw_on_ctlr_branch, 
 975			      unsigned short *fw_on_ctlr_build, 
 976			      u32 *init_connect_result)
 977{
 978	TW_Command_Full *full_command_packet;
 979	TW_Initconnect *tw_initconnect;
 980	int request_id = 0, retval = 1;
 981
 982	/* Initialize InitConnection command packet */
 983	full_command_packet = tw_dev->command_packet_virt[request_id];
 984	memset(full_command_packet, 0, sizeof(TW_Command_Full));
 985	full_command_packet->header.header_desc.size_header = 128;
 986	
 987	tw_initconnect = (TW_Initconnect *)&full_command_packet->command.oldcommand;
 988	tw_initconnect->opcode__reserved = TW_OPRES_IN(0, TW_OP_INIT_CONNECTION);
 989	tw_initconnect->request_id = request_id;
 990	tw_initconnect->message_credits = cpu_to_le16(message_credits);
 991	tw_initconnect->features = set_features;
 992
 993	/* Turn on 64-bit sgl support if we need to */
 994	tw_initconnect->features |= sizeof(dma_addr_t) > 4 ? 1 : 0;
 995
 996	tw_initconnect->features = cpu_to_le32(tw_initconnect->features);
 997
 998	if (set_features & TW_EXTENDED_INIT_CONNECT) {
 999		tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE_EXTENDED;
1000		tw_initconnect->fw_srl = cpu_to_le16(current_fw_srl);
1001		tw_initconnect->fw_arch_id = cpu_to_le16(current_fw_arch_id);
1002		tw_initconnect->fw_branch = cpu_to_le16(current_fw_branch);
1003		tw_initconnect->fw_build = cpu_to_le16(current_fw_build);
1004	} else 
1005		tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE;
1006
1007	/* Send command packet to the board */
1008	twl_post_command_packet(tw_dev, request_id);
1009
1010	/* Poll for completion */
1011	if (twl_poll_response(tw_dev, request_id, 30)) {
1012		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x8, "No valid response during init connection");
1013	} else {
1014		if (set_features & TW_EXTENDED_INIT_CONNECT) {
1015			*fw_on_ctlr_srl = le16_to_cpu(tw_initconnect->fw_srl);
1016			*fw_on_ctlr_arch_id = le16_to_cpu(tw_initconnect->fw_arch_id);
1017			*fw_on_ctlr_branch = le16_to_cpu(tw_initconnect->fw_branch);
1018			*fw_on_ctlr_build = le16_to_cpu(tw_initconnect->fw_build);
1019			*init_connect_result = le32_to_cpu(tw_initconnect->result);
1020		}
1021		retval = 0;
1022	}
1023
1024	tw_dev->posted_request_count--;
1025	tw_dev->state[request_id] = TW_S_INITIAL;
1026
1027	return retval;
1028} /* End twl_initconnection() */
1029
1030/* This function will initialize the fields of a device extension */
1031static int twl_initialize_device_extension(TW_Device_Extension *tw_dev)
1032{
1033	int i, retval = 1;
1034
1035	/* Initialize command packet buffers */
1036	if (twl_allocate_memory(tw_dev, sizeof(TW_Command_Full), 0)) {
1037		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x9, "Command packet memory allocation failed");
1038		goto out;
1039	}
1040
1041	/* Initialize generic buffer */
1042	if (twl_allocate_memory(tw_dev, TW_SECTOR_SIZE, 1)) {
1043		TW_PRINTK(tw_dev->host, TW_DRIVER, 0xa, "Generic memory allocation failed");
1044		goto out;
1045	}
1046
1047	/* Allocate sense buffers */
1048	if (twl_allocate_memory(tw_dev, sizeof(TW_Command_Apache_Header), 2)) {
1049		TW_PRINTK(tw_dev->host, TW_DRIVER, 0xb, "Sense buffer allocation failed");
1050		goto out;
1051	}
1052
1053	/* Allocate event info space */
1054	tw_dev->event_queue[0] = kcalloc(TW_Q_LENGTH, sizeof(TW_Event), GFP_KERNEL);
1055	if (!tw_dev->event_queue[0]) {
1056		TW_PRINTK(tw_dev->host, TW_DRIVER, 0xc, "Event info memory allocation failed");
1057		goto out;
1058	}
1059
1060	for (i = 0; i < TW_Q_LENGTH; i++) {
1061		tw_dev->event_queue[i] = (TW_Event *)((unsigned char *)tw_dev->event_queue[0] + (i * sizeof(TW_Event)));
1062		tw_dev->free_queue[i] = i;
1063		tw_dev->state[i] = TW_S_INITIAL;
1064	}
1065
1066	tw_dev->free_head = TW_Q_START;
1067	tw_dev->free_tail = TW_Q_START;
1068	tw_dev->error_sequence_id = 1;
1069	tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1070
1071	mutex_init(&tw_dev->ioctl_lock);
1072	init_waitqueue_head(&tw_dev->ioctl_wqueue);
1073
1074	retval = 0;
1075out:
1076	return retval;
1077} /* End twl_initialize_device_extension() */
1078
 
 
 
 
 
 
 
 
 
1079/* This function will handle attention interrupts */
1080static int twl_handle_attention_interrupt(TW_Device_Extension *tw_dev)
1081{
1082	int retval = 1;
1083	u32 request_id, doorbell;
1084
1085	/* Read doorbell status */
1086	doorbell = readl(TWL_HOBDB_REG_ADDR(tw_dev));
1087
1088	/* Check for controller errors */
1089	if (doorbell & TWL_DOORBELL_CONTROLLER_ERROR) {
1090		TW_PRINTK(tw_dev->host, TW_DRIVER, 0xd, "Microcontroller Error: clearing");
1091		goto out;
1092	}
1093
1094	/* Check if we need to perform an AEN drain */
1095	if (doorbell & TWL_DOORBELL_ATTENTION_INTERRUPT) {
1096		if (!(test_and_set_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags))) {
1097			twl_get_request_id(tw_dev, &request_id);
1098			if (twl_aen_read_queue(tw_dev, request_id)) {
1099				tw_dev->state[request_id] = TW_S_COMPLETED;
1100				twl_free_request_id(tw_dev, request_id);
1101				clear_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags);
1102			}
1103		}
1104	}
1105
1106	retval = 0;
1107out:
1108	/* Clear doorbell interrupt */
1109	TWL_CLEAR_DB_INTERRUPT(tw_dev);
1110
1111	/* Make sure the clear was flushed by reading it back */
1112	readl(TWL_HOBDBC_REG_ADDR(tw_dev));
1113
1114	return retval;
1115} /* End twl_handle_attention_interrupt() */
1116
1117/* Interrupt service routine */
1118static irqreturn_t twl_interrupt(int irq, void *dev_instance)
1119{
1120	TW_Device_Extension *tw_dev = (TW_Device_Extension *)dev_instance;
1121	int i, handled = 0, error = 0;
1122	dma_addr_t mfa = 0;
1123	u32 reg, regl, regh, response, request_id = 0;
1124	struct scsi_cmnd *cmd;
1125	TW_Command_Full *full_command_packet;
1126
1127	spin_lock(tw_dev->host->host_lock);
1128
1129	/* Read host interrupt status */
1130	reg = readl(TWL_HISTAT_REG_ADDR(tw_dev));
1131
1132	/* Check if this is our interrupt, otherwise bail */
1133	if (!(reg & TWL_HISTATUS_VALID_INTERRUPT))
1134		goto twl_interrupt_bail;
1135
1136	handled = 1;
1137
1138	/* If we are resetting, bail */
1139	if (test_bit(TW_IN_RESET, &tw_dev->flags))
1140		goto twl_interrupt_bail;
1141
1142	/* Attention interrupt */
1143	if (reg & TWL_HISTATUS_ATTENTION_INTERRUPT) {
1144		if (twl_handle_attention_interrupt(tw_dev)) {
1145			TWL_MASK_INTERRUPTS(tw_dev);
1146			goto twl_interrupt_bail;
1147		}
1148	}
1149
1150	/* Response interrupt */
1151	while (reg & TWL_HISTATUS_RESPONSE_INTERRUPT) {
1152		if (sizeof(dma_addr_t) > 4) {
1153			regh = readl(TWL_HOBQPH_REG_ADDR(tw_dev));
1154			regl = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
1155			mfa = ((u64)regh << 32) | regl;
1156		} else
1157			mfa = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
1158
1159		error = 0;
1160		response = (u32)mfa;
1161
1162		/* Check for command packet error */
1163		if (!TW_NOTMFA_OUT(response)) {
1164			for (i=0;i<TW_Q_LENGTH;i++) {
1165				if (tw_dev->sense_buffer_phys[i] == mfa) {
1166					request_id = le16_to_cpu(tw_dev->sense_buffer_virt[i]->header_desc.request_id);
1167					if (tw_dev->srb[request_id] != NULL)
1168						error = twl_fill_sense(tw_dev, i, request_id, 1, 1);
1169					else {
1170						/* Skip ioctl error prints */
1171						if (request_id != tw_dev->chrdev_request_id)
1172							error = twl_fill_sense(tw_dev, i, request_id, 0, 1);
1173						else
1174							memcpy(tw_dev->command_packet_virt[request_id], tw_dev->sense_buffer_virt[i], sizeof(TW_Command_Apache_Header));
1175					}
1176
1177					/* Now re-post the sense buffer */
1178					writel((u32)((u64)tw_dev->sense_buffer_phys[i] >> 32), TWL_HOBQPH_REG_ADDR(tw_dev));
1179					writel((u32)tw_dev->sense_buffer_phys[i], TWL_HOBQPL_REG_ADDR(tw_dev));
1180					break;
1181				}
1182			}
1183		} else
1184			request_id = TW_RESID_OUT(response);
1185
1186		full_command_packet = tw_dev->command_packet_virt[request_id];
1187
1188		/* Check for correct state */
1189		if (tw_dev->state[request_id] != TW_S_POSTED) {
1190			if (tw_dev->srb[request_id] != NULL) {
1191				TW_PRINTK(tw_dev->host, TW_DRIVER, 0xe, "Received a request id that wasn't posted");
1192				TWL_MASK_INTERRUPTS(tw_dev);
1193				goto twl_interrupt_bail;
1194			}
1195		}
1196
1197		/* Check for internal command completion */
1198		if (tw_dev->srb[request_id] == NULL) {
1199			if (request_id != tw_dev->chrdev_request_id) {
1200				if (twl_aen_complete(tw_dev, request_id))
1201					TW_PRINTK(tw_dev->host, TW_DRIVER, 0xf, "Error completing AEN during attention interrupt");
1202			} else {
1203				tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1204				wake_up(&tw_dev->ioctl_wqueue);
1205			}
1206		} else {
1207			cmd = tw_dev->srb[request_id];
1208
1209			if (!error)
1210				cmd->result = (DID_OK << 16);
1211			
1212			/* Report residual bytes for single sgl */
1213			if ((scsi_sg_count(cmd) <= 1) && (full_command_packet->command.newcommand.status == 0)) {
1214				if (full_command_packet->command.newcommand.sg_list[0].length < scsi_bufflen(tw_dev->srb[request_id]))
1215					scsi_set_resid(cmd, scsi_bufflen(cmd) - full_command_packet->command.newcommand.sg_list[0].length);
1216			}
1217
1218			/* Now complete the io */
1219			scsi_dma_unmap(cmd);
1220			cmd->scsi_done(cmd);
1221			tw_dev->state[request_id] = TW_S_COMPLETED;
1222			twl_free_request_id(tw_dev, request_id);
1223			tw_dev->posted_request_count--;
 
 
1224		}
1225
1226		/* Check for another response interrupt */
1227		reg = readl(TWL_HISTAT_REG_ADDR(tw_dev));
1228	}
1229
1230twl_interrupt_bail:
1231	spin_unlock(tw_dev->host->host_lock);
1232	return IRQ_RETVAL(handled);
1233} /* End twl_interrupt() */
1234
1235/* This function will poll for a register change */
1236static int twl_poll_register(TW_Device_Extension *tw_dev, void *reg, u32 value, u32 result, int seconds)
1237{
1238	unsigned long before;
1239	int retval = 1;
1240	u32 reg_value;
1241
1242	reg_value = readl(reg);
1243	before = jiffies;
1244
1245        while ((reg_value & value) != result) {
1246		reg_value = readl(reg);
1247		if (time_after(jiffies, before + HZ * seconds))
1248			goto out;
1249		msleep(50);
1250	}
1251	retval = 0;
1252out:
1253	return retval;
1254} /* End twl_poll_register() */
1255
1256/* This function will reset a controller */
1257static int twl_reset_sequence(TW_Device_Extension *tw_dev, int soft_reset)
1258{
1259	int retval = 1;
1260	int i = 0;
1261	u32 status = 0;
1262	unsigned short fw_on_ctlr_srl = 0, fw_on_ctlr_arch_id = 0;
1263	unsigned short fw_on_ctlr_branch = 0, fw_on_ctlr_build = 0;
1264	u32 init_connect_result = 0;
1265	int tries = 0;
1266	int do_soft_reset = soft_reset;
1267
1268	while (tries < TW_MAX_RESET_TRIES) {
1269		/* Do a soft reset if one is needed */
1270		if (do_soft_reset) {
1271			TWL_SOFT_RESET(tw_dev);
1272
1273			/* Make sure controller is in a good state */
1274			if (twl_poll_register(tw_dev, TWL_SCRPD3_REG_ADDR(tw_dev), TWL_CONTROLLER_READY, 0x0, 30)) {
1275				TW_PRINTK(tw_dev->host, TW_DRIVER, 0x10, "Controller never went non-ready during reset sequence");
1276				tries++;
1277				continue;
1278			}
1279			if (twl_poll_register(tw_dev, TWL_SCRPD3_REG_ADDR(tw_dev), TWL_CONTROLLER_READY, TWL_CONTROLLER_READY, 60)) {
1280				TW_PRINTK(tw_dev->host, TW_DRIVER, 0x11, "Controller not ready during reset sequence");
1281				tries++;
1282				continue;
1283			}
1284		}
1285
1286		/* Initconnect */
1287		if (twl_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS,
1288				       TW_EXTENDED_INIT_CONNECT, TW_CURRENT_DRIVER_SRL,
1289				       TW_9750_ARCH_ID, TW_CURRENT_DRIVER_BRANCH,
1290				       TW_CURRENT_DRIVER_BUILD, &fw_on_ctlr_srl,
1291				       &fw_on_ctlr_arch_id, &fw_on_ctlr_branch,
1292				       &fw_on_ctlr_build, &init_connect_result)) {
1293			TW_PRINTK(tw_dev->host, TW_DRIVER, 0x12, "Initconnection failed while checking SRL");
1294			do_soft_reset = 1;
1295			tries++;
1296			continue;
1297		}
1298
1299		/* Load sense buffers */
1300		while (i < TW_Q_LENGTH) {
1301			writel((u32)((u64)tw_dev->sense_buffer_phys[i] >> 32), TWL_HOBQPH_REG_ADDR(tw_dev));
1302			writel((u32)tw_dev->sense_buffer_phys[i], TWL_HOBQPL_REG_ADDR(tw_dev));
1303
1304			/* Check status for over-run after each write */
1305			status = readl(TWL_STATUS_REG_ADDR(tw_dev));
1306			if (!(status & TWL_STATUS_OVERRUN_SUBMIT))
1307			    i++;
1308		}
1309
1310		/* Now check status */
1311		status = readl(TWL_STATUS_REG_ADDR(tw_dev));
1312		if (status) {
1313			TW_PRINTK(tw_dev->host, TW_DRIVER, 0x13, "Bad controller status after loading sense buffers");
1314			do_soft_reset = 1;
1315			tries++;
1316			continue;
1317		}
1318
1319		/* Drain the AEN queue */
1320		if (twl_aen_drain_queue(tw_dev, soft_reset)) {
1321			TW_PRINTK(tw_dev->host, TW_DRIVER, 0x14, "AEN drain failed during reset sequence");
1322			do_soft_reset = 1;
1323			tries++;
1324			continue;
1325		}
1326
1327		/* Load rest of compatibility struct */
1328		strncpy(tw_dev->tw_compat_info.driver_version, TW_DRIVER_VERSION, strlen(TW_DRIVER_VERSION));
1329		tw_dev->tw_compat_info.driver_srl_high = TW_CURRENT_DRIVER_SRL;
1330		tw_dev->tw_compat_info.driver_branch_high = TW_CURRENT_DRIVER_BRANCH;
1331		tw_dev->tw_compat_info.driver_build_high = TW_CURRENT_DRIVER_BUILD;
1332		tw_dev->tw_compat_info.driver_srl_low = TW_BASE_FW_SRL;
1333		tw_dev->tw_compat_info.driver_branch_low = TW_BASE_FW_BRANCH;
1334		tw_dev->tw_compat_info.driver_build_low = TW_BASE_FW_BUILD;
1335		tw_dev->tw_compat_info.fw_on_ctlr_srl = fw_on_ctlr_srl;
1336		tw_dev->tw_compat_info.fw_on_ctlr_branch = fw_on_ctlr_branch;
1337		tw_dev->tw_compat_info.fw_on_ctlr_build = fw_on_ctlr_build;
1338
1339		/* If we got here, controller is in a good state */
1340		retval = 0;
1341		goto out;
1342	}
1343out:
1344	return retval;
1345} /* End twl_reset_sequence() */
1346
1347/* This function will reset a device extension */
1348static int twl_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_reset)
1349{
1350	int i = 0, retval = 1;
1351	unsigned long flags = 0;
1352
1353	/* Block SCSI requests while we are resetting */
1354	if (ioctl_reset)
1355		scsi_block_requests(tw_dev->host);
1356
1357	set_bit(TW_IN_RESET, &tw_dev->flags);
1358	TWL_MASK_INTERRUPTS(tw_dev);
1359	TWL_CLEAR_DB_INTERRUPT(tw_dev);
1360
1361	spin_lock_irqsave(tw_dev->host->host_lock, flags);
1362
1363	/* Abort all requests that are in progress */
1364	for (i = 0; i < TW_Q_LENGTH; i++) {
1365		if ((tw_dev->state[i] != TW_S_FINISHED) &&
1366		    (tw_dev->state[i] != TW_S_INITIAL) &&
1367		    (tw_dev->state[i] != TW_S_COMPLETED)) {
1368			struct scsi_cmnd *cmd = tw_dev->srb[i];
1369
1370			if (cmd) {
1371				cmd->result = (DID_RESET << 16);
1372				scsi_dma_unmap(cmd);
1373				cmd->scsi_done(cmd);
1374			}
1375		}
1376	}
1377
1378	/* Reset queues and counts */
1379	for (i = 0; i < TW_Q_LENGTH; i++) {
1380		tw_dev->free_queue[i] = i;
1381		tw_dev->state[i] = TW_S_INITIAL;
1382	}
1383	tw_dev->free_head = TW_Q_START;
1384	tw_dev->free_tail = TW_Q_START;
1385	tw_dev->posted_request_count = 0;
1386
1387	spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
1388
1389	if (twl_reset_sequence(tw_dev, 1))
1390		goto out;
1391
1392	TWL_UNMASK_INTERRUPTS(tw_dev);
1393
1394	clear_bit(TW_IN_RESET, &tw_dev->flags);
1395	tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1396
1397	retval = 0;
1398out:
1399	if (ioctl_reset)
1400		scsi_unblock_requests(tw_dev->host);
1401	return retval;
1402} /* End twl_reset_device_extension() */
1403
1404/* This funciton returns unit geometry in cylinders/heads/sectors */
1405static int twl_scsi_biosparam(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int geom[])
1406{
1407	int heads, sectors;
1408	TW_Device_Extension *tw_dev;
1409
1410	tw_dev = (TW_Device_Extension *)sdev->host->hostdata;
1411
1412	if (capacity >= 0x200000) {
1413		heads = 255;
1414		sectors = 63;
1415	} else {
1416		heads = 64;
1417		sectors = 32;
1418	}
1419
1420	geom[0] = heads;
1421	geom[1] = sectors;
1422	geom[2] = sector_div(capacity, heads * sectors); /* cylinders */
1423
1424	return 0;
1425} /* End twl_scsi_biosparam() */
1426
1427/* This is the new scsi eh reset function */
1428static int twl_scsi_eh_reset(struct scsi_cmnd *SCpnt)
1429{
1430	TW_Device_Extension *tw_dev = NULL;
1431	int retval = FAILED;
1432
1433	tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
1434
1435	tw_dev->num_resets++;
1436
1437	sdev_printk(KERN_WARNING, SCpnt->device,
1438		"WARNING: (0x%02X:0x%04X): Command (0x%x) timed out, resetting card.\n",
1439		TW_DRIVER, 0x2c, SCpnt->cmnd[0]);
1440
1441	/* Make sure we are not issuing an ioctl or resetting from ioctl */
1442	mutex_lock(&tw_dev->ioctl_lock);
1443
1444	/* Now reset the card and some of the device extension data */
1445	if (twl_reset_device_extension(tw_dev, 0)) {
1446		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x15, "Controller reset failed during scsi host reset");
1447		goto out;
1448	}
1449
1450	retval = SUCCESS;
1451out:
1452	mutex_unlock(&tw_dev->ioctl_lock);
1453	return retval;
1454} /* End twl_scsi_eh_reset() */
1455
1456/* This is the main scsi queue function to handle scsi opcodes */
1457static int twl_scsi_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1458{
1459	int request_id, retval;
1460	TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
1461
1462	/* If we are resetting due to timed out ioctl, report as busy */
1463	if (test_bit(TW_IN_RESET, &tw_dev->flags)) {
1464		retval = SCSI_MLQUEUE_HOST_BUSY;
1465		goto out;
1466	}
1467
1468	/* Save done function into scsi_cmnd struct */
1469	SCpnt->scsi_done = done;
1470		
1471	/* Get a free request id */
1472	twl_get_request_id(tw_dev, &request_id);
1473
1474	/* Save the scsi command for use by the ISR */
1475	tw_dev->srb[request_id] = SCpnt;
1476
 
 
 
1477	retval = twl_scsiop_execute_scsi(tw_dev, request_id, NULL, 0, NULL);
1478	if (retval) {
1479		tw_dev->state[request_id] = TW_S_COMPLETED;
1480		twl_free_request_id(tw_dev, request_id);
1481		SCpnt->result = (DID_ERROR << 16);
1482		done(SCpnt);
1483		retval = 0;
1484	}
1485out:
1486	return retval;
1487} /* End twl_scsi_queue() */
1488
1489static DEF_SCSI_QCMD(twl_scsi_queue)
1490
1491/* This function tells the controller to shut down */
1492static void __twl_shutdown(TW_Device_Extension *tw_dev)
1493{
1494	/* Disable interrupts */
1495	TWL_MASK_INTERRUPTS(tw_dev);
1496
1497	/* Free up the IRQ */
1498	free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
1499
1500	printk(KERN_WARNING "3w-sas: Shutting down host %d.\n", tw_dev->host->host_no);
1501
1502	/* Tell the card we are shutting down */
1503	if (twl_initconnection(tw_dev, 1, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL)) {
1504		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x16, "Connection shutdown failed");
1505	} else {
1506		printk(KERN_WARNING "3w-sas: Shutdown complete.\n");
1507	}
1508
1509	/* Clear doorbell interrupt just before exit */
1510	TWL_CLEAR_DB_INTERRUPT(tw_dev);
1511} /* End __twl_shutdown() */
1512
1513/* Wrapper for __twl_shutdown */
1514static void twl_shutdown(struct pci_dev *pdev)
1515{
1516	struct Scsi_Host *host = pci_get_drvdata(pdev);
1517	TW_Device_Extension *tw_dev;
1518
1519	if (!host)
1520		return;
1521
1522	tw_dev = (TW_Device_Extension *)host->hostdata;
1523
1524	if (tw_dev->online) 
1525		__twl_shutdown(tw_dev);
1526} /* End twl_shutdown() */
1527
1528/* This function configures unit settings when a unit is coming on-line */
1529static int twl_slave_configure(struct scsi_device *sdev)
1530{
1531	/* Force 60 second timeout */
1532	blk_queue_rq_timeout(sdev->request_queue, 60 * HZ);
1533
1534	return 0;
1535} /* End twl_slave_configure() */
1536
1537/* scsi_host_template initializer */
1538static struct scsi_host_template driver_template = {
1539	.module			= THIS_MODULE,
1540	.name			= "3w-sas",
1541	.queuecommand		= twl_scsi_queue,
1542	.eh_host_reset_handler	= twl_scsi_eh_reset,
1543	.bios_param		= twl_scsi_biosparam,
1544	.change_queue_depth	= scsi_change_queue_depth,
1545	.can_queue		= TW_Q_LENGTH-2,
1546	.slave_configure	= twl_slave_configure,
1547	.this_id		= -1,
1548	.sg_tablesize		= TW_LIBERATOR_MAX_SGL_LENGTH,
1549	.max_sectors		= TW_MAX_SECTORS,
1550	.cmd_per_lun		= TW_MAX_CMDS_PER_LUN,
1551	.use_clustering		= ENABLE_CLUSTERING,
1552	.shost_attrs		= twl_host_attrs,
1553	.emulated		= 1,
1554	.no_write_same		= 1,
1555};
1556
1557/* This function will probe and initialize a card */
1558static int twl_probe(struct pci_dev *pdev, const struct pci_device_id *dev_id)
1559{
1560	struct Scsi_Host *host = NULL;
1561	TW_Device_Extension *tw_dev;
1562	int retval = -ENODEV;
1563	int *ptr_phycount, phycount=0;
1564
1565	retval = pci_enable_device(pdev);
1566	if (retval) {
1567		TW_PRINTK(host, TW_DRIVER, 0x17, "Failed to enable pci device");
1568		goto out_disable_device;
1569	}
1570
1571	pci_set_master(pdev);
1572	pci_try_set_mwi(pdev);
1573
1574	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
1575	    || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)))
1576		if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1577		    || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
1578			TW_PRINTK(host, TW_DRIVER, 0x18, "Failed to set dma mask");
1579			retval = -ENODEV;
1580			goto out_disable_device;
1581		}
1582
1583	host = scsi_host_alloc(&driver_template, sizeof(TW_Device_Extension));
1584	if (!host) {
1585		TW_PRINTK(host, TW_DRIVER, 0x19, "Failed to allocate memory for device extension");
1586		retval = -ENOMEM;
1587		goto out_disable_device;
1588	}
1589	tw_dev = shost_priv(host);
1590
1591	/* Save values to device extension */
1592	tw_dev->host = host;
1593	tw_dev->tw_pci_dev = pdev;
1594
1595	if (twl_initialize_device_extension(tw_dev)) {
1596		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1a, "Failed to initialize device extension");
1597		goto out_free_device_extension;
1598	}
1599
1600	/* Request IO regions */
1601	retval = pci_request_regions(pdev, "3w-sas");
1602	if (retval) {
1603		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1b, "Failed to get mem region");
1604		goto out_free_device_extension;
1605	}
1606
1607	/* Save base address, use region 1 */
1608	tw_dev->base_addr = pci_iomap(pdev, 1, 0);
1609	if (!tw_dev->base_addr) {
1610		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1c, "Failed to ioremap");
1611		goto out_release_mem_region;
1612	}
1613
1614	/* Disable interrupts on the card */
1615	TWL_MASK_INTERRUPTS(tw_dev);
1616
1617	/* Initialize the card */
1618	if (twl_reset_sequence(tw_dev, 0)) {
1619		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1d, "Controller reset failed during probe");
1620		goto out_iounmap;
1621	}
1622
1623	/* Set host specific parameters */
1624	host->max_id = TW_MAX_UNITS;
1625	host->max_cmd_len = TW_MAX_CDB_LEN;
1626	host->max_lun = TW_MAX_LUNS;
1627	host->max_channel = 0;
1628
1629	/* Register the card with the kernel SCSI layer */
1630	retval = scsi_add_host(host, &pdev->dev);
1631	if (retval) {
1632		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1e, "scsi add host failed");
1633		goto out_iounmap;
1634	}
1635
1636	pci_set_drvdata(pdev, host);
1637
1638	printk(KERN_WARNING "3w-sas: scsi%d: Found an LSI 3ware %s Controller at 0x%llx, IRQ: %d.\n",
1639	       host->host_no,
1640	       (char *)twl_get_param(tw_dev, 1, TW_VERSION_TABLE,
1641				     TW_PARAM_MODEL, TW_PARAM_MODEL_LENGTH),
1642	       (u64)pci_resource_start(pdev, 1), pdev->irq);
1643
1644	ptr_phycount = twl_get_param(tw_dev, 2, TW_PARAM_PHY_SUMMARY_TABLE,
1645				     TW_PARAM_PHYCOUNT, TW_PARAM_PHYCOUNT_LENGTH);
1646	if (ptr_phycount)
1647		phycount = le32_to_cpu(*(int *)ptr_phycount);
1648
1649	printk(KERN_WARNING "3w-sas: scsi%d: Firmware %s, BIOS %s, Phys: %d.\n",
1650	       host->host_no,
1651	       (char *)twl_get_param(tw_dev, 1, TW_VERSION_TABLE,
1652				     TW_PARAM_FWVER, TW_PARAM_FWVER_LENGTH),
1653	       (char *)twl_get_param(tw_dev, 2, TW_VERSION_TABLE,
1654				     TW_PARAM_BIOSVER, TW_PARAM_BIOSVER_LENGTH),
1655	       phycount);
1656
1657	/* Try to enable MSI */
1658	if (use_msi && !pci_enable_msi(pdev))
1659		set_bit(TW_USING_MSI, &tw_dev->flags);
1660
1661	/* Now setup the interrupt handler */
1662	retval = request_irq(pdev->irq, twl_interrupt, IRQF_SHARED, "3w-sas", tw_dev);
1663	if (retval) {
1664		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1f, "Error requesting IRQ");
1665		goto out_remove_host;
1666	}
1667
1668	twl_device_extension_list[twl_device_extension_count] = tw_dev;
1669	twl_device_extension_count++;
1670
1671	/* Re-enable interrupts on the card */
1672	TWL_UNMASK_INTERRUPTS(tw_dev);
1673	
1674	/* Finally, scan the host */
1675	scsi_scan_host(host);
1676
1677	/* Add sysfs binary files */
1678	if (sysfs_create_bin_file(&host->shost_dev.kobj, &twl_sysfs_aen_read_attr))
1679		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x20, "Failed to create sysfs binary file: 3ware_aen_read");
1680	if (sysfs_create_bin_file(&host->shost_dev.kobj, &twl_sysfs_compat_info_attr))
1681		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x21, "Failed to create sysfs binary file: 3ware_compat_info");
1682
1683	if (twl_major == -1) {
1684		if ((twl_major = register_chrdev (0, "twl", &twl_fops)) < 0)
1685			TW_PRINTK(host, TW_DRIVER, 0x22, "Failed to register character device");
1686	}
1687	tw_dev->online = 1;
1688	return 0;
1689
1690out_remove_host:
1691	if (test_bit(TW_USING_MSI, &tw_dev->flags))
1692		pci_disable_msi(pdev);
1693	scsi_remove_host(host);
1694out_iounmap:
1695	iounmap(tw_dev->base_addr);
1696out_release_mem_region:
1697	pci_release_regions(pdev);
1698out_free_device_extension:
1699	twl_free_device_extension(tw_dev);
1700	scsi_host_put(host);
1701out_disable_device:
1702	pci_disable_device(pdev);
1703
1704	return retval;
1705} /* End twl_probe() */
1706
1707/* This function is called to remove a device */
1708static void twl_remove(struct pci_dev *pdev)
1709{
1710	struct Scsi_Host *host = pci_get_drvdata(pdev);
1711	TW_Device_Extension *tw_dev;
1712
1713	if (!host)
1714		return;
1715
1716	tw_dev = (TW_Device_Extension *)host->hostdata;
1717
1718	if (!tw_dev->online)
1719		return;
1720
1721	/* Remove sysfs binary files */
1722	sysfs_remove_bin_file(&host->shost_dev.kobj, &twl_sysfs_aen_read_attr);
1723	sysfs_remove_bin_file(&host->shost_dev.kobj, &twl_sysfs_compat_info_attr);
1724
1725	scsi_remove_host(tw_dev->host);
1726
1727	/* Unregister character device */
1728	if (twl_major >= 0) {
1729		unregister_chrdev(twl_major, "twl");
1730		twl_major = -1;
1731	}
1732
1733	/* Shutdown the card */
1734	__twl_shutdown(tw_dev);
1735
1736	/* Disable MSI if enabled */
1737	if (test_bit(TW_USING_MSI, &tw_dev->flags))
1738		pci_disable_msi(pdev);
1739
1740	/* Free IO remapping */
1741	iounmap(tw_dev->base_addr);
1742
1743	/* Free up the mem region */
1744	pci_release_regions(pdev);
1745
1746	/* Free up device extension resources */
1747	twl_free_device_extension(tw_dev);
1748
1749	scsi_host_put(tw_dev->host);
1750	pci_disable_device(pdev);
1751	twl_device_extension_count--;
1752} /* End twl_remove() */
1753
1754#ifdef CONFIG_PM
1755/* This function is called on PCI suspend */
1756static int twl_suspend(struct pci_dev *pdev, pm_message_t state)
1757{
1758	struct Scsi_Host *host = pci_get_drvdata(pdev);
1759	TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
1760
1761	printk(KERN_WARNING "3w-sas: Suspending host %d.\n", tw_dev->host->host_no);
1762	/* Disable interrupts */
1763	TWL_MASK_INTERRUPTS(tw_dev);
1764
1765	free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
1766
1767	/* Tell the card we are shutting down */
1768	if (twl_initconnection(tw_dev, 1, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL)) {
1769		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x23, "Connection shutdown failed during suspend");
1770	} else {
1771		printk(KERN_WARNING "3w-sas: Suspend complete.\n");
1772	}
1773
1774	/* Clear doorbell interrupt */
1775	TWL_CLEAR_DB_INTERRUPT(tw_dev);
1776
1777	pci_save_state(pdev);
1778	pci_disable_device(pdev);
1779	pci_set_power_state(pdev, pci_choose_state(pdev, state));
1780
1781	return 0;
1782} /* End twl_suspend() */
1783
1784/* This function is called on PCI resume */
1785static int twl_resume(struct pci_dev *pdev)
1786{
1787	int retval = 0;
1788	struct Scsi_Host *host = pci_get_drvdata(pdev);
1789	TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
1790
1791	printk(KERN_WARNING "3w-sas: Resuming host %d.\n", tw_dev->host->host_no);
1792	pci_set_power_state(pdev, PCI_D0);
1793	pci_enable_wake(pdev, PCI_D0, 0);
1794	pci_restore_state(pdev);
1795
1796	retval = pci_enable_device(pdev);
1797	if (retval) {
1798		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x24, "Enable device failed during resume");
1799		return retval;
1800	}
1801
1802	pci_set_master(pdev);
1803	pci_try_set_mwi(pdev);
1804
1805	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
1806	    || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)))
1807		if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1808		    || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
1809			TW_PRINTK(host, TW_DRIVER, 0x25, "Failed to set dma mask during resume");
1810			retval = -ENODEV;
1811			goto out_disable_device;
1812		}
1813
1814	/* Initialize the card */
1815	if (twl_reset_sequence(tw_dev, 0)) {
1816		retval = -ENODEV;
1817		goto out_disable_device;
1818	}
1819
1820	/* Now setup the interrupt handler */
1821	retval = request_irq(pdev->irq, twl_interrupt, IRQF_SHARED, "3w-sas", tw_dev);
1822	if (retval) {
1823		TW_PRINTK(tw_dev->host, TW_DRIVER, 0x26, "Error requesting IRQ during resume");
1824		retval = -ENODEV;
1825		goto out_disable_device;
1826	}
1827
1828	/* Now enable MSI if enabled */
1829	if (test_bit(TW_USING_MSI, &tw_dev->flags))
1830		pci_enable_msi(pdev);
1831
1832	/* Re-enable interrupts on the card */
1833	TWL_UNMASK_INTERRUPTS(tw_dev);
1834
1835	printk(KERN_WARNING "3w-sas: Resume complete.\n");
1836	return 0;
1837
1838out_disable_device:
1839	scsi_remove_host(host);
1840	pci_disable_device(pdev);
1841
1842	return retval;
1843} /* End twl_resume() */
1844#endif
1845
1846/* PCI Devices supported by this driver */
1847static struct pci_device_id twl_pci_tbl[] = {
1848	{ PCI_VDEVICE(3WARE, PCI_DEVICE_ID_3WARE_9750) },
1849	{ }
1850};
1851MODULE_DEVICE_TABLE(pci, twl_pci_tbl);
1852
1853/* pci_driver initializer */
1854static struct pci_driver twl_driver = {
1855	.name		= "3w-sas",
1856	.id_table	= twl_pci_tbl,
1857	.probe		= twl_probe,
1858	.remove		= twl_remove,
1859#ifdef CONFIG_PM
1860	.suspend	= twl_suspend,
1861	.resume		= twl_resume,
1862#endif
1863	.shutdown	= twl_shutdown
1864};
1865
1866/* This function is called on driver initialization */
1867static int __init twl_init(void)
1868{
1869	printk(KERN_INFO "LSI 3ware SAS/SATA-RAID Controller device driver for Linux v%s.\n", TW_DRIVER_VERSION);
1870
1871	return pci_register_driver(&twl_driver);
1872} /* End twl_init() */
1873
1874/* This function is called on driver exit */
1875static void __exit twl_exit(void)
1876{
1877	pci_unregister_driver(&twl_driver);
1878} /* End twl_exit() */
1879
1880module_init(twl_init);
1881module_exit(twl_exit);
1882