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 53 dprintk((KERN_DEBUG "aac_rx_intr(%d,%p,%p)\n", irq, dev_id, regs)); 54 if (dev->new_comm_interface) { 55 u32 Index = rx_readl(dev, MUnit.OutboundQueue); 56 if (Index == 0xFFFFFFFFL) 57 Index = rx_readl(dev, MUnit.OutboundQueue); 58 if (Index != 0xFFFFFFFFL) { 59 do { 60 if (aac_intr_normal(dev, Index)) { 61 rx_writel(dev, MUnit.OutboundQueue, Index); 62 rx_writel(dev, MUnit.ODR, DoorBellAdapterNormRespReady); 63 } 64 Index = rx_readl(dev, MUnit.OutboundQueue); 65 } while (Index != 0xFFFFFFFFL); 66 return IRQ_HANDLED; 67 } 68 } else { 69 unsigned long bellbits; 70 u8 intstat; 71 intstat = rx_readb(dev, MUnit.OISR); 72 /* 73 * Read mask and invert because drawbridge is reversed. 74 * This allows us to only service interrupts that have 75 * been enabled. 76 * Check to see if this is our interrupt. If it isn't just return 77 */ 78 if (intstat & ~(dev->OIMR)) 79 { 80 bellbits = rx_readl(dev, OutboundDoorbellReg); 81 if (bellbits & DoorBellPrintfReady) { 82 aac_printf(dev, rx_readl (dev, IndexRegs.Mailbox[5])); 83 rx_writel(dev, MUnit.ODR,DoorBellPrintfReady); 84 rx_writel(dev, InboundDoorbellReg,DoorBellPrintfDone); 85 } 86 else if (bellbits & DoorBellAdapterNormCmdReady) { 87 rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdReady); 88 aac_command_normal(&dev->queues->queue[HostNormCmdQueue]); 89 } 90 else if (bellbits & DoorBellAdapterNormRespReady) { 91 rx_writel(dev, MUnit.ODR,DoorBellAdapterNormRespReady); 92 aac_response_normal(&dev->queues->queue[HostNormRespQueue]); 93 } 94 else if (bellbits & DoorBellAdapterNormCmdNotFull) { 95 rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull); 96 } 97 else if (bellbits & DoorBellAdapterNormRespNotFull) { 98 rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull); 99 rx_writel(dev, MUnit.ODR, DoorBellAdapterNormRespNotFull); 100 } 101 return IRQ_HANDLED; 102 } 103 } 104 return IRQ_NONE; 105 } 106 107 /** 108 * aac_rx_disable_interrupt - Disable interrupts 109 * @dev: Adapter 110 */ 111 112 static void aac_rx_disable_interrupt(struct aac_dev *dev) 113 { 114 rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xff); 115 } 116 117 /** 118 * rx_sync_cmd - send a command and wait 119 * @dev: Adapter 120 * @command: Command to execute 121 * @p1: first parameter 122 * @ret: adapter status 123 * 124 * This routine will send a synchronous command to the adapter and wait 125 * for its completion. 126 */ 127 128 static int rx_sync_cmd(struct aac_dev *dev, u32 command, 129 u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6, 130 u32 *status, u32 * r1, u32 * r2, u32 * r3, u32 * r4) 131 { 132 unsigned long start; 133 int ok; 134 /* 135 * Write the command into Mailbox 0 136 */ 137 rx_writel(dev, InboundMailbox0, command); 138 /* 139 * Write the parameters into Mailboxes 1 - 6 140 */ 141 rx_writel(dev, InboundMailbox1, p1); 142 rx_writel(dev, InboundMailbox2, p2); 143 rx_writel(dev, InboundMailbox3, p3); 144 rx_writel(dev, InboundMailbox4, p4); 145 /* 146 * Clear the synch command doorbell to start on a clean slate. 147 */ 148 rx_writel(dev, OutboundDoorbellReg, OUTBOUNDDOORBELL_0); 149 /* 150 * Disable doorbell interrupts 151 */ 152 rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xff); 153 /* 154 * Force the completion of the mask register write before issuing 155 * the interrupt. 156 */ 157 rx_readb (dev, MUnit.OIMR); 158 /* 159 * Signal that there is a new synch command 160 */ 161 rx_writel(dev, InboundDoorbellReg, INBOUNDDOORBELL_0); 162 163 ok = 0; 164 start = jiffies; 165 166 /* 167 * Wait up to 30 seconds 168 */ 169 while (time_before(jiffies, start+30*HZ)) 170 { 171 udelay(5); /* Delay 5 microseconds to let Mon960 get info. */ 172 /* 173 * Mon960 will set doorbell0 bit when it has completed the command. 174 */ 175 if (rx_readl(dev, OutboundDoorbellReg) & OUTBOUNDDOORBELL_0) { 176 /* 177 * Clear the doorbell. 178 */ 179 rx_writel(dev, OutboundDoorbellReg, OUTBOUNDDOORBELL_0); 180 ok = 1; 181 break; 182 } 183 /* 184 * Yield the processor in case we are slow 185 */ 186 set_current_state(TASK_UNINTERRUPTIBLE); 187 schedule_timeout(1); 188 } 189 if (ok != 1) { 190 /* 191 * Restore interrupt mask even though we timed out 192 */ 193 if (dev->new_comm_interface) 194 rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xf7); 195 else 196 rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb); 197 return -ETIMEDOUT; 198 } 199 /* 200 * Pull the synch status from Mailbox 0. 201 */ 202 if (status) 203 *status = rx_readl(dev, IndexRegs.Mailbox[0]); 204 if (r1) 205 *r1 = rx_readl(dev, IndexRegs.Mailbox[1]); 206 if (r2) 207 *r2 = rx_readl(dev, IndexRegs.Mailbox[2]); 208 if (r3) 209 *r3 = rx_readl(dev, IndexRegs.Mailbox[3]); 210 if (r4) 211 *r4 = rx_readl(dev, IndexRegs.Mailbox[4]); 212 /* 213 * Clear the synch command doorbell. 214 */ 215 rx_writel(dev, OutboundDoorbellReg, OUTBOUNDDOORBELL_0); 216 /* 217 * Restore interrupt mask 218 */ 219 if (dev->new_comm_interface) 220 rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xf7); 221 else 222 rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb); 223 return 0; 224 225 } 226 227 /** 228 * aac_rx_interrupt_adapter - interrupt adapter 229 * @dev: Adapter 230 * 231 * Send an interrupt to the i960 and breakpoint it. 232 */ 233 234 static void aac_rx_interrupt_adapter(struct aac_dev *dev) 235 { 236 rx_sync_cmd(dev, BREAKPOINT_REQUEST, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL); 237 } 238 239 /** 240 * aac_rx_notify_adapter - send an event to the adapter 241 * @dev: Adapter 242 * @event: Event to send 243 * 244 * Notify the i960 that something it probably cares about has 245 * happened. 246 */ 247 248 static void aac_rx_notify_adapter(struct aac_dev *dev, u32 event) 249 { 250 switch (event) { 251 252 case AdapNormCmdQue: 253 rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_1); 254 break; 255 case HostNormRespNotFull: 256 rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_4); 257 break; 258 case AdapNormRespQue: 259 rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_2); 260 break; 261 case HostNormCmdNotFull: 262 rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_3); 263 break; 264 case HostShutdown: 265 // rx_sync_cmd(dev, HOST_CRASHING, 0, 0, 0, 0, 0, 0, 266 // NULL, NULL, NULL, NULL, NULL); 267 break; 268 case FastIo: 269 rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_6); 270 break; 271 case AdapPrintfDone: 272 rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_5); 273 break; 274 default: 275 BUG(); 276 break; 277 } 278 } 279 280 /** 281 * aac_rx_start_adapter - activate adapter 282 * @dev: Adapter 283 * 284 * Start up processing on an i960 based AAC adapter 285 */ 286 287 static void aac_rx_start_adapter(struct aac_dev *dev) 288 { 289 struct aac_init *init; 290 291 init = dev->init; 292 init->HostElapsedSeconds = cpu_to_le32(get_seconds()); 293 // We can only use a 32 bit address here 294 rx_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa, 295 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL); 296 } 297 298 /** 299 * aac_rx_check_health 300 * @dev: device to check if healthy 301 * 302 * Will attempt to determine if the specified adapter is alive and 303 * capable of handling requests, returning 0 if alive. 304 */ 305 static int aac_rx_check_health(struct aac_dev *dev) 306 { 307 u32 status = rx_readl(dev, MUnit.OMRx[0]); 308 309 /* 310 * Check to see if the board failed any self tests. 311 */ 312 if (status & SELF_TEST_FAILED) 313 return -1; 314 /* 315 * Check to see if the board panic'd. 316 */ 317 if (status & KERNEL_PANIC) { 318 char * buffer; 319 struct POSTSTATUS { 320 __le32 Post_Command; 321 __le32 Post_Address; 322 } * post; 323 dma_addr_t paddr, baddr; 324 int ret; 325 326 if ((status & 0xFF000000L) == 0xBC000000L) 327 return (status >> 16) & 0xFF; 328 buffer = pci_alloc_consistent(dev->pdev, 512, &baddr); 329 ret = -2; 330 if (buffer == NULL) 331 return ret; 332 post = pci_alloc_consistent(dev->pdev, 333 sizeof(struct POSTSTATUS), &paddr); 334 if (post == NULL) { 335 pci_free_consistent(dev->pdev, 512, buffer, baddr); 336 return ret; 337 } 338 memset(buffer, 0, 512); 339 post->Post_Command = cpu_to_le32(COMMAND_POST_RESULTS); 340 post->Post_Address = cpu_to_le32(baddr); 341 rx_writel(dev, MUnit.IMRx[0], paddr); 342 rx_sync_cmd(dev, COMMAND_POST_RESULTS, baddr, 0, 0, 0, 0, 0, 343 NULL, NULL, NULL, NULL, NULL); 344 pci_free_consistent(dev->pdev, sizeof(struct POSTSTATUS), 345 post, paddr); 346 if ((buffer[0] == '0') && (buffer[1] == 'x')) { 347 ret = (buffer[2] <= '9') ? (buffer[2] - '0') : (buffer[2] - 'A' + 10); 348 ret <<= 4; 349 ret += (buffer[3] <= '9') ? (buffer[3] - '0') : (buffer[3] - 'A' + 10); 350 } 351 pci_free_consistent(dev->pdev, 512, buffer, baddr); 352 return ret; 353 } 354 /* 355 * Wait for the adapter to be up and running. 356 */ 357 if (!(status & KERNEL_UP_AND_RUNNING)) 358 return -3; 359 /* 360 * Everything is OK 361 */ 362 return 0; 363 } 364 365 /** 366 * aac_rx_send 367 * @fib: fib to issue 368 * 369 * Will send a fib, returning 0 if successful. 370 */ 371 static int aac_rx_send(struct fib * fib) 372 { 373 u64 addr = fib->hw_fib_pa; 374 struct aac_dev *dev = fib->dev; 375 volatile void __iomem *device = dev->regs.rx; 376 u32 Index; 377 378 dprintk((KERN_DEBUG "%p->aac_rx_send(%p->%llx)\n", dev, fib, addr)); 379 Index = rx_readl(dev, MUnit.InboundQueue); 380 if (Index == 0xFFFFFFFFL) 381 Index = rx_readl(dev, MUnit.InboundQueue); 382 dprintk((KERN_DEBUG "Index = 0x%x\n", Index)); 383 if (Index == 0xFFFFFFFFL) 384 return Index; 385 device += Index; 386 dprintk((KERN_DEBUG "entry = %x %x %u\n", (u32)(addr & 0xffffffff), 387 (u32)(addr >> 32), (u32)le16_to_cpu(fib->hw_fib->header.Size))); 388 writel((u32)(addr & 0xffffffff), device); 389 device += sizeof(u32); 390 writel((u32)(addr >> 32), device); 391 device += sizeof(u32); 392 writel(le16_to_cpu(fib->hw_fib->header.Size), device); 393 rx_writel(dev, MUnit.InboundQueue, Index); 394 dprintk((KERN_DEBUG "aac_rx_send - return 0\n")); 395 return 0; 396 } 397 398 /** 399 * aac_rx_init - initialize an i960 based AAC card 400 * @dev: device to configure 401 * 402 * Allocate and set up resources for the i960 based AAC variants. The 403 * device_interface in the commregion will be allocated and linked 404 * to the comm region. 405 */ 406 407 int aac_rx_init(struct aac_dev *dev) 408 { 409 unsigned long start; 410 unsigned long status; 411 int instance; 412 const char * name; 413 414 instance = dev->id; 415 name = dev->name; 416 417 /* 418 * Check to see if the board panic'd while booting. 419 */ 420 /* 421 * Check to see if the board failed any self tests. 422 */ 423 if (rx_readl(dev, MUnit.OMRx[0]) & SELF_TEST_FAILED) { 424 printk(KERN_ERR "%s%d: adapter self-test failed.\n", dev->name, instance); 425 goto error_iounmap; 426 } 427 /* 428 * Check to see if the board panic'd while booting. 429 */ 430 if (rx_readl(dev, MUnit.OMRx[0]) & KERNEL_PANIC) { 431 printk(KERN_ERR "%s%d: adapter kernel panic.\n", dev->name, instance); 432 goto error_iounmap; 433 } 434 /* 435 * Check to see if the monitor panic'd while booting. 436 */ 437 if (rx_readl(dev, MUnit.OMRx[0]) & MONITOR_PANIC) { 438 printk(KERN_ERR "%s%d: adapter monitor panic.\n", dev->name, instance); 439 goto error_iounmap; 440 } 441 start = jiffies; 442 /* 443 * Wait for the adapter to be up and running. Wait up to 3 minutes 444 */ 445 while ((!(rx_readl(dev, IndexRegs.Mailbox[7]) & KERNEL_UP_AND_RUNNING)) 446 || (!(rx_readl(dev, MUnit.OMRx[0]) & KERNEL_UP_AND_RUNNING))) 447 { 448 if(time_after(jiffies, start+180*HZ)) 449 { 450 status = rx_readl(dev, IndexRegs.Mailbox[7]); 451 printk(KERN_ERR "%s%d: adapter kernel failed to start, init status = %lx.\n", 452 dev->name, instance, status); 453 goto error_iounmap; 454 } 455 set_current_state(TASK_UNINTERRUPTIBLE); 456 schedule_timeout(1); 457 } 458 if (request_irq(dev->scsi_host_ptr->irq, aac_rx_intr, SA_SHIRQ|SA_INTERRUPT, "aacraid", (void *)dev)<0) 459 { 460 printk(KERN_ERR "%s%d: Interrupt unavailable.\n", name, instance); 461 goto error_iounmap; 462 } 463 /* 464 * Fill in the function dispatch table. 465 */ 466 dev->a_ops.adapter_interrupt = aac_rx_interrupt_adapter; 467 dev->a_ops.adapter_disable_int = aac_rx_disable_interrupt; 468 dev->a_ops.adapter_notify = aac_rx_notify_adapter; 469 dev->a_ops.adapter_sync_cmd = rx_sync_cmd; 470 dev->a_ops.adapter_check_health = aac_rx_check_health; 471 dev->a_ops.adapter_send = aac_rx_send; 472 473 /* 474 * First clear out all interrupts. Then enable the one's that we 475 * can handle. 476 */ 477 rx_writeb(dev, MUnit.OIMR, 0xff); 478 rx_writel(dev, MUnit.ODR, 0xffffffff); 479 rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb); 480 481 if (aac_init_adapter(dev) == NULL) 482 goto error_irq; 483 if (dev->new_comm_interface) 484 rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xf7); 485 486 /* 487 * Tell the adapter that all is configured, and it can start 488 * accepting requests 489 */ 490 aac_rx_start_adapter(dev); 491 return 0; 492 493 error_irq: 494 rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xff); 495 free_irq(dev->scsi_host_ptr->irq, (void *)dev); 496 497 error_iounmap: 498 499 return -1; 500 } 501