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