]> err.no Git - linux-2.6/commitdiff
[SCSI] aacraid: Newer adapter communication iterface support
authorMark Haverkamp <markh@osdl.org>
Mon, 24 Oct 2005 17:52:22 +0000 (10:52 -0700)
committerJames Bottomley <jejb@mulgrave.(none)>
Fri, 28 Oct 2005 16:41:53 +0000 (11:41 -0500)
Received from Mark Salyzyn.

This patch adds the 'new comm' interface, which modern AAC based
adapters that are less than a year old support in the name of much
improved performance. These modern adapters support both the legacy and
the 'new comm' interfaces.

Signed-off-by: Mark Haverkamp <markh@osdl.org>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
drivers/scsi/aacraid/README
drivers/scsi/aacraid/TODO
drivers/scsi/aacraid/aachba.c
drivers/scsi/aacraid/aacraid.h
drivers/scsi/aacraid/comminit.c
drivers/scsi/aacraid/commsup.c
drivers/scsi/aacraid/dpcsup.c
drivers/scsi/aacraid/linit.c
drivers/scsi/aacraid/rkt.c
drivers/scsi/aacraid/rx.c
drivers/scsi/aacraid/sa.c

index 4fa524687bc51c6bd48cb5fe582748d022da6094..4193865d419cc183cf79ffa20a778bf7778c2690 100644 (file)
@@ -57,7 +57,7 @@ Deanna Bonds                            (non-DASD support, PAE fibs and 64 bit,
                                        (fixed 64bit and 64G memory model, changed confusing naming convention
                                         where fibs that go to the hardware are consistently called hw_fibs and
                                         not just fibs like the name of the driver tracking structure)
-Mark Salyzyn <Mark_Salyzyn@adaptec.com> Fixed panic issues and added some new product ids for upcoming hbas.
+Mark Salyzyn <Mark_Salyzyn@adaptec.com> Fixed panic issues and added some new product ids for upcoming hbas. Performance tuning, card failover and bug mitigations.
 
 Original Driver
 -------------------------
index 2f148b4617dc96f842395a2ea22badd7b659c928..78dc863eff4f72b8f06ccf6b9c6a696211ccbde6 100644 (file)
@@ -1,4 +1,3 @@
 o      Testing
 o      More testing
-o      Drop irq_mask, basically unused
 o      I/O size increase
index a913196459d549608dd4056ba490390e4d9ed0a2..acc3d920987938396042559f9e4dea030b5f8a2d 100644 (file)
@@ -359,15 +359,6 @@ int aac_get_containers(struct aac_dev *dev)
        return status;
 }
 
-static void aac_io_done(struct scsi_cmnd * scsicmd)
-{
-       unsigned long cpu_flags;
-       struct Scsi_Host *host = scsicmd->device->host;
-       spin_lock_irqsave(host->host_lock, cpu_flags);
-       scsicmd->scsi_done(scsicmd);
-       spin_unlock_irqrestore(host->host_lock, cpu_flags);
-}
-
 static void aac_internal_transfer(struct scsi_cmnd *scsicmd, void *data, unsigned int offset, unsigned int len)
 {
        void *buf;
@@ -424,7 +415,7 @@ static void get_container_name_callback(void *context, struct fib * fibptr)
 
        fib_complete(fibptr);
        fib_free(fibptr);
-       aac_io_done(scsicmd);
+       scsicmd->scsi_done(scsicmd);
 }
 
 /**
@@ -988,7 +979,7 @@ static void io_callback(void *context, struct fib * fibptr)
        fib_complete(fibptr);
        fib_free(fibptr);
 
-       aac_io_done(scsicmd);
+       scsicmd->scsi_done(scsicmd);
 }
 
 static int aac_read(struct scsi_cmnd * scsicmd, int cid)
@@ -1167,7 +1158,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid)
         *      For some reason, the Fib didn't queue, return QUEUE_FULL
         */
        scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_TASK_SET_FULL;
-       aac_io_done(scsicmd);
+       scsicmd->scsi_done(scsicmd);
        fib_complete(cmd_fibcontext);
        fib_free(cmd_fibcontext);
        return 0;
@@ -1239,7 +1230,7 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid)
         */
        if (!(cmd_fibcontext = fib_alloc(dev))) {
                scsicmd->result = DID_ERROR << 16;
-               aac_io_done(scsicmd);
+               scsicmd->scsi_done(scsicmd);
                return 0;
        }
        fib_init(cmd_fibcontext);
@@ -1336,7 +1327,7 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid)
         *      For some reason, the Fib didn't queue, return QUEUE_FULL
         */
        scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_TASK_SET_FULL;
-       aac_io_done(scsicmd);
+       scsicmd->scsi_done(scsicmd);
 
        fib_complete(cmd_fibcontext);
        fib_free(cmd_fibcontext);
@@ -1380,7 +1371,7 @@ static void synchronize_callback(void *context, struct fib *fibptr)
 
        fib_complete(fibptr);
        fib_free(fibptr);
-       aac_io_done(cmd);
+       cmd->scsi_done(cmd);
 }
 
 static int aac_synchronize(struct scsi_cmnd *scsicmd, int cid)
@@ -2097,7 +2088,7 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
 
        fib_complete(fibptr);
        fib_free(fibptr);
-       aac_io_done(scsicmd);
+       scsicmd->scsi_done(scsicmd);
 }
 
 /**
index 2ebe402bc31ab36583ea4e76aa1c9a2199cd144e..30fd8d6e3f31081042f56ba897a87bae84fa9dab 100644 (file)
@@ -481,6 +481,7 @@ enum aac_log_level {
 #define FSAFS_NTC_FIB_CONTEXT                  0x030c
 
 struct aac_dev;
+struct fib;
 
 struct adapter_ops
 {
@@ -489,6 +490,7 @@ struct adapter_ops
        void (*adapter_disable_int)(struct aac_dev *dev);
        int  (*adapter_sync_cmd)(struct aac_dev *dev, u32 command, u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6, u32 *status, u32 *r1, u32 *r2, u32 *r3, u32 *r4);
        int  (*adapter_check_health)(struct aac_dev *dev);
+       int  (*adapter_send)(struct fib * fib);
 };
 
 /*
@@ -659,6 +661,10 @@ struct rx_mu_registers {
                                                Status Register */
        __le32  OIMR;       /*  1334h  | 34h | Outbound Interrupt 
                                                Mask Register */
