scsi: aacraid: Fix typo in blink status
[pandora-kernel.git] / drivers / scsi / aacraid / src.c
1 /*
2  *      Adaptec AAC series RAID controller driver
3  *      (c) Copyright 2001 Red Hat Inc.
4  *
5  * based on the old aacraid driver that is..
6  * Adaptec aacraid device driver for Linux.
7  *
8  * Copyright (c) 2000-2010 Adaptec, Inc.
9  *               2010 PMC-Sierra, Inc. (aacraid@pmc-sierra.com)
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2, or (at your option)
14  * any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; see the file COPYING.  If not, write to
23  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24  *
25  * Module Name:
26  *  src.c
27  *
28  * Abstract: Hardware Device Interface for PMC SRC based controllers
29  *
30  */
31
32 #include <linux/kernel.h>
33 #include <linux/init.h>
34 #include <linux/types.h>
35 #include <linux/pci.h>
36 #include <linux/spinlock.h>
37 #include <linux/slab.h>
38 #include <linux/blkdev.h>
39 #include <linux/delay.h>
40 #include <linux/completion.h>
41 #include <linux/time.h>
42 #include <linux/interrupt.h>
43 #include <scsi/scsi_host.h>
44
45 #include "aacraid.h"
46
47 static irqreturn_t aac_src_intr_message(int irq, void *dev_id)
48 {
49         struct aac_dev *dev = dev_id;
50         unsigned long bellbits, bellbits_shifted;
51         int our_interrupt = 0;
52         int isFastResponse;
53         u32 index, handle;
54
55         bellbits = src_readl(dev, MUnit.ODR_R);
56         if (bellbits & PmDoorBellResponseSent) {
57                 bellbits = PmDoorBellResponseSent;
58                 /* handle async. status */
59                 our_interrupt = 1;
60                 index = dev->host_rrq_idx;
61                 if (dev->host_rrq[index] == 0) {
62                         u32 old_index = index;
63                         /* adjust index */
64                         do {
65                                 index++;
66                                 if (index == dev->scsi_host_ptr->can_queue +
67                                                         AAC_NUM_MGT_FIB)
68                                         index = 0;
69                                 if (dev->host_rrq[index] != 0)
70                                         break;
71                         } while (index != old_index);
72                         dev->host_rrq_idx = index;
73                 }
74                 for (;;) {
75                         isFastResponse = 0;
76                         /* remove toggle bit (31) */
77                         handle = (dev->host_rrq[index] & 0x7fffffff);
78                         /* check fast response bit (30) */
79                         if (handle & 0x40000000)
80                                 isFastResponse = 1;
81                         handle &= 0x0000ffff;
82                         if (handle == 0)
83                                 break;
84
85                         aac_intr_normal(dev, handle-1, 0, isFastResponse, NULL);
86
87                         dev->host_rrq[index++] = 0;
88                         if (index == dev->scsi_host_ptr->can_queue +
89                                                 AAC_NUM_MGT_FIB)
90                                 index = 0;
91                         dev->host_rrq_idx = index;
92                 }
93         } else {
94                 bellbits_shifted = (bellbits >> SRC_ODR_SHIFT);
95                 if (bellbits_shifted & DoorBellAifPending) {
96                         our_interrupt = 1;
97                         /* handle AIF */
98                         aac_intr_normal(dev, 0, 2, 0, NULL);
99                 }
100         }
101
102         if (our_interrupt) {
103                 src_writel(dev, MUnit.ODR_C, bellbits);
104                 return IRQ_HANDLED;
105         }
106         return IRQ_NONE;
107 }
108
109 /**
110  *      aac_src_disable_interrupt       -       Disable interrupts
111  *      @dev: Adapter
112  */
113
114 static void aac_src_disable_interrupt(struct aac_dev *dev)
115 {
116         src_writel(dev, MUnit.OIMR, dev->OIMR = 0xffffffff);
117 }
118
119 /**
120  *      aac_src_enable_interrupt_message        -       Enable interrupts
121  *      @dev: Adapter
122  */
123
124 static void aac_src_enable_interrupt_message(struct aac_dev *dev)
125 {
126         src_writel(dev, MUnit.OIMR, dev->OIMR = 0xfffffff8);
127 }
128
129 /**
130  *      src_sync_cmd    -       send a command and wait
131  *      @dev: Adapter
132  *      @command: Command to execute
133  *      @p1: first parameter
134  *      @ret: adapter status
135  *
136  *      This routine will send a synchronous command to the adapter and wait
137  *      for its completion.
138  */
139
140 static int src_sync_cmd(struct aac_dev *dev, u32 command,
141         u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6,
142         u32 *status, u32 * r1, u32 * r2, u32 * r3, u32 * r4)
143 {
144         unsigned long start;
145         int ok;
146
147         /*
148          *      Write the command into Mailbox 0
149          */
150         writel(command, &dev->IndexRegs->Mailbox[0]);
151         /*
152          *      Write the parameters into Mailboxes 1 - 6
153          */
154         writel(p1, &dev->IndexRegs->Mailbox[1]);
155         writel(p2, &dev->IndexRegs->Mailbox[2]);
156         writel(p3, &dev->IndexRegs->Mailbox[3]);
157         writel(p4, &dev->IndexRegs->Mailbox[4]);
158
159         /*
160          *      Clear the synch command doorbell to start on a clean slate.
161          */
162         src_writel(dev, MUnit.ODR_C, OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
163
164         /*
165          *      Disable doorbell interrupts
166          */
167         src_writel(dev, MUnit.OIMR, dev->OIMR = 0xffffffff);
168
169         /*
170          *      Force the completion of the mask register write before issuing
171          *      the interrupt.
172          */
173         src_readl(dev, MUnit.OIMR);
174
175         /*
176          *      Signal that there is a new synch command
177          */
178         src_writel(dev, MUnit.IDR, INBOUNDDOORBELL_0 << SRC_IDR_SHIFT);
179
180         ok = 0;
181         start = jiffies;
182
183         /*
184          *      Wait up to 30 seconds
185          */
186         while (time_before(jiffies, start+30*HZ)) {
187                 /* Delay 5 microseconds to let Mon960 get info. */
188                 udelay(5);
189
190                 /* Mon960 will set doorbell0 bit
191                  * when it has completed the command
192                  */
193                 if ((src_readl(dev, MUnit.ODR_R) >> SRC_ODR_SHIFT) & OUTBOUNDDOORBELL_0) {
194                         /* Clear the doorbell */
195                         src_writel(dev,
196                                 MUnit.ODR_C,
197                                 OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
198                         ok = 1;
199                         break;
200                 }
201
202                  /* Yield the processor in case we are slow */
203                 msleep(1);
204         }
205         if (unlikely(ok != 1)) {
206                  /* Restore interrupt mask even though we timed out */
207                 aac_adapter_enable_int(dev);
208                 return -ETIMEDOUT;
209         }
210
211          /* Pull the synch status from Mailbox 0 */
212         if (status)
213                 *status = readl(&dev->IndexRegs->Mailbox[0]);
214         if (r1)
215                 *r1 = readl(&dev->IndexRegs->Mailbox[1]);
216         if (r2)
217                 *r2 = readl(&dev->IndexRegs->Mailbox[2]);
218         if (r3)
219                 *r3 = readl(&dev->IndexRegs->Mailbox[3]);
220         if (r4)
221                 *r4 = readl(&dev->IndexRegs->Mailbox[4]);
222
223          /* Clear the synch command doorbell */
224         src_writel(dev, MUnit.ODR_C, OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
225
226          /* Restore interrupt mask */
227         aac_adapter_enable_int(dev);
228         return 0;
229
230 }
231
232 /**
233  *      aac_src_interrupt_adapter       -       interrupt adapter
234  *      @dev: Adapter
235  *
236  *      Send an interrupt to the i960 and breakpoint it.
237  */
238
239 static void aac_src_interrupt_adapter(struct aac_dev *dev)
240 {
241         src_sync_cmd(dev, BREAKPOINT_REQUEST,
242                 0, 0, 0, 0, 0, 0,
243                 NULL, NULL, NULL, NULL, NULL);
244 }
245
246 /**
247  *      aac_src_notify_adapter          -       send an event to the adapter
248  *      @dev: Adapter
249  *      @event: Event to send
250  *
251  *      Notify the i960 that something it probably cares about has
252  *      happened.
253  */
254
255 static void aac_src_notify_adapter(struct aac_dev *dev, u32 event)
256 {
257         switch (event) {
258
259         case AdapNormCmdQue:
260                 src_writel(dev, MUnit.ODR_C,
261                         INBOUNDDOORBELL_1 << SRC_ODR_SHIFT);
262                 break;
263         case HostNormRespNotFull:
264                 src_writel(dev, MUnit.ODR_C,
265                         INBOUNDDOORBELL_4 << SRC_ODR_SHIFT);
266                 break;
267         case AdapNormRespQue:
268                 src_writel(dev, MUnit.ODR_C,
269                         INBOUNDDOORBELL_2 << SRC_ODR_SHIFT);
270                 break;
271         case HostNormCmdNotFull:
272                 src_writel(dev, MUnit.ODR_C,
273                         INBOUNDDOORBELL_3 << SRC_ODR_SHIFT);
274                 break;
275         case FastIo:
276                 src_writel(dev, MUnit.ODR_C,
277                         INBOUNDDOORBELL_6 << SRC_ODR_SHIFT);
278                 break;
279         case AdapPrintfDone:
280                 src_writel(dev, MUnit.ODR_C,
281                         INBOUNDDOORBELL_5 << SRC_ODR_SHIFT);
282                 break;
283         default:
284                 BUG();
285                 break;
286         }
287 }
288
289 /**
290  *      aac_src_start_adapter           -       activate adapter
291  *      @dev:   Adapter
292  *
293  *      Start up processing on an i960 based AAC adapter
294  */
295
296 static void aac_src_start_adapter(struct aac_dev *dev)
297 {
298         struct aac_init *init;
299
300         init = dev->init;
301         init->HostElapsedSeconds = cpu_to_le32(get_seconds());
302
303         /* We can only use a 32 bit address here */
304         src_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa,
305           0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL);
306 }
307
308 /**
309  *      aac_src_check_health
310  *      @dev: device to check if healthy
311  *
312  *      Will attempt to determine if the specified adapter is alive and
313  *      capable of handling requests, returning 0 if alive.
314  */
315 static int aac_src_check_health(struct aac_dev *dev)
316 {
317         u32 status = src_readl(dev, MUnit.OMR);
318
319         /*
320          *      Check to see if the board panic'd.
321          */
322         if (unlikely(status & KERNEL_PANIC))
323                 goto err_blink;
324
325         /*
326          *      Check to see if the board failed any self tests.
327          */
328         if (unlikely(status & SELF_TEST_FAILED))
329                 goto err_out;
330
331         /*
332          *      Check to see if the board failed any self tests.
333          */
334         if (unlikely(status & MONITOR_PANIC))
335                 goto err_out;
336
337         /*
338          *      Wait for the adapter to be up and running.
339          */
340         if (unlikely(!(status & KERNEL_UP_AND_RUNNING)))
341                 return -3;
342         /*
343          *      Everything is OK
344          */
345         return 0;
346
347 err_out:
348         return -1;
349
350 err_blink:
351         return (status >> 16) & 0xFF;
352 }
353
354 /**
355  *      aac_src_deliver_message
356  *      @fib: fib to issue
357  *
358  *      Will send a fib, returning 0 if successful.
359  */
360 static int aac_src_deliver_message(struct fib *fib)
361 {
362         struct aac_dev *dev = fib->dev;
363         struct aac_queue *q = &dev->queues->queue[AdapNormCmdQueue];
364         unsigned long qflags;
365         u32 fibsize;
366         u64 address;
367         struct aac_fib_xporthdr *pFibX;
368
369         spin_lock_irqsave(q->lock, qflags);
370         q->numpending++;
371         spin_unlock_irqrestore(q->lock, qflags);
372
373         /* Calculate the amount to the fibsize bits */
374         fibsize = (sizeof(struct aac_fib_xporthdr) +
375                 fib->hw_fib_va->header.Size + 127) / 128 - 1;
376         if (fibsize > (ALIGN32 - 1))
377                 fibsize = ALIGN32 - 1;
378
379     /* Fill XPORT header */
380         pFibX = (struct aac_fib_xporthdr *)
381                 ((unsigned char *)fib->hw_fib_va -
382                 sizeof(struct aac_fib_xporthdr));
383         pFibX->Handle = fib->hw_fib_va->header.SenderData + 1;
384         pFibX->HostAddress = fib->hw_fib_pa;
385         pFibX->Size = fib->hw_fib_va->header.Size;
386         address = fib->hw_fib_pa - (u64)sizeof(struct aac_fib_xporthdr);
387
388         src_writel(dev, MUnit.IQ_H, (u32)(address >> 32));
389         src_writel(dev, MUnit.IQ_L, (u32)(address & 0xffffffff) + fibsize);
390         return 0;
391 }
392
393 /**
394  *      aac_src_ioremap
395  *      @size: mapping resize request
396  *
397  */
398 static int aac_src_ioremap(struct aac_dev *dev, u32 size)
399 {
400         if (!size) {
401                 iounmap(dev->regs.src.bar0);
402                 dev->regs.src.bar0 = NULL;
403                 iounmap(dev->base);
404                 dev->base = NULL;
405                 return 0;
406         }
407         dev->regs.src.bar1 = ioremap(pci_resource_start(dev->pdev, 2),
408                 AAC_MIN_SRC_BAR1_SIZE);
409         dev->base = NULL;
410         if (dev->regs.src.bar1 == NULL)
411                 return -1;
412         dev->base = dev->regs.src.bar0 = ioremap(dev->scsi_host_ptr->base,
413                                 size);
414         if (dev->base == NULL) {
415                 iounmap(dev->regs.src.bar1);
416                 dev->regs.src.bar1 = NULL;
417                 return -1;
418         }
419         dev->IndexRegs = &((struct src_registers __iomem *)
420                 dev->base)->IndexRegs;
421         return 0;
422 }
423
424 static int aac_src_restart_adapter(struct aac_dev *dev, int bled)
425 {
426         u32 var, reset_mask;
427
428         if (bled >= 0) {
429                 if (bled)
430                         printk(KERN_ERR "%s%d: adapter kernel panic'd %x.\n",
431                                 dev->name, dev->id, bled);
432                 bled = aac_adapter_sync_cmd(dev, IOP_RESET_ALWAYS,
433                         0, 0, 0, 0, 0, 0, &var, &reset_mask, NULL, NULL, NULL);
434                         if (bled || (var != 0x00000001))
435                                 bled = -EINVAL;
436                 if (dev->supplement_adapter_info.SupportedOptions2 &
437                         AAC_OPTION_DOORBELL_RESET) {
438                         src_writel(dev, MUnit.IDR, reset_mask);
439                         msleep(5000); /* Delay 5 seconds */
440                 }
441         }
442
443         if (src_readl(dev, MUnit.OMR) & KERNEL_PANIC)
444                 return -ENODEV;
445
446         if (startup_timeout < 300)
447                 startup_timeout = 300;
448
449         return 0;
450 }
451
452 /**
453  *      aac_src_select_comm     -       Select communications method
454  *      @dev: Adapter
455  *      @comm: communications method
456  */
457 int aac_src_select_comm(struct aac_dev *dev, int comm)
458 {
459         switch (comm) {
460         case AAC_COMM_MESSAGE:
461                 dev->a_ops.adapter_enable_int = aac_src_enable_interrupt_message;
462                 dev->a_ops.adapter_intr = aac_src_intr_message;
463                 dev->a_ops.adapter_deliver = aac_src_deliver_message;
464                 break;
465         default:
466                 return 1;
467         }
468         return 0;
469 }
470
471 /**
472  *  aac_src_init        -       initialize an Cardinal Frey Bar card
473  *  @dev: device to configure
474  *
475  */
476
477 int aac_src_init(struct aac_dev *dev)
478 {
479         unsigned long start;
480         unsigned long status;
481         int restart = 0;
482         int instance = dev->id;
483         const char *name = dev->name;
484
485         dev->a_ops.adapter_ioremap = aac_src_ioremap;
486         dev->a_ops.adapter_comm = aac_src_select_comm;
487
488         dev->base_size = AAC_MIN_SRC_BAR0_SIZE;
489         if (aac_adapter_ioremap(dev, dev->base_size)) {
490                 printk(KERN_WARNING "%s: unable to map adapter.\n", name);
491                 goto error_iounmap;
492         }
493
494         /* Failure to reset here is an option ... */
495         dev->a_ops.adapter_sync_cmd = src_sync_cmd;
496         dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
497         if ((aac_reset_devices || reset_devices) &&
498                 !aac_src_restart_adapter(dev, 0))
499                 ++restart;
500         /*
501          *      Check to see if the board panic'd while booting.
502          */
503         status = src_readl(dev, MUnit.OMR);
504         if (status & KERNEL_PANIC) {
505                 if (aac_src_restart_adapter(dev, aac_src_check_health(dev)))
506                         goto error_iounmap;
507                 ++restart;
508         }
509         /*
510          *      Check to see if the board failed any self tests.
511          */
512         status = src_readl(dev, MUnit.OMR);
513         if (status & SELF_TEST_FAILED) {
514                 printk(KERN_ERR "%s%d: adapter self-test failed.\n",
515                         dev->name, instance);
516                 goto error_iounmap;
517         }
518         /*
519          *      Check to see if the monitor panic'd while booting.
520          */
521         if (status & MONITOR_PANIC) {
522                 printk(KERN_ERR "%s%d: adapter monitor panic.\n",
523                         dev->name, instance);
524                 goto error_iounmap;
525         }
526         start = jiffies;
527         /*
528          *      Wait for the adapter to be up and running. Wait up to 3 minutes
529          */
530         while (!((status = src_readl(dev, MUnit.OMR)) &
531                 KERNEL_UP_AND_RUNNING)) {
532                 if ((restart &&
533                   (status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC))) ||
534                   time_after(jiffies, start+HZ*startup_timeout)) {
535                         printk(KERN_ERR "%s%d: adapter kernel failed to start, init status = %lx.\n",
536                                         dev->name, instance, status);
537                         goto error_iounmap;
538                 }
539                 if (!restart &&
540                   ((status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC)) ||
541                   time_after(jiffies, start + HZ *
542                   ((startup_timeout > 60)
543                     ? (startup_timeout - 60)
544                     : (startup_timeout / 2))))) {
545                         if (likely(!aac_src_restart_adapter(dev,
546                             aac_src_check_health(dev))))
547                                 start = jiffies;
548                         ++restart;
549                 }
550                 msleep(1);
551         }
552         if (restart && aac_commit)
553                 aac_commit = 1;
554         /*
555          *      Fill in the common function dispatch table.
556          */
557         dev->a_ops.adapter_interrupt = aac_src_interrupt_adapter;
558         dev->a_ops.adapter_disable_int = aac_src_disable_interrupt;
559         dev->a_ops.adapter_notify = aac_src_notify_adapter;
560         dev->a_ops.adapter_sync_cmd = src_sync_cmd;
561         dev->a_ops.adapter_check_health = aac_src_check_health;
562         dev->a_ops.adapter_restart = aac_src_restart_adapter;
563
564         /*
565          *      First clear out all interrupts.  Then enable the one's that we
566          *      can handle.
567          */
568         aac_adapter_comm(dev, AAC_COMM_MESSAGE);
569         aac_adapter_disable_int(dev);
570         src_writel(dev, MUnit.ODR_C, 0xffffffff);
571         aac_adapter_enable_int(dev);
572
573         if (aac_init_adapter(dev) == NULL)
574                 goto error_iounmap;
575         if (dev->comm_interface != AAC_COMM_MESSAGE_TYPE1)
576                 goto error_iounmap;
577
578         dev->msi = aac_msi && !pci_enable_msi(dev->pdev);
579
580         if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr,
581                         IRQF_SHARED|IRQF_DISABLED, "aacraid", dev) < 0) {
582
583                 if (dev->msi)
584                         pci_disable_msi(dev->pdev);
585
586                 printk(KERN_ERR "%s%d: Interrupt unavailable.\n",
587                         name, instance);
588                 goto error_iounmap;
589         }
590         dev->dbg_base = pci_resource_start(dev->pdev, 2);
591         dev->dbg_base_mapped = dev->regs.src.bar1;
592         dev->dbg_size = AAC_MIN_SRC_BAR1_SIZE;
593
594         aac_adapter_enable_int(dev);
595         /*
596          *      Tell the adapter that all is configured, and it can
597          * start accepting requests
598          */
599         aac_src_start_adapter(dev);
600
601         return 0;
602
603 error_iounmap:
604
605         return -1;
606 }