rx.c revision 76a7f8fdc0c2381ae1ba55ef71837712223ecb3c
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 49static 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, 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 112static 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 128static 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 writel(command, &dev->IndexRegs->Mailbox[0]); 138 /* 139 * Write the parameters into Mailboxes 1 - 6 140 */ 141 writel(p1, &dev->IndexRegs->Mailbox[1]); 142 writel(p2, &dev->IndexRegs->Mailbox[2]); 143 writel(p3, &dev->IndexRegs->Mailbox[3]); 144 writel(p4, &dev->IndexRegs->Mailbox[4]); 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 msleep(1); 187 } 188 if (ok != 1) { 189 /* 190 * Restore interrupt mask even though we timed out 191 */ 192 if (dev->new_comm_interface) 193 rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xf7); 194 else 195 rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb); 196 return -ETIMEDOUT; 197 } 198 /* 199 * Pull the synch status from Mailbox 0. 200 */ 201 if (status) 202 *status = readl(&dev->IndexRegs->Mailbox[0]); 203 if (r1) 204 *r1 = readl(&dev->IndexRegs->Mailbox[1]); 205 if (r2) 206 *r2 = readl(&dev->IndexRegs->Mailbox[2]); 207 if (r3) 208 *r3 = readl(&dev->IndexRegs->Mailbox[3]); 209 if (r4) 210 *r4 = readl(&dev->IndexRegs->Mailbox[4]); 211 /* 212 * Clear the synch command doorbell. 213 */ 214 rx_writel(dev, OutboundDoorbellReg, OUTBOUNDDOORBELL_0); 215 /* 216 * Restore interrupt mask 217 */ 218 if (dev->new_comm_interface) 219 rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xf7); 220 else 221 rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb); 222 return 0; 223 224} 225 226/** 227 * aac_rx_interrupt_adapter - interrupt adapter 228 * @dev: Adapter 229 * 230 * Send an interrupt to the i960 and breakpoint it. 231 */ 232 233static void aac_rx_interrupt_adapter(struct aac_dev *dev) 234{ 235 rx_sync_cmd(dev, BREAKPOINT_REQUEST, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL); 236} 237 238/** 239 * aac_rx_notify_adapter - send an event to the adapter 240 * @dev: Adapter 241 * @event: Event to send 242 * 243 * Notify the i960 that something it probably cares about has 244 * happened. 245 */ 246 247static void aac_rx_notify_adapter(struct aac_dev *dev, u32 event) 248{ 249 switch (event) { 250 251 case AdapNormCmdQue: 252 rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_1); 253 break; 254 case HostNormRespNotFull: 255 rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_4); 256 break; 257 case AdapNormRespQue: 258 rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_2); 259 break; 260 case HostNormCmdNotFull: 261 rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_3); 262 break; 263 case HostShutdown: 264 break; 265 case FastIo: 266 rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_6); 267 break; 268 case AdapPrintfDone: 269 rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_5); 270 break; 271 default: 272 BUG(); 273 break; 274 } 275} 276 277/** 278 * aac_rx_start_adapter - activate adapter 279 * @dev: Adapter 280 * 281 * Start up processing on an i960 based AAC adapter 282 */ 283 284void aac_rx_start_adapter(struct aac_dev *dev) 285{ 286 struct aac_init *init; 287 288 init = dev->init; 289 init->HostElapsedSeconds = cpu_to_le32(get_seconds()); 290 // We can only use a 32 bit address here 291 rx_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa, 292 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL); 293} 294 295/** 296 * aac_rx_check_health 297 * @dev: device to check if healthy 298 * 299 * Will attempt to determine if the specified adapter is alive and 300 * capable of handling requests, returning 0 if alive. 301 */ 302static int aac_rx_check_health(struct aac_dev *dev) 303{ 304 u32 status = rx_readl(dev, MUnit.OMRx[0]); 305 306 /* 307 * Check to see if the board failed any self tests. 308 */ 309 if (status & SELF_TEST_FAILED) 310 return -1; 311 /* 312 * Check to see if the board panic'd. 313 */ 314 if (status & KERNEL_PANIC) { 315 char * buffer; 316 struct POSTSTATUS { 317 __le32 Post_Command; 318 __le32 Post_Address; 319 } * post; 320 dma_addr_t paddr, baddr; 321 int ret; 322 323 if ((status & 0xFF000000L) == 0xBC000000L) 324 return (status >> 16) & 0xFF; 325 buffer = pci_alloc_consistent(dev->pdev, 512, &baddr); 326 ret = -2; 327 if (buffer == NULL) 328 return ret; 329 post = pci_alloc_consistent(dev->pdev, 330 sizeof(struct POSTSTATUS), &paddr); 331 if (post == NULL) { 332 pci_free_consistent(dev->pdev, 512, buffer, baddr); 333 return ret; 334 } 335 memset(buffer, 0, 512); 336 post->Post_Command = cpu_to_le32(COMMAND_POST_RESULTS); 337 post->Post_Address = cpu_to_le32(baddr); 338 rx_writel(dev, MUnit.IMRx[0], paddr); 339 rx_sync_cmd(dev, COMMAND_POST_RESULTS, baddr, 0, 0, 0, 0, 0, 340 NULL, NULL, NULL, NULL, NULL); 341 pci_free_consistent(dev->pdev, sizeof(struct POSTSTATUS), 342 post, paddr); 343 if ((buffer[0] == '0') && ((buffer[1] == 'x') || (buffer[1] == 'X'))) { 344 ret = (buffer[2] <= '9') ? (buffer[2] - '0') : (buffer[2] - 'A' + 10); 345 ret <<= 4; 346 ret += (buffer[3] <= '9') ? (buffer[3] - '0') : (buffer[3] - 'A' + 10); 347 } 348 pci_free_consistent(dev->pdev, 512, buffer, baddr); 349 return ret; 350 } 351 /* 352 * Wait for the adapter to be up and running. 353 */ 354 if (!(status & KERNEL_UP_AND_RUNNING)) 355 return -3; 356 /* 357 * Everything is OK 358 */ 359 return 0; 360} 361 362/** 363 * aac_rx_send 364 * @fib: fib to issue 365 * 366 * Will send a fib, returning 0 if successful. 367 */ 368static int aac_rx_send(struct fib * fib) 369{ 370 u64 addr = fib->hw_fib_pa; 371 struct aac_dev *dev = fib->dev; 372 volatile void __iomem *device = dev->regs.rx; 373 u32 Index; 374 375 dprintk((KERN_DEBUG "%p->aac_rx_send(%p->%llx)\n", dev, fib, addr)); 376 Index = rx_readl(dev, MUnit.InboundQueue); 377 if (Index == 0xFFFFFFFFL) 378 Index = rx_readl(dev, MUnit.InboundQueue); 379 dprintk((KERN_DEBUG "Index = 0x%x\n", Index)); 380 if (Index == 0xFFFFFFFFL) 381 return Index; 382 device = dev->base + Index; 383 dprintk((KERN_DEBUG "entry = %x %x %u\n", (u32)(addr & 0xffffffff), 384 (u32)(addr >> 32), (u32)le16_to_cpu(fib->hw_fib->header.Size))); 385 writel((u32)(addr & 0xffffffff), device); 386 device += sizeof(u32); 387 writel((u32)(addr >> 32), device); 388 device += sizeof(u32); 389 writel(le16_to_cpu(fib->hw_fib->header.Size), device); 390 rx_writel(dev, MUnit.InboundQueue, Index); 391 dprintk((KERN_DEBUG "aac_rx_send - return 0\n")); 392 return 0; 393} 394 395/** 396 * aac_rx_ioremap 397 * @size: mapping resize request 398 * 399 */ 400static int aac_rx_ioremap(struct aac_dev * dev, u32 size) 401{ 402 if (!size) { 403 iounmap(dev->regs.rx); 404 return 0; 405 } 406 dev->base = dev->regs.rx = ioremap(dev->scsi_host_ptr->base, size); 407 if (dev->base == NULL) 408 return -1; 409 dev->IndexRegs = &dev->regs.rx->IndexRegs; 410 return 0; 411} 412 413static int aac_rx_restart_adapter(struct aac_dev *dev) 414{ 415 u32 var; 416 417 printk(KERN_ERR "%s%d: adapter kernel panic'd.\n", 418 dev->name, dev->id); 419 420 if (aac_rx_check_health(dev) <= 0) 421 return 1; 422 if (rx_sync_cmd(dev, IOP_RESET, 0, 0, 0, 0, 0, 0, 423 &var, NULL, NULL, NULL, NULL)) 424 return 1; 425 if (var != 0x00000001) 426 return 1; 427 if (rx_readl(dev, MUnit.OMRx[0]) & KERNEL_PANIC) 428 return 1; 429 return 0; 430} 431 432/** 433 * aac_rx_init - initialize an i960 based AAC card 434 * @dev: device to configure 435 * 436 * Allocate and set up resources for the i960 based AAC variants. The 437 * device_interface in the commregion will be allocated and linked 438 * to the comm region. 439 */ 440 441int _aac_rx_init(struct aac_dev *dev) 442{ 443 unsigned long start; 444 unsigned long status; 445 int instance; 446 const char * name; 447 448 instance = dev->id; 449 name = dev->name; 450 451 if (aac_adapter_ioremap(dev, dev->base_size)) { 452 printk(KERN_WARNING "%s: unable to map adapter.\n", name); 453 goto error_iounmap; 454 } 455 456 /* 457 * Check to see if the board panic'd while booting. 458 */ 459 status = rx_readl(dev, MUnit.OMRx[0]); 460 if (status & KERNEL_PANIC) 461 if (aac_rx_restart_adapter(dev)) 462 goto error_iounmap; 463 /* 464 * Check to see if the board failed any self tests. 465 */ 466 status = rx_readl(dev, MUnit.OMRx[0]); 467 if (status & SELF_TEST_FAILED) { 468 printk(KERN_ERR "%s%d: adapter self-test failed.\n", dev->name, instance); 469 goto error_iounmap; 470 } 471 /* 472 * Check to see if the monitor panic'd while booting. 473 */ 474 if (status & MONITOR_PANIC) { 475 printk(KERN_ERR "%s%d: adapter monitor panic.\n", dev->name, instance); 476 goto error_iounmap; 477 } 478 start = jiffies; 479 /* 480 * Wait for the adapter to be up and running. Wait up to 3 minutes 481 */ 482 while (!((status = rx_readl(dev, MUnit.OMRx[0])) & KERNEL_UP_AND_RUNNING)) 483 { 484 if(time_after(jiffies, start+startup_timeout*HZ)) 485 { 486 printk(KERN_ERR "%s%d: adapter kernel failed to start, init status = %lx.\n", 487 dev->name, instance, status); 488 goto error_iounmap; 489 } 490 msleep(1); 491 } 492 if (request_irq(dev->scsi_host_ptr->irq, aac_rx_intr, IRQF_SHARED|IRQF_DISABLED, "aacraid", (void *)dev)<0) 493 { 494 printk(KERN_ERR "%s%d: Interrupt unavailable.\n", name, instance); 495 goto error_iounmap; 496 } 497 /* 498 * Fill in the function dispatch table. 499 */ 500 dev->a_ops.adapter_interrupt = aac_rx_interrupt_adapter; 501 dev->a_ops.adapter_disable_int = aac_rx_disable_interrupt; 502 dev->a_ops.adapter_notify = aac_rx_notify_adapter; 503 dev->a_ops.adapter_sync_cmd = rx_sync_cmd; 504 dev->a_ops.adapter_check_health = aac_rx_check_health; 505 dev->a_ops.adapter_send = aac_rx_send; 506 507 /* 508 * First clear out all interrupts. Then enable the one's that we 509 * can handle. 510 */ 511 rx_writeb(dev, MUnit.OIMR, 0xff); 512 rx_writel(dev, MUnit.ODR, 0xffffffff); 513 rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb); 514 515 if (aac_init_adapter(dev) == NULL) 516 goto error_irq; 517 if (dev->new_comm_interface) 518 rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xf7); 519 520 return 0; 521 522error_irq: 523 rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xff); 524 free_irq(dev->scsi_host_ptr->irq, (void *)dev); 525 526error_iounmap: 527 528 return -1; 529} 530 531int aac_rx_init(struct aac_dev *dev) 532{ 533 int retval; 534 535 /* 536 * Fill in the function dispatch table. 537 */ 538 dev->a_ops.adapter_ioremap = aac_rx_ioremap; 539 540 retval = _aac_rx_init(dev); 541 if (!retval) { 542 /* 543 * Tell the adapter that all is configured, and it can 544 * start accepting requests 545 */ 546 aac_rx_start_adapter(dev); 547 } 548 return retval; 549} 550