+       __le32  reserved2;  /*  1338h  | 38h | Reserved */
+       __le32  reserved3;  /*  133Ch  | 3Ch | Reserved */
+       __le32  InboundQueue;/* 1340h  | 40h | Inbound Queue Port relative to firmware */
+       __le32  OutboundQueue;/*1344h  | 44h | Outbound Queue Port relative to firmware */
                            /* * Must access through ATU Inbound 
                                 Translation Window */
 };
@@ -693,8 +699,8 @@ struct rx_inbound {
 #define OutboundDoorbellReg    MUnit.ODR
 
 struct rx_registers {
-       struct rx_mu_registers          MUnit;          /* 1300h - 1334h */
-       __le32                          reserved1[6];   /* 1338h - 134ch */
+       struct rx_mu_registers          MUnit;          /* 1300h - 1344h */
+       __le32                          reserved1[2];   /* 1348h - 134ch */
        struct rx_inbound               IndexRegs;
 };
 
@@ -711,8 +717,8 @@ struct rx_registers {
 #define rkt_inbound rx_inbound
 
 struct rkt_registers {
-       struct rkt_mu_registers         MUnit;           /* 1300h - 1334h */
-       __le32                          reserved1[1010]; /* 1338h - 22fch */
+       struct rkt_mu_registers         MUnit;           /* 1300h - 1344h */
+       __le32                          reserved1[1006]; /* 1348h - 22fch */
        struct rkt_inbound              IndexRegs;       /* 2300h - */
 };
 
@@ -721,8 +727,6 @@ struct rkt_registers {
 #define rkt_writeb(AEP, CSR, value)    writeb(value, &((AEP)->regs.rkt->CSR))
 #define rkt_writel(AEP, CSR, value)    writel(value, &((AEP)->regs.rkt->CSR))
 
-struct fib;
-
 typedef void (*fib_callback)(void *ctxt, struct fib *fibctx);
 
 struct aac_fib_context {
@@ -937,7 +941,6 @@ struct aac_dev
        const char              *name;
        int                     id;
 
-       u16                     irq_mask;
        /*
         *      negotiated FIB settings
         */
@@ -972,6 +975,7 @@ struct aac_dev
        struct adapter_ops      a_ops;
        unsigned long           fsrev;          /* Main driver's revision number */
        
+       unsigned                base_size;      /* Size of mapped in region */
        struct aac_init         *init;          /* Holds initialization info to communicate with adapter */
        dma_addr_t              init_pa;        /* Holds physical address of the init struct */
        
@@ -992,6 +996,9 @@ struct aac_dev
        /*
         *      The following is the device specific extension.
         */
+#if (!defined(AAC_MIN_FOOTPRINT_SIZE))
+#      define AAC_MIN_FOOTPRINT_SIZE 8192
+#endif
        union
        {
                struct sa_registers __iomem *sa;
@@ -1012,6 +1019,7 @@ struct aac_dev
        u8                      nondasd_support; 
        u8                      dac_support;
        u8                      raid_scsi_mode;
+       u8                      new_comm_interface;
        /* macro side-effects BEWARE */
 #      define                  raw_io_interface \
          init->InitStructRevision==cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_4)
@@ -1034,6 +1042,8 @@ struct aac_dev
 #define aac_adapter_check_health(dev) \
        (dev)->a_ops.adapter_check_health(dev)
 
+#define aac_adapter_send(fib) \
+       ((fib)->dev)->a_ops.adapter_send(fib)
 
 #define FIB_CONTEXT_FLAG_TIMED_OUT             (0x00000001)
 
@@ -1779,6 +1789,7 @@ int aac_rkt_init(struct aac_dev *dev);
 int aac_sa_init(struct aac_dev *dev);
 unsigned int aac_response_normal(struct aac_queue * q);
 unsigned int aac_command_normal(struct aac_queue * q);
+unsigned int aac_intr_normal(struct aac_dev * dev, u32 Index);
 int aac_command_thread(struct aac_dev * dev);
 int aac_close_fib_context(struct aac_dev * dev, struct aac_fib_context *fibctx);
 int fib_adapter_complete(struct fib * fibptr, unsigned short size);
index 59a341b2aedcc6ab233ddf295b7c756b618cd8c9..82821d331c07322211d4a9f72f4f21862deb9b53 100644 (file)
@@ -116,6 +116,10 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
        }
 
        init->InitFlags = 0;
+       if (dev->new_comm_interface) {
+               init->InitFlags = cpu_to_le32(INITFLAGS_NEW_COMM_SUPPORTED);
+               dprintk((KERN_WARNING"aacraid: New Comm Interface enabled\n"));
+       }
        init->MaxIoCommands = cpu_to_le32(dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB);
        init->MaxIoSize = cpu_to_le32(dev->scsi_host_ptr->max_sectors << 9);
        init->MaxFibSize = cpu_to_le32(dev->max_fib_size);
@@ -315,12 +319,33 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
                - sizeof(struct aac_fibhdr)
                - sizeof(struct aac_write) + sizeof(struct sgentry))
                        / sizeof(struct sgentry);
+       dev->new_comm_interface = 0;
        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] & AAC_OPT_NEW_COMM_64)
                        dev->raw_io_64 = 1;
