[SCSI] 2.6 aacraid: Variable FIB size (updated patch)
[linux-2.6] / drivers / scsi / aacraid / rx.c
1 /*
2  *      Adaptec AAC series RAID controller driver
3  *      (c) Copyright 2001 Red Hat Inc. <alan@redhat.com>
4  *
5  * based on the old aacraid driver that is..
6  * Adaptec aacraid device driver for Linux.
7  *
8  * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2, or (at your option)
13  * any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; see the file COPYING.  If not, write to
22  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23  *
24  * Module Name:
25  *  rx.c
26  *
27  * Abstract: Hardware miniport for Drawbridge specific hardware functions.
28  *
29  */
30
31 #include <linux/kernel.h>
32 #include <linux/init.h>
33 #include <linux/types.h>
34 #include <linux/sched.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 <asm/semaphore.h>
44
45 #include <scsi/scsi_host.h>
46
47 #include "aacraid.h"
48
49 static irqreturn_t aac_rx_intr(int irq, void *dev_id, struct pt_regs *regs)
50 {
51         struct aac_dev *dev = dev_id;
52         unsigned long bellbits;
53         u8 intstat, mask;
54         intstat = rx_readb(dev, MUnit.OISR);
55         /*
56          *      Read mask and invert because drawbridge is reversed.
57          *      This allows us to only service interrupts that have 
58          *      been enabled.
59          */
60         mask = ~(dev->OIMR);
61         /* Check to see if this is our interrupt.  If it isn't just return */
62         if (intstat & mask) 
63         {
64                 bellbits = rx_readl(dev, OutboundDoorbellReg);
65                 if (bellbits & DoorBellPrintfReady) {
66                         aac_printf(dev, rx_readl(dev, IndexRegs.Mailbox[5]));
67                         rx_writel(dev, MUnit.ODR,DoorBellPrintfReady);
68                         rx_writel(dev, InboundDoorbellReg,DoorBellPrintfDone);
69                 }
70                 else if (bellbits & DoorBellAdapterNormCmdReady) {
71                         rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdReady);
72                         aac_command_normal(&dev->queues->queue[HostNormCmdQueue]);
73                 }
74                 else if (bellbits & DoorBellAdapterNormRespReady) {
75                         aac_response_normal(&dev->queues->queue[HostNormRespQueue]);
76                         rx_writel(dev, MUnit.ODR,DoorBellAdapterNormRespReady);
77                 }
78                 else if (bellbits & DoorBellAdapterNormCmdNotFull) {
79                         rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull);
80                 }
81                 else if (bellbits & DoorBellAdapterNormRespNotFull) {
82                         rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull);
83                         rx_writel(dev, MUnit.ODR, DoorBellAdapterNormRespNotFull);
84                 }
85                 return IRQ_HANDLED;
86         }
87         return IRQ_NONE;
88 }
89
90 /**
91  *      rx_sync_cmd     -       send a command and wait
92  *      @dev: Adapter
93  *      @command: Command to execute
94  *      @p1: first parameter
95  *      @ret: adapter status
96  *
97  *      This routine will send a synchronous command to the adapter and wait 
98  *      for its completion.
99  */
100
101 static int rx_sync_cmd(struct aac_dev *dev, u32 command,
102         u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6,
103         u32 *status, u32 * r1, u32 * r2, u32 * r3, u32 * r4)
104 {
105         unsigned long start;
106         int ok;
107         /*
108          *      Write the command into Mailbox 0
109          */
110         rx_writel(dev, InboundMailbox0, command);
111         /*
112          *      Write the parameters into Mailboxes 1 - 6
113          */
114         rx_writel(dev, InboundMailbox1, p1);
115         rx_writel(dev, InboundMailbox2, p2);
116         rx_writel(dev, InboundMailbox3, p3);
117         rx_writel(dev, InboundMailbox4, p4);
118         /*
119          *      Clear the synch command doorbell to start on a clean slate.
120          */
121         rx_writel(dev, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
122         /*
123          *      Disable doorbell interrupts
124          */
125         rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xff);
126         /*
127          *      Force the completion of the mask register write before issuing
128          *      the interrupt.
129          */
130         rx_readb (dev, MUnit.OIMR);
131         /*
132          *      Signal that there is a new synch command
133          */
134         rx_writel(dev, InboundDoorbellReg, INBOUNDDOORBELL_0);
135
136         ok = 0;
137         start = jiffies;
138
139         /*
140          *      Wait up to 30 seconds
141          */
142         while (time_before(jiffies, start+30*HZ)) 
143         {
144                 udelay(5);      /* Delay 5 microseconds to let Mon960 get info. */
145                 /*
146                  *      Mon960 will set doorbell0 bit when it has completed the command.
147                  */
148                 if (rx_readl(dev, OutboundDoorbellReg) & OUTBOUNDDOORBELL_0) {
149                         /*
150                          *      Clear the doorbell.
151                          */
152                         rx_writel(dev, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
153                         ok = 1;
154                         break;
155                 }
156                 /*
157                  *      Yield the processor in case we are slow 
158                  */
159                 set_current_state(TASK_UNINTERRUPTIBLE);
160                 schedule_timeout(1);
161         }
162         if (ok != 1) {
163                 /*
164                  *      Restore interrupt mask even though we timed out
165                  */
166                 rx_writeb(dev, MUnit.OIMR, dev->OIMR &= 0xfb);
167                 return -ETIMEDOUT;
168         }
169         /*
170          *      Pull the synch status from Mailbox 0.
171          */
172         if (status)
173                 *status = rx_readl(dev, IndexRegs.Mailbox[0]);
174         if (r1)
175                 *r1 = rx_readl(dev, IndexRegs.Mailbox[1]);
176         if (r2)
177                 *r2 = rx_readl(dev, IndexRegs.Mailbox[2]);
178         if (r3)
179                 *r3 = rx_readl(dev, IndexRegs.Mailbox[3]);
180         if (r4)
181                 *r4 = rx_readl(dev, IndexRegs.Mailbox[4]);
182         /*
183          *      Clear the synch command doorbell.
184          */
185         rx_writel(dev, OutboundDoorbellReg, OUTBOUNDDOORBELL_0);
186         /*
187          *      Restore interrupt mask
188          */
189         rx_writeb(dev, MUnit.OIMR, dev->OIMR &= 0xfb);
190         return 0;
191
192 }
193
194 /**
195  *      aac_rx_interrupt_adapter        -       interrupt adapter
196  *      @dev: Adapter
197  *
198  *      Send an interrupt to the i960 and breakpoint it.
199  */
200
201 static void aac_rx_interrupt_adapter(struct aac_dev *dev)
202 {
203         rx_sync_cmd(dev, BREAKPOINT_REQUEST, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL);
204 }
205
206 /**
207  *      aac_rx_notify_adapter           -       send an event to the adapter
208  *      @dev: Adapter
209  *      @event: Event to send
210  *
211  *      Notify the i960 that something it probably cares about has
212  *      happened.
213  */
214
215 static void aac_rx_notify_adapter(struct aac_dev *dev, u32 event)
216 {
217         switch (event) {
218
219         case AdapNormCmdQue:
220                 rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_1);
221                 break;
222         case HostNormRespNotFull:
223                 rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_4);
224                 break;
225         case AdapNormRespQue:
226                 rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_2);
227                 break;
228         case HostNormCmdNotFull:
229                 rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_3);
230                 break;
231         case HostShutdown:
232 //              rx_sync_cmd(dev, HOST_CRASHING, 0, 0, 0, 0, 0, 0,
233 //                NULL, NULL, NULL, NULL, NULL);
234                 break;
235         case FastIo:
236                 rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_6);
237                 break;
238         case AdapPrintfDone:
239                 rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_5);
240                 break;
241         default:
242                 BUG();
243                 break;
244         }
245 }
246
247 /**
248  *      aac_rx_start_adapter            -       activate adapter
249  *      @dev:   Adapter
250  *
251  *      Start up processing on an i960 based AAC adapter
252  */
253
254 static void aac_rx_start_adapter(struct aac_dev *dev)
255 {
256         struct aac_init *init;
257
258         init = dev->init;
259         init->HostElapsedSeconds = cpu_to_le32(get_seconds());
260         /*
261          *      First clear out all interrupts.  Then enable the one's that we
262          *      can handle.
263          */
264         rx_writeb(dev, MUnit.OIMR, 0xff);
265         rx_writel(dev, MUnit.ODR, 0xffffffff);
266 //      rx_writeb(dev, MUnit.OIMR, ~(u8)OUTBOUND_DOORBELL_INTERRUPT_MASK);
267         rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb);
268
269         // We can only use a 32 bit address here
270         rx_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa,
271           0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL);
272 }
273
274 /**
275  *      aac_rx_check_health
276  *      @dev: device to check if healthy
277  *
278  *      Will attempt to determine if the specified adapter is alive and
279  *      capable of handling requests, returning 0 if alive.
280  */
281 static int aac_rx_check_health(struct aac_dev *dev)
282 {
283         u32 status = rx_readl(dev, MUnit.OMRx[0]);
284
285         /*
286          *      Check to see if the board failed any self tests.
287          */
288         if (status & SELF_TEST_FAILED)
289                 return -1;
290         /*
291          *      Check to see if the board panic'd.
292          */
293         if (status & KERNEL_PANIC) {
294                 char * buffer;
295                 struct POSTSTATUS {
296                         __le32 Post_Command;
297                         __le32 Post_Address;
298                 } * post;
299                 dma_addr_t paddr, baddr;
300                 int ret;
301
302                 if ((status & 0xFF000000L) == 0xBC000000L)
303                         return (status >> 16) & 0xFF;
304                 buffer = pci_alloc_consistent(dev->pdev, 512, &baddr);
305                 ret = -2;
306                 if (buffer == NULL)
307                         return ret;
308                 post = pci_alloc_consistent(dev->pdev,
309                   sizeof(struct POSTSTATUS), &paddr);
310                 if (post == NULL) {
311                         pci_free_consistent(dev->pdev, 512, buffer, baddr);
312                         return ret;
313                 }
314                 memset(buffer, 0, 512);
315                 post->Post_Command = cpu_to_le32(COMMAND_POST_RESULTS);
316                 post->Post_Address = cpu_to_le32(baddr);
317                 rx_writel(dev, MUnit.IMRx[0], paddr);
318                 rx_sync_cmd(dev, COMMAND_POST_RESULTS, baddr, 0, 0, 0, 0, 0,
319                   NULL, NULL, NULL, NULL, NULL);
320                 pci_free_consistent(dev->pdev, sizeof(struct POSTSTATUS),
321                   post, paddr);
322                 if ((buffer[0] == '0') && (buffer[1] == 'x')) {
323                         ret = (buffer[2] <= '9') ? (buffer[2] - '0') : (buffer[2] - 'A' + 10);
324                         ret <<= 4;
325                         ret += (buffer[3] <= '9') ? (buffer[3] - '0') : (buffer[3] - 'A' + 10);
326                 }
327                 pci_free_consistent(dev->pdev, 512, buffer, baddr);
328                 return ret;
329         }
330         /*
331          *      Wait for the adapter to be up and running.
332          */
333         if (!(status & KERNEL_UP_AND_RUNNING))
334                 return -3;
335         /*
336          *      Everything is OK
337          */
338         return 0;
339 }
340
341 /**
342  *      aac_rx_init     -       initialize an i960 based AAC card
343  *      @dev: device to configure
344  *
345  *      Allocate and set up resources for the i960 based AAC variants. The 
346  *      device_interface in the commregion will be allocated and linked 
347  *      to the comm region.
348  */
349
350 int aac_rx_init(struct aac_dev *dev)
351 {
352         unsigned long start;
353         unsigned long status;
354         int instance;
355         const char * name;
356
357         instance = dev->id;
358         name     = dev->name;
359
360         /*
361          *      Map in the registers from the adapter.
362          */
363         if((dev->regs.rx = ioremap((unsigned long)dev->scsi_host_ptr->base, 8192))==NULL)
364         {       
365                 printk(KERN_WARNING "aacraid: unable to map i960.\n" );
366                 return -1;
367         }
368         /*
369          *      Check to see if the board failed any self tests.
370          */
371         if (rx_readl(dev, MUnit.OMRx[0]) & SELF_TEST_FAILED) {
372                 printk(KERN_ERR "%s%d: adapter self-test failed.\n", dev->name, instance);
373                 goto error_iounmap;
374         }
375         /*
376          *      Check to see if the board panic'd while booting.
377          */
378         if (rx_readl(dev, MUnit.OMRx[0]) & KERNEL_PANIC) {
379                 printk(KERN_ERR "%s%d: adapter kernel panic.\n", dev->name, instance);
380                 goto error_iounmap;
381         }
382         /*
383          *      Check to see if the monitor panic'd while booting.
384          */
385         if (rx_readl(dev, MUnit.OMRx[0]) & MONITOR_PANIC) {
386                 printk(KERN_ERR "%s%d: adapter monitor panic.\n", dev->name, instance);
387                 goto error_iounmap;
388         }
389         start = jiffies;
390         /*
391          *      Wait for the adapter to be up and running. Wait up to 3 minutes
392          */
393         while ((!(rx_readl(dev, IndexRegs.Mailbox[7]) & KERNEL_UP_AND_RUNNING))
394                 || (!(rx_readl(dev, MUnit.OMRx[0]) & KERNEL_UP_AND_RUNNING)))
395         {
396                 if(time_after(jiffies, start+180*HZ))
397                 {
398                         status = rx_readl(dev, IndexRegs.Mailbox[7]);
399                         printk(KERN_ERR "%s%d: adapter kernel failed to start, init status = %lx.\n", 
400                                         dev->name, instance, status);
401                         goto error_iounmap;
402                 }
403                 set_current_state(TASK_UNINTERRUPTIBLE);
404                 schedule_timeout(1);
405         }
406         if (request_irq(dev->scsi_host_ptr->irq, aac_rx_intr, SA_SHIRQ|SA_INTERRUPT, "aacraid", (void *)dev)<0) 
407         {
408                 printk(KERN_ERR "%s%d: Interrupt unavailable.\n", name, instance);
409                 goto error_iounmap;
410         }
411         /*
412          *      Fill in the function dispatch table.
413          */
414         dev->a_ops.adapter_interrupt = aac_rx_interrupt_adapter;
415         dev->a_ops.adapter_notify = aac_rx_notify_adapter;
416         dev->a_ops.adapter_sync_cmd = rx_sync_cmd;
417         dev->a_ops.adapter_check_health = aac_rx_check_health;
418
419         if (aac_init_adapter(dev) == NULL)
420                 goto error_irq;
421         /*
422          *      Start any kernel threads needed
423          */
424         dev->thread_pid = kernel_thread((int (*)(void *))aac_command_thread, dev, 0);
425         if(dev->thread_pid < 0)
426         {
427                 printk(KERN_ERR "aacraid: Unable to create rx thread.\n");
428                 goto error_kfree;
429         }
430         /*
431          *      Tell the adapter that all is configured, and it can start
432          *      accepting requests
433          */
434         aac_rx_start_adapter(dev);
435         return 0;
436
437 error_kfree:
438         kfree(dev->queues);
439
440 error_irq:
441         free_irq(dev->scsi_host_ptr->irq, (void *)dev);
442
443 error_iounmap:
444         iounmap(dev->regs.rx);
445
446         return -1;
447 }