Linux Audio

Check our new training course

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