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