+               if (status[1] & AAC_OPT_NEW_COMM)
+                       dev->new_comm_interface = dev->a_ops.adapter_send != 0;
+               if (dev->new_comm_interface && (status[2] > dev->base_size)) {
+                       iounmap(dev->regs.sa);
+                       dev->base_size = status[2];
+                       dprintk((KERN_DEBUG "ioremap(%lx,%d)\n",
+                         host->base, status[2]));
+                       dev->regs.sa = ioremap(host->base, status[2]);
+                       if (dev->regs.sa == NULL) {
+                               /* remap failed, go back ... */
+                               dev->new_comm_interface = 0;
+                               dev->regs.sa = ioremap(host->base, 
+                                               AAC_MIN_FOOTPRINT_SIZE);
+                               if (dev->regs.sa == NULL) {     
+                                       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,
index e4d543a474ae7182cde72d0b3472952414e9c829..ee9067255930f8943505cdd6b694af0932ad349f 100644 (file)
@@ -212,7 +212,7 @@ void fib_init(struct fib *fibptr)
        hw_fib->header.StructType = FIB_MAGIC;
        hw_fib->header.Size = cpu_to_le16(fibptr->dev->max_fib_size);
        hw_fib->header.XferState = cpu_to_le32(HostOwned | FibInitialized | FibEmpty | FastResponseCapable);
-       hw_fib->header.SenderFibAddress = cpu_to_le32(fibptr->hw_fib_pa);
+       hw_fib->header.SenderFibAddress = 0; /* Filled in later if needed */
        hw_fib->header.ReceiverFibAddress = cpu_to_le32(fibptr->hw_fib_pa);
        hw_fib->header.SenderSize = cpu_to_le16(fibptr->dev->max_fib_size);
 }
@@ -380,9 +380,7 @@ static int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_f
  
 int fib_send(u16 command, struct fib * fibptr, unsigned long size,  int priority, int wait, int reply, fib_callback callback, void * callback_data)
 {
-       u32 index;
        struct aac_dev * dev = fibptr->dev;
-       unsigned long nointr = 0;
        struct hw_fib * hw_fib = fibptr->hw_fib;
        struct aac_queue * q;
        unsigned long flags = 0;
@@ -417,7 +415,7 @@ int fib_send(u16 command, struct fib * fibptr, unsigned long size,  int priority
         *      Map the fib into 32bits by using the fib number
         */
 
-       hw_fib->header.SenderFibAddress = cpu_to_le32(((u32)(fibptr-dev->fibs)) << 1);
+       hw_fib->header.SenderFibAddress = cpu_to_le32(((u32)(fibptr - dev->fibs)) << 2);
        hw_fib->header.SenderData = (u32)(fibptr - dev->fibs);
        /*
         *      Set FIB state to indicate where it came from and if we want a
@@ -456,10 +454,10 @@ int fib_send(u16 command, struct fib * fibptr, unsigned long size,  int priority
 
        FIB_COUNTER_INCREMENT(aac_config.FibsSent);
 
-       dprintk((KERN_DEBUG "fib_send: inserting a queue entry at index %d.\n",index));
        dprintk((KERN_DEBUG "Fib contents:.\n"));
-       dprintk((KERN_DEBUG "  Command =               %d.\n", hw_fib->header.Command));
-       dprintk((KERN_DEBUG "  XferState  =            %x.\n", hw_fib->header.XferState));
+       dprintk((KERN_DEBUG "  Command =               %d.\n", le32_to_cpu(hw_fib->header.Command)));
+       dprintk((KERN_DEBUG "  SubCommand =            %d.\n", le32_to_cpu(((struct aac_query_mount *)fib_data(fibptr))->command)));
+       dprintk((KERN_DEBUG "  XferState  =            %x.\n", le32_to_cpu(hw_fib->header.XferState)));
        dprintk((KERN_DEBUG "  hw_fib va being sent=%p\n",fibptr->hw_fib));
        dprintk((KERN_DEBUG "  hw_fib pa being sent=%lx\n",(ulong)fibptr->hw_fib_pa));
        dprintk((KERN_DEBUG "  fib being sent=%p\n",fibptr));
@@ -469,14 +467,37 @@ int fib_send(u16 command, struct fib * fibptr, unsigned long size,  int priority
        if(wait)
                spin_lock_irqsave(&fibptr->event_lock, flags);
        spin_lock_irqsave(q->lock, qflags);
-       aac_queue_get( dev, &index, AdapNormCmdQueue, hw_fib, 1, fibptr, &nointr);
-
-       list_add_tail(&fibptr->queue, &q->pendingq);
-       q->numpending++;
-       *(q->headers.producer) = cpu_to_le32(index + 1);
-       spin_unlock_irqrestore(q->lock, qflags);
-       if (!(nointr & aac_config.irq_mod))
-               aac_adapter_notify(dev, AdapNormCmdQueue);
+       if (dev->new_comm_interface) {
+               unsigned long count = 10000000L; /* 50 seconds */
+               list_add_tail(&fibptr->queue, &q->pendingq);
+               q->numpending++;
+               spin_unlock_irqrestore(q->lock, qflags);
+               while (aac_adapter_send(fibptr) != 0) {
+                       if (--count == 0) {
+                               if (wait)
+                                       spin_unlock_irqrestore(&fibptr->event_lock, flags);
+                               spin_lock_irqsave(q->lock, qflags);
+                               q->numpending--;
+                               list_del(&fibptr->queue);
+                               spin_unlock_irqrestore(q->lock, qflags);
+                               return -ETIMEDOUT;
+                       }
+                       udelay(5);
+               }
+       } else {
+               u32 index;
+               unsigned long nointr = 0;
+               aac_queue_get( dev, &index, AdapNormCmdQueue, hw_fib, 1, fibptr, &nointr);
+
+               list_add_tail(&fibptr->queue, &q->pendingq);
+               q->numpending++;
+               *(q->headers.producer) = cpu_to_le32(index + 1);
+               spin_unlock_irqrestore(q->lock, qflags);
+               dprintk((KERN_DEBUG "fib_send: inserting a queue entry at index %d.\n",index));
+               if (!(nointr & aac_config.irq_mod))
+                       aac_adapter_notify(dev, AdapNormCmdQueue);
+       }
+
        /*
         *      If the caller wanted us to wait for response wait now. 
         */
@@ -492,7 +513,6 @@ int fib_send(u16 command, struct fib * fibptr, unsigned long size,  int priority
                         * hardware failure has occurred.
                         */
                        unsigned long count = 36000000L; /* 3 minutes */
-                       unsigned long qflags;
                        while (down_trylock(&fibptr->event_wait)) {
                                if (--count == 0) {
                                        spin_lock_irqsave(q->lock, qflags);
@@ -621,12 +641,16 @@ int fib_adapter_complete(struct fib * fibptr, unsigned short size)
        unsigned long qflags;
 
        if (hw_fib->header.XferState == 0) {
+               if (dev->new_comm_interface)
+                       kfree (hw_fib);
                return 0;
        }
        /*
         *      If we plan to do anything check the structure type first.
         */ 
        if ( hw_fib->header.StructType != FIB_MAGIC ) {
+               if (dev->new_comm_interface)
+                       kfree (hw_fib);
                return -EINVAL;
        }
        /*
@@ -637,21 +661,25 @@ int fib_adapter_complete(struct fib * fibptr, unsigned short size)
         *      send the completed cdb to the adapter.
         */
        if (hw_fib->header.XferState & cpu_to_le32(SentFromAdapter)) {
-               u32 index;
-               hw_fib->header.XferState |= cpu_to_le32(HostProcessed);
-               if (size) {
-                       size += sizeof(struct aac_fibhdr);
-                       if (size > le16_to_cpu(hw_fib->header.SenderSize)) 
-                               return -EMSGSIZE;
-                       hw_fib->header.Size = cpu_to_le16(size);
+               if (dev->new_comm_interface) {
+                       kfree (hw_fib);
+               } else {
+                       u32 index;
+                       hw_fib->header.XferState |= cpu_to_le32(HostProcessed);
+                       if (size) {
+                               size += sizeof(struct aac_fibhdr);
+                               if (size > le16_to_cpu(hw_fib->header.SenderSize)) 
+                                       return -EMSGSIZE;
+                               hw_fib->header.Size = cpu_to_le16(size);
+                       }
+                       q = &dev->queues->queue[AdapNormRespQueue];
+                       spin_lock_irqsave(q->lock, qflags);
+                       aac_queue_get(dev, &index, AdapNormRespQueue, hw_fib, 1, NULL, &nointr);
+                       *(q->headers.producer) = cpu_to_le32(index + 1);
+                       spin_unlock_irqrestore(q->lock, qflags);
+                       if (!(nointr & (int)aac_config.irq_mod))
+                               aac_adapter_notify(dev, AdapNormRespQueue);
                }
-               q = &dev->queues->queue[AdapNormRespQueue];
-               spin_lock_irqsave(q->lock, qflags);
-               aac_queue_get(dev, &index, AdapNormRespQueue, hw_fib, 1, NULL, &nointr);
-               *(q->headers.producer) = cpu_to_le32(index + 1);
-               spin_unlock_irqrestore(q->lock, qflags);
-               if (!(nointr & (int)aac_config.irq_mod))
-                       aac_adapter_notify(dev, AdapNormRespQueue);
        }
        else 
        {
index be2e98de9fabc565f25e2e9357224698af033e4d..439948ef82516535d66e2cec3df0e515530e119a 100644 (file)
@@ -73,7 +73,7 @@ unsigned int aac_response_normal(struct aac_queue * q)
                int fast;
                u32 index = le32_to_cpu(entry->addr);
                fast = index & 0x01;
-               fib = &dev->fibs[index >> 1];
+               fib = &dev->fibs[index >> 2];
                hwfib = fib->hw_fib;
                
                aac_consumer_free(dev, q, HostNormRespQueue);
@@ -213,3 +213,116 @@ unsigned int aac_command_normal(struct aac_queue *q)
        spin_unlock_irqrestore(q->lock, flags);
        return 0;
 }
+
+
+/**
+ *     aac_intr_normal -       Handle command replies
+ *     @dev: Device
+ *     @index: completion reference
+ *
+ *     This DPC routine will be run when the adapter interrupts us to let us
+ *     know there is a response on our normal priority queue. We will pull off
+ *     all QE there are and wake up all the waiters before exiting.
+ */
+
+unsigned int aac_intr_normal(struct aac_dev * dev, u32 Index)
+{
+       u32 index = le32_to_cpu(Index);
+
+       dprintk((KERN_INFO "aac_intr_normal(%p,%x)\n", dev, Index));
+       if ((index & 0x00000002L)) {
+               struct hw_fib * hw_fib;
+               struct fib * fib;
+               struct aac_queue *q = &dev->queues->queue[HostNormCmdQueue];
+               unsigned long flags;
+
+               if (index == 0xFFFFFFFEL) /* Special Case */
+                       return 0;         /* Do nothing */
+               /*
+                *      Allocate a FIB. For non queued stuff we can just use
+                * the stack so we are happy. We need a fib object in order to
+                * manage the linked lists.
+                */
+               if ((!dev->aif_thread)
+                || (!(fib = kmalloc(sizeof(struct fib),GFP_ATOMIC))))
+                       return 1;
+               if (!(hw_fib = kmalloc(sizeof(struct hw_fib),GFP_ATOMIC))) {
+                       kfree (fib);
+                       return 1;
+               }
+               memset(hw_fib, 0, sizeof(struct hw_fib));
+               memcpy(hw_fib, (struct hw_fib *)(((unsigned long)(dev->regs.sa)) + (index & ~0x00000002L)), sizeof(struct hw_fib));
+               memset(fib, 0, sizeof(struct fib));
+               INIT_LIST_HEAD(&fib->fiblink);
+               fib->type = FSAFS_NTC_FIB_CONTEXT;
+               fib->size = sizeof(struct fib);
+               fib->hw_fib = hw_fib;
+               fib->data = hw_fib->data;
+               fib->dev = dev;
+       
+               spin_lock_irqsave(q->lock, flags);
+               list_add_tail(&fib->fiblink, &q->cmdq);
+               wake_up_interruptible(&q->cmdready);
+               spin_unlock_irqrestore(q->lock, flags);
+               return 1;
+       } else {
+               int fast = index & 0x01;
+               struct fib * fib = &dev->fibs[index >> 2];
+               struct hw_fib * hwfib = fib->hw_fib;
+
+               /*
+                *      Remove this fib from the Outstanding I/O queue.
+                *      But only if it has not already been timed out.
+                *
+                *      If the fib has been timed out already, then just 
+                *      continue. The caller has already been notified that
+                *      the fib timed out.
+                */
+               if ((fib->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) {
+                       printk(KERN_WARNING "aacraid: FIB timeout (%x).\n", fib->flags);
+                       printk(KERN_DEBUG"aacraid: hwfib=%p index=%i fib=%p\n",hwfib, hwfib->header.SenderData,fib);
+                       return 0;
+               }
+
+               list_del(&fib->queue);
+               dev->queues->queue[AdapNormCmdQueue].numpending--;
+
+               if (fast) {
+                       /*
+                        *      Doctor the fib
+                        */
+                       *(__le32 *)hwfib->data = cpu_to_le32(ST_OK);
+                       hwfib->header.XferState |= cpu_to_le32(AdapterProcessed);
+               }
+
+               FIB_COUNTER_INCREMENT(aac_config.FibRecved);
+
+               if (hwfib->header.Command == cpu_to_le16(NuFileSystem))
+               {
+                       u32 *pstatus = (u32 *)hwfib->data;
+                       if (*pstatus & cpu_to_le32(0xffff0000))
+                               *pstatus = cpu_to_le32(ST_OK);
+               }
+               if (hwfib->header.XferState & cpu_to_le32(NoResponseExpected | Async)) 
+               {
+                       if (hwfib->header.XferState & cpu_to_le32(NoResponseExpected))
+                               FIB_COUNTER_INCREMENT(aac_config.NoResponseRecved);
+                       else 
+                               FIB_COUNTER_INCREMENT(aac_config.AsyncRecved);
+                       /*
+                        *      NOTE:  we cannot touch the fib after this
+                        *          call, because it may have been deallocated.
+                        */
+                       fib->callback(fib->callback_data, fib);
+               } else {
+                       unsigned long flagv;
+                       dprintk((KERN_INFO "event_wait up\n"));
+                       spin_lock_irqsave(&fib->event_lock, flagv);
+                       fib->done = 1;
+                       up(&fib->event_wait);
+                       spin_unlock_irqrestore(&fib->event_lock, flagv);
+                       FIB_COUNTER_INCREMENT(aac_config.NormalRecved);
+               }
+               return 0;
+       }
+}
index c235d0c0e7a7071b23bd105c2dca63667812fef3..ab383d1f59e2e29489f48e88064093d51e8773e0 100644 (file)
@@ -788,8 +788,29 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
                goto out_free_host;
        spin_lock_init(&aac->fib_lock);
 
-       if ((*aac_drivers[index].init)(aac))
+       /*
+        *      Map in the registers from the adapter.
+        */
+       aac->base_size = AAC_MIN_FOOTPRINT_SIZE;
+       if ((aac->regs.sa = ioremap(
+         (unsigned long)aac->scsi_host_ptr->base, AAC_MIN_FOOTPRINT_SIZE))
+         == NULL) {    
+               printk(KERN_WARNING "%s: unable to map adapter.\n",
+                 AAC_DRIVERNAME);
                goto out_free_fibs;
+       }
+       if ((*aac_drivers[index].init)(aac))
+               goto out_unmap;
+
+       /*
+        *      Start any kernel threads needed
+        */
+       aac->thread_pid = kernel_thread((int (*)(void *))aac_command_thread,
+         aac, 0);
+       if (aac->thread_pid < 0) {
+               printk(KERN_ERR "aacraid: Unable to create command thread.\n");
+               goto out_deinit;
+       }
 
        /*
         * If we had set a smaller DMA mask earlier, set it to 4gig
@@ -866,10 +887,11 @@ static int __devinit aac_probe_one(struct pci_dev *pdev,
 
        aac_send_shutdown(aac);
        aac_adapter_disable_int(aac);
+       free_irq(pdev->irq, aac);
+ out_unmap:
        fib_map_free(aac);
        pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr, aac->comm_phys);
        kfree(aac->queues);
-       free_irq(pdev->irq, aac);
        iounmap(aac->regs.sa);
  out_free_fibs:
        kfree(aac->fibs);
@@ -910,6 +932,7 @@ static void __devexit aac_remove_one(struct pci_dev *pdev)
        iounmap(aac->regs.sa);
        
        kfree(aac->fibs);
+       kfree(aac->fsa_dev);
        
        list_del(&aac->entry);
        scsi_host_put(shost);
index 557287a0b80bdbfde17a349efb9aa7666cd7d7ca..fc4c73c2a6a9ec81b4759b5fd8691f72759c7857 100644 (file)
 static irqreturn_t aac_rkt_intr(int irq, void *dev_id, struct pt_regs *regs)
 {
        struct aac_dev *dev = dev_id;
-       unsigned long bellbits;
-       u8 intstat, mask;
-       intstat = rkt_readb(dev, MUnit.OISR);
-       /*
-        *      Read mask and invert because drawbridge is reversed.
-        *      This allows us to only service interrupts that have 
-        *      been enabled.
-        */
-       mask = ~(dev->OIMR);
-       /* Check to see if this is our interrupt.  If it isn't just return */
-       if (intstat & mask) 
-       {
-               bellbits = rkt_readl(dev, OutboundDoorbellReg);
-               if (bellbits & DoorBellPrintfReady) {
-                       aac_printf(dev, rkt_readl(dev, IndexRegs.Mailbox[5]));
-                       rkt_writel(dev, MUnit.ODR,DoorBellPrintfReady);
-                       rkt_writel(dev, InboundDoorbellReg,DoorBellPrintfDone);
-               }
-               else if (bellbits & DoorBellAdapterNormCmdReady) {
-                       rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdReady);
-                       aac_command_normal(&dev->queues->queue[HostNormCmdQueue]);
-               }
-               else if (bellbits & DoorBellAdapterNormRespReady) {
-                       aac_response_normal(&dev->queues->queue[HostNormRespQueue]);
-                       rkt_writel(dev, MUnit.ODR,DoorBellAdapterNormRespReady);
-               }
-               else if (bellbits & DoorBellAdapterNormCmdNotFull) {
-                       rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull);
+
+       if (dev->new_comm_interface) {
+               u32 Index = rkt_readl(dev, MUnit.OutboundQueue);
+               if (Index == 0xFFFFFFFFL)
+                       Index = rkt_readl(dev, MUnit.OutboundQueue);
+               if (Index != 0xFFFFFFFFL) {
+                       do {
+                               if (aac_intr_normal(dev, Index)) {
+                                       rkt_writel(dev, MUnit.OutboundQueue, Index);
+                                       rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormRespReady);
+                               }
+                               Index = rkt_readl(dev, MUnit.OutboundQueue);
+                       } while (Index != 0xFFFFFFFFL);
+                       return IRQ_HANDLED;
                }
-               else if (bellbits & DoorBellAdapterNormRespNotFull) {
-                       rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull);
-                       rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormRespNotFull);
+       } else {
+               unsigned long bellbits;
+               u8 intstat;
+               intstat = rkt_readb(dev, MUnit.OISR);
+               /*
+                *      Read mask and invert because drawbridge is reversed.
+                *      This allows us to only service interrupts that have 
+                *      been enabled.
+                *      Check to see if this is our interrupt.  If it isn't just return
+                */
+               if (intstat & ~(dev->OIMR))
+               {
+                       bellbits = rkt_readl(dev, OutboundDoorbellReg);
+                       if (bellbits & DoorBellPrintfReady) {
+                               aac_printf(dev, rkt_readl (dev, IndexRegs.Mailbox[5]));
+                               rkt_writel(dev, MUnit.ODR,DoorBellPrintfReady);
+                               rkt_writel(dev, InboundDoorbellReg,DoorBellPrintfDone);
+                       }
+                       else if (bellbits & DoorBellAdapterNormCmdReady) {
+                               rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdReady);
+                               aac_command_normal(&dev->queues->queue[HostNormCmdQueue]);
+//                             rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdReady);
+                       }
+                       else if (bellbits & DoorBellAdapterNormRespReady) {
+                               rkt_writel(dev, MUnit.ODR,DoorBellAdapterNormRespReady);
+                               aac_response_normal(&dev->queues->queue[HostNormRespQueue]);
+                       }
+                       else if (bellbits & DoorBellAdapterNormCmdNotFull) {
+                               rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull);
+                       }
+                       else if (bellbits & DoorBellAdapterNormRespNotFull) {
+                               rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull);
+                               rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormRespNotFull);
+                       }
+                       return IRQ_HANDLED;
                }
-               return IRQ_HANDLED;
        }
        return IRQ_NONE;
 }
@@ -173,7 +190,10 @@ static int rkt_sync_cmd(struct aac_dev *dev, u32 command,
                /*
                 *      Restore interrupt mask even though we timed out
                 */
-               rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb);
+               if (dev->new_comm_interface)
+                       rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xf7);
+               else
+                       rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb);
                return -ETIMEDOUT;
        }
        /*
@@ -196,7 +216,10 @@ static int rkt_sync_cmd(struct aac_dev *dev, u32 command,
        /*
         *      Restore interrupt mask
         */
