int _aac_rx_init(struct aac_dev *dev) { unsigned long start; unsigned long status; int restart = 0; int instance = dev->id; const char * name = dev->name; if (aac_adapter_ioremap(dev, dev->base_size)) { printk(KERN_WARNING "%s: unable to map adapter.\n", name); goto error_iounmap; } /* Failure to reset here is an option ... */ dev->a_ops.adapter_sync_cmd = rx_sync_cmd; dev->a_ops.adapter_enable_int = aac_rx_disable_interrupt; dev->OIMR = status = rx_readb (dev, MUnit.OIMR); if ((((status & 0x0c) != 0x0c) || aac_reset_devices || reset_devices) && !aac_rx_restart_adapter(dev, 0)) /* Make sure the Hardware FIFO is empty */ while ((++restart < 512) && (rx_readl(dev, MUnit.OutboundQueue) != 0xFFFFFFFFL)); /* * Check to see if the board panic'd while booting. */ status = rx_readl(dev, MUnit.OMRx[0]); if (status & KERNEL_PANIC) { if (aac_rx_restart_adapter(dev, aac_rx_check_health(dev))) goto error_iounmap; ++restart; } /* * Check to see if the board failed any self tests. */ status = rx_readl(dev, MUnit.OMRx[0]); if (status & SELF_TEST_FAILED) { printk(KERN_ERR "%s%d: adapter self-test failed.\n", dev->name, instance); goto error_iounmap; } /* * Check to see if the monitor panic'd while booting. */ if (status & MONITOR_PANIC) { printk(KERN_ERR "%s%d: adapter monitor panic.\n", dev->name, instance); goto error_iounmap; } start = jiffies; /* * Wait for the adapter to be up and running. Wait up to 3 minutes */ while (!((status = rx_readl(dev, MUnit.OMRx[0])) & KERNEL_UP_AND_RUNNING)) { if ((restart && (status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC))) || time_after(jiffies, start+HZ*startup_timeout)) { printk(KERN_ERR "%s%d: adapter kernel failed to start, init status = %lx.\n", dev->name, instance, status); goto error_iounmap; } if (!restart && ((status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC)) || time_after(jiffies, start + HZ * ((startup_timeout > 60) ? (startup_timeout - 60) : (startup_timeout / 2))))) { if (likely(!aac_rx_restart_adapter(dev, aac_rx_check_health(dev)))) start = jiffies; ++restart; } msleep(1); } if (restart && aac_commit) aac_commit = 1; /* * Fill in the common function dispatch table. */ dev->a_ops.adapter_interrupt = aac_rx_interrupt_adapter; dev->a_ops.adapter_disable_int = aac_rx_disable_interrupt; dev->a_ops.adapter_notify = aac_rx_notify_adapter; dev->a_ops.adapter_sync_cmd = rx_sync_cmd; dev->a_ops.adapter_check_health = aac_rx_check_health; dev->a_ops.adapter_restart = aac_rx_restart_adapter; /* * First clear out all interrupts. Then enable the one's that we * can handle. */ aac_adapter_comm(dev, AAC_COMM_PRODUCER); aac_adapter_disable_int(dev); rx_writel(dev, MUnit.ODR, 0xffffffff); aac_adapter_enable_int(dev); if (aac_init_adapter(dev) == NULL) goto error_iounmap; aac_adapter_comm(dev, dev->comm_interface); dev->msi = aac_msi && !pci_enable_msi(dev->pdev); if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr, IRQF_SHARED|IRQF_DISABLED, "aacraid", dev) < 0) { if (dev->msi) pci_disable_msi(dev->pdev); printk(KERN_ERR "%s%d: Interrupt unavailable.\n", name, instance); goto error_iounmap; } aac_adapter_enable_int(dev); /* * Tell the adapter that all is configured, and it can * start accepting requests */ aac_rx_start_adapter(dev); return 0; error_iounmap: return -1; }
struct aac_dev *aac_init_adapter(struct aac_dev *dev) { u32 status[5]; struct Scsi_Host * host = dev->scsi_host_ptr; /* * Check the preferred comm settings, defaults from template. */ dev->max_fib_size = sizeof(struct hw_fib); dev->sg_tablesize = host->sg_tablesize = (dev->max_fib_size - sizeof(struct aac_fibhdr) - sizeof(struct aac_write) + sizeof(struct sgentry)) / sizeof(struct sgentry); dev->comm_interface = AAC_COMM_PRODUCER; dev->raw_io_64 = 0; if ((!aac_adapter_sync_cmd(dev, GET_ADAPTER_PROPERTIES, 0, 0, 0, 0, 0, 0, status+0, status+1, status+2, NULL, NULL)) && (status[0] == 0x00000001)) { if (status[1] & le32_to_cpu(AAC_OPT_NEW_COMM_64)) dev->raw_io_64 = 1; if (dev->a_ops.adapter_comm && (status[1] & le32_to_cpu(AAC_OPT_NEW_COMM))) dev->comm_interface = AAC_COMM_MESSAGE; if ((dev->comm_interface == AAC_COMM_MESSAGE) && (status[2] > dev->base_size)) { aac_adapter_ioremap(dev, 0); dev->base_size = status[2]; if (aac_adapter_ioremap(dev, status[2])) { /* remap failed, go back ... */ dev->comm_interface = AAC_COMM_PRODUCER; if (aac_adapter_ioremap(dev, AAC_MIN_FOOTPRINT_SIZE)) { printk(KERN_WARNING "aacraid: unable to map adapter.\n"); return NULL; } } } } if ((!aac_adapter_sync_cmd(dev, GET_COMM_PREFERRED_SETTINGS, 0, 0, 0, 0, 0, 0, status+0, status+1, status+2, status+3, status+4)) && (status[0] == 0x00000001)) { /* * status[1] >> 16 maximum command size in KB * status[1] & 0xFFFF maximum FIB size * status[2] >> 16 maximum SG elements to driver * status[2] & 0xFFFF maximum SG elements from driver * status[3] & 0xFFFF maximum number FIBs outstanding */ host->max_sectors = (status[1] >> 16) << 1; dev->max_fib_size = status[1] & 0xFFFF; host->sg_tablesize = status[2] >> 16; dev->sg_tablesize = status[2] & 0xFFFF; host->can_queue = (status[3] & 0xFFFF) - AAC_NUM_MGT_FIB; /* * NOTE: * All these overrides are based on a fixed internal * knowledge and understanding of existing adapters, * acbsize should be set with caution. */ if (acbsize == 512) { host->max_sectors = AAC_MAX_32BIT_SGBCOUNT; dev->max_fib_size = 512; dev->sg_tablesize = host->sg_tablesize = (512 - sizeof(struct aac_fibhdr) - sizeof(struct aac_write) + sizeof(struct sgentry)) / sizeof(struct sgentry); host->can_queue = AAC_NUM_IO_FIB; } else if (acbsize == 2048) { host->max_sectors = 512; dev->max_fib_size = 2048; host->sg_tablesize = 65; dev->sg_tablesize = 81; host->can_queue = 512 - AAC_NUM_MGT_FIB; } else if (acbsize == 4096) { host->max_sectors = 1024; dev->max_fib_size = 4096; host->sg_tablesize = 129; dev->sg_tablesize = 166; host->can_queue = 256 - AAC_NUM_MGT_FIB; } else if (acbsize == 8192) { host->max_sectors = 2048; dev->max_fib_size = 8192; host->sg_tablesize = 257; dev->sg_tablesize = 337; host->can_queue = 128 - AAC_NUM_MGT_FIB; } else if (acbsize > 0) { printk("Illegal acbsize=%d ignored\n", acbsize); } }
int _aac_rx_init(struct aac_dev *dev) { unsigned long start; unsigned long status; int restart = 0; int instance = dev->id; const char * name = dev->name; if (aac_adapter_ioremap(dev, dev->base_size)) { printk(KERN_WARNING "%s: unable to map adapter.\n", name); goto error_iounmap; } dev->a_ops.adapter_sync_cmd = rx_sync_cmd; dev->a_ops.adapter_enable_int = aac_rx_disable_interrupt; dev->OIMR = status = rx_readb (dev, MUnit.OIMR); if ((((status & 0x0c) != 0x0c) || aac_reset_devices || reset_devices) && !aac_rx_restart_adapter(dev, 0)) while ((++restart < 512) && (rx_readl(dev, MUnit.OutboundQueue) != 0xFFFFFFFFL)); status = rx_readl(dev, MUnit.OMRx[0]); if (status & KERNEL_PANIC) { if (aac_rx_restart_adapter(dev, aac_rx_check_health(dev))) goto error_iounmap; ++restart; } status = rx_readl(dev, MUnit.OMRx[0]); if (status & SELF_TEST_FAILED) { printk(KERN_ERR "%s%d: adapter self-test failed.\n", dev->name, instance); goto error_iounmap; } if (status & MONITOR_PANIC) { printk(KERN_ERR "%s%d: adapter monitor panic.\n", dev->name, instance); goto error_iounmap; } start = jiffies; while (!((status = rx_readl(dev, MUnit.OMRx[0])) & KERNEL_UP_AND_RUNNING)) { if ((restart && (status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC))) || time_after(jiffies, start+HZ*startup_timeout)) { printk(KERN_ERR "%s%d: adapter kernel failed to start, init status = %lx.\n", dev->name, instance, status); goto error_iounmap; } if (!restart && ((status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC)) || time_after(jiffies, start + HZ * ((startup_timeout > 60) ? (startup_timeout - 60) : (startup_timeout / 2))))) { if (likely(!aac_rx_restart_adapter(dev, aac_rx_check_health(dev)))) start = jiffies; ++restart; } msleep(1); } if (restart && aac_commit) aac_commit = 1; dev->a_ops.adapter_interrupt = aac_rx_interrupt_adapter; dev->a_ops.adapter_disable_int = aac_rx_disable_interrupt; dev->a_ops.adapter_notify = aac_rx_notify_adapter; dev->a_ops.adapter_sync_cmd = rx_sync_cmd; dev->a_ops.adapter_check_health = aac_rx_check_health; dev->a_ops.adapter_restart = aac_rx_restart_adapter; aac_adapter_comm(dev, AAC_COMM_PRODUCER); aac_adapter_disable_int(dev); rx_writel(dev, MUnit.ODR, 0xffffffff); aac_adapter_enable_int(dev); if (aac_init_adapter(dev) == NULL) goto error_iounmap; aac_adapter_comm(dev, dev->comm_interface); dev->msi = aac_msi && !pci_enable_msi(dev->pdev); if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr, IRQF_SHARED|IRQF_DISABLED, "aacraid", dev) < 0) { if (dev->msi) pci_disable_msi(dev->pdev); printk(KERN_ERR "%s%d: Interrupt unavailable.\n", name, instance); goto error_iounmap; } aac_adapter_enable_int(dev); aac_rx_start_adapter(dev); return 0; error_iounmap: return -1; }