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