-       rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb);
+       if (dev->new_comm_interface)
+               rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xf7);
+       else
+               rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb);
        return 0;
 
 }
@@ -268,15 +291,6 @@ static void aac_rkt_start_adapter(struct aac_dev *dev)
 
        init = dev->init;
        init->HostElapsedSeconds = cpu_to_le32(get_seconds());
-       /*
-        *      First clear out all interrupts.  Then enable the one's that we
-        *      can handle.
-        */
-       rkt_writeb(dev, MUnit.OIMR, 0xff);
-       rkt_writel(dev, MUnit.ODR, 0xffffffff);
-//     rkt_writeb(dev, MUnit.OIMR, ~(u8)OUTBOUND_DOORBELL_INTERRUPT_MASK);
-       rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb);
-
        // We can only use a 32 bit address here
        rkt_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa,
          0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL);
@@ -349,6 +363,39 @@ static int aac_rkt_check_health(struct aac_dev *dev)
        return 0;
 }
 
+/**
+ *     aac_rkt_send
+ *     @fib: fib to issue
+ *
+ *     Will send a fib, returning 0 if successful.
+ */
+static int aac_rkt_send(struct fib * fib)
+{
+       u64 addr = fib->hw_fib_pa;
+       struct aac_dev *dev = fib->dev;
+       volatile void __iomem *device = dev->regs.rkt;
+       u32 Index;
+
+       dprintk((KERN_DEBUG "%p->aac_rkt_send(%p->%llx)\n", dev, fib, addr));
+       Index = rkt_readl(dev, MUnit.InboundQueue);
+       if (Index == 0xFFFFFFFFL)
+               Index = rkt_readl(dev, MUnit.InboundQueue);
+       dprintk((KERN_DEBUG "Index = 0x%x\n", Index));
+       if (Index == 0xFFFFFFFFL)
+               return Index;
+       device += Index;
+       dprintk((KERN_DEBUG "entry = %x %x %u\n", (u32)(addr & 0xffffffff),
+         (u32)(addr >> 32), (u32)le16_to_cpu(fib->hw_fib->header.Size)));
+       writel((u32)(addr & 0xffffffff), device);
+       device += sizeof(u32);
+       writel((u32)(addr >> 32), device);
+       device += sizeof(u32);
+       writel(le16_to_cpu(fib->hw_fib->header.Size), device);
+       rkt_writel(dev, MUnit.InboundQueue, Index);
+       dprintk((KERN_DEBUG "aac_rkt_send - return 0\n"));
+       return 0;
+}
+
 /**
  *     aac_rkt_init    -       initialize an i960 based AAC card
  *     @dev: device to configure
@@ -369,13 +416,8 @@ int aac_rkt_init(struct aac_dev *dev)
        name     = dev->name;
 
        /*
-        *      Map in the registers from the adapter.
+        *      Check to see if the board panic'd while booting.
         */
