X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fscsi%2Faacraid%2Frx.c;h=e111087c06b6ae8f79c56762c98d6de799b6bf69;hb=9bf4aaab3e101692164d49b7ca357651eb691cb6;hp=3963287c238bb24af3b985fbc1770fd31c87d497;hpb=db216c3d5e4c040e557a50f8f5d35d5c415e8c1c;p=linux-2.6.git diff --git a/drivers/scsi/aacraid/rx.c b/drivers/scsi/aacraid/rx.c index 3963287c2..e111087c0 100644 --- a/drivers/scsi/aacraid/rx.c +++ b/drivers/scsi/aacraid/rx.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -67,8 +68,8 @@ static irqreturn_t aac_rx_intr(int irq, void *dev_id, struct pt_regs *regs) rx_writel(dev, InboundDoorbellReg,DoorBellPrintfDone); } else if (bellbits & DoorBellAdapterNormCmdReady) { - aac_command_normal(&dev->queues->queue[HostNormCmdQueue]); rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdReady); + aac_command_normal(&dev->queues->queue[HostNormCmdQueue]); } else if (bellbits & DoorBellAdapterNormRespReady) { aac_response_normal(&dev->queues->queue[HostNormRespQueue]); @@ -305,7 +306,7 @@ static void aac_rx_start_adapter(struct aac_dev *dev) struct aac_init *init; init = dev->init; - init->HostElapsedSeconds = cpu_to_le32(jiffies/HZ); + init->HostElapsedSeconds = cpu_to_le32(get_seconds()); /* * Tell the adapter we are back and up and running so it will scan * its command queues and enable our interrupts @@ -341,12 +342,36 @@ static int aac_rx_check_health(struct aac_dev *dev) if (status & SELF_TEST_FAILED) return -1; /* - * Check to see if the board panic'd while booting. + * Check to see if the board panic'd. */ - if (status & KERNEL_PANIC) - return -2; + if (status & KERNEL_PANIC) { + char * buffer = kmalloc(512, GFP_KERNEL); + struct POSTSTATUS { + u32 Post_Command; + u32 Post_Address; + } * post = kmalloc(sizeof(struct POSTSTATUS), GFP_KERNEL); + dma_addr_t paddr = pci_map_single(dev->pdev, post, sizeof(struct POSTSTATUS), 2); + dma_addr_t baddr = pci_map_single(dev->pdev, buffer, 512, 1); + u32 status = -1; + int ret = -2; + memset(buffer, 0, 512); + post->Post_Command = cpu_to_le32(COMMAND_POST_RESULTS); + post->Post_Address = cpu_to_le32(baddr); + rx_writel(dev, MUnit.IMRx[0], cpu_to_le32(paddr)); + rx_sync_cmd(dev, COMMAND_POST_RESULTS, baddr, &status); + pci_unmap_single(dev->pdev, paddr, sizeof(struct POSTSTATUS), 2); + kfree(post); + if ((buffer[0] == '0') && (buffer[1] == 'x')) { + ret = (buffer[2] <= '9') ? (buffer[2] - '0') : (buffer[2] - 'A' + 10); + ret <<= 4; + ret += (buffer[3] <= '9') ? (buffer[3] - '0') : (buffer[3] - 'A' + 10); + } + pci_unmap_single(dev->pdev, baddr, 512, 1); + kfree(buffer); + return ret; + } /* - * Wait for the adapter to be up and running. Wait up to 3 minutes + * Wait for the adapter to be up and running. */ if (!(status & KERNEL_UP_AND_RUNNING)) return -3; @@ -359,21 +384,19 @@ static int aac_rx_check_health(struct aac_dev *dev) /** * aac_rx_init - initialize an i960 based AAC card * @dev: device to configure - * @devnum: adapter number * * Allocate and set up resources for the i960 based AAC variants. The * device_interface in the commregion will be allocated and linked * to the comm region. */ -int aac_rx_init(struct aac_dev *dev, unsigned long num) +int aac_rx_init(struct aac_dev *dev) { unsigned long start; unsigned long status; int instance; const char * name; - dev->devnum = num; instance = dev->id; name = dev->name; @@ -388,28 +411,36 @@ int aac_rx_init(struct aac_dev *dev, unsigned long num) /* * Check to see if the board failed any self tests. */ - if (rx_readl(dev, IndexRegs.Mailbox[7]) & SELF_TEST_FAILED) { + if (rx_readl(dev, MUnit.OMRx[0]) & SELF_TEST_FAILED) { printk(KERN_ERR "%s%d: adapter self-test failed.\n", dev->name, instance); - return -1; + goto error_iounmap; } /* * Check to see if the board panic'd while booting. */ - if (rx_readl(dev, IndexRegs.Mailbox[7]) & KERNEL_PANIC) { - printk(KERN_ERR "%s%d: adapter kernel panic'd.\n", dev->name, instance); - return -1; + if (rx_readl(dev, MUnit.OMRx[0]) & KERNEL_PANIC) { + printk(KERN_ERR "%s%d: adapter kernel panic.\n", dev->name, instance); + goto error_iounmap; + } + /* + * Check to see if the monitor panic'd while booting. + */ + if (rx_readl(dev, MUnit.OMRx[0]) & 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 (!(rx_readl(dev, IndexRegs.Mailbox[7]) & KERNEL_UP_AND_RUNNING)) + while ((!(rx_readl(dev, IndexRegs.Mailbox[7]) & KERNEL_UP_AND_RUNNING)) + || (!(rx_readl(dev, MUnit.OMRx[0]) & KERNEL_UP_AND_RUNNING))) { if(time_after(jiffies, start+180*HZ)) { status = rx_readl(dev, IndexRegs.Mailbox[7]) >> 16; printk(KERN_ERR "%s%d: adapter kernel failed to start, init status = %ld.\n", dev->name, instance, status); - return -1; + goto error_iounmap; } set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(1); @@ -417,7 +448,7 @@ int aac_rx_init(struct aac_dev *dev, unsigned long num) if (request_irq(dev->scsi_host_ptr->irq, aac_rx_intr, SA_SHIRQ|SA_INTERRUPT, "aacraid", (void *)dev)<0) { printk(KERN_ERR "%s%d: Interrupt unavailable.\n", name, instance); - return -1; + goto error_iounmap; } /* * Fill in the function dispatch table. @@ -430,15 +461,31 @@ int aac_rx_init(struct aac_dev *dev, unsigned long num) dev->a_ops.adapter_check_health = aac_rx_check_health; if (aac_init_adapter(dev) == NULL) - return -1; + goto error_irq; /* * Start any kernel threads needed */ dev->thread_pid = kernel_thread((int (*)(void *))aac_command_thread, dev, 0); + if(dev->thread_pid < 0) + { + printk(KERN_ERR "aacraid: Unable to create rx thread.\n"); + goto error_kfree; + } /* * Tell the adapter that all is configured, and it can start * accepting requests */ aac_rx_start_adapter(dev); return 0; + +error_kfree: + kfree(dev->queues); + +error_irq: + free_irq(dev->scsi_host_ptr->irq, (void *)dev); + +error_iounmap: + iounmap(dev->regs.rx); + + return -1; }