#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/completion.h>
+#include <linux/time.h>
#include <linux/interrupt.h>
#include <asm/semaphore.h>
rkt_writel(dev, InboundDoorbellReg,DoorBellPrintfDone);
}
else if (bellbits & DoorBellAdapterNormCmdReady) {
- aac_command_normal(&dev->queues->queue[HostNormCmdQueue]);
rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdReady);
+ aac_command_normal(&dev->queues->queue[HostNormCmdQueue]);
}
else if (bellbits & DoorBellAdapterNormRespReady) {
aac_response_normal(&dev->queues->queue[HostNormRespQueue]);
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
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;
+ {
+ char * buffer = kmalloc(512, GFP_KERNEL|__GFP_DMA);
+ 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);
+ rkt_writel(dev, MUnit.IMRx[0], cpu_to_le32(paddr));
+ rkt_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;
* Everything is OK
*/
return 0;
-} /* aac_rkt_check_health */
+}
/**
* aac_rkt_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_rkt_init(struct aac_dev *dev, unsigned long num)
+int aac_rkt_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;
if((dev->regs.rkt = (struct rkt_registers *)ioremap((unsigned long)dev->scsi_host_ptr->base, 8192))==NULL)
{
printk(KERN_WARNING "aacraid: unable to map i960.\n" );
- return -1;
+ goto error_iounmap;
}
/*
* Check to see if the board failed any self tests.
*/
- if (rkt_readl(dev, IndexRegs.Mailbox[7]) & SELF_TEST_FAILED) {
+ if (rkt_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 monitor panic'd while booting.
+ */
+ if (rkt_readl(dev, MUnit.OMRx[0]) & MONITOR_PANIC) {
+ printk(KERN_ERR "%s%d: adapter monitor panic.\n", dev->name, instance);
+ goto error_iounmap;
}
/*
* Check to see if the board panic'd while booting.
*/
- if (rkt_readl(dev, IndexRegs.Mailbox[7]) & KERNEL_PANIC) {
+ if (rkt_readl(dev, MUnit.OMRx[0]) & KERNEL_PANIC) {
printk(KERN_ERR "%s%d: adapter kernel panic'd.\n", dev->name, instance);
- return -1;
+ goto error_iounmap;
}
start = jiffies;
/*
* Wait for the adapter to be up and running. Wait up to 3 minutes
*/
- while (!(rkt_readl(dev, IndexRegs.Mailbox[7]) & KERNEL_UP_AND_RUNNING))
+ while (!(rkt_readl(dev, MUnit.OMRx[0]) & KERNEL_UP_AND_RUNNING))
{
if(time_after(jiffies, start+180*HZ))
{
status = rkt_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);
if (request_irq(dev->scsi_host_ptr->irq, aac_rkt_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.
dev->a_ops.adapter_check_health = aac_rkt_check_health;
if (aac_init_adapter(dev) == NULL)
- return -1;
+ goto error_irq;
/*
* Start any kernel threads needed
*/
if(dev->thread_pid < 0)
{
printk(KERN_ERR "aacraid: Unable to create rkt thread.\n");
- return -1;
+ goto error_kfree;
}
/*
* Tell the adapter that all is configured, and it can start
*/
aac_rkt_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.rkt);
+
+ return -1;
}