-       if((dev->regs.rkt = ioremap((unsigned long)dev->scsi_host_ptr->base, 8192))==NULL)
-       {       
-               printk(KERN_WARNING "aacraid: unable to map i960.\n" );
-               goto error_iounmap;
-       }
        /*
         *      Check to see if the board failed any self tests.
         */
@@ -426,6 +468,7 @@ int aac_rkt_init(struct aac_dev *dev)
        dev->a_ops.adapter_notify = aac_rkt_notify_adapter;
        dev->a_ops.adapter_sync_cmd = rkt_sync_cmd;
        dev->a_ops.adapter_check_health = aac_rkt_check_health;
+       dev->a_ops.adapter_send = aac_rkt_send;
 
        /*
         *      First clear out all interrupts.  Then enable the one's that we
@@ -437,15 +480,24 @@ int aac_rkt_init(struct aac_dev *dev)
 
        if (aac_init_adapter(dev) == NULL)
                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 rkt thread.\n");
-               goto error_kfree;
-       }       
+       if (dev->new_comm_interface) {
+               /*
+                * FIB Setup has already been done, but we can minimize the
+                * damage by at least ensuring the OS never issues more
+                * commands than we can handle. The Rocket adapters currently
+                * can only handle 246 commands and 8 AIFs at the same time,
+                * and in fact do notify us accordingly if we negotiate the
+                * FIB size. The problem that causes us to add this check is
+                * to ensure that we do not overdo it with the adapter when a
+                * hard coded FIB override is being utilized. This special
+                * case warrants this half baked, but convenient, check here.
+                */
+               if (dev->scsi_host_ptr->can_queue > (246 - AAC_NUM_MGT_FIB)) {
+                       dev->init->MaxIoCommands = cpu_to_le32(246);
+                       dev->scsi_host_ptr->can_queue = 246 - AAC_NUM_MGT_FIB;
+               }
+               rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xf7);
+       }
        /*
         *      Tell the adapter that all is configured, and it can start
         *      accepting requests
@@ -453,15 +505,11 @@ int aac_rkt_init(struct aac_dev *dev)
        aac_rkt_start_adapter(dev);
        return 0;
 
-error_kfree:
-       kfree(dev->queues);
-
 error_irq:
        rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xff);
        free_irq(dev->scsi_host_ptr->irq, (void *)dev);
 
 error_iounmap:
-       iounmap(dev->regs.rkt);
 
        return -1;
 }
index a8459faf87caf88facabe65a6dee10982ac481f6..da99046e539342e7047ba2d82247086cc3ed9a82 100644 (file)
 static irqreturn_t aac_rx_intr(int irq, void *dev_id, struct pt_regs *regs)
 {
        struct aac_dev *dev = dev_id;
-       unsigned long bellbits;
-       u8 intstat, mask;
-       intstat = rx_readb(dev, MUnit.OISR);
-       /*
-        *      Read mask and invert because drawbridge is reversed.
-        *      This allows us to only service interrupts that have 
-        *      been enabled.
-        */
-       mask = ~(dev->OIMR);
-       /* Check to see if this is our interrupt.  If it isn't just return */
-       if (intstat & mask) 
-       {
-               bellbits = rx_readl(dev, OutboundDoorbellReg);
-               if (bellbits & DoorBellPrintfReady) {
-                       aac_printf(dev, rx_readl(dev, IndexRegs.Mailbox[5]));
-                       rx_writel(dev, MUnit.ODR,DoorBellPrintfReady);
-                       rx_writel(dev, InboundDoorbellReg,DoorBellPrintfDone);
-               }
-               else if (bellbits & DoorBellAdapterNormCmdReady) {
-                       rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdReady);
-                       aac_command_normal(&dev->queues->queue[HostNormCmdQueue]);
-               }
-               else if (bellbits & DoorBellAdapterNormRespReady) {
-                       aac_response_normal(&dev->queues->queue[HostNormRespQueue]);
-                       rx_writel(dev, MUnit.ODR,DoorBellAdapterNormRespReady);
-               }
-               else if (bellbits & DoorBellAdapterNormCmdNotFull) {
-                       rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull);
+
+       dprintk((KERN_DEBUG "aac_rx_intr(%d,%p,%p)\n", irq, dev_id, regs));
+       if (dev->new_comm_interface) {
+               u32 Index = rx_readl(dev, MUnit.OutboundQueue);
+               if (Index == 0xFFFFFFFFL)
+                       Index = rx_readl(dev, MUnit.OutboundQueue);
+               if (Index != 0xFFFFFFFFL) {
+                       do {
+                               if (aac_intr_normal(dev, Index)) {
+                                       rx_writel(dev, MUnit.OutboundQueue, Index);
+                                       rx_writel(dev, MUnit.ODR, DoorBellAdapterNormRespReady);
+                               }
+                               Index = rx_readl(dev, MUnit.OutboundQueue);
+                       } while (Index != 0xFFFFFFFFL);
+                       return IRQ_HANDLED;
                }
-               else if (bellbits & DoorBellAdapterNormRespNotFull) {
-                       rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull);
-                       rx_writel(dev, MUnit.ODR, DoorBellAdapterNormRespNotFull);
+       } else {
+               unsigned long bellbits;
+               u8 intstat;
+               intstat = rx_readb(dev, MUnit.OISR);
+               /*
+                *      Read mask and invert because drawbridge is reversed.
+                *      This allows us to only service interrupts that have 
+                *      been enabled.
+                *      Check to see if this is our interrupt.  If it isn't just return
+                */
+               if (intstat & ~(dev->OIMR)) 
+               {
+                       bellbits = rx_readl(dev, OutboundDoorbellReg);
+                       if (bellbits & DoorBellPrintfReady) {
+                               aac_printf(dev, rx_readl (dev, IndexRegs.Mailbox[5]));
+                               rx_writel(dev, MUnit.ODR,DoorBellPrintfReady);
+                               rx_writel(dev, InboundDoorbellReg,DoorBellPrintfDone);
+                       }
+                       else if (bellbits & DoorBellAdapterNormCmdReady) {
+                               rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdReady);
+                               aac_command_normal(&dev->queues->queue[HostNormCmdQueue]);
+                       }
+                       else if (bellbits & DoorBellAdapterNormRespReady) {
+                               rx_writel(dev, MUnit.ODR,DoorBellAdapterNormRespReady);
+                               aac_response_normal(&dev->queues->queue[HostNormRespQueue]);
+                       }
+                       else if (bellbits & DoorBellAdapterNormCmdNotFull) {
+                               rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull);
+                       }
+                       else if (bellbits & DoorBellAdapterNormRespNotFull) {
+                               rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull);
+                               rx_writel(dev, MUnit.ODR, DoorBellAdapterNormRespNotFull);
+                       }
+                       return IRQ_HANDLED;
                }
