}
 EXPORT_SYMBOL(ecard_release_resources);
 
+void ecard_setirq(struct expansion_card *ec, const struct expansion_card_ops *ops, void *irq_data)
+{
+       ec->irq_data = irq_data;
+       barrier();
+       ec->ops = ops;
+}
+EXPORT_SYMBOL(ecard_setirq);
+
 /*
  * Probe for an expansion card.
  *
        drv->remove(ec);
        ecard_release(ec);
 
+       /*
+        * Restore the default operations.  We ensure that the
+        * ops are set before we change the data.
+        */
+       ec->ops = &ecard_default_ops;
+       barrier();
+       ec->irq_data = NULL;
+
        return 0;
 }
 
 
 
        ec->irqaddr = base + ICS_ARCIN_V5_INTRSTAT;
        ec->irqmask = 1;
-       ec->irq_data = state;
-       ec->ops = &pata_icside_ops_arcin_v5;
+
+       ecard_setirq(ec, &pata_icside_ops_arcin_v5, state);
 
        /*
         * Be on the safe side - disable interrupts
 
        writeb(sel, ioc_base);
 
-       ec->irq_data = state;
-       ec->ops = &pata_icside_ops_arcin_v6;
+       ecard_setirq(ec, &pata_icside_ops_arcin_v6, state);
 
        state->irq_port = easi_base;
        state->ioc_base = ioc_base;
         * this register via that region.
         */
        local_irq_save(flags);
-       if (ec->ops)
-               ec->ops->irqdisable(ec, ec->irq);
+       ec->ops->irqdisable(ec, ec->irq);
        local_irq_restore(flags);
 
        /*
         * don't NULL out the drvdata - devres/libata wants it
         * to free the ata_host structure.
         */
-       ec->ops = NULL;
-       ec->irq_data = NULL;
-
        if (state->dma != NO_DMA)
                free_dma(state->dma);
        if (state->ioc_base)
 
 
        ec->irqaddr  = base + ICS_ARCIN_V5_INTRSTAT;
        ec->irqmask  = 1;
-       ec->irq_data = state;
-       ec->ops      = &icside_ops_arcin_v5;
+
+       ecard_setirq(ec, &icside_ops_arcin_v5, state);
 
        /*
         * Be on the safe side - disable interrupts
 
        writeb(sel, ioc_base);
 
-       ec->irq_data      = state;
-       ec->ops           = &icside_ops_arcin_v6;
+       ecard_setirq(ec, &icside_ops_arcin_v6, state);
 
        state->irq_port   = easi_base;
        state->ioc_base   = ioc_base;
        }
 
        ecard_set_drvdata(ec, NULL);
-       ec->ops = NULL;
-       ec->irq_data = NULL;
 
        if (state->ioc_base)
                iounmap(state->ioc_base);
 
         * IRQ and control port handling - only for non-NIC slot cards.
         */
        if (ec->slot_no != 8) {
-               ec->ops         = ðerh_ops;
-               ec->irq_data    = eh;
+               ecard_setirq(ec, ðerh_ops, eh);
        } else {
                /*
                 * If we're in the NIC slot, make sure the IRQ is enabled
        ecard_set_drvdata(ec, NULL);
 
        unregister_netdev(dev);
-       ec->ops = NULL;
 
        if (eh->ioc_fast)
                iounmap(eh->ioc_fast);
 
 
        ec->irqaddr     = info->base + CUMANASCSI2_STATUS;
        ec->irqmask     = STATUS_INT;
-       ec->irq_data    = info;
-       ec->ops         = &cumanascsi_2_ops;
+
+       ecard_setirq(ec, &cumanascsi_2_ops, info);
 
        ret = fas216_init(host);
        if (ret)
 
 
        ec->irqaddr     = base + EESOX_DMASTAT;
        ec->irqmask     = EESOX_STAT_INTR;
-       ec->irq_data    = info;
-       ec->ops         = &eesoxscsi_ops;
+
+       ecard_setirq(ec, &eesoxscsi_ops, info);
 
        device_create_file(&ec->dev, &dev_attr_bus_term);
 
 
 
        ec->irqaddr     = base + POWERTEC_INTR_STATUS;
        ec->irqmask     = POWERTEC_INTR_BIT;
-       ec->irq_data    = info;
-       ec->ops         = &powertecscsi_ops;
+
+       ecard_setirq(ec, &powertecscsi_ops, info);
 
        device_create_file(&ec->dev, &dev_attr_bus_term);
 
 
 typedef struct expansion_card ecard_t;
 typedef unsigned long *loader_t;
 
-typedef struct {                       /* Card handler routines        */
+typedef struct expansion_card_ops {    /* Card handler routines        */
        void (*irqenable)(ecard_t *ec, int irqnr);
        void (*irqdisable)(ecard_t *ec, int irqnr);
        int  (*irqpending)(ecard_t *ec);
        u64                     dma_mask;
 };
 
+void ecard_setirq(struct expansion_card *ec, const struct expansion_card_ops *ops, void *irq_data);
+
 struct in_chunk_dir {
        unsigned int start_offset;
        union {