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-2015 PMC-Sierra, Inc. (aacraid@pmc-sierra.com) 10 * 2016-2017 Microsemi Corp. (aacraid@microsemi.com) 11 * 12 * This program is free software; you can redistribute it and/or modify 13 * it under the terms of the GNU General Public License as published by 14 * the Free Software Foundation; either version 2, or (at your option) 15 * any later version. 16 * 17 * This program is distributed in the hope that it will be useful, 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 * GNU General Public License for more details. 21 * 22 * You should have received a copy of the GNU General Public License 23 * along with this program; see the file COPYING. If not, write to 24 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 25 * 26 * Module Name: 27 * rx.c 28 * 29 * Abstract: Hardware miniport for Drawbridge specific hardware functions. 30 * 31 */ 32 33 #include <linux/kernel.h> 34 #include <linux/init.h> 35 #include <linux/types.h> 36 #include <linux/pci.h> 37 #include <linux/spinlock.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 44 #include <scsi/scsi_host.h> 45 46 #include "aacraid.h" 47 48 static irqreturn_t aac_rx_intr_producer(int irq, void *dev_id) 49 { 50 struct aac_dev *dev = dev_id; 51 unsigned long bellbits; 52 u8 intstat = rx_readb(dev, MUnit.OISR); 53 54 /* 55 * Read mask and invert because drawbridge is reversed. 56 * This allows us to only service interrupts that have 57 * been enabled. 58 * Check to see if this is our interrupt. If it isn't just return 59 */ 60 if (likely(intstat & ~(dev->OIMR))) { 61 bellbits = rx_readl(dev, OutboundDoorbellReg); 62 if (unlikely(bellbits & DoorBellPrintfReady)) { 63 aac_printf(dev, readl (&dev->IndexRegs->Mailbox[5])); 64 rx_writel(dev, MUnit.ODR,DoorBellPrintfReady); 65 rx_writel(dev, InboundDoorbellReg,DoorBellPrintfDone); 66 } 67 else if (unlikely(bellbits & DoorBellAdapterNormCmdReady)) { 68 rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdReady); 69 aac_command_normal(&dev->queues->queue[HostNormCmdQueue]); 70 } 71 else if (likely(bellbits & DoorBellAdapterNormRespReady)) { 72 rx_writel(dev, MUnit.ODR,DoorBellAdapterNormRespReady); 73 aac_response_normal(&dev->queues->queue[HostNormRespQueue]); 74 } 75 else if (unlikely(bellbits & DoorBellAdapterNormCmdNotFull)) { 76 rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull); 77 } 78 else if (unlikely(bellbits & DoorBellAdapterNormRespNotFull)) { 79 rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull); 80 rx_writel(dev, MUnit.ODR, DoorBellAdapterNormRespNotFull); 81 } 82 return IRQ_HANDLED; 83 } 84 return IRQ_NONE; 85 } 86 87 static irqreturn_t aac_rx_intr_message(int irq, void *dev_id) 88 { 89 int isAif, isFastResponse, isSpecial; 90 struct aac_dev *dev = dev_id; 91 u32 Index = rx_readl(dev, MUnit.OutboundQueue); 92 if (unlikely(Index == 0xFFFFFFFFL)) 93 Index = rx_readl(dev, MUnit.OutboundQueue); 94 if (likely(Index != 0xFFFFFFFFL)) { 95 do { 96 isAif = isFastResponse = isSpecial = 0; 97 if (Index & 0x00000002L) { 98 isAif = 1; 99 if (Index == 0xFFFFFFFEL) 100 isSpecial = 1; 101 Index &= ~0x00000002L; 102 } else { 103 if (Index & 0x00000001L) 104 isFastResponse = 1; 105 Index >>= 2; 106 } 107 if (!isSpecial) { 108 if (unlikely(aac_intr_normal(dev, 109 Index, isAif, 110 isFastResponse, NULL))) { 111 rx_writel(dev, 112 MUnit.OutboundQueue, 113 Index); 114 rx_writel(dev, 115 MUnit.ODR, 116 DoorBellAdapterNormRespReady); 117 } 118 } 119 Index = rx_readl(dev, MUnit.OutboundQueue); 120 } while (Index != 0xFFFFFFFFL); 121 return IRQ_HANDLED; 122 } 123 return IRQ_NONE; 124 } 125 126 /** 127 * aac_rx_disable_interrupt - Disable interrupts 128 * @dev: Adapter 129 */ 130 131 static void aac_rx_disable_interrupt(struct aac_dev *dev) 132 { 133 rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xff); 134 } 135 136 /** 137 * aac_rx_enable_interrupt_producer - Enable interrupts 138 * @dev: Adapter 139 */ 140 141 static void aac_rx_enable_interrupt_producer(struct aac_dev *dev) 142 { 143 rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb); 144 } 145 146 /** 147 * aac_rx_enable_interrupt_message - Enable interrupts 148 * @dev: Adapter 149 */ 150 151 static void aac_rx_enable_interrupt_message(struct aac_dev *dev) 152 { 153 rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xf7); 154 } 155 156 /** 157 * rx_sync_cmd - send a command and wait 158 * @dev: Adapter 159 * @command: Command to execute 160 * @p1: first parameter 161 * @ret: adapter status 162 * 163 * This routine will send a synchronous command to the adapter and wait 164 * for its completion. 165 */ 166 167 static int rx_sync_cmd(struct aac_dev *dev, u32 command, 168 u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6, 169 u32 *status, u32 * r1, u32 * r2, u32 * r3, u32 * r4) 170 { 171 unsigned long start; 172 int ok; 173 /* 174 * Write the command into Mailbox 0 175 */ 176 writel(command, &dev->IndexRegs->Mailbox[0]); 177 /* 178 * Write the parameters into Mailboxes 1 - 6 179 */ 180 writel(p1, &dev->IndexRegs->Mailbox[1]); 181 writel(p2, &dev->IndexRegs->Mailbox[2]); 182 writel(p3, &dev->IndexRegs->Mailbox[3]); 183 writel(p4, &dev->IndexRegs->Mailbox[4]); 184 /* 185 * Clear the synch command doorbell to start on a clean slate. 186 */ 187 rx_writel(dev, OutboundDoorbellReg, OUTBOUNDDOORBELL_0); 188 /* 189 * Disable doorbell interrupts 190 */ 191 rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xff); 192 /* 193 * Force the completion of the mask register write before issuing 194 * the interrupt. 195 */ 196 rx_readb (dev, MUnit.OIMR); 197 /* 198 * Signal that there is a new synch command 199 */ 200 rx_writel(dev, InboundDoorbellReg, INBOUNDDOORBELL_0); 201 202 ok = 0; 203 start = jiffies; 204 205 /* 206 * Wait up to 30 seconds 207 */ 208 while (time_before(jiffies, start+30*HZ)) 209 { 210 udelay(5); /* Delay 5 microseconds to let Mon960 get info. */ 211 /* 212 * Mon960 will set doorbell0 bit when it has completed the command. 213 */ 214 if (rx_readl(dev, OutboundDoorbellReg) & OUTBOUNDDOORBELL_0) { 215 /* 216 * Clear the doorbell. 217 */ 218 rx_writel(dev, OutboundDoorbellReg, OUTBOUNDDOORBELL_0); 219 ok = 1; 220 break; 221 } 222 /* 223 * Yield the processor in case we are slow 224 */ 225 msleep(1); 226 } 227 if (unlikely(ok != 1)) { 228 /* 229 * Restore interrupt mask even though we timed out 230 */ 231 aac_adapter_enable_int(dev); 232 return -ETIMEDOUT; 233 } 234 /* 235 * Pull the synch status from Mailbox 0. 236 */ 237 if (status) 238 *status = readl(&dev->IndexRegs->Mailbox[0]); 239 if (r1) 240 *r1 = readl(&dev->IndexRegs->Mailbox[1]); 241 if (r2) 242 *r2 = readl(&dev->IndexRegs->Mailbox[2]); 243 if (r3) 244 *r3 = readl(&dev->IndexRegs->Mailbox[3]); 245 if (r4) 246 *r4 = readl(&dev->IndexRegs->Mailbox[4]); 247 /* 248 * Clear the synch command doorbell. 249 */ 250 rx_writel(dev, OutboundDoorbellReg, OUTBOUNDDOORBELL_0); 251 /* 252 * Restore interrupt mask 253 */ 254 aac_adapter_enable_int(dev); 255 return 0; 256 257 } 258 259 /** 260 * aac_rx_interrupt_adapter - interrupt adapter 261 * @dev: Adapter 262 * 263 * Send an interrupt to the i960 and breakpoint it. 264 */ 265 266 static void aac_rx_interrupt_adapter(struct aac_dev *dev) 267 { 268 rx_sync_cmd(dev, BREAKPOINT_REQUEST, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL); 269 } 270 271 /** 272 * aac_rx_notify_adapter - send an event to the adapter 273 * @dev: Adapter 274 * @event: Event to send 275 * 276 * Notify the i960 that something it probably cares about has 277 * happened. 278 */ 279 280 static void aac_rx_notify_adapter(struct aac_dev *dev, u32 event) 281 { 282 switch (event) { 283 284 case AdapNormCmdQue: 285 rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_1); 286 break; 287 case HostNormRespNotFull: 288 rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_4); 289 break; 290 case AdapNormRespQue: 291 rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_2); 292 break; 293 case HostNormCmdNotFull: 294 rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_3); 295 break; 296 case HostShutdown: 297 break; 298 case FastIo: 299 rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_6); 300 break; 301 case AdapPrintfDone: 302 rx_writel(dev, MUnit.IDR,INBOUNDDOORBELL_5); 303 break; 304 default: 305 BUG(); 306 break; 307 } 308 } 309 310 /** 311 * aac_rx_start_adapter - activate adapter 312 * @dev: Adapter 313 * 314 * Start up processing on an i960 based AAC adapter 315 */ 316 317 static void aac_rx_start_adapter(struct aac_dev *dev) 318 { 319 union aac_init *init; 320 321 init = dev->init; 322 init->r7.host_elapsed_seconds = cpu_to_le32(get_seconds()); 323 // We can only use a 32 bit address here 324 rx_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa, 325 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL); 326 } 327 328 /** 329 * aac_rx_check_health 330 * @dev: device to check if healthy 331 * 332 * Will attempt to determine if the specified adapter is alive and 333 * capable of handling requests, returning 0 if alive. 334 */ 335 static int aac_rx_check_health(struct aac_dev *dev) 336 { 337 u32 status = rx_readl(dev, MUnit.OMRx[0]); 338 339 /* 340 * Check to see if the board failed any self tests. 341 */ 342 if (unlikely(status & SELF_TEST_FAILED)) 343 return -1; 344 /* 345 * Check to see if the board panic'd. 346 */ 347 if (unlikely(status & KERNEL_PANIC)) { 348 char * buffer; 349 struct POSTSTATUS { 350 __le32 Post_Command; 351 __le32 Post_Address; 352 } * post; 353 dma_addr_t paddr, baddr; 354 int ret; 355 356 if (likely((status & 0xFF000000L) == 0xBC000000L)) 357 return (status >> 16) & 0xFF; 358 buffer = dma_alloc_coherent(&dev->pdev->dev, 512, &baddr, 359 GFP_KERNEL); 360 ret = -2; 361 if (unlikely(buffer == NULL)) 362 return ret; 363 post = dma_alloc_coherent(&dev->pdev->dev, 364 sizeof(struct POSTSTATUS), &paddr, 365 GFP_KERNEL); 366 if (unlikely(post == NULL)) { 367 dma_free_coherent(&dev->pdev->dev, 512, buffer, baddr); 368 return ret; 369 } 370 memset(buffer, 0, 512); 371 post->Post_Command = cpu_to_le32(COMMAND_POST_RESULTS); 372 post->Post_Address = cpu_to_le32(baddr); 373 rx_writel(dev, MUnit.IMRx[0], paddr); 374 rx_sync_cmd(dev, COMMAND_POST_RESULTS, baddr, 0, 0, 0, 0, 0, 375 NULL, NULL, NULL, NULL, NULL); 376 dma_free_coherent(&dev->pdev->dev, sizeof(struct POSTSTATUS), 377 post, paddr); 378 if (likely((buffer[0] == '0') && ((buffer[1] == 'x') || (buffer[1] == 'X')))) { 379 ret = (hex_to_bin(buffer[2]) << 4) + 380 hex_to_bin(buffer[3]); 381 } 382 dma_free_coherent(&dev->pdev->dev, 512, buffer, baddr); 383 return ret; 384 } 385 /* 386 * Wait for the adapter to be up and running. 387 */ 388 if (unlikely(!(status & KERNEL_UP_AND_RUNNING))) 389 return -3; 390 /* 391 * Everything is OK 392 */ 393 return 0; 394 } 395 396 /** 397 * aac_rx_deliver_producer 398 * @fib: fib to issue 399 * 400 * Will send a fib, returning 0 if successful. 401 */ 402 int aac_rx_deliver_producer(struct fib * fib) 403 { 404 struct aac_dev *dev = fib->dev; 405 struct aac_queue *q = &dev->queues->queue[AdapNormCmdQueue]; 406 u32 Index; 407 unsigned long nointr = 0; 408 409 aac_queue_get( dev, &Index, AdapNormCmdQueue, fib->hw_fib_va, 1, fib, &nointr); 410 411 atomic_inc(&q->numpending); 412 *(q->headers.producer) = cpu_to_le32(Index + 1); 413 if (!(nointr & aac_config.irq_mod)) 414 aac_adapter_notify(dev, AdapNormCmdQueue); 415 416 return 0; 417 } 418 419 /** 420 * aac_rx_deliver_message 421 * @fib: fib to issue 422 * 423 * Will send a fib, returning 0 if successful. 424 */ 425 static int aac_rx_deliver_message(struct fib * fib) 426 { 427 struct aac_dev *dev = fib->dev; 428 struct aac_queue *q = &dev->queues->queue[AdapNormCmdQueue]; 429 u32 Index; 430 u64 addr; 431 volatile void __iomem *device; 432 433 unsigned long count = 10000000L; /* 50 seconds */ 434 atomic_inc(&q->numpending); 435 for(;;) { 436 Index = rx_readl(dev, MUnit.InboundQueue); 437 if (unlikely(Index == 0xFFFFFFFFL)) 438 Index = rx_readl(dev, MUnit.InboundQueue); 439 if (likely(Index != 0xFFFFFFFFL)) 440 break; 441 if (--count == 0) { 442 atomic_dec(&q->numpending); 443 return -ETIMEDOUT; 444 } 445 udelay(5); 446 } 447 device = dev->base + Index; 448 addr = fib->hw_fib_pa; 449 writel((u32)(addr & 0xffffffff), device); 450 device += sizeof(u32); 451 writel((u32)(addr >> 32), device); 452 device += sizeof(u32); 453 writel(le16_to_cpu(fib->hw_fib_va->header.Size), device); 454 rx_writel(dev, MUnit.InboundQueue, Index); 455 return 0; 456 } 457 458 /** 459 * aac_rx_ioremap 460 * @size: mapping resize request 461 * 462 */ 463 static int aac_rx_ioremap(struct aac_dev * dev, u32 size) 464 { 465 if (!size) { 466 iounmap(dev->regs.rx); 467 return 0; 468 } 469 dev->base = dev->regs.rx = ioremap(dev->base_start, size); 470 if (dev->base == NULL) 471 return -1; 472 dev->IndexRegs = &dev->regs.rx->IndexRegs; 473 return 0; 474 } 475 476 static int aac_rx_restart_adapter(struct aac_dev *dev, int bled, u8 reset_type) 477 { 478 u32 var = 0; 479 480 if (!(dev->supplement_adapter_info.supported_options2 & 481 AAC_OPTION_MU_RESET) || (bled >= 0) || (bled == -2)) { 482 if (bled) 483 printk(KERN_ERR "%s%d: adapter kernel panic'd %x.\n", 484 dev->name, dev->id, bled); 485 else { 486 bled = aac_adapter_sync_cmd(dev, IOP_RESET_ALWAYS, 487 0, 0, 0, 0, 0, 0, &var, NULL, NULL, NULL, NULL); 488 if (!bled && (var != 0x00000001) && (var != 0x3803000F)) 489 bled = -EINVAL; 490 } 491 if (bled && (bled != -ETIMEDOUT)) 492 bled = aac_adapter_sync_cmd(dev, IOP_RESET, 493 0, 0, 0, 0, 0, 0, &var, NULL, NULL, NULL, NULL); 494 495 if (bled && (bled != -ETIMEDOUT)) 496 return -EINVAL; 497 } 498 if (bled && (var == 0x3803000F)) { /* USE_OTHER_METHOD */ 499 rx_writel(dev, MUnit.reserved2, 3); 500 msleep(5000); /* Delay 5 seconds */ 501 var = 0x00000001; 502 } 503 if (bled && (var != 0x00000001)) 504 return -EINVAL; 505 ssleep(5); 506 if (rx_readl(dev, MUnit.OMRx[0]) & KERNEL_PANIC) 507 return -ENODEV; 508 if (startup_timeout < 300) 509 startup_timeout = 300; 510 return 0; 511 } 512 513 /** 514 * aac_rx_select_comm - Select communications method 515 * @dev: Adapter 516 * @comm: communications method 517 */ 518 519 int aac_rx_select_comm(struct aac_dev *dev, int comm) 520 { 521 switch (comm) { 522 case AAC_COMM_PRODUCER: 523 dev->a_ops.adapter_enable_int = aac_rx_enable_interrupt_producer; 524 dev->a_ops.adapter_intr = aac_rx_intr_producer; 525 dev->a_ops.adapter_deliver = aac_rx_deliver_producer; 526 break; 527 case AAC_COMM_MESSAGE: 528 dev->a_ops.adapter_enable_int = aac_rx_enable_interrupt_message; 529 dev->a_ops.adapter_intr = aac_rx_intr_message; 530 dev->a_ops.adapter_deliver = aac_rx_deliver_message; 531 break; 532 default: 533 return 1; 534 } 535 return 0; 536 } 537 538 /** 539 * aac_rx_init - initialize an i960 based AAC card 540 * @dev: device to configure 541 * 542 * Allocate and set up resources for the i960 based AAC variants. The 543 * device_interface in the commregion will be allocated and linked 544 * to the comm region. 545 */ 546 547 int _aac_rx_init(struct aac_dev *dev) 548 { 549 unsigned long start; 550 unsigned long status; 551 int restart = 0; 552 int instance = dev->id; 553 const char * name = dev->name; 554 555 if (aac_adapter_ioremap(dev, dev->base_size)) { 556 printk(KERN_WARNING "%s: unable to map adapter.\n", name); 557 goto error_iounmap; 558 } 559 560 /* Failure to reset here is an option ... */ 561 dev->a_ops.adapter_sync_cmd = rx_sync_cmd; 562 dev->a_ops.adapter_enable_int = aac_rx_disable_interrupt; 563 dev->OIMR = status = rx_readb (dev, MUnit.OIMR); 564 if ((((status & 0x0c) != 0x0c) || aac_reset_devices || reset_devices) && 565 !aac_rx_restart_adapter(dev, 0, IOP_HWSOFT_RESET)) 566 /* Make sure the Hardware FIFO is empty */ 567 while ((++restart < 512) && 568 (rx_readl(dev, MUnit.OutboundQueue) != 0xFFFFFFFFL)); 569 /* 570 * Check to see if the board panic'd while booting. 571 */ 572 status = rx_readl(dev, MUnit.OMRx[0]); 573 if (status & KERNEL_PANIC) { 574 if (aac_rx_restart_adapter(dev, 575 aac_rx_check_health(dev), IOP_HWSOFT_RESET)) 576 goto error_iounmap; 577 ++restart; 578 } 579 /* 580 * Check to see if the board failed any self tests. 581 */ 582 status = rx_readl(dev, MUnit.OMRx[0]); 583 if (status & SELF_TEST_FAILED) { 584 printk(KERN_ERR "%s%d: adapter self-test failed.\n", dev->name, instance); 585 goto error_iounmap; 586 } 587 /* 588 * Check to see if the monitor panic'd while booting. 589 */ 590 if (status & MONITOR_PANIC) { 591 printk(KERN_ERR "%s%d: adapter monitor panic.\n", dev->name, instance); 592 goto error_iounmap; 593 } 594 start = jiffies; 595 /* 596 * Wait for the adapter to be up and running. Wait up to 3 minutes 597 */ 598 while (!((status = rx_readl(dev, MUnit.OMRx[0])) & KERNEL_UP_AND_RUNNING)) 599 { 600 if ((restart && 601 (status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC))) || 602 time_after(jiffies, start+HZ*startup_timeout)) { 603 printk(KERN_ERR "%s%d: adapter kernel failed to start, init status = %lx.\n", 604 dev->name, instance, status); 605 goto error_iounmap; 606 } 607 if (!restart && 608 ((status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC)) || 609 time_after(jiffies, start + HZ * 610 ((startup_timeout > 60) 611 ? (startup_timeout - 60) 612 : (startup_timeout / 2))))) { 613 if (likely(!aac_rx_restart_adapter(dev, 614 aac_rx_check_health(dev), IOP_HWSOFT_RESET))) 615 start = jiffies; 616 ++restart; 617 } 618 msleep(1); 619 } 620 if (restart && aac_commit) 621 aac_commit = 1; 622 /* 623 * Fill in the common function dispatch table. 624 */ 625 dev->a_ops.adapter_interrupt = aac_rx_interrupt_adapter; 626 dev->a_ops.adapter_disable_int = aac_rx_disable_interrupt; 627 dev->a_ops.adapter_notify = aac_rx_notify_adapter; 628 dev->a_ops.adapter_sync_cmd = rx_sync_cmd; 629 dev->a_ops.adapter_check_health = aac_rx_check_health; 630 dev->a_ops.adapter_restart = aac_rx_restart_adapter; 631 dev->a_ops.adapter_start = aac_rx_start_adapter; 632 633 /* 634 * First clear out all interrupts. Then enable the one's that we 635 * can handle. 636 */ 637 aac_adapter_comm(dev, AAC_COMM_PRODUCER); 638 aac_adapter_disable_int(dev); 639 rx_writel(dev, MUnit.ODR, 0xffffffff); 640 aac_adapter_enable_int(dev); 641 642 if (aac_init_adapter(dev) == NULL) 643 goto error_iounmap; 644 aac_adapter_comm(dev, dev->comm_interface); 645 dev->sync_mode = 0; /* sync. mode not supported */ 646 dev->msi = aac_msi && !pci_enable_msi(dev->pdev); 647 if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr, 648 IRQF_SHARED, "aacraid", dev) < 0) { 649 if (dev->msi) 650 pci_disable_msi(dev->pdev); 651 printk(KERN_ERR "%s%d: Interrupt unavailable.\n", 652 name, instance); 653 goto error_iounmap; 654 } 655 dev->dbg_base = dev->base_start; 656 dev->dbg_base_mapped = dev->base; 657 dev->dbg_size = dev->base_size; 658 659 aac_adapter_enable_int(dev); 660 /* 661 * Tell the adapter that all is configured, and it can 662 * start accepting requests 663 */ 664 aac_rx_start_adapter(dev); 665 666 return 0; 667 668 error_iounmap: 669 670 return -1; 671 } 672 673 int aac_rx_init(struct aac_dev *dev) 674 { 675 /* 676 * Fill in the function dispatch table. 677 */ 678 dev->a_ops.adapter_ioremap = aac_rx_ioremap; 679 dev->a_ops.adapter_comm = aac_rx_select_comm; 680 681 return _aac_rx_init(dev); 682 } 683