-               return IRQ_HANDLED;
        }
        return IRQ_NONE;
 }
@@ -173,7 +190,10 @@ static int rx_sync_cmd(struct aac_dev *dev, u32 command,
                /*
                 *      Restore interrupt mask even though we timed out
                 */
-               rx_writeb(dev, MUnit.OIMR, dev->OIMR &= 0xfb);
+               if (dev->new_comm_interface)
+                       rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xf7);
+               else
+                       rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb);
                return -ETIMEDOUT;
        }
        /*
@@ -196,7 +216,10 @@ static int rx_sync_cmd(struct aac_dev *dev, u32 command,
        /*
         *      Restore interrupt mask
         */
-       rx_writeb(dev, MUnit.OIMR, dev->OIMR &= 0xfb);
+       if (dev->new_comm_interface)
+               rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xf7);
+       else
+               rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb);
        return 0;
 
 }
@@ -267,15 +290,6 @@ static void aac_rx_start_adapter(struct aac_dev *dev)
 
        init = dev->init;
        init->HostElapsedSeconds = cpu_to_le32(get_seconds());
-       /*
-        *      First clear out all interrupts.  Then enable the one's that we
-        *      can handle.
-        */
-       rx_writeb(dev, MUnit.OIMR, 0xff);
-       rx_writel(dev, MUnit.ODR, 0xffffffff);
-//     rx_writeb(dev, MUnit.OIMR, ~(u8)OUTBOUND_DOORBELL_INTERRUPT_MASK);
-       rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb);
-
        // We can only use a 32 bit address here
        rx_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa,
          0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL);
@@ -348,6 +362,39 @@ static int aac_rx_check_health(struct aac_dev *dev)
        return 0;
 }
 
+/**
+ *     aac_rx_send
+ *     @fib: fib to issue
+ *
+ *     Will send a fib, returning 0 if successful.
+ */
+static int aac_rx_send(struct fib * fib)
+{
+       u64 addr = fib->hw_fib_pa;
+       struct aac_dev *dev = fib->dev;
+       volatile void __iomem *device = dev->regs.rx;
+       u32 Index;
+
+       dprintk((KERN_DEBUG "%p->aac_rx_send(%p->%llx)\n", dev, fib, addr));
+       Index = rx_readl(dev, MUnit.InboundQueue);
+       if (Index == 0xFFFFFFFFL)
+               Index = rx_readl(dev, MUnit.InboundQueue);
+       dprintk((KERN_DEBUG "Index = 0x%x\n", Index));
+       if (Index == 0xFFFFFFFFL)
+               return Index;
+       device += Index;
+       dprintk((KERN_DEBUG "entry = %x %x %u\n", (u32)(addr & 0xffffffff),
+         (u32)(addr >> 32), (u32)le16_to_cpu(fib->hw_fib->header.Size)));
+       writel((u32)(addr & 0xffffffff), device);
+       device += sizeof(u32);
+       writel((u32)(addr >> 32), device);
+       device += sizeof(u32);
+       writel(le16_to_cpu(fib->hw_fib->header.Size), device);
+       rx_writel(dev, MUnit.InboundQueue, Index);
+       dprintk((KERN_DEBUG "aac_rx_send - return 0\n"));
+       return 0;
+}
+
 /**
  *     aac_rx_init     -       initialize an i960 based AAC card
  *     @dev: device to configure
@@ -368,13 +415,8 @@ int aac_rx_init(struct aac_dev *dev)
        name     = dev->name;
 
        /*
-        *      Map in the registers from the adapter.
+        *      Check to see if the board panic'd while booting.
         */
-       if((dev->regs.rx = ioremap((unsigned long)dev->scsi_host_ptr->base, 8192))==NULL)
-       {       
-               printk(KERN_WARNING "aacraid: unable to map i960.\n" );
-               return -1;
-       }
        /*
         *      Check to see if the board failed any self tests.
         */
@@ -426,6 +468,7 @@ int aac_rx_init(struct aac_dev *dev)
        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_send = aac_rx_send;
 
        /*
         *      First clear out all interrupts.  Then enable the one's that we
@@ -437,15 +480,9 @@ int aac_rx_init(struct aac_dev *dev)
 
        if (aac_init_adapter(dev) == NULL)
                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;
-       }
+       if (dev->new_comm_interface)
+               rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xf7);
+
        /*
         *      Tell the adapter that all is configured, and it can start
         *      accepting requests
@@ -453,15 +490,11 @@ int aac_rx_init(struct aac_dev *dev)
        aac_rx_start_adapter(dev);
        return 0;
 
-error_kfree:
-       kfree(dev->queues);
-
 error_irq:
        rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xff);
        free_irq(dev->scsi_host_ptr->irq, (void *)dev);
 
 error_iounmap:
-       iounmap(dev->regs.rx);
 
        return -1;
 }
index 3900abc5850d35e9d731f1c19840c912f63c98fe..8b9596209164904d63b4bf8f197a5ed9f488ed4e 100644 (file)
@@ -237,29 +237,16 @@ static void aac_sa_interrupt_adapter (struct aac_dev *dev)
 
 static void aac_sa_start_adapter(struct aac_dev *dev)
 {
-       u32 ret;
        struct aac_init *init;
        /*
         * Fill in the remaining pieces of the init.
         */
        init = dev->init;
        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
-        */
-       dev->irq_mask = (PrintfReady | DOORBELL_1 | DOORBELL_2 | DOORBELL_3 | DOORBELL_4);
-       /*
-        *      First clear out all interrupts.  Then enable the one's that 
-        *      we can handle.
-        */
-       sa_writew(dev, SaDbCSR.PRISETIRQMASK, 0xffff);
-       sa_writew(dev, SaDbCSR.PRICLEARIRQMASK, (PrintfReady | DOORBELL_1 | DOORBELL_2 | DOORBELL_3 | DOORBELL_4));
        /* We can only use a 32 bit address here */
        sa_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, 
                        (u32)(ulong)dev->init_pa, 0, 0, 0, 0, 0,
-                       &ret, NULL, NULL, NULL, NULL);
+                       NULL, NULL, NULL, NULL, NULL);
 }
 
 /**
@@ -313,15 +300,6 @@ int aac_sa_init(struct aac_dev *dev)
        instance = dev->id;
        name     = dev->name;
 
-       /*
-        *      Map in the registers from the adapter.
-        */
-
-       if((dev->regs.sa = ioremap((unsigned long)dev->scsi_host_ptr->base, 8192))==NULL)
-       {       
-               printk(KERN_WARNING "aacraid: unable to map ARM.\n" );
-               goto error_iounmap;
-       }
        /*
         *      Check to see if the board failed any self tests.
         */
@@ -377,15 +355,6 @@ int aac_sa_init(struct aac_dev *dev)
        if(aac_init_adapter(dev) == NULL)
                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 command thread.\n");
-               goto error_kfree;
-       }
-
        /*
         *      Tell the adapter that all is configure, and it can start 
         *      accepting requests
@@ -393,16 +362,11 @@ int aac_sa_init(struct aac_dev *dev)
        aac_sa_start_adapter(dev);
        return 0;
 
-
-error_kfree:
-       kfree(dev->queues);
-
 error_irq:
        sa_writew(dev, SaDbCSR.PRISETIRQMASK, 0xffff);
        free_irq(dev->scsi_host_ptr->irq, (void *)dev);
 
 error_iounmap:
-       iounmap(dev->regs.sa);
 
        return -1;
 }