hisi_sas: Restrict SCSI_HISI_SAS to arm64
[deliverable/linux.git] / drivers / scsi / atp870u.c
index e398ea5ea8f1f51d75b605f5c941fcdd60d8f4ad..8b52a9dbb9cf5a5fd18dd572f9459db57783b074 100644 (file)
 
 static struct scsi_host_template atp870u_template;
 static void send_s870(struct atp_unit *dev,unsigned char c);
-static void is885(struct atp_unit *dev, unsigned int wkport,unsigned char c);
-static void tscam_885(void);
+static void atp_is(struct atp_unit *dev, unsigned char c, bool wide_chip, unsigned char lvdmode);
+
+static inline void atp_writeb_base(struct atp_unit *atp, u8 reg, u8 val)
+{
+       outb(val, atp->baseport + reg);
+}
+
+static inline void atp_writew_base(struct atp_unit *atp, u8 reg, u16 val)
+{
+       outw(val, atp->baseport + reg);
+}
+
+static inline void atp_writeb_io(struct atp_unit *atp, u8 channel, u8 reg, u8 val)
+{
+       outb(val, atp->ioport[channel] + reg);
+}
+
+static inline void atp_writew_io(struct atp_unit *atp, u8 channel, u8 reg, u16 val)
+{
+       outw(val, atp->ioport[channel] + reg);
+}
+
+static inline void atp_writeb_pci(struct atp_unit *atp, u8 channel, u8 reg, u8 val)
+{
+       outb(val, atp->pciport[channel] + reg);
+}
+
+static inline void atp_writel_pci(struct atp_unit *atp, u8 channel, u8 reg, u32 val)
+{
+       outl(val, atp->pciport[channel] + reg);
+}
+
+static inline u8 atp_readb_base(struct atp_unit *atp, u8 reg)
+{
+       return inb(atp->baseport + reg);
+}
+
+static inline u16 atp_readw_base(struct atp_unit *atp, u8 reg)
+{
+       return inw(atp->baseport + reg);
+}
+
+static inline u32 atp_readl_base(struct atp_unit *atp, u8 reg)
+{
+       return inl(atp->baseport + reg);
+}
+
+static inline u8 atp_readb_io(struct atp_unit *atp, u8 channel, u8 reg)
+{
+       return inb(atp->ioport[channel] + reg);
+}
+
+static inline u16 atp_readw_io(struct atp_unit *atp, u8 channel, u8 reg)
+{
+       return inw(atp->ioport[channel] + reg);
+}
+
+static inline u8 atp_readb_pci(struct atp_unit *atp, u8 channel, u8 reg)
+{
+       return inb(atp->pciport[channel] + reg);
+}
+
+static inline bool is880(struct atp_unit *atp)
+{
+       return atp->pdev->device == ATP880_DEVID1 ||
+              atp->pdev->device == ATP880_DEVID2;
+}
+
+static inline bool is885(struct atp_unit *atp)
+{
+       return atp->pdev->device == ATP885_DEVID;
+}
 
 static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
 {
        unsigned long flags;
-       unsigned short int tmpcip, id;
+       unsigned short int id;
        unsigned char i, j, c, target_id, lun,cmdp;
        unsigned char *prd;
        struct scsi_cmnd *workreq;
@@ -55,56 +125,44 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
 #ifdef ED_DBGP
        unsigned long l;
 #endif
-       int errstus;
        struct Scsi_Host *host = dev_id;
        struct atp_unit *dev = (struct atp_unit *)&host->hostdata;
 
        for (c = 0; c < 2; c++) {
-               j = inb(dev->ioport[c] + 0x1f);
+               j = atp_readb_io(dev, c, 0x1f);
                if ((j & 0x80) != 0)
-               {                       
-                       goto ch_sel;
-               }
+                       break;
                dev->in_int[c] = 0;
        }
-       return IRQ_NONE;
-ch_sel:
+       if ((j & 0x80) == 0)
+               return IRQ_NONE;
 #ifdef ED_DBGP 
        printk("atp870u_intr_handle enter\n");
 #endif 
        dev->in_int[c] = 1;
-       cmdp = inb(dev->ioport[c] + 0x10);
+       cmdp = atp_readb_io(dev, c, 0x10);
        if (dev->working[c] != 0) {
-               if (dev->dev_id == ATP885_DEVID) {
-                       if ((inb(dev->ioport[c] + 0x16) & 0x80) == 0)
-                               outb((inb(dev->ioport[c] + 0x16) | 0x80), dev->ioport[c] + 0x16);
+               if (is885(dev)) {
+                       if ((atp_readb_io(dev, c, 0x16) & 0x80) == 0)
+                               atp_writeb_io(dev, c, 0x16, (atp_readb_io(dev, c, 0x16) | 0x80));
                }               
-               tmpcip = dev->pciport[c];
-               if ((inb(tmpcip) & 0x08) != 0)
+               if ((atp_readb_pci(dev, c, 0x00) & 0x08) != 0)
                {
-                       tmpcip += 0x2;
                        for (k=0; k < 1000; k++) {
-                               if ((inb(tmpcip) & 0x08) == 0) {
-                                       goto stop_dma;
-                               }
-                               if ((inb(tmpcip) & 0x01) == 0) {
-                                       goto stop_dma;
-                               }
+                               if ((atp_readb_pci(dev, c, 2) & 0x08) == 0)
+                                       break;
+                               if ((atp_readb_pci(dev, c, 2) & 0x01) == 0)
+                                       break;
                        }
                }
-stop_dma:
-               tmpcip = dev->pciport[c];
-               outb(0x00, tmpcip);
+               atp_writeb_pci(dev, c, 0, 0x00);
                
-               i = inb(dev->ioport[c] + 0x17);
+               i = atp_readb_io(dev, c, 0x17);
                
-               if (dev->dev_id == ATP885_DEVID) {
-                       tmpcip += 2;
-                       outb(0x06, tmpcip);
-                       tmpcip -= 2;
-               }
+               if (is885(dev))
+                       atp_writeb_pci(dev, c, 2, 0x06);
 
-               target_id = inb(dev->ioport[c] + 0x15);
+               target_id = atp_readb_io(dev, c, 0x15);
 
                /*
                 *      Remap wide devices onto id numbers
@@ -122,7 +180,7 @@ stop_dma:
                     }
                     dev->last_cmd[c] |= 0x40;
                }
-               if (dev->dev_id == ATP885_DEVID) 
+               if (is885(dev))
                        dev->r1f[c][target_id] |= j;
 #ifdef ED_DBGP
                printk("atp870u_intr_handle status = %x\n",i);
@@ -131,11 +189,11 @@ stop_dma:
                        if ((dev->last_cmd[c] & 0xf0) != 0x40) {
                           dev->last_cmd[c] = 0xff;
                        }
-                       if (dev->dev_id == ATP885_DEVID) {
+                       if (is885(dev)) {
                                adrcnt = 0;
-                               ((unsigned char *) &adrcnt)[2] = inb(dev->ioport[c] + 0x12);
-                               ((unsigned char *) &adrcnt)[1] = inb(dev->ioport[c] + 0x13);
-                               ((unsigned char *) &adrcnt)[0] = inb(dev->ioport[c] + 0x14);
+                               ((unsigned char *) &adrcnt)[2] = atp_readb_io(dev, c, 0x12);
+                               ((unsigned char *) &adrcnt)[1] = atp_readb_io(dev, c, 0x13);
+                               ((unsigned char *) &adrcnt)[0] = atp_readb_io(dev, c, 0x14);
                                if (dev->id[c][target_id].last_len != adrcnt)
                                {
                                        k = dev->id[c][target_id].last_len;
@@ -152,10 +210,9 @@ stop_dma:
                         *      Flip wide
                         */                     
                        if (dev->wide_id[c] != 0) {
-                               outb(0x01, dev->ioport[c] + 0x1b);
-                               while ((inb(dev->ioport[c] + 0x1b) & 0x01) != 0x01) {
-                                       outb(0x01, dev->ioport[c] + 0x1b);
-                               }
+                               atp_writeb_io(dev, c, 0x1b, 0x01);
+                               while ((atp_readb_io(dev, c, 0x1b) & 0x01) != 0x01)
+                                       atp_writeb_io(dev, c, 0x1b, 0x01);
                        }               
                        /*
                         *      Issue more commands
@@ -176,13 +233,13 @@ stop_dma:
 #ifdef ED_DBGP
                                printk("Status 0x85 return\n");
 #endif                         
-                       goto handled;
+                       return IRQ_HANDLED;
                }
 
                if (i == 0x40) {
                     dev->last_cmd[c] |= 0x40;
                     dev->in_int[c] = 0;
-                    goto handled;
+                    return IRQ_HANDLED;
                }
 
                if (i == 0x21) {
@@ -190,20 +247,20 @@ stop_dma:
                           dev->last_cmd[c] = 0xff;
                        }
                        adrcnt = 0;
-                       ((unsigned char *) &adrcnt)[2] = inb(dev->ioport[c] + 0x12);
-                       ((unsigned char *) &adrcnt)[1] = inb(dev->ioport[c] + 0x13);
-                       ((unsigned char *) &adrcnt)[0] = inb(dev->ioport[c] + 0x14);
+                       ((unsigned char *) &adrcnt)[2] = atp_readb_io(dev, c, 0x12);
+                       ((unsigned char *) &adrcnt)[1] = atp_readb_io(dev, c, 0x13);
+                       ((unsigned char *) &adrcnt)[0] = atp_readb_io(dev, c, 0x14);
                        k = dev->id[c][target_id].last_len;
                        k -= adrcnt;
                        dev->id[c][target_id].tran_len = k;
                        dev->id[c][target_id].last_len = adrcnt;
-                       outb(0x41, dev->ioport[c] + 0x10);
-                       outb(0x08, dev->ioport[c] + 0x18);
+                       atp_writeb_io(dev, c, 0x10, 0x41);
+                       atp_writeb_io(dev, c, 0x18, 0x08);
                        dev->in_int[c] = 0;
-                       goto handled;
+                       return IRQ_HANDLED;
                }
 
-               if (dev->dev_id == ATP885_DEVID) {
+               if (is885(dev)) {
                        if ((i == 0x4c) || (i == 0x4d) || (i == 0x8c) || (i == 0x8d)) {
                                if ((i == 0x4c) || (i == 0x8c)) 
                                        i=0x48;
@@ -217,9 +274,9 @@ stop_dma:
                        printk(KERN_DEBUG "Device reselect\n");
 #endif                 
                        lun = 0;
-                       if (cmdp == 0x44 || i==0x80) {
-                               lun = inb(dev->ioport[c] + 0x1d) & 0x07;
-                       else {
+                       if (cmdp == 0x44 || i == 0x80)
+                               lun = atp_readb_io(dev, c, 0x1d) & 0x07;
+                       else {
                                if ((dev->last_cmd[c] & 0xf0) != 0x40) {
                                   dev->last_cmd[c] = 0xff;
                                }
@@ -228,40 +285,40 @@ stop_dma:
                                        printk("cmdp = 0x41\n");
 #endif                                         
                                        adrcnt = 0;
-                                       ((unsigned char *) &adrcnt)[2] = inb(dev->ioport[c] + 0x12);
-                                       ((unsigned char *) &adrcnt)[1] = inb(dev->ioport[c] + 0x13);
-                                       ((unsigned char *) &adrcnt)[0] = inb(dev->ioport[c] + 0x14);
+                                       ((unsigned char *) &adrcnt)[2] = atp_readb_io(dev, c, 0x12);
+                                       ((unsigned char *) &adrcnt)[1] = atp_readb_io(dev, c, 0x13);
+                                       ((unsigned char *) &adrcnt)[0] = atp_readb_io(dev, c, 0x14);
                                        k = dev->id[c][target_id].last_len;
                                        k -= adrcnt;
                                        dev->id[c][target_id].tran_len = k;
                                        dev->id[c][target_id].last_len = adrcnt;
-                                       outb(0x08, dev->ioport[c] + 0x18);
+                                       atp_writeb_io(dev, c, 0x18, 0x08);
                                        dev->in_int[c] = 0;
-                                       goto handled;
+                                       return IRQ_HANDLED;
                                } else {
 #ifdef ED_DBGP
                                        printk("cmdp != 0x41\n");
 #endif                                         
-                                       outb(0x46, dev->ioport[c] + 0x10);
+                                       atp_writeb_io(dev, c, 0x10, 0x46);
                                        dev->id[c][target_id].dirct = 0x00;
-                                       outb(0x00, dev->ioport[c] + 0x12);
-                                       outb(0x00, dev->ioport[c] + 0x13);
-                                       outb(0x00, dev->ioport[c] + 0x14);
-                                       outb(0x08, dev->ioport[c] + 0x18);
+                                       atp_writeb_io(dev, c, 0x12, 0x00);
+                                       atp_writeb_io(dev, c, 0x13, 0x00);
+                                       atp_writeb_io(dev, c, 0x14, 0x00);
+                                       atp_writeb_io(dev, c, 0x18, 0x08);
                                        dev->in_int[c] = 0;
-                                       goto handled;
+                                       return IRQ_HANDLED;
                                }
                        }
                        if (dev->last_cmd[c] != 0xff) {
                           dev->last_cmd[c] |= 0x40;
                        }
-                       if (dev->dev_id == ATP885_DEVID) {
-                               j = inb(dev->baseport + 0x29) & 0xfe;
-                               outb(j, dev->baseport + 0x29);
+                       if (is885(dev)) {
+                               j = atp_readb_base(dev, 0x29) & 0xfe;
+                               atp_writeb_base(dev, 0x29, j);
                        } else
-                               outb(0x45, dev->ioport[c] + 0x10);
+                               atp_writeb_io(dev, c, 0x10, 0x45);
 
-                       target_id = inb(dev->ioport[c] + 0x16);
+                       target_id = atp_readb_io(dev, c, 0x16);
                        /*
                         *      Remap wide identifiers
                         */
@@ -270,8 +327,8 @@ stop_dma:
                        } else {
                                target_id &= 0x07;
                        }
-                       if (dev->dev_id == ATP885_DEVID)
-                               outb(0x45, dev->ioport[c] + 0x10);
+                       if (is885(dev))
+                               atp_writeb_io(dev, c, 0x10, 0x45);
                        workreq = dev->id[c][target_id].curr_req;
 #ifdef ED_DBGP                 
                        scmd_printk(KERN_DEBUG, workreq, "CDB");
@@ -280,16 +337,16 @@ stop_dma:
                        printk("\n");
 #endif 
                        
-                       outb(lun, dev->ioport[c] + 0x0f);
-                       outb(dev->id[c][target_id].devsp, dev->ioport[c] + 0x11);
+                       atp_writeb_io(dev, c, 0x0f, lun);
+                       atp_writeb_io(dev, c, 0x11, dev->id[c][target_id].devsp);
                        adrcnt = dev->id[c][target_id].tran_len;
                        k = dev->id[c][target_id].last_len;
 
-                       outb(((unsigned char *) &k)[2], dev->ioport[c] + 0x12);
-                       outb(((unsigned char *) &k)[1], dev->ioport[c] + 0x13);
-                       outb(((unsigned char *) &k)[0], dev->ioport[c] + 0x14);
+                       atp_writeb_io(dev, c, 0x12, ((unsigned char *) &k)[2]);
+                       atp_writeb_io(dev, c, 0x13, ((unsigned char *) &k)[1]);
+                       atp_writeb_io(dev, c, 0x14, ((unsigned char *) &k)[0]);
 #ifdef ED_DBGP                 
-                       printk("k %x, k[0] 0x%x k[1] 0x%x k[2] 0x%x\n", k, inb(dev->ioport[c] + 0x14), inb(dev->ioport[c] + 0x13), inb(dev->ioport[c] + 0x12));
+                       printk("k %x, k[0] 0x%x k[1] 0x%x k[2] 0x%x\n", k, atp_readb_io(dev, c, 0x14), atp_readb_io(dev, c, 0x13), atp_readb_io(dev, c, 0x12));
 #endif                 
                        /* Remap wide */
                        j = target_id;
@@ -298,31 +355,27 @@ stop_dma:
                        }
                        /* Add direction */
                        j |= dev->id[c][target_id].dirct;
-                       outb(j, dev->ioport[c] + 0x15);
-                       outb(0x80, dev->ioport[c] + 0x16);
+                       atp_writeb_io(dev, c, 0x15, j);
+                       atp_writeb_io(dev, c, 0x16, 0x80);
                        
                        /* enable 32 bit fifo transfer */       
-                       if (dev->dev_id == ATP885_DEVID) {
-                               tmpcip = dev->pciport[c] + 1;
-                               i=inb(tmpcip) & 0xf3;
+                       if (is885(dev)) {
+                               i = atp_readb_pci(dev, c, 1) & 0xf3;
                                //j=workreq->cmnd[0];                           
                                if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) {
                                   i |= 0x0c;
                                }
-                               outb(i,tmpcip);                                         
-                       } else if ((dev->dev_id == ATP880_DEVID1) ||
-                                  (dev->dev_id == ATP880_DEVID2) ) {
-                               if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) {
-                                       outb((unsigned char) ((inb(dev->ioport[c] - 0x05) & 0x3f) | 0xc0), dev->ioport[c] - 0x05);///minus 0x05???
-                               } else {
-                                       outb((unsigned char) (inb(dev->ioport[c] - 0x05) & 0x3f), dev->ioport[c] - 0x05);///minus 0x05???
-                               }
+                               atp_writeb_pci(dev, c, 1, i);
+                       } else if (is880(dev)) {
+                               if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a))
+                                       atp_writeb_base(dev, 0x3b, (atp_readb_base(dev, 0x3b) & 0x3f) | 0xc0);
+                               else
+                                       atp_writeb_base(dev, 0x3b, atp_readb_base(dev, 0x3b) & 0x3f);
                        } else {                                
-                               if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) {
-                                       outb((unsigned char) ((inb(dev->ioport[c] + 0x3a) & 0xf3) | 0x08), dev->ioport[c] + 0x3a);
-                               } else {
-                                       outb((unsigned char) (inb(dev->ioport[c] + 0x3a) & 0xf3), dev->ioport[c] + 0x3a);
-                               }                                                                                                               
+                               if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a))
+                                       atp_writeb_base(dev, 0x3a, (atp_readb_base(dev, 0x3a) & 0xf3) | 0x08);
+                               else
+                                       atp_writeb_base(dev, 0x3a, atp_readb_base(dev, 0x3a) & 0xf3);
                        }       
                        j = 0;
                        id = 1;
@@ -333,17 +386,16 @@ stop_dma:
                        if ((id & dev->wide_id[c]) != 0) {
                                j |= 0x01;
                        }
-                       outb(j, dev->ioport[c] + 0x1b);
-                       while ((inb(dev->ioport[c] + 0x1b) & 0x01) != j) {
-                               outb(j,dev->ioport[c] + 0x1b);
-                       }
+                       atp_writeb_io(dev, c, 0x1b, j);
+                       while ((atp_readb_io(dev, c, 0x1b) & 0x01) != j)
+                               atp_writeb_io(dev, c, 0x1b, j);
                        if (dev->id[c][target_id].last_len == 0) {
-                               outb(0x08, dev->ioport[c] + 0x18);
+                               atp_writeb_io(dev, c, 0x18, 0x08);
                                dev->in_int[c] = 0;
 #ifdef ED_DBGP
                                printk("dev->id[c][target_id].last_len = 0\n");
 #endif                                 
-                               goto handled;
+                               return IRQ_HANDLED;
                        }
 #ifdef ED_DBGP
                        printk("target_id = %d adrcnt = %d\n",target_id,adrcnt);
@@ -371,38 +423,33 @@ stop_dma:
                                        }
                                }                               
                        }
-                       tmpcip = dev->pciport[c] + 0x04;
-                       outl(dev->id[c][target_id].prdaddr, tmpcip);
+                       atp_writel_pci(dev, c, 0x04, dev->id[c][target_id].prdaddr);
 #ifdef ED_DBGP
                        printk("dev->id[%d][%d].prdaddr 0x%8x\n", c, target_id, dev->id[c][target_id].prdaddr);
 #endif
-                       if (dev->dev_id == ATP885_DEVID) {
-                               tmpcip -= 0x04;
-                       } else {
-                               tmpcip -= 0x02;
-                               outb(0x06, tmpcip);
-                               outb(0x00, tmpcip);
-                               tmpcip -= 0x02;
+                       if (!is885(dev)) {
+                               atp_writeb_pci(dev, c, 2, 0x06);
+                               atp_writeb_pci(dev, c, 2, 0x00);
                        }
                        /*
                         *      Check transfer direction
                         */
                        if (dev->id[c][target_id].dirct != 0) {
-                               outb(0x08, dev->ioport[c] + 0x18);
-                               outb(0x01, tmpcip);
+                               atp_writeb_io(dev, c, 0x18, 0x08);
+                               atp_writeb_pci(dev, c, 0, 0x01);
                                dev->in_int[c] = 0;
 #ifdef ED_DBGP
                                printk("status 0x80 return dirct != 0\n");
 #endif                         
-                               goto handled;
+                               return IRQ_HANDLED;
                        }
-                       outb(0x08, dev->ioport[c] + 0x18);
-                       outb(0x09, tmpcip);
+                       atp_writeb_io(dev, c, 0x18, 0x08);
+                       atp_writeb_pci(dev, c, 0, 0x09);
                        dev->in_int[c] = 0;
 #ifdef ED_DBGP
                        printk("status 0x80 return dirct = 0\n");
 #endif                 
-                       goto handled;
+                       return IRQ_HANDLED;
                }
 
                /*
@@ -411,30 +458,22 @@ stop_dma:
 
                workreq = dev->id[c][target_id].curr_req;
 
-               if (i == 0x42) {
-                       if ((dev->last_cmd[c] & 0xf0) != 0x40)
-                       {
-                          dev->last_cmd[c] = 0xff;
-                       }
-                       errstus = 0x02;
-                       workreq->result = errstus;
-                       goto go_42;
-               }
-               if (i == 0x16) {
+               if (i == 0x42 || i == 0x16) {
                        if ((dev->last_cmd[c] & 0xf0) != 0x40) {
                           dev->last_cmd[c] = 0xff;
                        }
-                       errstus = 0;
-                       errstus = inb(dev->ioport[c] + 0x0f);
-                       if (((dev->r1f[c][target_id] & 0x10) != 0)&&(dev->dev_id==ATP885_DEVID)) {
-                          printk(KERN_WARNING "AEC67162 CRC ERROR !\n");
-                          errstus = 0x02;
-                       }
-                       workreq->result = errstus;
-go_42:
-                       if (dev->dev_id == ATP885_DEVID) {              
-                               j = inb(dev->baseport + 0x29) | 0x01;
-                               outb(j, dev->baseport + 0x29);
+                       if (i == 0x16) {
+                               workreq->result = atp_readb_io(dev, c, 0x0f);
+                               if (((dev->r1f[c][target_id] & 0x10) != 0) && is885(dev)) {
+                                       printk(KERN_WARNING "AEC67162 CRC ERROR !\n");
+                                       workreq->result = 0x02;
+                               }
+                       } else
+                               workreq->result = 0x02;
+
+                       if (is885(dev)) {
+                               j = atp_readb_base(dev, 0x29) | 0x01;
+                               atp_writeb_base(dev, 0x29, j);
                        }
                        /*
                         *      Complete the command
@@ -456,10 +495,9 @@ go_42:
                         *      Take it back wide
                         */
                        if (dev->wide_id[c] != 0) {
-                               outb(0x01, dev->ioport[c] + 0x1b);
-                               while ((inb(dev->ioport[c] + 0x1b) & 0x01) != 0x01) {
-                                       outb(0x01, dev->ioport[c] + 0x1b);
-                               }       
+                               atp_writeb_io(dev, c, 0x1b, 0x01);
+                               while ((atp_readb_io(dev, c, 0x1b) & 0x01) != 0x01)
+                                       atp_writeb_io(dev, c, 0x1b, 0x01);
                        } 
                        /*
                         *      If there is stuff to send and nothing going then send it
@@ -474,7 +512,7 @@ go_42:
                        }
                        spin_unlock_irqrestore(dev->host->host_lock, flags);
                        dev->in_int[c] = 0;
-                       goto handled;
+                       return IRQ_HANDLED;
                }
                if ((dev->last_cmd[c] & 0xf0) != 0x40) {
                   dev->last_cmd[c] = 0xff;
@@ -484,71 +522,54 @@ go_42:
                }
                i &= 0x0f;
                if (i == 0x09) {
-                       tmpcip += 4;
-                       outl(dev->id[c][target_id].prdaddr, tmpcip);
-                       tmpcip = tmpcip - 2;
-                       outb(0x06, tmpcip);
-                       outb(0x00, tmpcip);
-                       tmpcip = tmpcip - 2;
-                       outb(0x41, dev->ioport[c] + 0x10);
-                       if (dev->dev_id == ATP885_DEVID) {
+                       atp_writel_pci(dev, c, 4, dev->id[c][target_id].prdaddr);
+                       atp_writeb_pci(dev, c, 2, 0x06);
+                       atp_writeb_pci(dev, c, 2, 0x00);
+                       atp_writeb_io(dev, c, 0x10, 0x41);
+                       if (is885(dev)) {
                                k = dev->id[c][target_id].last_len;
-                               outb((unsigned char) (((unsigned char *) (&k))[2]), dev->ioport[c] + 0x12);
-                               outb((unsigned char) (((unsigned char *) (&k))[1]), dev->ioport[c] + 0x13);
-                               outb((unsigned char) (((unsigned char *) (&k))[0]), dev->ioport[c] + 0x14);
+                               atp_writeb_io(dev, c, 0x12, ((unsigned char *) (&k))[2]);
+                               atp_writeb_io(dev, c, 0x13, ((unsigned char *) (&k))[1]);
+                               atp_writeb_io(dev, c, 0x14, ((unsigned char *) (&k))[0]);
                                dev->id[c][target_id].dirct = 0x00;
                        } else {
                                dev->id[c][target_id].dirct = 0x00;
                        }
-                       outb(0x08, dev->ioport[c] + 0x18);
-                       outb(0x09, tmpcip);
+                       atp_writeb_io(dev, c, 0x18, 0x08);
+                       atp_writeb_pci(dev, c, 0, 0x09);
                        dev->in_int[c] = 0;
-                       goto handled;
+                       return IRQ_HANDLED;
                }
                if (i == 0x08) {
-                       tmpcip += 4;
-                       outl(dev->id[c][target_id].prdaddr, tmpcip);
-                       tmpcip = tmpcip - 2;
-                       outb(0x06, tmpcip);
-                       outb(0x00, tmpcip);
-                       tmpcip = tmpcip - 2;
-                       outb(0x41, dev->ioport[c] + 0x10);
-                       if (dev->dev_id == ATP885_DEVID) {              
+                       atp_writel_pci(dev, c, 4, dev->id[c][target_id].prdaddr);
+                       atp_writeb_pci(dev, c, 2, 0x06);
+                       atp_writeb_pci(dev, c, 2, 0x00);
+                       atp_writeb_io(dev, c, 0x10, 0x41);
+                       if (is885(dev)) {
                                k = dev->id[c][target_id].last_len;
-                               outb((unsigned char) (((unsigned char *) (&k))[2]), dev->ioport[c] + 0x12);
-                               outb((unsigned char) (((unsigned char *) (&k))[1]), dev->ioport[c] + 0x13);
-                               outb((unsigned char) (((unsigned char *) (&k))[0]), dev->ioport[c] + 0x14);
+                               atp_writeb_io(dev, c, 0x12, ((unsigned char *) (&k))[2]);
+                               atp_writeb_io(dev, c, 0x13, ((unsigned char *) (&k))[1]);
+                               atp_writeb_io(dev, c, 0x14, ((unsigned char *) (&k))[0]);
                        }
-                       outb((unsigned char) (inb(dev->ioport[c] + 0x15) | 0x20), dev->ioport[c] + 0x15);
+                       atp_writeb_io(dev, c, 0x15, atp_readb_io(dev, c, 0x15) | 0x20);
                        dev->id[c][target_id].dirct = 0x20;
-                       outb(0x08, dev->ioport[c] + 0x18);
-                       outb(0x01, tmpcip);
+                       atp_writeb_io(dev, c, 0x18, 0x08);
+                       atp_writeb_pci(dev, c, 0, 0x01);
                        dev->in_int[c] = 0;
-                       goto handled;
-               }
-               if (i == 0x0a) {
-                       outb(0x30, dev->ioport[c] + 0x10);
-               } else {
-                       outb(0x46, dev->ioport[c] + 0x10);
+                       return IRQ_HANDLED;
                }
+               if (i == 0x0a)
+                       atp_writeb_io(dev, c, 0x10, 0x30);
+               else
+                       atp_writeb_io(dev, c, 0x10, 0x46);
                dev->id[c][target_id].dirct = 0x00;
-               outb(0x00, dev->ioport[c] + 0x12);
-               outb(0x00, dev->ioport[c] + 0x13);
-               outb(0x00, dev->ioport[c] + 0x14);
-               outb(0x08, dev->ioport[c] + 0x18);
-               dev->in_int[c] = 0;
-               goto handled;
-       } else {
-//             inb(dev->ioport[c] + 0x17);
-//             dev->working[c] = 0;
-               dev->in_int[c] = 0;
-               goto handled;
+               atp_writeb_io(dev, c, 0x12, 0x00);
+               atp_writeb_io(dev, c, 0x13, 0x00);
+               atp_writeb_io(dev, c, 0x14, 0x00);
+               atp_writeb_io(dev, c, 0x18, 0x08);
        }
-       
-handled:
-#ifdef ED_DBGP
-       printk("atp870u_intr_handle exit\n");
-#endif                 
+       dev->in_int[c] = 0;
+
        return IRQ_HANDLED;
 }
 /**
@@ -632,9 +653,9 @@ static int atp870u_queuecommand_lck(struct scsi_cmnd *req_p,
        }
        dev->quereq[c][dev->quend[c]] = req_p;
 #ifdef ED_DBGP 
-       printk("dev->ioport[c] = %x inb(dev->ioport[c] + 0x1c) = %x dev->in_int[%d] = %d dev->in_snd[%d] = %d\n",dev->ioport[c],inb(dev->ioport[c] + 0x1c),c,dev->in_int[c],c,dev->in_snd[c]);
+       printk("dev->ioport[c] = %x atp_readb_io(dev, c, 0x1c) = %x dev->in_int[%d] = %d dev->in_snd[%d] = %d\n",dev->ioport[c],atp_readb_io(dev, c, 0x1c),c,dev->in_int[c],c,dev->in_snd[c]);
 #endif
-       if ((inb(dev->ioport[c] + 0x1c) == 0) && (dev->in_int[c] == 0) && (dev->in_snd[c] == 0)) {
+       if ((atp_readb_io(dev, c, 0x1c) == 0) && (dev->in_int[c] == 0) && (dev->in_snd[c] == 0)) {
 #ifdef ED_DBGP
                printk("Call sent_s870(atp870u_queuecommand)\n");
 #endif         
@@ -659,11 +680,11 @@ static DEF_SCSI_QCMD(atp870u_queuecommand)
  */
 static void send_s870(struct atp_unit *dev,unsigned char c)
 {
-       struct scsi_cmnd *workreq;
+       struct scsi_cmnd *workreq = NULL;
        unsigned int i;//,k;
        unsigned char  j, target_id;
        unsigned char *prd;
-       unsigned short int tmpcip, w;
+       unsigned short int w;
        unsigned long l, bttl = 0;
        unsigned long  sg_count;
 
@@ -680,50 +701,42 @@ static void send_s870(struct atp_unit *dev,unsigned char c)
        if ((dev->last_cmd[c] != 0xff) && ((dev->last_cmd[c] & 0x40) != 0)) {
                dev->last_cmd[c] &= 0x0f;
                workreq = dev->id[c][dev->last_cmd[c]].curr_req;
-               if (workreq != NULL) {  /* check NULL pointer */
-                  goto cmd_subp;
-               }
-               dev->last_cmd[c] = 0xff;        
-               if (dev->quhd[c] == dev->quend[c]) {
-                       dev->in_snd[c] = 0;
-                       return ;
+               if (!workreq) {
+                       dev->last_cmd[c] = 0xff;
+                       if (dev->quhd[c] == dev->quend[c]) {
+                               dev->in_snd[c] = 0;
+                               return;
+                       }
                }
        }
-       if ((dev->last_cmd[c] != 0xff) && (dev->working[c] != 0)) {
-               dev->in_snd[c] = 0;
-               return ;
-       }
-       dev->working[c]++;
-       j = dev->quhd[c];
-       dev->quhd[c]++;
-       if (dev->quhd[c] >= qcnt) {
-               dev->quhd[c] = 0;
-       }
-       workreq = dev->quereq[c][dev->quhd[c]];
-       if (dev->id[c][scmd_id(workreq)].curr_req == NULL) {
+       if (!workreq) {
+               if ((dev->last_cmd[c] != 0xff) && (dev->working[c] != 0)) {
+                       dev->in_snd[c] = 0;
+                       return;
+               }
+               dev->working[c]++;
+               j = dev->quhd[c];
+               dev->quhd[c]++;
+               if (dev->quhd[c] >= qcnt)
+                       dev->quhd[c] = 0;
+               workreq = dev->quereq[c][dev->quhd[c]];
+               if (dev->id[c][scmd_id(workreq)].curr_req != NULL) {
+                       dev->quhd[c] = j;
+                       dev->working[c]--;
+                       dev->in_snd[c] = 0;
+                       return;
+               }
                dev->id[c][scmd_id(workreq)].curr_req = workreq;
                dev->last_cmd[c] = scmd_id(workreq);
-               goto cmd_subp;
-       }       
-       dev->quhd[c] = j;
-       dev->working[c]--;
-       dev->in_snd[c] = 0;
-       return;
-cmd_subp:
-       if ((inb(dev->ioport[c] + 0x1f) & 0xb0) != 0) {
-               goto abortsnd;
        }
-       if (inb(dev->ioport[c] + 0x1c) == 0) {
-               goto oktosend;
-       }
-abortsnd:
+       if ((atp_readb_io(dev, c, 0x1f) & 0xb0) != 0 || atp_readb_io(dev, c, 0x1c) != 0) {
 #ifdef ED_DBGP
-       printk("Abort to Send\n");
+               printk("Abort to Send\n");
 #endif
-       dev->last_cmd[c] |= 0x40;
-       dev->in_snd[c] = 0;
-       return;
-oktosend:
+               dev->last_cmd[c] |= 0x40;
+               dev->in_snd[c] = 0;
+               return;
+       }
 #ifdef ED_DBGP
        printk("OK to Send\n");
        scmd_printk(KERN_DEBUG, workreq, "CDB");
@@ -734,9 +747,9 @@ oktosend:
 #endif 
        l = scsi_bufflen(workreq);
 
-       if (dev->dev_id == ATP885_DEVID) {
-               j = inb(dev->baseport + 0x29) & 0xfe;
-               outb(j, dev->baseport + 0x29);
+       if (is885(dev)) {
+               j = atp_readb_base(dev, 0x29) & 0xfe;
+               atp_writeb_base(dev, 0x29, j);
                dev->r1f[c][scmd_id(workreq)] = 0;
        }
        
@@ -759,9 +772,9 @@ oktosend:
        if ((w & dev->wide_id[c]) != 0) {
                j |= 0x01;
        }
-       outb(j, dev->ioport[c] + 0x1b);
-       while ((inb(dev->ioport[c] + 0x1b) & 0x01) != j) {
-               outb(j,dev->ioport[c] + 0x1b);
+       atp_writeb_io(dev, c, 0x1b, j);
+       while ((atp_readb_io(dev, c, 0x1b) & 0x01) != j) {
+               atp_writeb_pci(dev, c, 0x1b, j);
 #ifdef ED_DBGP
                printk("send_s870 while loop 1\n");
 #endif
@@ -770,21 +783,19 @@ oktosend:
         *      Write the command
         */
 
-       outb(workreq->cmd_len, dev->ioport[c] + 0x00);
-       outb(0x2c, dev->ioport[c] + 0x01);
-       if (dev->dev_id == ATP885_DEVID) {
-               outb(0x7f, dev->ioport[c] + 0x02);
-       } else {
-               outb(0xcf, dev->ioport[c] + 0x02);
-       }       
-       for (i = 0; i < workreq->cmd_len; i++) {
-               outb(workreq->cmnd[i], dev->ioport[c] + 0x03 + i);
-       }
-       outb(workreq->device->lun, dev->ioport[c] + 0x0f);
+       atp_writeb_io(dev, c, 0x00, workreq->cmd_len);
+       atp_writeb_io(dev, c, 0x01, 0x2c);
+       if (is885(dev))
+               atp_writeb_io(dev, c, 0x02, 0x7f);
+       else
+               atp_writeb_io(dev, c, 0x02, 0xcf);
+       for (i = 0; i < workreq->cmd_len; i++)
+               atp_writeb_io(dev, c, 0x03 + i, workreq->cmnd[i]);
+       atp_writeb_io(dev, c, 0x0f, workreq->device->lun);
        /*
         *      Write the target
         */
-       outb(dev->id[c][target_id].devsp, dev->ioport[c] + 0x11);
+       atp_writeb_io(dev, c, 0x11, dev->id[c][target_id].devsp);
 #ifdef ED_DBGP 
        printk("dev->id[%d][%d].devsp = %2x\n",c,target_id,dev->id[c][target_id].devsp);
 #endif
@@ -793,9 +804,9 @@ oktosend:
        /*
         *      Write transfer size
         */
-       outb((unsigned char) (((unsigned char *) (&l))[2]), dev->ioport[c] + 0x12);
-       outb((unsigned char) (((unsigned char *) (&l))[1]), dev->ioport[c] + 0x13);
-       outb((unsigned char) (((unsigned char *) (&l))[0]), dev->ioport[c] + 0x14);
+       atp_writeb_io(dev, c, 0x12, ((unsigned char *) (&l))[2]);
+       atp_writeb_io(dev, c, 0x13, ((unsigned char *) (&l))[1]);
+       atp_writeb_io(dev, c, 0x14, ((unsigned char *) (&l))[0]);
        j = target_id;  
        dev->id[c][j].last_len = l;
        dev->id[c][j].tran_len = 0;
@@ -811,27 +822,24 @@ oktosend:
        /*
         *      Check transfer direction
         */
-       if (workreq->sc_data_direction == DMA_TO_DEVICE) {
-               outb((unsigned char) (j | 0x20), dev->ioport[c] + 0x15);
-       } else {
-               outb(j, dev->ioport[c] + 0x15);
-       }
-       outb((unsigned char) (inb(dev->ioport[c] + 0x16) | 0x80), dev->ioport[c] + 0x16);
-       outb(0x80, dev->ioport[c] + 0x16);
+       if (workreq->sc_data_direction == DMA_TO_DEVICE)
+               atp_writeb_io(dev, c, 0x15, j | 0x20);
+       else
+               atp_writeb_io(dev, c, 0x15, j);
+       atp_writeb_io(dev, c, 0x16, atp_readb_io(dev, c, 0x16) | 0x80);
+       atp_writeb_io(dev, c, 0x16, 0x80);
        dev->id[c][target_id].dirct = 0;
        if (l == 0) {
-               if (inb(dev->ioport[c] + 0x1c) == 0) {
+               if (atp_readb_io(dev, c, 0x1c) == 0) {
 #ifdef ED_DBGP
                        printk("change SCSI_CMD_REG 0x08\n");   
 #endif                         
-                       outb(0x08, dev->ioport[c] + 0x18);
-               } else {
+                       atp_writeb_io(dev, c, 0x18, 0x08);
+               } else
                        dev->last_cmd[c] |= 0x40;
-               }
                dev->in_snd[c] = 0;
                return;
        }
-       tmpcip = dev->pciport[c];
        prd = dev->id[c][target_id].prd_table;
        dev->id[c][target_id].prd_pos = prd;
 
@@ -868,46 +876,37 @@ oktosend:
                printk("2. bttl %x, l %x\n",bttl, l);
 #endif                 
        }
-       tmpcip += 4;
 #ifdef ED_DBGP         
-       printk("send_s870: prdaddr_2 0x%8x tmpcip %x target_id %d\n", dev->id[c][target_id].prdaddr,tmpcip,target_id);
+       printk("send_s870: prdaddr_2 0x%8x target_id %d\n", dev->id[c][target_id].prdaddr,target_id);
 #endif 
        dev->id[c][target_id].prdaddr = dev->id[c][target_id].prd_bus;
-       outl(dev->id[c][target_id].prdaddr, tmpcip);
-       tmpcip = tmpcip - 2;
-       outb(0x06, tmpcip);
-       outb(0x00, tmpcip);
-       if (dev->dev_id == ATP885_DEVID) {
-               tmpcip--;
-               j=inb(tmpcip) & 0xf3;
+       atp_writel_pci(dev, c, 4, dev->id[c][target_id].prdaddr);
+       atp_writeb_pci(dev, c, 2, 0x06);
+       atp_writeb_pci(dev, c, 2, 0x00);
+       if (is885(dev)) {
+               j = atp_readb_pci(dev, c, 1) & 0xf3;
                if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) ||
                (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) {
                        j |= 0x0c;
                }
-               outb(j,tmpcip);
-               tmpcip--;               
-       } else if ((dev->dev_id == ATP880_DEVID1) ||
-                  (dev->dev_id == ATP880_DEVID2)) {
-               tmpcip =tmpcip -2;      
-               if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) {
-                       outb((unsigned char) ((inb(dev->ioport[c] - 0x05) & 0x3f) | 0xc0), dev->ioport[c] - 0x05);
-               } else {
-                       outb((unsigned char) (inb(dev->ioport[c] - 0x05) & 0x3f), dev->ioport[c] - 0x05);
-               }               
+               atp_writeb_pci(dev, c, 1, j);
+       } else if (is880(dev)) {
+               if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a))
+                       atp_writeb_base(dev, 0x3b, (atp_readb_base(dev, 0x3b) & 0x3f) | 0xc0);
+               else
+                       atp_writeb_base(dev, 0x3b, atp_readb_base(dev, 0x3b) & 0x3f);
        } else {                
-               tmpcip =tmpcip -2;
-               if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) {
-                       outb((inb(dev->ioport[c] + 0x3a) & 0xf3) | 0x08, dev->ioport[c] + 0x3a);
-               } else {
-                       outb(inb(dev->ioport[c] + 0x3a) & 0xf3, dev->ioport[c] + 0x3a);
-               }               
+               if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a))
+                       atp_writeb_base(dev, 0x3a, (atp_readb_base(dev, 0x3a) & 0xf3) | 0x08);
+               else
+                       atp_writeb_base(dev, 0x3a, atp_readb_base(dev, 0x3a) & 0xf3);
        }       
 
        if(workreq->sc_data_direction == DMA_TO_DEVICE) {
                dev->id[c][target_id].dirct = 0x20;
-               if (inb(dev->ioport[c] + 0x1c) == 0) {
-                       outb(0x08, dev->ioport[c] + 0x18);
-                       outb(0x01, tmpcip);
+               if (atp_readb_io(dev, c, 0x1c) == 0) {
+                       atp_writeb_io(dev, c, 0x18, 0x08);
+                       atp_writeb_pci(dev, c, 0, 0x01);
 #ifdef ED_DBGP         
                printk( "start DMA(to target)\n");
 #endif                         
@@ -917,9 +916,9 @@ oktosend:
                dev->in_snd[c] = 0;
                return;
        }
-       if (inb(dev->ioport[c] + 0x1c) == 0) {
-               outb(0x08, dev->ioport[c] + 0x18);
-               outb(0x09, tmpcip);
+       if (atp_readb_io(dev, c, 0x1c) == 0) {
+               atp_writeb_io(dev, c, 0x18, 0x08);
+               atp_writeb_pci(dev, c, 0, 0x09);
 #ifdef ED_DBGP         
                printk( "start DMA(to host)\n");
 #endif                 
@@ -936,41 +935,35 @@ static unsigned char fun_scam(struct atp_unit *dev, unsigned short int *val)
        unsigned short int i, k;
        unsigned char j;
 
-       outw(*val, dev->ioport[0] + 0x1c);
-FUN_D7:
+       atp_writew_io(dev, 0, 0x1c, *val);
        for (i = 0; i < 10; i++) {      /* stable >= bus settle delay(400 ns)  */
-               k = inw(dev->ioport[0] + 0x1c);
+               k = atp_readw_io(dev, 0, 0x1c);
                j = (unsigned char) (k >> 8);
-               if ((k & 0x8000) != 0) {        /* DB7 all release?    */
-                       goto FUN_D7;
-               }
+               if ((k & 0x8000) != 0)  /* DB7 all release?    */
+                       i = 0;
        }
        *val |= 0x4000;         /* assert DB6           */
-       outw(*val, dev->ioport[0] + 0x1c);
+       atp_writew_io(dev, 0, 0x1c, *val);
        *val &= 0xdfff;         /* assert DB5           */
-       outw(*val, dev->ioport[0] + 0x1c);
-FUN_D5:
+       atp_writew_io(dev, 0, 0x1c, *val);
        for (i = 0; i < 10; i++) {      /* stable >= bus settle delay(400 ns) */
-               if ((inw(dev->ioport[0] + 0x1c) & 0x2000) != 0) {       /* DB5 all release?       */
-                       goto FUN_D5;
-               }
+               if ((atp_readw_io(dev, 0, 0x1c) & 0x2000) != 0) /* DB5 all release?       */
+                       i = 0;
        }
        *val |= 0x8000;         /* no DB4-0, assert DB7    */
        *val &= 0xe0ff;
-       outw(*val, dev->ioport[0] + 0x1c);
+       atp_writew_io(dev, 0, 0x1c, *val);
        *val &= 0xbfff;         /* release DB6             */
-       outw(*val, dev->ioport[0] + 0x1c);
-FUN_D6:
+       atp_writew_io(dev, 0, 0x1c, *val);
        for (i = 0; i < 10; i++) {      /* stable >= bus settle delay(400 ns)  */
-               if ((inw(dev->ioport[0] + 0x1c) & 0x4000) != 0) {       /* DB6 all release?  */
-                       goto FUN_D6;
-               }
+               if ((atp_readw_io(dev, 0, 0x1c) & 0x4000) != 0) /* DB6 all release?  */
+                       i = 0;
        }
 
        return j;
 }
 
-static void tscam(struct Scsi_Host *host)
+static void tscam(struct Scsi_Host *host, bool wide_chip, u8 scam_on)
 {
 
        unsigned char i, j, k;
@@ -989,28 +982,28 @@ static void tscam(struct Scsi_Host *host)
        }
  */
 
-       outb(0x08, dev->ioport[0] + 1);
-       outb(0x7f, dev->ioport[0] + 2);
-       outb(0x20, dev->ioport[0] + 0x11);
+       atp_writeb_io(dev, 0, 1, 0x08);
+       atp_writeb_io(dev, 0, 2, 0x7f);
+       atp_writeb_io(dev, 0, 0x11, 0x20);
 
-       if ((dev->scam_on & 0x40) == 0) {
+       if ((scam_on & 0x40) == 0) {
                return;
        }
        m = 1;
        m <<= dev->host_id[0];
        j = 16;
-       if (dev->chip_ver < 4) {
+       if (!wide_chip) {
                m |= 0xff00;
                j = 8;
        }
        assignid_map = m;
-       outb(0x02, dev->ioport[0] + 0x02);      /* 2*2=4ms,3EH 2/32*3E=3.9ms */
-       outb(0, dev->ioport[0] + 0x03);
-       outb(0, dev->ioport[0] + 0x04);
-       outb(0, dev->ioport[0] + 0x05);
-       outb(0, dev->ioport[0] + 0x06);
-       outb(0, dev->ioport[0] + 0x07);
-       outb(0, dev->ioport[0] + 0x08);
+       atp_writeb_io(dev, 0, 0x02, 0x02);      /* 2*2=4ms,3EH 2/32*3E=3.9ms */
+       atp_writeb_io(dev, 0, 0x03, 0);
+       atp_writeb_io(dev, 0, 0x04, 0);
+       atp_writeb_io(dev, 0, 0x05, 0);
+       atp_writeb_io(dev, 0, 0x06, 0);
+       atp_writeb_io(dev, 0, 0x07, 0);
+       atp_writeb_io(dev, 0, 0x08, 0);
 
        for (i = 0; i < j; i++) {
                m = 1;
@@ -1018,82 +1011,73 @@ static void tscam(struct Scsi_Host *host)
                if ((m & assignid_map) != 0) {
                        continue;
                }
-               outb(0, dev->ioport[0] + 0x0f);
-               outb(0, dev->ioport[0] + 0x12);
-               outb(0, dev->ioport[0] + 0x13);
-               outb(0, dev->ioport[0] + 0x14);
+               atp_writeb_io(dev, 0, 0x0f, 0);
+               atp_writeb_io(dev, 0, 0x12, 0);
+               atp_writeb_io(dev, 0, 0x13, 0);
+               atp_writeb_io(dev, 0, 0x14, 0);
                if (i > 7) {
                        k = (i & 0x07) | 0x40;
                } else {
                        k = i;
                }
-               outb(k, dev->ioport[0] + 0x15);
-               if (dev->chip_ver == 4) {
-                       outb(0x01, dev->ioport[0] + 0x1b);
-               } else {
-                       outb(0x00, dev->ioport[0] + 0x1b);
-               }
-wait_rdyok:
-               outb(0x09, dev->ioport[0] + 0x18);
-
-               while ((inb(dev->ioport[0] + 0x1f) & 0x80) == 0x00)
-                       cpu_relax();
-               k = inb(dev->ioport[0] + 0x17);
-               if (k != 0x16) {
-                       if ((k == 0x85) || (k == 0x42)) {
-                               continue;
-                       }
-                       outb(0x41, dev->ioport[0] + 0x10);
-                       goto wait_rdyok;
-               }
+               atp_writeb_io(dev, 0, 0x15, k);
+               if (wide_chip)
+                       atp_writeb_io(dev, 0, 0x1b, 0x01);
+               else
+                       atp_writeb_io(dev, 0, 0x1b, 0x00);
+               do {
+                       atp_writeb_io(dev, 0, 0x18, 0x09);
+
+                       while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0x00)
+                               cpu_relax();
+                       k = atp_readb_io(dev, 0, 0x17);
+                       if ((k == 0x85) || (k == 0x42))
+                               break;
+                       if (k != 0x16)
+                               atp_writeb_io(dev, 0, 0x10, 0x41);
+               } while (k != 0x16);
+               if ((k == 0x85) || (k == 0x42))
+                       continue;
                assignid_map |= m;
 
        }
-       outb(0x7f, dev->ioport[0] + 0x02);
-       outb(0x02, dev->ioport[0] + 0x1b);
+       atp_writeb_io(dev, 0, 0x02, 0x7f);
+       atp_writeb_io(dev, 0, 0x1b, 0x02);
 
-       outb(0, 0x80);
+       udelay(2);
 
        val = 0x0080;           /* bsy  */
-       outw(val, dev->ioport[0] + 0x1c);
+       atp_writew_io(dev, 0, 0x1c, val);
        val |= 0x0040;          /* sel  */
-       outw(val, dev->ioport[0] + 0x1c);
+       atp_writew_io(dev, 0, 0x1c, val);
        val |= 0x0004;          /* msg  */
-       outw(val, dev->ioport[0] + 0x1c);
-       inb(0x80);              /* 2 deskew delay(45ns*2=90ns) */
+       atp_writew_io(dev, 0, 0x1c, val);
+       udelay(2);              /* 2 deskew delay(45ns*2=90ns) */
        val &= 0x007f;          /* no bsy  */
-       outw(val, dev->ioport[0] + 0x1c);
+       atp_writew_io(dev, 0, 0x1c, val);
        mdelay(128);
        val &= 0x00fb;          /* after 1ms no msg */
-       outw(val, dev->ioport[0] + 0x1c);
-wait_nomsg:
-       if ((inb(dev->ioport[0] + 0x1c) & 0x04) != 0) {
-               goto wait_nomsg;
-       }
-       outb(1, 0x80);
+       atp_writew_io(dev, 0, 0x1c, val);
+       while ((atp_readb_io(dev, 0, 0x1c) & 0x04) != 0)
+               ;
+       udelay(2);
        udelay(100);
-       for (n = 0; n < 0x30000; n++) {
-               if ((inb(dev->ioport[0] + 0x1c) & 0x80) != 0) { /* bsy ? */
-                       goto wait_io;
-               }
-       }
-       goto TCM_SYNC;
-wait_io:
-       for (n = 0; n < 0x30000; n++) {
-               if ((inb(dev->ioport[0] + 0x1c) & 0x81) == 0x0081) {
-                       goto wait_io1;
-               }
-       }
-       goto TCM_SYNC;
-wait_io1:
-       inb(0x80);
-       val |= 0x8003;          /* io,cd,db7  */
-       outw(val, dev->ioport[0] + 0x1c);
-       inb(0x80);
-       val &= 0x00bf;          /* no sel     */
-       outw(val, dev->ioport[0] + 0x1c);
-       outb(2, 0x80);
-TCM_SYNC:
+       for (n = 0; n < 0x30000; n++)
+               if ((atp_readb_io(dev, 0, 0x1c) & 0x80) != 0)   /* bsy ? */
+                       break;
+       if (n < 0x30000)
+               for (n = 0; n < 0x30000; n++)
+                       if ((atp_readb_io(dev, 0, 0x1c) & 0x81) == 0x0081) {
+                               udelay(2);
+                               val |= 0x8003;          /* io,cd,db7  */
+                               atp_writew_io(dev, 0, 0x1c, val);
+                               udelay(2);
+                               val &= 0x00bf;          /* no sel     */
+                               atp_writew_io(dev, 0, 0x1c, val);
+                               udelay(2);
+                               break;
+                       }
+       while (1) {
        /*
         * The funny division into multiple delays is to accomodate
         * arches like ARM where udelay() multiplies its argument by
@@ -1104,51 +1088,48 @@ TCM_SYNC:
         */
        mdelay(2);
        udelay(48);
-       if ((inb(dev->ioport[0] + 0x1c) & 0x80) == 0x00) {      /* bsy ? */
-               outw(0, dev->ioport[0] + 0x1c);
-               outb(0, dev->ioport[0] + 0x1b);
-               outb(0, dev->ioport[0] + 0x15);
-               outb(0x09, dev->ioport[0] + 0x18);
-               while ((inb(dev->ioport[0] + 0x1f) & 0x80) == 0)
+       if ((atp_readb_io(dev, 0, 0x1c) & 0x80) == 0x00) {      /* bsy ? */
+               atp_writew_io(dev, 0, 0x1c, 0);
+               atp_writeb_io(dev, 0, 0x1b, 0);
+               atp_writeb_io(dev, 0, 0x15, 0);
+               atp_writeb_io(dev, 0, 0x18, 0x09);
+               while ((atp_readb_io(dev, 0, 0x1f) & 0x80) == 0)
                        cpu_relax();
-               inb(dev->ioport[0] + 0x17);
+               atp_readb_io(dev, 0, 0x17);
                return;
        }
        val &= 0x00ff;          /* synchronization  */
        val |= 0x3f00;
        fun_scam(dev, &val);
-       outb(3, 0x80);
+       udelay(2);
        val &= 0x00ff;          /* isolation        */
        val |= 0x2000;
        fun_scam(dev, &val);
-       outb(4, 0x80);
+       udelay(2);
        i = 8;
        j = 0;
-TCM_ID:
-       if ((inw(dev->ioport[0] + 0x1c) & 0x2000) == 0) {
-               goto TCM_ID;
-       }
-       outb(5, 0x80);
-       val &= 0x00ff;          /* get ID_STRING */
-       val |= 0x2000;
-       k = fun_scam(dev, &val);
-       if ((k & 0x03) == 0) {
-               goto TCM_5;
-       }
-       mbuf[j] <<= 0x01;
-       mbuf[j] &= 0xfe;
-       if ((k & 0x02) != 0) {
-               mbuf[j] |= 0x01;
-       }
-       i--;
-       if (i > 0) {
-               goto TCM_ID;
+
+       while (1) {
+               if ((atp_readw_io(dev, 0, 0x1c) & 0x2000) == 0)
+                       continue;
+               udelay(2);
+               val &= 0x00ff;          /* get ID_STRING */
+               val |= 0x2000;
+               k = fun_scam(dev, &val);
+               if ((k & 0x03) == 0)
+                       break;
+               mbuf[j] <<= 0x01;
+               mbuf[j] &= 0xfe;
+               if ((k & 0x02) != 0)
+                       mbuf[j] |= 0x01;
+               i--;
+               if (i > 0)
+                       continue;
+               j++;
+               i = 8;
        }
-       j++;
-       i = 8;
-       goto TCM_ID;
 
-TCM_5:                 /* isolation complete..  */
+       /* isolation complete..  */
 /*    mbuf[32]=0;
        printk(" \n%x %x %x %s\n ",assignid_map,mbuf[0],mbuf[1],&mbuf[2]); */
        i = 15;
@@ -1156,33 +1137,33 @@ TCM_5:                  /* isolation complete..  */
        if ((j & 0x20) != 0) {  /* bit5=1:ID up to 7      */
                i = 7;
        }
-       if ((j & 0x06) == 0) {  /* IDvalid?             */
-               goto G2Q5;
-       }
-       k = mbuf[1];
-small_id:
-       m = 1;
-       m <<= k;
-       if ((m & assignid_map) == 0) {
-               goto G2Q_QUIN;
-       }
-       if (k > 0) {
-               k--;
-               goto small_id;
-       }
-G2Q5:                  /* srch from max acceptable ID#  */
-       k = i;                  /* max acceptable ID#            */
-G2Q_LP:
-       m = 1;
-       m <<= k;
-       if ((m & assignid_map) == 0) {
-               goto G2Q_QUIN;
+       if ((j & 0x06) != 0) {  /* IDvalid?             */
+               k = mbuf[1];
+               while (1) {
+                       m = 1;
+                       m <<= k;
+                       if ((m & assignid_map) == 0)
+                               break;
+                       if (k > 0)
+                               k--;
+                       else
+                               break;
+               }
        }
-       if (k > 0) {
-               k--;
-               goto G2Q_LP;
+       if ((m & assignid_map) != 0) {  /* srch from max acceptable ID#  */
+               k = i;                  /* max acceptable ID#            */
+               while (1) {
+                       m = 1;
+                       m <<= k;
+                       if ((m & assignid_map) == 0)
+                               break;
+                       if (k > 0)
+                               k--;
+                       else
+                               break;
+               }
        }
-G2Q_QUIN:              /* k=binID#,       */
+       /* k=binID#,       */
        assignid_map |= m;
        if (k < 8) {
                quintet[0] = 0x38;      /* 1st dft ID<8    */
@@ -1201,1511 +1182,400 @@ G2Q_QUIN:            /* k=binID#,       */
        val |= m;
        fun_scam(dev, &val);
 
-       goto TCM_SYNC;
+       }
+}
 
+static void atp870u_free_tables(struct Scsi_Host *host)
+{
+       struct atp_unit *atp_dev = (struct atp_unit *)&host->hostdata;
+       int j, k;
+       for (j=0; j < 2; j++) {
+               for (k = 0; k < 16; k++) {
+                       if (!atp_dev->id[j][k].prd_table)
+                               continue;
+                       pci_free_consistent(atp_dev->pdev, 1024, atp_dev->id[j][k].prd_table, atp_dev->id[j][k].prd_bus);
+                       atp_dev->id[j][k].prd_table = NULL;
+               }
+       }
 }
 
-static void is870(struct atp_unit *dev, unsigned int wkport)
+static int atp870u_init_tables(struct Scsi_Host *host)
 {
-       unsigned char i, j, k, rmb, n;
-       unsigned short int m;
-       static unsigned char mbuf[512];
-       static unsigned char satn[9] = { 0, 0, 0, 0, 0, 0, 0, 6, 6 };
-       static unsigned char inqd[9] = { 0x12, 0, 0, 0, 0x24, 0, 0, 0x24, 6 };
-       static unsigned char synn[6] = { 0x80, 1, 3, 1, 0x19, 0x0e };
-       static unsigned char synu[6] = { 0x80, 1, 3, 1, 0x0c, 0x0e };
-       static unsigned char synw[6] = { 0x80, 1, 3, 1, 0x0c, 0x07 };
-       static unsigned char wide[6] = { 0x80, 1, 2, 3, 1, 0 };
-       
-       outb((unsigned char) (inb(wkport + 0x3a) | 0x10), wkport + 0x3a);
+       struct atp_unit *atp_dev = (struct atp_unit *)&host->hostdata;
+       int c,k;
+       for(c=0;c < 2;c++) {
+               for(k=0;k<16;k++) {
+                               atp_dev->id[c][k].prd_table = pci_alloc_consistent(atp_dev->pdev, 1024, &(atp_dev->id[c][k].prd_bus));
+                               if (!atp_dev->id[c][k].prd_table) {
+                                       printk("atp870u_init_tables fail\n");
+                               atp870u_free_tables(host);
+                               return -ENOMEM;
+                       }
+                       atp_dev->id[c][k].prdaddr = atp_dev->id[c][k].prd_bus;
+                       atp_dev->id[c][k].devsp=0x20;
+                       atp_dev->id[c][k].devtype = 0x7f;
+                       atp_dev->id[c][k].curr_req = NULL;                         
+               }
+                               
+               atp_dev->active_id[c] = 0;
+               atp_dev->wide_id[c] = 0;
+               atp_dev->host_id[c] = 0x07;
+               atp_dev->quhd[c] = 0;
+               atp_dev->quend[c] = 0;
+               atp_dev->last_cmd[c] = 0xff;
+               atp_dev->in_snd[c] = 0;
+               atp_dev->in_int[c] = 0;
+               
+               for (k = 0; k < qcnt; k++) {
+                         atp_dev->quereq[c][k] = NULL;
+               }                          
+               for (k = 0; k < 16; k++) {
+                          atp_dev->id[c][k].curr_req = NULL;
+                          atp_dev->sp[c][k] = 0x04;
+               }                  
+       }
+       return 0;
+}
 
-       for (i = 0; i < 16; i++) {
-               if ((dev->chip_ver != 4) && (i > 7)) {
+static void atp_set_host_id(struct atp_unit *atp, u8 c, u8 host_id)
+{
+       atp_writeb_io(atp, c, 0, host_id | 0x08);
+       atp_writeb_io(atp, c, 0x18, 0);
+       while ((atp_readb_io(atp, c, 0x1f) & 0x80) == 0)
+               mdelay(1);
+       atp_readb_io(atp, c, 0x17);
+       atp_writeb_io(atp, c, 1, 8);
+       atp_writeb_io(atp, c, 2, 0x7f);
+       atp_writeb_io(atp, c, 0x11, 0x20);
+}
+
+static void atp870_init(struct Scsi_Host *shpnt)
+{
+       struct atp_unit *atpdev = shost_priv(shpnt);
+       struct pci_dev *pdev = atpdev->pdev;
+       unsigned char k, host_id;
+       u8 scam_on;
+       bool wide_chip =
+               (pdev->device == PCI_DEVICE_ID_ARTOP_AEC7610 &&
+                pdev->revision == 4) ||
+               (pdev->device == PCI_DEVICE_ID_ARTOP_AEC7612UW) ||
+               (pdev->device == PCI_DEVICE_ID_ARTOP_AEC7612SUW);
+
+       pci_read_config_byte(pdev, 0x49, &host_id);
+
+       dev_info(&pdev->dev, "ACARD AEC-671X PCI Ultra/W SCSI-2/3 Host Adapter: IO:%lx, IRQ:%d.\n",
+                shpnt->io_port, shpnt->irq);
+
+       atpdev->ioport[0] = shpnt->io_port;
+       atpdev->pciport[0] = shpnt->io_port + 0x20;
+       host_id &= 0x07;
+       atpdev->host_id[0] = host_id;
+       scam_on = atp_readb_pci(atpdev, 0, 2);
+       atpdev->global_map[0] = atp_readb_base(atpdev, 0x2d);
+       atpdev->ultra_map[0] = atp_readw_base(atpdev, 0x2e);
+
+       if (atpdev->ultra_map[0] == 0) {
+               scam_on = 0x00;
+               atpdev->global_map[0] = 0x20;
+               atpdev->ultra_map[0] = 0xffff;
+       }
+
+       if (pdev->revision > 0x07)      /* check if atp876 chip */
+               atp_writeb_base(atpdev, 0x3e, 0x00); /* enable terminator */
+
+       k = (atp_readb_base(atpdev, 0x3a) & 0xf3) | 0x10;
+       atp_writeb_base(atpdev, 0x3a, k);
+       atp_writeb_base(atpdev, 0x3a, k & 0xdf);
+       mdelay(32);
+       atp_writeb_base(atpdev, 0x3a, k);
+       mdelay(32);
+       atp_set_host_id(atpdev, 0, host_id);
+
+       tscam(shpnt, wide_chip, scam_on);
+       atp_writeb_base(atpdev, 0x3a, atp_readb_base(atpdev, 0x3a) | 0x10);
+       atp_is(atpdev, 0, wide_chip, 0);
+       atp_writeb_base(atpdev, 0x3a, atp_readb_base(atpdev, 0x3a) & 0xef);
+       atp_writeb_base(atpdev, 0x3b, atp_readb_base(atpdev, 0x3b) | 0x20);
+       shpnt->max_id = wide_chip ? 16 : 8;
+       shpnt->this_id = host_id;
+}
+
+static void atp880_init(struct Scsi_Host *shpnt)
+{
+       struct atp_unit *atpdev = shost_priv(shpnt);
+       struct pci_dev *pdev = atpdev->pdev;
+       unsigned char k, m, host_id;
+       unsigned int n;
+
+       pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80);
+
+       atpdev->ioport[0] = shpnt->io_port + 0x40;
+       atpdev->pciport[0] = shpnt->io_port + 0x28;
+
+       host_id = atp_readb_base(atpdev, 0x39) >> 4;
+
+       dev_info(&pdev->dev, "ACARD AEC-67160 PCI Ultra3 LVD Host Adapter: IO:%lx, IRQ:%d.\n",
+                shpnt->io_port, shpnt->irq);
+       atpdev->host_id[0] = host_id;
+
+       atpdev->global_map[0] = atp_readb_base(atpdev, 0x35);
+       atpdev->ultra_map[0] = atp_readw_base(atpdev, 0x3c);
+
+       n = 0x3f09;
+       while (n < 0x4000) {
+               m = 0;
+               atp_writew_base(atpdev, 0x34, n);
+               n += 0x0002;
+               if (atp_readb_base(atpdev, 0x30) == 0xff)
                        break;
-               }
-               m = 1;
-               m = m << i;
-               if ((m & dev->active_id[0]) != 0) {
-                       continue;
-               }
-               if (i == dev->host_id[0]) {
-                       printk(KERN_INFO "         ID: %2d  Host Adapter\n", dev->host_id[0]);
-                       continue;
-               }
-               if (dev->chip_ver == 4) {
-                       outb(0x01, wkport + 0x1b);
-               } else {
-                       outb(0x00, wkport + 0x1b);
-               }
-               outb(0x08, wkport + 1);
-               outb(0x7f, wkport + 2);
-               outb(satn[0], wkport + 3);
-               outb(satn[1], wkport + 4);
-               outb(satn[2], wkport + 5);
-               outb(satn[3], wkport + 6);
-               outb(satn[4], wkport + 7);
-               outb(satn[5], wkport + 8);
-               outb(0, wkport + 0x0f);
-               outb(dev->id[0][i].devsp, wkport + 0x11);
-               outb(0, wkport + 0x12);
-               outb(satn[6], wkport + 0x13);
-               outb(satn[7], wkport + 0x14);
-               j = i;
-               if ((j & 0x08) != 0) {
-                       j = (j & 0x07) | 0x40;
-               }
-               outb(j, wkport + 0x15);
-               outb(satn[8], wkport + 0x18);
 
-               while ((inb(wkport + 0x1f) & 0x80) == 0x00)
-                       cpu_relax();
+               atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x30);
+               atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x31);
+               atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x32);
+               atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x33);
+               atp_writew_base(atpdev, 0x34, n);
+               n += 0x0002;
+               atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x30);
+               atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x31);
+               atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x32);
+               atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x33);
+               atp_writew_base(atpdev, 0x34, n);
+               n += 0x0002;
+               atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x30);
+               atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x31);
+               atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x32);
+               atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x33);
+               atp_writew_base(atpdev, 0x34, n);
+               n += 0x0002;
+               atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x30);
+               atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x31);
+               atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x32);
+               atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x33);
+               n += 0x0018;
+       }
+       atp_writew_base(atpdev, 0x34, 0);
+       atpdev->ultra_map[0] = 0;
+       atpdev->async[0] = 0;
+       for (k = 0; k < 16; k++) {
+               n = 1 << k;
+               if (atpdev->sp[0][k] > 1)
+                       atpdev->ultra_map[0] |= n;
+               else
+                       if (atpdev->sp[0][k] == 0)
+                               atpdev->async[0] |= n;
+       }
+       atpdev->async[0] = ~(atpdev->async[0]);
+       atp_writeb_base(atpdev, 0x35, atpdev->global_map[0]);
+
+       k = atp_readb_base(atpdev, 0x38) & 0x80;
+       atp_writeb_base(atpdev, 0x38, k);
+       atp_writeb_base(atpdev, 0x3b, 0x20);
+       mdelay(32);
+       atp_writeb_base(atpdev, 0x3b, 0);
+       mdelay(32);
+       atp_readb_io(atpdev, 0, 0x1b);
+       atp_readb_io(atpdev, 0, 0x17);
+
+       atp_set_host_id(atpdev, 0, host_id);
+
+       tscam(shpnt, true, atp_readb_base(atpdev, 0x22));
+       atp_is(atpdev, 0, true, atp_readb_base(atpdev, 0x3f) & 0x40);
+       atp_writeb_base(atpdev, 0x38, 0xb0);
+       shpnt->max_id = 16;
+       shpnt->this_id = host_id;
+}
 
-               if (inb(wkport + 0x17) != 0x11 && inb(wkport + 0x17) != 0x8e)
-                       continue;
+static void atp885_init(struct Scsi_Host *shpnt)
+{
+       struct atp_unit *atpdev = shost_priv(shpnt);
+       struct pci_dev *pdev = atpdev->pdev;
+       unsigned char k, m, c;
+       unsigned int n;
+       unsigned char setupdata[2][16];
 
-               while (inb(wkport + 0x17) != 0x8e)
-                       cpu_relax();
+       dev_info(&pdev->dev, "ACARD AEC-67162 PCI Ultra3 LVD Host Adapter: IO:%lx, IRQ:%d.\n",
+                shpnt->io_port, shpnt->irq);
 
-               dev->active_id[0] |= m;
+       atpdev->ioport[0] = shpnt->io_port + 0x80;
+       atpdev->ioport[1] = shpnt->io_port + 0xc0;
+       atpdev->pciport[0] = shpnt->io_port + 0x40;
+       atpdev->pciport[1] = shpnt->io_port + 0x50;
 
-               outb(0x30, wkport + 0x10);
-               outb(0x00, wkport + 0x04);
+       c = atp_readb_base(atpdev, 0x29);
+       atp_writeb_base(atpdev, 0x29, c | 0x04);
 
-phase_cmd:
-               outb(0x08, wkport + 0x18);
-               while ((inb(wkport + 0x1f) & 0x80) == 0x00)
-                       cpu_relax();
-               j = inb(wkport + 0x17);
-               if (j != 0x16) {
-                       outb(0x41, wkport + 0x10);
-                       goto phase_cmd;
+       n = 0x1f80;
+       while (n < 0x2000) {
+               atp_writew_base(atpdev, 0x3c, n);
+               if (atp_readl_base(atpdev, 0x38) == 0xffffffff)
+                       break;
+               for (m = 0; m < 2; m++) {
+                       atpdev->global_map[m] = 0;
+                       for (k = 0; k < 4; k++) {
+                               atp_writew_base(atpdev, 0x3c, n++);
+                               ((unsigned long *)&setupdata[m][0])[k] = atp_readl_base(atpdev, 0x38);
+                       }
+                       for (k = 0; k < 4; k++) {
+                               atp_writew_base(atpdev, 0x3c, n++);
+                               ((unsigned long *)&atpdev->sp[m][0])[k] = atp_readl_base(atpdev, 0x38);
+                       }
+                       n += 8;
                }
-sel_ok:
-               outb(inqd[0], wkport + 3);
-               outb(inqd[1], wkport + 4);
-               outb(inqd[2], wkport + 5);
-               outb(inqd[3], wkport + 6);
-               outb(inqd[4], wkport + 7);
-               outb(inqd[5], wkport + 8);
-               outb(0, wkport + 0x0f);
-               outb(dev->id[0][i].devsp, wkport + 0x11);
-               outb(0, wkport + 0x12);
-               outb(inqd[6], wkport + 0x13);
-               outb(inqd[7], wkport + 0x14);
-               outb(inqd[8], wkport + 0x18);
-
-               while ((inb(wkport + 0x1f) & 0x80) == 0x00)
-                       cpu_relax();
-                       
-               if (inb(wkport + 0x17) != 0x11 && inb(wkport + 0x17) != 0x8e)
-                       continue;
+       }
+       c = atp_readb_base(atpdev, 0x29);
+       atp_writeb_base(atpdev, 0x29, c & 0xfb);
+       for (c = 0; c < 2; c++) {
+               atpdev->ultra_map[c] = 0;
+               atpdev->async[c] = 0;
+               for (k = 0; k < 16; k++) {
+                       n = 1 << k;
+                       if (atpdev->sp[c][k] > 1)
+                               atpdev->ultra_map[c] |= n;
+                       else
+                               if (atpdev->sp[c][k] == 0)
+                                       atpdev->async[c] |= n;
+               }
+               atpdev->async[c] = ~(atpdev->async[c]);
+
+               if (atpdev->global_map[c] == 0) {
+                       k = setupdata[c][1];
+                       if ((k & 0x40) != 0)
+                               atpdev->global_map[c] |= 0x20;
+                       k &= 0x07;
+                       atpdev->global_map[c] |= k;
+                       if ((setupdata[c][2] & 0x04) != 0)
+                               atpdev->global_map[c] |= 0x08;
+                       atpdev->host_id[c] = setupdata[c][0] & 0x07;
+               }
+       }
 
-               while (inb(wkport + 0x17) != 0x8e)
-                       cpu_relax();
-                       
-               if (dev->chip_ver == 4)
-                       outb(0x00, wkport + 0x1b);
-
-               outb(0x08, wkport + 0x18);
-               j = 0;
-rd_inq_data:
-               k = inb(wkport + 0x1f);
-               if ((k & 0x01) != 0) {
-                       mbuf[j++] = inb(wkport + 0x19);
-                       goto rd_inq_data;
-               }
-               if ((k & 0x80) == 0) {
-                       goto rd_inq_data;
-               }
-               j = inb(wkport + 0x17);
-               if (j == 0x16) {
-                       goto inq_ok;
-               }
-               outb(0x46, wkport + 0x10);
-               outb(0, wkport + 0x12);
-               outb(0, wkport + 0x13);
-               outb(0, wkport + 0x14);
-               outb(0x08, wkport + 0x18);
-
-               while ((inb(wkport + 0x1f) & 0x80) == 0x00)
-                       cpu_relax();
-                       
-               if (inb(wkport + 0x17) != 0x16) {
-                       goto sel_ok;
-               }
-inq_ok:
-               mbuf[36] = 0;
-               printk(KERN_INFO "         ID: %2d  %s\n", i, &mbuf[8]);
-               dev->id[0][i].devtype = mbuf[0];
-               rmb = mbuf[1];
-               n = mbuf[7];
-               if (dev->chip_ver != 4) {
-                       goto not_wide;
-               }
-               if ((mbuf[7] & 0x60) == 0) {
-                       goto not_wide;
-               }
-               if ((dev->global_map[0] & 0x20) == 0) {
-                       goto not_wide;
-               }
-               outb(0x01, wkport + 0x1b);
-               outb(satn[0], wkport + 3);
-               outb(satn[1], wkport + 4);
-               outb(satn[2], wkport + 5);
-               outb(satn[3], wkport + 6);
-               outb(satn[4], wkport + 7);
-               outb(satn[5], wkport + 8);
-               outb(0, wkport + 0x0f);
-               outb(dev->id[0][i].devsp, wkport + 0x11);
-               outb(0, wkport + 0x12);
-               outb(satn[6], wkport + 0x13);
-               outb(satn[7], wkport + 0x14);
-               outb(satn[8], wkport + 0x18);
-
-               while ((inb(wkport + 0x1f) & 0x80) == 0x00)
-                       cpu_relax();
-                       
-               if (inb(wkport + 0x17) != 0x11 && inb(wkport + 0x17) != 0x8e)
-                       continue;
-
-               while (inb(wkport + 0x17) != 0x8e)
-                       cpu_relax();
-                       
-try_wide:
-               j = 0;
-               outb(0x05, wkport + 0x14);
-               outb(0x20, wkport + 0x18);
-
-               while ((inb(wkport + 0x1f) & 0x80) == 0) {
-                       if ((inb(wkport + 0x1f) & 0x01) != 0)
-                               outb(wide[j++], wkport + 0x19);
-               }
-               
-               while ((inb(wkport + 0x17) & 0x80) == 0x00)
-                       cpu_relax();
-                       
-               j = inb(wkport + 0x17) & 0x0f;
-               if (j == 0x0f) {
-                       goto widep_in;
-               }
-               if (j == 0x0a) {
-                       goto widep_cmd;
-               }
-               if (j == 0x0e) {
-                       goto try_wide;
-               }
-               continue;
-widep_out:
-               outb(0x20, wkport + 0x18);
-               while ((inb(wkport + 0x1f) & 0x80) == 0) {
-                       if ((inb(wkport + 0x1f) & 0x01) != 0)
-                               outb(0, wkport + 0x19);
-               }
-               j = inb(wkport + 0x17) & 0x0f;
-               if (j == 0x0f) {
-                       goto widep_in;
-               }
-               if (j == 0x0a) {
-                       goto widep_cmd;
-               }
-               if (j == 0x0e) {
-                       goto widep_out;
-               }
-               continue;
-widep_in:
-               outb(0xff, wkport + 0x14);
-               outb(0x20, wkport + 0x18);
-               k = 0;
-widep_in1:
-               j = inb(wkport + 0x1f);
-               if ((j & 0x01) != 0) {
-                       mbuf[k++] = inb(wkport + 0x19);
-                       goto widep_in1;
-               }
-               if ((j & 0x80) == 0x00) {
-                       goto widep_in1;
-               }
-               j = inb(wkport + 0x17) & 0x0f;
-               if (j == 0x0f) {
-                       goto widep_in;
-               }
-               if (j == 0x0a) {
-                       goto widep_cmd;
-               }
-               if (j == 0x0e) {
-                       goto widep_out;
-               }
-               continue;
-widep_cmd:
-               outb(0x30, wkport + 0x10);
-               outb(0x00, wkport + 0x14);
-               outb(0x08, wkport + 0x18);
-               
-               while ((inb(wkport + 0x1f) & 0x80) == 0x00)
-                       cpu_relax();
-
-               j = inb(wkport + 0x17);
-               if (j != 0x16) {
-                       if (j == 0x4e) {
-                               goto widep_out;
-                       }
-                       continue;
-               }
-               if (mbuf[0] != 0x01) {
-                       goto not_wide;
-               }
-               if (mbuf[1] != 0x02) {
-                       goto not_wide;
-               }
-               if (mbuf[2] != 0x03) {
-                       goto not_wide;
-               }
-               if (mbuf[3] != 0x01) {
-                       goto not_wide;
-               }
-               m = 1;
-               m = m << i;
-               dev->wide_id[0] |= m;
-not_wide:
-               if ((dev->id[0][i].devtype == 0x00) || (dev->id[0][i].devtype == 0x07) || ((dev->id[0][i].devtype == 0x05) && ((n & 0x10) != 0))) {
-                       goto set_sync;
-               }
-               continue;
-set_sync:
-               j = 0;
-               if ((m & dev->wide_id[0]) != 0) {
-                       j |= 0x01;
-               }
-               outb(j, wkport + 0x1b);
-               outb(satn[0], wkport + 3);
-               outb(satn[1], wkport + 4);
-               outb(satn[2], wkport + 5);
-               outb(satn[3], wkport + 6);
-               outb(satn[4], wkport + 7);
-               outb(satn[5], wkport + 8);
-               outb(0, wkport + 0x0f);
-               outb(dev->id[0][i].devsp, wkport + 0x11);
-               outb(0, wkport + 0x12);
-               outb(satn[6], wkport + 0x13);
-               outb(satn[7], wkport + 0x14);
-               outb(satn[8], wkport + 0x18);
-
-               while ((inb(wkport + 0x1f) & 0x80) == 0x00)
-                       cpu_relax();
-                       
-               if (inb(wkport + 0x17) != 0x11 && inb(wkport + 0x17) != 0x8e)
-                       continue;
-
-               while (inb(wkport + 0x17) != 0x8e)
-                       cpu_relax();
-                       
-try_sync:
-               j = 0;
-               outb(0x06, wkport + 0x14);
-               outb(0x20, wkport + 0x18);
-
-               while ((inb(wkport + 0x1f) & 0x80) == 0) {
-                       if ((inb(wkport + 0x1f) & 0x01) != 0) {
-                               if ((m & dev->wide_id[0]) != 0) {
-                                       outb(synw[j++], wkport + 0x19);
-                               } else {
-                                       if ((m & dev->ultra_map[0]) != 0) {
-                                               outb(synu[j++], wkport + 0x19);
-                                       } else {
-                                               outb(synn[j++], wkport + 0x19);
-                                       }
-                               }
-                       }
-               }
-               
-               while ((inb(wkport + 0x17) & 0x80) == 0x00)
-                       cpu_relax();
-                       
-               j = inb(wkport + 0x17) & 0x0f;
-               if (j == 0x0f) {
-                       goto phase_ins;
-               }
-               if (j == 0x0a) {
-                       goto phase_cmds;
-               }
-               if (j == 0x0e) {
-                       goto try_sync;
-               }
-               continue;
-phase_outs:
-               outb(0x20, wkport + 0x18);
-               while ((inb(wkport + 0x1f) & 0x80) == 0x00) {
-                       if ((inb(wkport + 0x1f) & 0x01) != 0x00)
-                               outb(0x00, wkport + 0x19);
-               }
-               j = inb(wkport + 0x17);
-               if (j == 0x85) {
-                       goto tar_dcons;
-               }
-               j &= 0x0f;
-               if (j == 0x0f) {
-                       goto phase_ins;
-               }
-               if (j == 0x0a) {
-                       goto phase_cmds;
-               }
-               if (j == 0x0e) {
-                       goto phase_outs;
-               }
-               continue;
-phase_ins:
-               outb(0xff, wkport + 0x14);
-               outb(0x20, wkport + 0x18);
-               k = 0;
-phase_ins1:
-               j = inb(wkport + 0x1f);
-               if ((j & 0x01) != 0x00) {
-                       mbuf[k++] = inb(wkport + 0x19);
-                       goto phase_ins1;
-               }
-               if ((j & 0x80) == 0x00) {
-                       goto phase_ins1;
-               }
-
-               while ((inb(wkport + 0x17) & 0x80) == 0x00)
-                       cpu_relax();
-                       
-               j = inb(wkport + 0x17);
-               if (j == 0x85) {
-                       goto tar_dcons;
-               }
-               j &= 0x0f;
-               if (j == 0x0f) {
-                       goto phase_ins;
-               }
-               if (j == 0x0a) {
-                       goto phase_cmds;
-               }
-               if (j == 0x0e) {
-                       goto phase_outs;
-               }
-               continue;
-phase_cmds:
-               outb(0x30, wkport + 0x10);
-tar_dcons:
-               outb(0x00, wkport + 0x14);
-               outb(0x08, wkport + 0x18);
-               
-               while ((inb(wkport + 0x1f) & 0x80) == 0x00)
-                       cpu_relax();
-                       
-               j = inb(wkport + 0x17);
-               if (j != 0x16) {
-                       continue;
-               }
-               if (mbuf[0] != 0x01) {
-                       continue;
-               }
-               if (mbuf[1] != 0x03) {
-                       continue;
-               }
-               if (mbuf[4] == 0x00) {
-                       continue;
-               }
-               if (mbuf[3] > 0x64) {
-                       continue;
-               }
-               if (mbuf[4] > 0x0c) {
-                       mbuf[4] = 0x0c;
-               }
-               dev->id[0][i].devsp = mbuf[4];
-               if ((mbuf[3] < 0x0d) && (rmb == 0)) {
-                       j = 0xa0;
-                       goto set_syn_ok;
-               }
-               if (mbuf[3] < 0x1a) {
-                       j = 0x20;
-                       goto set_syn_ok;
-               }
-               if (mbuf[3] < 0x33) {
-                       j = 0x40;
-                       goto set_syn_ok;
-               }
-               if (mbuf[3] < 0x4c) {
-                       j = 0x50;
-                       goto set_syn_ok;
-               }
-               j = 0x60;
-set_syn_ok:
-               dev->id[0][i].devsp = (dev->id[0][i].devsp & 0x0f) | j;
-       }
-       outb((unsigned char) (inb(wkport + 0x3a) & 0xef), wkport + 0x3a);
-}
-
-static void is880(struct atp_unit *dev, unsigned int wkport)
-{
-       unsigned char i, j, k, rmb, n, lvdmode;
-       unsigned short int m;
-       static unsigned char mbuf[512];
-       static unsigned char satn[9] = { 0, 0, 0, 0, 0, 0, 0, 6, 6 };
-       static unsigned char inqd[9] = { 0x12, 0, 0, 0, 0x24, 0, 0, 0x24, 6 };
-       static unsigned char synn[6] = { 0x80, 1, 3, 1, 0x19, 0x0e };
-       unsigned char synu[6] = { 0x80, 1, 3, 1, 0x0a, 0x0e };
-       static unsigned char synw[6] = { 0x80, 1, 3, 1, 0x19, 0x0e };
-       unsigned char synuw[6] = { 0x80, 1, 3, 1, 0x0a, 0x0e };
-       static unsigned char wide[6] = { 0x80, 1, 2, 3, 1, 0 };
-       static unsigned char u3[9] = { 0x80, 1, 6, 4, 0x09, 00, 0x0e, 0x01, 0x02 };
-
-       lvdmode = inb(wkport + 0x3f) & 0x40;
-
-       for (i = 0; i < 16; i++) {
-               m = 1;
-               m = m << i;
-               if ((m & dev->active_id[0]) != 0) {
-                       continue;
-               }
-               if (i == dev->host_id[0]) {
-                       printk(KERN_INFO "         ID: %2d  Host Adapter\n", dev->host_id[0]);
-                       continue;
-               }
-               outb(0x01, wkport + 0x5b);
-               outb(0x08, wkport + 0x41);
-               outb(0x7f, wkport + 0x42);
-               outb(satn[0], wkport + 0x43);
-               outb(satn[1], wkport + 0x44);
-               outb(satn[2], wkport + 0x45);
-               outb(satn[3], wkport + 0x46);
-               outb(satn[4], wkport + 0x47);
-               outb(satn[5], wkport + 0x48);
-               outb(0, wkport + 0x4f);
-               outb(dev->id[0][i].devsp, wkport + 0x51);
-               outb(0, wkport + 0x52);
-               outb(satn[6], wkport + 0x53);
-               outb(satn[7], wkport + 0x54);
-               j = i;
-               if ((j & 0x08) != 0) {
-                       j = (j & 0x07) | 0x40;
-               }
-               outb(j, wkport + 0x55);
-               outb(satn[8], wkport + 0x58);
-
-               while ((inb(wkport + 0x5f) & 0x80) == 0x00)
-                       cpu_relax();
-
-               if (inb(wkport + 0x57) != 0x11 && inb(wkport + 0x57) != 0x8e)
-                       continue;
-
-               while (inb(wkport + 0x57) != 0x8e)
-                       cpu_relax();
-                       
-               dev->active_id[0] |= m;
-
-               outb(0x30, wkport + 0x50);
-               outb(0x00, wkport + 0x54);
-
-phase_cmd:
-               outb(0x08, wkport + 0x58);
-               
-               while ((inb(wkport + 0x5f) & 0x80) == 0x00)
-                       cpu_relax();
-
-               j = inb(wkport + 0x57);
-               if (j != 0x16) {
-                       outb(0x41, wkport + 0x50);
-                       goto phase_cmd;
-               }
-sel_ok:
-               outb(inqd[0], wkport + 0x43);
-               outb(inqd[1], wkport + 0x44);
-               outb(inqd[2], wkport + 0x45);
-               outb(inqd[3], wkport + 0x46);
-               outb(inqd[4], wkport + 0x47);
-               outb(inqd[5], wkport + 0x48);
-               outb(0, wkport + 0x4f);
-               outb(dev->id[0][i].devsp, wkport + 0x51);
-               outb(0, wkport + 0x52);
-               outb(inqd[6], wkport + 0x53);
-               outb(inqd[7], wkport + 0x54);
-               outb(inqd[8], wkport + 0x58);
-               
-               while ((inb(wkport + 0x5f) & 0x80) == 0x00)
-                       cpu_relax();
-                       
-               if (inb(wkport + 0x57) != 0x11 && inb(wkport + 0x57) != 0x8e)
-                       continue;
-
-               while (inb(wkport + 0x57) != 0x8e)
-                       cpu_relax();
-                       
-               outb(0x00, wkport + 0x5b);
-               outb(0x08, wkport + 0x58);
-               j = 0;
-rd_inq_data:
-               k = inb(wkport + 0x5f);
-               if ((k & 0x01) != 0) {
-                       mbuf[j++] = inb(wkport + 0x59);
-                       goto rd_inq_data;
-               }
-               if ((k & 0x80) == 0) {
-                       goto rd_inq_data;
-               }
-               j = inb(wkport + 0x57);
-               if (j == 0x16) {
-                       goto inq_ok;
-               }
-               outb(0x46, wkport + 0x50);
-               outb(0, wkport + 0x52);
-               outb(0, wkport + 0x53);
-               outb(0, wkport + 0x54);
-               outb(0x08, wkport + 0x58);
-               while ((inb(wkport + 0x5f) & 0x80) == 0x00)
-                       cpu_relax();
-                       
-               if (inb(wkport + 0x57) != 0x16)
-                       goto sel_ok;
-
-inq_ok:
-               mbuf[36] = 0;
-               printk(KERN_INFO "         ID: %2d  %s\n", i, &mbuf[8]);
-               dev->id[0][i].devtype = mbuf[0];
-               rmb = mbuf[1];
-               n = mbuf[7];
-               if ((mbuf[7] & 0x60) == 0) {
-                       goto not_wide;
-               }
-               if ((i < 8) && ((dev->global_map[0] & 0x20) == 0)) {
-                       goto not_wide;
-               }
-               if (lvdmode == 0) {
-                       goto chg_wide;
-               }
-               if (dev->sp[0][i] != 0x04)      // force u2
-               {
-                       goto chg_wide;
-               }
-
-               outb(0x01, wkport + 0x5b);
-               outb(satn[0], wkport + 0x43);
-               outb(satn[1], wkport + 0x44);
-               outb(satn[2], wkport + 0x45);
-               outb(satn[3], wkport + 0x46);
-               outb(satn[4], wkport + 0x47);
-               outb(satn[5], wkport + 0x48);
-               outb(0, wkport + 0x4f);
-               outb(dev->id[0][i].devsp, wkport + 0x51);
-               outb(0, wkport + 0x52);
-               outb(satn[6], wkport + 0x53);
-               outb(satn[7], wkport + 0x54);
-               outb(satn[8], wkport + 0x58);
-
-               while ((inb(wkport + 0x5f) & 0x80) == 0x00)
-                       cpu_relax();
-
-               if (inb(wkport + 0x57) != 0x11 && inb(wkport + 0x57) != 0x8e)
-                       continue;
-
-               while (inb(wkport + 0x57) != 0x8e)
-                       cpu_relax();
-
-try_u3:
-               j = 0;
-               outb(0x09, wkport + 0x54);
-               outb(0x20, wkport + 0x58);
-
-               while ((inb(wkport + 0x5f) & 0x80) == 0) {
-                       if ((inb(wkport + 0x5f) & 0x01) != 0)
-                               outb(u3[j++], wkport + 0x59);
-               }
-
-               while ((inb(wkport + 0x57) & 0x80) == 0x00)
-                       cpu_relax();
-                       
-               j = inb(wkport + 0x57) & 0x0f;
-               if (j == 0x0f) {
-                       goto u3p_in;
-               }
-               if (j == 0x0a) {
-                       goto u3p_cmd;
-               }
-               if (j == 0x0e) {
-                       goto try_u3;
-               }
-               continue;
-u3p_out:
-               outb(0x20, wkport + 0x58);
-               while ((inb(wkport + 0x5f) & 0x80) == 0) {
-                       if ((inb(wkport + 0x5f) & 0x01) != 0)
-                               outb(0, wkport + 0x59);
-               }
-               j = inb(wkport + 0x57) & 0x0f;
-               if (j == 0x0f) {
-                       goto u3p_in;
-               }
-               if (j == 0x0a) {
-                       goto u3p_cmd;
-               }
-               if (j == 0x0e) {
-                       goto u3p_out;
-               }
-               continue;
-u3p_in:
-               outb(0x09, wkport + 0x54);
-               outb(0x20, wkport + 0x58);
-               k = 0;
-u3p_in1:
-               j = inb(wkport + 0x5f);
-               if ((j & 0x01) != 0) {
-                       mbuf[k++] = inb(wkport + 0x59);
-                       goto u3p_in1;
-               }
-               if ((j & 0x80) == 0x00) {
-                       goto u3p_in1;
-               }
-               j = inb(wkport + 0x57) & 0x0f;
-               if (j == 0x0f) {
-                       goto u3p_in;
-               }
-               if (j == 0x0a) {
-                       goto u3p_cmd;
-               }
-               if (j == 0x0e) {
-                       goto u3p_out;
-               }
-               continue;
-u3p_cmd:
-               outb(0x30, wkport + 0x50);
-               outb(0x00, wkport + 0x54);
-               outb(0x08, wkport + 0x58);
-               
-               while ((inb(wkport + 0x5f) & 0x80) == 0x00)
-                       cpu_relax();
-                       
-               j = inb(wkport + 0x57);
-               if (j != 0x16) {
-                       if (j == 0x4e) {
-                               goto u3p_out;
-                       }
-                       continue;
-               }
-               if (mbuf[0] != 0x01) {
-                       goto chg_wide;
-               }
-               if (mbuf[1] != 0x06) {
-                       goto chg_wide;
-               }
-               if (mbuf[2] != 0x04) {
-                       goto chg_wide;
-               }
-               if (mbuf[3] == 0x09) {
-                       m = 1;
-                       m = m << i;
-                       dev->wide_id[0] |= m;
-                       dev->id[0][i].devsp = 0xce;
-                       continue;
-               }
-chg_wide:
-               outb(0x01, wkport + 0x5b);
-               outb(satn[0], wkport + 0x43);
-               outb(satn[1], wkport + 0x44);
-               outb(satn[2], wkport + 0x45);
-               outb(satn[3], wkport + 0x46);
-               outb(satn[4], wkport + 0x47);
-               outb(satn[5], wkport + 0x48);
-               outb(0, wkport + 0x4f);
-               outb(dev->id[0][i].devsp, wkport + 0x51);
-               outb(0, wkport + 0x52);
-               outb(satn[6], wkport + 0x53);
-               outb(satn[7], wkport + 0x54);
-               outb(satn[8], wkport + 0x58);
-
-               while ((inb(wkport + 0x5f) & 0x80) == 0x00)
-                       cpu_relax();
-                       
-               if (inb(wkport + 0x57) != 0x11 && inb(wkport + 0x57) != 0x8e)
-                       continue;
-
-               while (inb(wkport + 0x57) != 0x8e)
-                       cpu_relax();
-                       
-try_wide:
-               j = 0;
-               outb(0x05, wkport + 0x54);
-               outb(0x20, wkport + 0x58);
-
-               while ((inb(wkport + 0x5f) & 0x80) == 0) {
-                       if ((inb(wkport + 0x5f) & 0x01) != 0)
-                               outb(wide[j++], wkport + 0x59);
-               }
-               while ((inb(wkport + 0x57) & 0x80) == 0x00)
-                       cpu_relax();
-                       
-               j = inb(wkport + 0x57) & 0x0f;
-               if (j == 0x0f) {
-                       goto widep_in;
-               }
-               if (j == 0x0a) {
-                       goto widep_cmd;
-               }
-               if (j == 0x0e) {
-                       goto try_wide;
-               }
-               continue;
-widep_out:
-               outb(0x20, wkport + 0x58);
-               while ((inb(wkport + 0x5f) & 0x80) == 0) {
-                       if ((inb(wkport + 0x5f) & 0x01) != 0)
-                               outb(0, wkport + 0x59);
-               }
-               j = inb(wkport + 0x57) & 0x0f;
-               if (j == 0x0f) {
-                       goto widep_in;
-               }
-               if (j == 0x0a) {
-                       goto widep_cmd;
-               }
-               if (j == 0x0e) {
-                       goto widep_out;
-               }
-               continue;
-widep_in:
-               outb(0xff, wkport + 0x54);
-               outb(0x20, wkport + 0x58);
-               k = 0;
-widep_in1:
-               j = inb(wkport + 0x5f);
-               if ((j & 0x01) != 0) {
-                       mbuf[k++] = inb(wkport + 0x59);
-                       goto widep_in1;
-               }
-               if ((j & 0x80) == 0x00) {
-                       goto widep_in1;
-               }
-               j = inb(wkport + 0x57) & 0x0f;
-               if (j == 0x0f) {
-                       goto widep_in;
-               }
-               if (j == 0x0a) {
-                       goto widep_cmd;
-               }
-               if (j == 0x0e) {
-                       goto widep_out;
-               }
-               continue;
-widep_cmd:
-               outb(0x30, wkport + 0x50);
-               outb(0x00, wkport + 0x54);
-               outb(0x08, wkport + 0x58);
-
-               while ((inb(wkport + 0x5f) & 0x80) == 0x00)
-                       cpu_relax();
-
-               j = inb(wkport + 0x57);
-               if (j != 0x16) {
-                       if (j == 0x4e) {
-                               goto widep_out;
-                       }
-                       continue;
-               }
-               if (mbuf[0] != 0x01) {
-                       goto not_wide;
-               }
-               if (mbuf[1] != 0x02) {
-                       goto not_wide;
-               }
-               if (mbuf[2] != 0x03) {
-                       goto not_wide;
-               }
-               if (mbuf[3] != 0x01) {
-                       goto not_wide;
-               }
-               m = 1;
-               m = m << i;
-               dev->wide_id[0] |= m;
-not_wide:
-               if ((dev->id[0][i].devtype == 0x00) || (dev->id[0][i].devtype == 0x07) || ((dev->id[0][i].devtype == 0x05) && ((n & 0x10) != 0))) {
-                       m = 1;
-                       m = m << i;
-                       if ((dev->async[0] & m) != 0) {
-                               goto set_sync;
-                       }
-               }
-               continue;
-set_sync:
-               if (dev->sp[0][i] == 0x02) {
-                       synu[4] = 0x0c;
-                       synuw[4] = 0x0c;
-               } else {
-                       if (dev->sp[0][i] >= 0x03) {
-                               synu[4] = 0x0a;
-                               synuw[4] = 0x0a;
-                       }
-               }
-               j = 0;
-               if ((m & dev->wide_id[0]) != 0) {
-                       j |= 0x01;
-               }
-               outb(j, wkport + 0x5b);
-               outb(satn[0], wkport + 0x43);
-               outb(satn[1], wkport + 0x44);
-               outb(satn[2], wkport + 0x45);
-               outb(satn[3], wkport + 0x46);
-               outb(satn[4], wkport + 0x47);
-               outb(satn[5], wkport + 0x48);
-               outb(0, wkport + 0x4f);
-               outb(dev->id[0][i].devsp, wkport + 0x51);
-               outb(0, wkport + 0x52);
-               outb(satn[6], wkport + 0x53);
-               outb(satn[7], wkport + 0x54);
-               outb(satn[8], wkport + 0x58);
-
-               while ((inb(wkport + 0x5f) & 0x80) == 0x00)
-                       cpu_relax();
-
-               if ((inb(wkport + 0x57) != 0x11) && (inb(wkport + 0x57) != 0x8e)) {
-                       continue;
-               }
-               while (inb(wkport + 0x57) != 0x8e)
-                       cpu_relax();
-
-try_sync:
-               j = 0;
-               outb(0x06, wkport + 0x54);
-               outb(0x20, wkport + 0x58);
-
-               while ((inb(wkport + 0x5f) & 0x80) == 0) {
-                       if ((inb(wkport + 0x5f) & 0x01) != 0) {
-                               if ((m & dev->wide_id[0]) != 0) {
-                                       if ((m & dev->ultra_map[0]) != 0) {
-                                               outb(synuw[j++], wkport + 0x59);
-                                       } else {
-                                               outb(synw[j++], wkport + 0x59);
-                                       }
-                               } else {
-                                       if ((m & dev->ultra_map[0]) != 0) {
-                                               outb(synu[j++], wkport + 0x59);
-                                       } else {
-                                               outb(synn[j++], wkport + 0x59);
-                                       }
-                               }
-                       }
-               }
-
-               while ((inb(wkport + 0x57) & 0x80) == 0x00)
-                       cpu_relax();
-
-               j = inb(wkport + 0x57) & 0x0f;
-               if (j == 0x0f) {
-                       goto phase_ins;
-               }
-               if (j == 0x0a) {
-                       goto phase_cmds;
-               }
-               if (j == 0x0e) {
-                       goto try_sync;
-               }
-               continue;
-phase_outs:
-               outb(0x20, wkport + 0x58);
-               while ((inb(wkport + 0x5f) & 0x80) == 0x00) {
-                       if ((inb(wkport + 0x5f) & 0x01) != 0x00)
-                               outb(0x00, wkport + 0x59);
-               }
-               j = inb(wkport + 0x57);
-               if (j == 0x85) {
-                       goto tar_dcons;
-               }
-               j &= 0x0f;
-               if (j == 0x0f) {
-                       goto phase_ins;
-               }
-               if (j == 0x0a) {
-                       goto phase_cmds;
-               }
-               if (j == 0x0e) {
-                       goto phase_outs;
-               }
-               continue;
-phase_ins:
-               outb(0x06, wkport + 0x54);
-               outb(0x20, wkport + 0x58);
-               k = 0;
-phase_ins1:
-               j = inb(wkport + 0x5f);
-               if ((j & 0x01) != 0x00) {
-                       mbuf[k++] = inb(wkport + 0x59);
-                       goto phase_ins1;
-               }
-               if ((j & 0x80) == 0x00) {
-                       goto phase_ins1;
-               }
-
-               while ((inb(wkport + 0x57) & 0x80) == 0x00)
-                       cpu_relax();
-
-               j = inb(wkport + 0x57);
-               if (j == 0x85) {
-                       goto tar_dcons;
-               }
-               j &= 0x0f;
-               if (j == 0x0f) {
-                       goto phase_ins;
-               }
-               if (j == 0x0a) {
-                       goto phase_cmds;
-               }
-               if (j == 0x0e) {
-                       goto phase_outs;
-               }
-               continue;
-phase_cmds:
-               outb(0x30, wkport + 0x50);
-tar_dcons:
-               outb(0x00, wkport + 0x54);
-               outb(0x08, wkport + 0x58);
-
-               while ((inb(wkport + 0x5f) & 0x80) == 0x00)
-                       cpu_relax();
-
-               j = inb(wkport + 0x57);
-               if (j != 0x16) {
-                       continue;
-               }
-               if (mbuf[0] != 0x01) {
-                       continue;
-               }
-               if (mbuf[1] != 0x03) {
-                       continue;
-               }
-               if (mbuf[4] == 0x00) {
-                       continue;
-               }
-               if (mbuf[3] > 0x64) {
-                       continue;
-               }
-               if (mbuf[4] > 0x0e) {
-                       mbuf[4] = 0x0e;
-               }
-               dev->id[0][i].devsp = mbuf[4];
-               if (mbuf[3] < 0x0c) {
-                       j = 0xb0;
-                       goto set_syn_ok;
-               }
-               if ((mbuf[3] < 0x0d) && (rmb == 0)) {
-                       j = 0xa0;
-                       goto set_syn_ok;
-               }
-               if (mbuf[3] < 0x1a) {
-                       j = 0x20;
-                       goto set_syn_ok;
-               }
-               if (mbuf[3] < 0x33) {
-                       j = 0x40;
-                       goto set_syn_ok;
-               }
-               if (mbuf[3] < 0x4c) {
-                       j = 0x50;
-                       goto set_syn_ok;
-               }
-               j = 0x60;
-set_syn_ok:
-               dev->id[0][i].devsp = (dev->id[0][i].devsp & 0x0f) | j;
-       }
-}
-
-static void atp870u_free_tables(struct Scsi_Host *host)
-{
-       struct atp_unit *atp_dev = (struct atp_unit *)&host->hostdata;
-       int j, k;
-       for (j=0; j < 2; j++) {
-               for (k = 0; k < 16; k++) {
-                       if (!atp_dev->id[j][k].prd_table)
-                               continue;
-                       pci_free_consistent(atp_dev->pdev, 1024, atp_dev->id[j][k].prd_table, atp_dev->id[j][k].prd_bus);
-                       atp_dev->id[j][k].prd_table = NULL;
-               }
-       }
-}
-
-static int atp870u_init_tables(struct Scsi_Host *host)
-{
-       struct atp_unit *atp_dev = (struct atp_unit *)&host->hostdata;
-       int c,k;
-       for(c=0;c < 2;c++) {
-               for(k=0;k<16;k++) {
-                               atp_dev->id[c][k].prd_table = pci_alloc_consistent(atp_dev->pdev, 1024, &(atp_dev->id[c][k].prd_bus));
-                               if (!atp_dev->id[c][k].prd_table) {
-                                       printk("atp870u_init_tables fail\n");
-                               atp870u_free_tables(host);
-                               return -ENOMEM;
-                       }
-                       atp_dev->id[c][k].prdaddr = atp_dev->id[c][k].prd_bus;
-                       atp_dev->id[c][k].devsp=0x20;
-                       atp_dev->id[c][k].devtype = 0x7f;
-                       atp_dev->id[c][k].curr_req = NULL;                         
-               }
-                               
-               atp_dev->active_id[c] = 0;
-               atp_dev->wide_id[c] = 0;
-               atp_dev->host_id[c] = 0x07;
-               atp_dev->quhd[c] = 0;
-               atp_dev->quend[c] = 0;
-               atp_dev->last_cmd[c] = 0xff;
-               atp_dev->in_snd[c] = 0;
-               atp_dev->in_int[c] = 0;
-               
-               for (k = 0; k < qcnt; k++) {
-                         atp_dev->quereq[c][k] = NULL;
-               }                          
-               for (k = 0; k < 16; k++) {
-                          atp_dev->id[c][k].curr_req = NULL;
-                          atp_dev->sp[c][k] = 0x04;
-               }                  
-       }
-       return 0;
-}
+       k = atp_readb_base(atpdev, 0x28) & 0x8f;
+       k |= 0x10;
+       atp_writeb_base(atpdev, 0x28, k);
+       atp_writeb_pci(atpdev, 0, 1, 0x80);
+       atp_writeb_pci(atpdev, 1, 1, 0x80);
+       mdelay(100);
+       atp_writeb_pci(atpdev, 0, 1, 0);
+       atp_writeb_pci(atpdev, 1, 1, 0);
+       mdelay(1000);
+       atp_readb_io(atpdev, 0, 0x1b);
+       atp_readb_io(atpdev, 0, 0x17);
+       atp_readb_io(atpdev, 1, 0x1b);
+       atp_readb_io(atpdev, 1, 0x17);
+
+       k = atpdev->host_id[0];
+       if (k > 7)
+               k = (k & 0x07) | 0x40;
+       atp_set_host_id(atpdev, 0, k);
+
+       k = atpdev->host_id[1];
+       if (k > 7)
+               k = (k & 0x07) | 0x40;
+       atp_set_host_id(atpdev, 1, k);
+
+       mdelay(600); /* this delay used to be called tscam_885() */
+       dev_info(&pdev->dev, "Scanning Channel A SCSI Device ...\n");
+       atp_is(atpdev, 0, true, atp_readb_io(atpdev, 0, 0x1b) >> 7);
+       atp_writeb_io(atpdev, 0, 0x16, 0x80);
+       dev_info(&pdev->dev, "Scanning Channel B SCSI Device ...\n");
+       atp_is(atpdev, 1, true, atp_readb_io(atpdev, 1, 0x1b) >> 7);
+       atp_writeb_io(atpdev, 1, 0x16, 0x80);
+       k = atp_readb_base(atpdev, 0x28) & 0xcf;
+       k |= 0xc0;
+       atp_writeb_base(atpdev, 0x28, k);
+       k = atp_readb_base(atpdev, 0x1f) | 0x80;
+       atp_writeb_base(atpdev, 0x1f, k);
+       k = atp_readb_base(atpdev, 0x29) | 0x01;
+       atp_writeb_base(atpdev, 0x29, k);
+       shpnt->max_id = 16;
+       shpnt->max_lun = (atpdev->global_map[0] & 0x07) + 1;
+       shpnt->max_channel = 1;
+       shpnt->this_id = atpdev->host_id[0];
+}
 
 /* return non-zero on detection */
 static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
-       unsigned char k, m, c;
-       unsigned long flags;
-       unsigned int base_io, error,n;
-       unsigned char host_id;
        struct Scsi_Host *shpnt = NULL;
-       struct atp_unit *atpdev, *p;
-       unsigned char setupdata[2][16];
-       int count = 0;
+       struct atp_unit *atpdev;
+       int err;
 
-       atpdev = kzalloc(sizeof(*atpdev), GFP_KERNEL);
-       if (!atpdev)
-               return -ENOMEM;
+       if (ent->device == PCI_DEVICE_ID_ARTOP_AEC7610 && pdev->revision < 2) {
+               dev_err(&pdev->dev, "ATP850S chips (AEC6710L/F cards) are not supported.\n");
+               return -ENODEV;
+       }
 
-       if (pci_enable_device(pdev))
-               goto err_eio;
+       err = pci_enable_device(pdev);
+       if (err)
+               goto fail;
 
-        if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
-                printk(KERN_INFO "atp870u: use 32bit DMA mask.\n");
-        } else {
+       if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
                 printk(KERN_ERR "atp870u: DMA mask required but not available.\n");
-               goto err_eio;
+                err = -EIO;
+                goto disable_device;
         }
 
-       /*
-        * It's probably easier to weed out some revisions like
-        * this than via the PCI device table
-        */
-       if (ent->device == PCI_DEVICE_ID_ARTOP_AEC7610) {
-               atpdev->chip_ver = pdev->revision;
-               if (atpdev->chip_ver < 2)
-                       goto err_eio;
+       err = pci_request_regions(pdev, "atp870u");
+       if (err)
+               goto disable_device;
+       pci_set_master(pdev);
+
+        err = -ENOMEM;
+       shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit));
+       if (!shpnt)
+               goto release_region;
+
+       atpdev = shost_priv(shpnt);
+
+       atpdev->host = shpnt;
+       atpdev->pdev = pdev;
+       pci_set_drvdata(pdev, atpdev);
+
+       shpnt->io_port = pci_resource_start(pdev, 0);
+       shpnt->io_port &= 0xfffffff8;
+       shpnt->n_io_port = pci_resource_len(pdev, 0);
+       atpdev->baseport = shpnt->io_port;
+       shpnt->unique_id = shpnt->io_port;
+       shpnt->irq = pdev->irq;
+
+       err = atp870u_init_tables(shpnt);
+       if (err) {
+               dev_err(&pdev->dev, "Unable to allocate tables for Acard controller\n");
+               goto unregister;
        }
 
-       switch (ent->device) {
-       case PCI_DEVICE_ID_ARTOP_AEC7612UW:
-       case PCI_DEVICE_ID_ARTOP_AEC7612SUW:
-       case ATP880_DEVID1:     
-       case ATP880_DEVID2:     
-       case ATP885_DEVID:      
-               atpdev->chip_ver = 0x04;
-       default:
-               break;
+       if (is880(atpdev))
+               atp880_init(shpnt);
+       else if (is885(atpdev))
+               atp885_init(shpnt);
+       else
+               atp870_init(shpnt);
+
+       err = request_irq(shpnt->irq, atp870u_intr_handle, IRQF_SHARED, "atp870u", shpnt);
+       if (err) {
+               dev_err(&pdev->dev, "Unable to allocate IRQ %d.\n", shpnt->irq);
+               goto free_tables;
        }
-       base_io = pci_resource_start(pdev, 0);
-       base_io &= 0xfffffff8;
-
-       if ((ent->device == ATP880_DEVID1)||(ent->device == ATP880_DEVID2)) {
-               atpdev->chip_ver = pdev->revision;
-               pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80);//JCC082803
-
-               host_id = inb(base_io + 0x39);
-               host_id >>= 0x04;
-
-               printk(KERN_INFO "   ACARD AEC-67160 PCI Ultra3 LVD Host Adapter: %d"
-                       "    IO:%x, IRQ:%d.\n", count, base_io, pdev->irq);
-               atpdev->ioport[0] = base_io + 0x40;
-               atpdev->pciport[0] = base_io + 0x28;
-               atpdev->dev_id = ent->device;
-               atpdev->host_id[0] = host_id;
-
-               atpdev->scam_on = inb(base_io + 0x22);
-               atpdev->global_map[0] = inb(base_io + 0x35);
-               atpdev->ultra_map[0] = inw(base_io + 0x3c);
-
-               n = 0x3f09;
-next_fblk_880:
-               if (n >= 0x4000)
-                       goto flash_ok_880;
-
-               m = 0;
-               outw(n, base_io + 0x34);
-               n += 0x0002;
-               if (inb(base_io + 0x30) == 0xff)
-                       goto flash_ok_880;
-
-               atpdev->sp[0][m++] = inb(base_io + 0x30);
-               atpdev->sp[0][m++] = inb(base_io + 0x31);
-               atpdev->sp[0][m++] = inb(base_io + 0x32);
-               atpdev->sp[0][m++] = inb(base_io + 0x33);
-               outw(n, base_io + 0x34);
-               n += 0x0002;
-               atpdev->sp[0][m++] = inb(base_io + 0x30);
-               atpdev->sp[0][m++] = inb(base_io + 0x31);
-               atpdev->sp[0][m++] = inb(base_io + 0x32);
-               atpdev->sp[0][m++] = inb(base_io + 0x33);
-               outw(n, base_io + 0x34);
-               n += 0x0002;
-               atpdev->sp[0][m++] = inb(base_io + 0x30);
-               atpdev->sp[0][m++] = inb(base_io + 0x31);
-               atpdev->sp[0][m++] = inb(base_io + 0x32);
-               atpdev->sp[0][m++] = inb(base_io + 0x33);
-               outw(n, base_io + 0x34);
-               n += 0x0002;
-               atpdev->sp[0][m++] = inb(base_io + 0x30);
-               atpdev->sp[0][m++] = inb(base_io + 0x31);
-               atpdev->sp[0][m++] = inb(base_io + 0x32);
-               atpdev->sp[0][m++] = inb(base_io + 0x33);
-               n += 0x0018;
-               goto next_fblk_880;
-flash_ok_880:
-               outw(0, base_io + 0x34);
-               atpdev->ultra_map[0] = 0;
-               atpdev->async[0] = 0;
-               for (k = 0; k < 16; k++) {
-                       n = 1;
-                       n = n << k;
-                       if (atpdev->sp[0][k] > 1) {
-                               atpdev->ultra_map[0] |= n;
-                       } else {
-                               if (atpdev->sp[0][k] == 0)
-                                       atpdev->async[0] |= n;
-                       }
-               }
-               atpdev->async[0] = ~(atpdev->async[0]);
-               outb(atpdev->global_map[0], base_io + 0x35);
-               shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit));
-               if (!shpnt)
-                       goto err_nomem;
-
-               p = (struct atp_unit *)&shpnt->hostdata;
-
-               atpdev->host = shpnt;
-               atpdev->pdev = pdev;
-               pci_set_drvdata(pdev, p);
-               memcpy(p, atpdev, sizeof(*atpdev));
-               if (atp870u_init_tables(shpnt) < 0) {
-                       printk(KERN_ERR "Unable to allocate tables for Acard controller\n");
-                       goto unregister;
-               }
-
-               if (request_irq(pdev->irq, atp870u_intr_handle, IRQF_SHARED, "atp880i", shpnt)) {
-                       printk(KERN_ERR "Unable to allocate IRQ%d for Acard controller.\n", pdev->irq);
-                       goto free_tables;
-               }
-
-               spin_lock_irqsave(shpnt->host_lock, flags);
-               k = inb(base_io + 0x38) & 0x80;
-               outb(k, base_io + 0x38);
-               outb(0x20, base_io + 0x3b);
-               mdelay(32);
-               outb(0, base_io + 0x3b);
-               mdelay(32);
-               inb(base_io + 0x5b);
-               inb(base_io + 0x57);
-               outb((host_id | 0x08), base_io + 0x40);
-               outb(0, base_io + 0x58);
-               while ((inb(base_io + 0x5f) & 0x80) == 0)
-                       mdelay(1);
-               inb(base_io + 0x57);
-               outb(8, base_io + 0x41);
-               outb(0x7f, base_io + 0x42);
-               outb(0x20, base_io + 0x51);
-
-               tscam(shpnt);
-               is880(p, base_io);
-               outb(0xb0, base_io + 0x38);
-               shpnt->max_id = 16;
-               shpnt->this_id = host_id;
-               shpnt->unique_id = base_io;
-               shpnt->io_port = base_io;
-               shpnt->n_io_port = 0x60;        /* Number of bytes of I/O space used */
-               shpnt->irq = pdev->irq;                 
-       } else if (ent->device == ATP885_DEVID) {       
-                       printk(KERN_INFO "   ACARD AEC-67162 PCI Ultra3 LVD Host Adapter:  IO:%x, IRQ:%d.\n"
-                              , base_io, pdev->irq);
-               
-               atpdev->pdev = pdev;
-               atpdev->dev_id  = ent->device;
-               atpdev->baseport = base_io;
-               atpdev->ioport[0] = base_io + 0x80;
-               atpdev->ioport[1] = base_io + 0xc0;
-               atpdev->pciport[0] = base_io + 0x40;
-               atpdev->pciport[1] = base_io + 0x50;
-                               
-               shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit));
-               if (!shpnt)
-                       goto err_nomem;
-               
-               p = (struct atp_unit *)&shpnt->hostdata;
-               
-               atpdev->host = shpnt;
-               atpdev->pdev = pdev;
-               pci_set_drvdata(pdev, p);
-               memcpy(p, atpdev, sizeof(struct atp_unit));
-               if (atp870u_init_tables(shpnt) < 0)
-                       goto unregister;
-                       
-#ifdef ED_DBGP         
-       printk("request_irq() shpnt %p hostdata %p\n", shpnt, p);
-#endif         
-               if (request_irq(pdev->irq, atp870u_intr_handle, IRQF_SHARED, "atp870u", shpnt)) {
-                               printk(KERN_ERR "Unable to allocate IRQ for Acard controller.\n");
-                       goto free_tables;
-               }
-               
-               spin_lock_irqsave(shpnt->host_lock, flags);                                             
-                               
-               c=inb(base_io + 0x29);
-               outb((c | 0x04),base_io + 0x29);
-               
-               n=0x1f80;
-next_fblk_885:
-               if (n >= 0x2000) {
-                  goto flash_ok_885;
-               }
-               outw(n,base_io + 0x3c);
-               if (inl(base_io + 0x38) == 0xffffffff) {
-                  goto flash_ok_885;
-               }
-               for (m=0; m < 2; m++) {
-                   p->global_map[m]= 0;
-                   for (k=0; k < 4; k++) {
-                       outw(n++,base_io + 0x3c);
-                       ((unsigned long *)&setupdata[m][0])[k]=inl(base_io + 0x38);
-                   }
-                   for (k=0; k < 4; k++) {
-                       outw(n++,base_io + 0x3c);
-                       ((unsigned long *)&p->sp[m][0])[k]=inl(base_io + 0x38);
-                   }
-                   n += 8;
-               }
-               goto next_fblk_885;
-flash_ok_885:
-#ifdef ED_DBGP
-               printk( "Flash Read OK\n");
-#endif 
-               c=inb(base_io + 0x29);
-               outb((c & 0xfb),base_io + 0x29);
-               for (c=0;c < 2;c++) {
-                   p->ultra_map[c]=0;
-                   p->async[c] = 0;
-                   for (k=0; k < 16; k++) {
-                       n=1;
-                       n = n << k;
-                       if (p->sp[c][k] > 1) {
-                          p->ultra_map[c] |= n;
-                       } else {
-                          if (p->sp[c][k] == 0) {
-                             p->async[c] |= n;
-                          }
-                       }
-                   }
-                   p->async[c] = ~(p->async[c]);
-
-                   if (p->global_map[c] == 0) {
-                      k=setupdata[c][1];
-                      if ((k & 0x40) != 0)
-                         p->global_map[c] |= 0x20;
-                      k &= 0x07;
-                      p->global_map[c] |= k;
-                      if ((setupdata[c][2] & 0x04) != 0)
-                         p->global_map[c] |= 0x08;
-                      p->host_id[c] = setupdata[c][0] & 0x07;
-                   }
-               }
-
-               k = inb(base_io + 0x28) & 0x8f;
-               k |= 0x10;
-               outb(k, base_io + 0x28);
-               outb(0x80, base_io + 0x41);
-               outb(0x80, base_io + 0x51);
-               mdelay(100);
-               outb(0, base_io + 0x41);
-               outb(0, base_io + 0x51);
-               mdelay(1000);
-               inb(base_io + 0x9b);
-               inb(base_io + 0x97);
-               inb(base_io + 0xdb);
-               inb(base_io + 0xd7);
-               k=p->host_id[0];
-               if (k > 7)
-                  k = (k & 0x07) | 0x40;
-               k |= 0x08;
-               outb(k, base_io + 0x80);
-               outb(0, base_io + 0x98);
-
-               while ((inb(base_io + 0x9f) & 0x80) == 0)
-                       cpu_relax();
-       
-               inb(base_io + 0x97);
-               outb(8, base_io + 0x81);
-               outb(0x7f, base_io + 0x82);
-               outb(0x20, base_io + 0x91);
-
-               k=p->host_id[1];
-               if (k > 7)
-                  k = (k & 0x07) | 0x40;
-               k |= 0x08;
-               outb(k, base_io + 0xc0);
-               outb(0, base_io + 0xd8);
-
-               while ((inb(base_io + 0xdf) & 0x80) == 0)
-                       cpu_relax();
-
-               inb(base_io + 0xd7);
-               outb(8, base_io + 0xc1);
-               outb(0x7f, base_io + 0xc2);
-               outb(0x20, base_io + 0xd1);
-
-               tscam_885();
-               printk(KERN_INFO "   Scanning Channel A SCSI Device ...\n");
-               is885(p, base_io + 0x80, 0);
-               printk(KERN_INFO "   Scanning Channel B SCSI Device ...\n");
-               is885(p, base_io + 0xc0, 1);
-
-               k = inb(base_io + 0x28) & 0xcf;
-               k |= 0xc0;
-               outb(k, base_io + 0x28);
-               k = inb(base_io + 0x1f) | 0x80;
-               outb(k, base_io + 0x1f);
-               k = inb(base_io + 0x29) | 0x01;
-               outb(k, base_io + 0x29);
-#ifdef ED_DBGP
-               //printk("atp885: atp_host[0] 0x%p\n", atp_host[0]);
-#endif         
-               shpnt->max_id = 16;
-               shpnt->max_lun = (p->global_map[0] & 0x07) + 1;
-               shpnt->max_channel = 1;
-               shpnt->this_id = p->host_id[0];
-               shpnt->unique_id = base_io;
-               shpnt->io_port = base_io;
-               shpnt->n_io_port = 0xff;        /* Number of bytes of I/O space used */
-               shpnt->irq = pdev->irq;
-                               
-       } else {
-               error = pci_read_config_byte(pdev, 0x49, &host_id);
-
-               printk(KERN_INFO "   ACARD AEC-671X PCI Ultra/W SCSI-2/3 Host Adapter: %d "
-                       "IO:%x, IRQ:%d.\n", count, base_io, pdev->irq);
-
-               atpdev->ioport[0] = base_io;
-               atpdev->pciport[0] = base_io + 0x20;
-               atpdev->dev_id = ent->device;
-               host_id &= 0x07;
-               atpdev->host_id[0] = host_id;
-               atpdev->scam_on = inb(base_io + 0x22);
-               atpdev->global_map[0] = inb(base_io + 0x2d);
-               atpdev->ultra_map[0] = inw(base_io + 0x2e);
-
-               if (atpdev->ultra_map[0] == 0) {
-                       atpdev->scam_on = 0x00;
-                       atpdev->global_map[0] = 0x20;
-                       atpdev->ultra_map[0] = 0xffff;
-               }
 
-               shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit));
-               if (!shpnt)
-                       goto err_nomem;
+       err = scsi_add_host(shpnt, &pdev->dev);
+       if (err)
+               goto scsi_add_fail;
+       scsi_scan_host(shpnt);
 
-               p = (struct atp_unit *)&shpnt->hostdata;
-               
-               atpdev->host = shpnt;
-               atpdev->pdev = pdev;
-               pci_set_drvdata(pdev, p);
-               memcpy(p, atpdev, sizeof(*atpdev));
-               if (atp870u_init_tables(shpnt) < 0)
-                       goto unregister;
-
-               if (request_irq(pdev->irq, atp870u_intr_handle, IRQF_SHARED, "atp870i", shpnt)) {
-                       printk(KERN_ERR "Unable to allocate IRQ%d for Acard controller.\n", pdev->irq);
-                       goto free_tables;
-               }
-
-               spin_lock_irqsave(shpnt->host_lock, flags);
-               if (atpdev->chip_ver > 0x07) {  /* check if atp876 chip then enable terminator */
-                       outb(0x00, base_io + 0x3e);
-               }
-               k = (inb(base_io + 0x3a) & 0xf3) | 0x10;
-               outb(k, base_io + 0x3a);
-               outb((k & 0xdf), base_io + 0x3a);
-               mdelay(32);
-               outb(k, base_io + 0x3a);
-               mdelay(32);
-               outb((host_id | 0x08), base_io + 0);
-               outb(0, base_io + 0x18);
-               while ((inb(base_io + 0x1f) & 0x80) == 0)
-                       mdelay(1);
-
-               inb(base_io + 0x17);
-               outb(8, base_io + 1);
-               outb(0x7f, base_io + 2);
-               outb(0x20, base_io + 0x11);
-
-               tscam(shpnt);
-               is870(p, base_io);
-               outb((inb(base_io + 0x3a) & 0xef), base_io + 0x3a);
-               outb((inb(base_io + 0x3b) | 0x20), base_io + 0x3b);
-               if (atpdev->chip_ver == 4)
-                       shpnt->max_id = 16;
-               else            
-                       shpnt->max_id = 8;
-               shpnt->this_id = host_id;
-               shpnt->unique_id = base_io;
-               shpnt->io_port = base_io;
-               shpnt->n_io_port = 0x40;        /* Number of bytes of I/O space used */
-               shpnt->irq = pdev->irq;         
-       } 
-               spin_unlock_irqrestore(shpnt->host_lock, flags);
-               if(ent->device==ATP885_DEVID) {
-                       if(!request_region(base_io, 0xff, "atp870u")) /* Register the IO ports that we use */
-                               goto request_io_fail;
-               } else if((ent->device==ATP880_DEVID1)||(ent->device==ATP880_DEVID2)) {
-                       if(!request_region(base_io, 0x60, "atp870u")) /* Register the IO ports that we use */
-                               goto request_io_fail;
-               } else {
-                       if(!request_region(base_io, 0x40, "atp870u")) /* Register the IO ports that we use */
-                               goto request_io_fail;
-               }                               
-               count++;
-               if (scsi_add_host(shpnt, &pdev->dev))
-                       goto scsi_add_fail;
-               scsi_scan_host(shpnt);
-#ifdef ED_DBGP                 
-               printk("atp870u_prob : exit\n");
-#endif         
-               return 0;
+       return 0;
 
 scsi_add_fail:
-       printk("atp870u_prob:scsi_add_fail\n");
-       if(ent->device==ATP885_DEVID) {
-               release_region(base_io, 0xff);
-       } else if((ent->device==ATP880_DEVID1)||(ent->device==ATP880_DEVID2)) {
-               release_region(base_io, 0x60);
-       } else {
-               release_region(base_io, 0x40);
-       }
-request_io_fail:
-       printk("atp870u_prob:request_io_fail\n");
-       free_irq(pdev->irq, shpnt);
+       free_irq(shpnt->irq, shpnt);
 free_tables:
-       printk("atp870u_prob:free_table\n");
        atp870u_free_tables(shpnt);
 unregister:
-       printk("atp870u_prob:unregister\n");
        scsi_host_put(shpnt);
-       return -1;              
-err_eio:
-       kfree(atpdev);
-       return -EIO;
-err_nomem:
-       kfree(atpdev);
-       return -ENOMEM;
+release_region:
+       pci_release_regions(pdev);
+disable_device:
+       pci_disable_device(pdev);
+fail:
+       return err;
 }
 
 /* The abort command does not leave the device in a clean state where
@@ -2716,7 +1586,6 @@ static int atp870u_abort(struct scsi_cmnd * SCpnt)
 {
        unsigned char  j, k, c;
        struct scsi_cmnd *workrequ;
-       unsigned int tmport;
        struct atp_unit *dev;   
        struct Scsi_Host *host;
        host = SCpnt->device->host;
@@ -2726,18 +1595,13 @@ static int atp870u_abort(struct scsi_cmnd * SCpnt)
        printk(" atp870u: abort Channel = %x \n", c);
        printk("working=%x last_cmd=%x ", dev->working[c], dev->last_cmd[c]);
        printk(" quhdu=%x quendu=%x ", dev->quhd[c], dev->quend[c]);
-       tmport = dev->ioport[c];
        for (j = 0; j < 0x18; j++) {
-               printk(" r%2x=%2x", j, inb(tmport++));
+               printk(" r%2x=%2x", j, atp_readb_io(dev, c, j));
        }
-       tmport += 0x04;
-       printk(" r1c=%2x", inb(tmport));
-       tmport += 0x03;
-       printk(" r1f=%2x in_snd=%2x ", inb(tmport), dev->in_snd[c]);
-       tmport= dev->pciport[c];
-       printk(" d00=%2x", inb(tmport));
-       tmport += 0x02;
-       printk(" d02=%2x", inb(tmport));
+       printk(" r1c=%2x", atp_readb_io(dev, c, 0x1c));
+       printk(" r1f=%2x in_snd=%2x ", atp_readb_io(dev, c, 0x1f), dev->in_snd[c]);
+       printk(" d00=%2x", atp_readb_pci(dev, c, 0x00));
+       printk(" d02=%2x", atp_readb_pci(dev, c, 0x02));
        for(j=0;j<16;j++) {
           if (dev->id[c][j].curr_req != NULL) {
                workrequ = dev->id[c][j].curr_req;
@@ -2797,12 +1661,10 @@ static void atp870u_remove (struct pci_dev *pdev)
        
        
        scsi_remove_host(pshost);
-       printk(KERN_INFO "free_irq : %d\n",pshost->irq);
        free_irq(pshost->irq, pshost);
-       release_region(pshost->io_port, pshost->n_io_port);
-       printk(KERN_INFO "atp870u_free_tables : %p\n",pshost);
+       pci_release_regions(pdev);
+       pci_disable_device(pdev);
        atp870u_free_tables(pshost);
-       printk(KERN_INFO "scsi_host_put : %p\n",pshost);
        scsi_host_put(pshost);
 }
 MODULE_LICENSE("GPL");
@@ -2846,52 +1708,26 @@ static struct pci_driver atp870u_driver = {
        .remove         = atp870u_remove,
 };
 
-static int __init atp870u_init(void)
-{
-#ifdef ED_DBGP 
-       printk("atp870u_init: Entry\n");
-#endif 
-       return pci_register_driver(&atp870u_driver);
-}
-
-static void __exit atp870u_exit(void)
-{
-#ifdef ED_DBGP 
-       printk("atp870u_exit: Entry\n");
-#endif
-       pci_unregister_driver(&atp870u_driver);
-}
-
-static void tscam_885(void)
-{
-       unsigned char i;
-
-       for (i = 0; i < 0x2; i++) {
-               mdelay(300);
-       }
-       return;
-}
-
-
+module_pci_driver(atp870u_driver);
 
-static void is885(struct atp_unit *dev, unsigned int wkport,unsigned char c)
+static void atp_is(struct atp_unit *dev, unsigned char c, bool wide_chip, unsigned char lvdmode)
 {
-       unsigned int tmport;
-       unsigned char i, j, k, rmb, n, lvdmode;
+       unsigned char i, j, k, rmb, n;
        unsigned short int m;
        static unsigned char mbuf[512];
-       static unsigned char satn[9] =  {0, 0, 0, 0, 0, 0, 0, 6, 6};
-       static unsigned char inqd[9] =  {0x12, 0, 0, 0, 0x24, 0, 0, 0x24, 6};
-       static unsigned char synn[6] =  {0x80, 1, 3, 1, 0x19, 0x0e};
-       unsigned char synu[6] =  {0x80, 1, 3, 1, 0x0a, 0x0e};
-       static unsigned char synw[6] =  {0x80, 1, 3, 1, 0x19, 0x0e};
-       unsigned char synuw[6] =  {0x80, 1, 3, 1, 0x0a, 0x0e};
-       static unsigned char wide[6] =  {0x80, 1, 2, 3, 1, 0};
-       static unsigned char u3[9] = { 0x80,1,6,4,0x09,00,0x0e,0x01,0x02 };
-
-       lvdmode=inb(wkport + 0x1b) >> 7;
+       static unsigned char satn[9] = { 0, 0, 0, 0, 0, 0, 0, 6, 6 };
+       static unsigned char inqd[9] = { 0x12, 0, 0, 0, 0x24, 0, 0, 0x24, 6 };
+       static unsigned char synn[6] = { 0x80, 1, 3, 1, 0x19, 0x0e };
+       unsigned char synu[6] = { 0x80, 1, 3, 1, 0x0a, 0x0e };
+       static unsigned char synw[6] = { 0x80, 1, 3, 1, 0x19, 0x0e };
+       static unsigned char synw_870[6] = { 0x80, 1, 3, 1, 0x0c, 0x07 };
+       unsigned char synuw[6] = { 0x80, 1, 3, 1, 0x0a, 0x0e };
+       static unsigned char wide[6] = { 0x80, 1, 2, 3, 1, 0 };
+       static unsigned char u3[9] = { 0x80, 1, 6, 4, 0x09, 00, 0x0e, 0x01, 0x02 };
 
        for (i = 0; i < 16; i++) {
+               if (!wide_chip && (i > 7))
+                       break;
                m = 1;
                m = m << i;
                if ((m & dev->active_id[c]) != 0) {
@@ -2901,192 +1737,172 @@ static void is885(struct atp_unit *dev, unsigned int wkport,unsigned char c)
                        printk(KERN_INFO "         ID: %2d  Host Adapter\n", dev->host_id[c]);
                        continue;
                }
-               tmport = wkport + 0x1b;
-               outb(0x01, tmport);
-               tmport = wkport + 0x01;
-               outb(0x08, tmport++);
-               outb(0x7f, tmport++);
-               outb(satn[0], tmport++);
-               outb(satn[1], tmport++);
-               outb(satn[2], tmport++);
-               outb(satn[3], tmport++);
-               outb(satn[4], tmport++);
-               outb(satn[5], tmport++);
-               tmport += 0x06;
-               outb(0, tmport);
-               tmport += 0x02;
-               outb(dev->id[c][i].devsp, tmport++);
-               
-               outb(0, tmport++);
-               outb(satn[6], tmport++);
-               outb(satn[7], tmport++);
+               atp_writeb_io(dev, c, 0x1b, wide_chip ? 0x01 : 0x00);
+               atp_writeb_io(dev, c, 1, 0x08);
+               atp_writeb_io(dev, c, 2, 0x7f);
+               atp_writeb_io(dev, c, 3, satn[0]);
+               atp_writeb_io(dev, c, 4, satn[1]);
+               atp_writeb_io(dev, c, 5, satn[2]);
+               atp_writeb_io(dev, c, 6, satn[3]);
+               atp_writeb_io(dev, c, 7, satn[4]);
+               atp_writeb_io(dev, c, 8, satn[5]);
+               atp_writeb_io(dev, c, 0x0f, 0);
+               atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp);
+               atp_writeb_io(dev, c, 0x12, 0);
+               atp_writeb_io(dev, c, 0x13, satn[6]);
+               atp_writeb_io(dev, c, 0x14, satn[7]);
                j = i;
                if ((j & 0x08) != 0) {
                        j = (j & 0x07) | 0x40;
                }
-               outb(j, tmport);
-               tmport += 0x03;
-               outb(satn[8], tmport);
-               tmport += 0x07;
+               atp_writeb_io(dev, c, 0x15, j);
+               atp_writeb_io(dev, c, 0x18, satn[8]);
 
-               while ((inb(tmport) & 0x80) == 0x00)
+               while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00)
                        cpu_relax();
-               tmport -= 0x08;
-               if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
+
+               if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e)
                        continue;
-               }
-               while (inb(tmport) != 0x8e)
+
+               while (atp_readb_io(dev, c, 0x17) != 0x8e)
                        cpu_relax();
+
                dev->active_id[c] |= m;
 
-               tmport = wkport + 0x10;
-               outb(0x30, tmport);
-               tmport = wkport + 0x14;
-               outb(0x00, tmport);
+               atp_writeb_io(dev, c, 0x10, 0x30);
+               if (is885(dev) || is880(dev))
+                       atp_writeb_io(dev, c, 0x14, 0x00);
+               else /* result of is870() merge - is this a bug? */
+                       atp_writeb_io(dev, c, 0x04, 0x00);
 
 phase_cmd:
-               tmport = wkport + 0x18;
-               outb(0x08, tmport);
-               tmport += 0x07;
-               while ((inb(tmport) & 0x80) == 0x00)
+               atp_writeb_io(dev, c, 0x18, 0x08);
+
+               while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00)
                        cpu_relax();
-               tmport -= 0x08;
-               j = inb(tmport);
+
+               j = atp_readb_io(dev, c, 0x17);
                if (j != 0x16) {
-                       tmport = wkport + 0x10;
-                       outb(0x41, tmport);
+                       atp_writeb_io(dev, c, 0x10, 0x41);
                        goto phase_cmd;
                }
 sel_ok:
-               tmport = wkport + 0x03;
-               outb(inqd[0], tmport++);
-               outb(inqd[1], tmport++);
-               outb(inqd[2], tmport++);
-               outb(inqd[3], tmport++);
-               outb(inqd[4], tmport++);
-               outb(inqd[5], tmport);
-               tmport += 0x07;
-               outb(0, tmport);
-               tmport += 0x02;
-               outb(dev->id[c][i].devsp, tmport++);
-               outb(0, tmport++);
-               outb(inqd[6], tmport++);
-               outb(inqd[7], tmport++);
-               tmport += 0x03;
-               outb(inqd[8], tmport);
-               tmport += 0x07;
-               while ((inb(tmport) & 0x80) == 0x00)
+               atp_writeb_io(dev, c, 3, inqd[0]);
+               atp_writeb_io(dev, c, 4, inqd[1]);
+               atp_writeb_io(dev, c, 5, inqd[2]);
+               atp_writeb_io(dev, c, 6, inqd[3]);
+               atp_writeb_io(dev, c, 7, inqd[4]);
+               atp_writeb_io(dev, c, 8, inqd[5]);
+               atp_writeb_io(dev, c, 0x0f, 0);
+               atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp);
+               atp_writeb_io(dev, c, 0x12, 0);
+               atp_writeb_io(dev, c, 0x13, inqd[6]);
+               atp_writeb_io(dev, c, 0x14, inqd[7]);
+               atp_writeb_io(dev, c, 0x18, inqd[8]);
+
+               while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00)
                        cpu_relax();
-               tmport -= 0x08;
-               if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
+
+               if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e)
                        continue;
-               }
-               while (inb(tmport) != 0x8e)
+
+               while (atp_readb_io(dev, c, 0x17) != 0x8e)
                        cpu_relax();
-               tmport = wkport + 0x1b;
-               outb(0x00, tmport);
-               tmport = wkport + 0x18;
-               outb(0x08, tmport);
-               tmport += 0x07;
+
+               if (wide_chip)
+                       atp_writeb_io(dev, c, 0x1b, 0x00);
+
+               atp_writeb_io(dev, c, 0x18, 0x08);
                j = 0;
 rd_inq_data:
-               k = inb(tmport);
+               k = atp_readb_io(dev, c, 0x1f);
                if ((k & 0x01) != 0) {
-                       tmport -= 0x06;
-                       mbuf[j++] = inb(tmport);
-                       tmport += 0x06;
+                       mbuf[j++] = atp_readb_io(dev, c, 0x19);
                        goto rd_inq_data;
                }
                if ((k & 0x80) == 0) {
                        goto rd_inq_data;
                }
-               tmport -= 0x08;
-               j = inb(tmport);
+               j = atp_readb_io(dev, c, 0x17);
                if (j == 0x16) {
                        goto inq_ok;
                }
-               tmport = wkport + 0x10;
-               outb(0x46, tmport);
-               tmport += 0x02;
-               outb(0, tmport++);
-               outb(0, tmport++);
-               outb(0, tmport++);
-               tmport += 0x03;
-               outb(0x08, tmport);
-               tmport += 0x07;
-               while ((inb(tmport) & 0x80) == 0x00)
+               atp_writeb_io(dev, c, 0x10, 0x46);
+               atp_writeb_io(dev, c, 0x12, 0);
+               atp_writeb_io(dev, c, 0x13, 0);
+               atp_writeb_io(dev, c, 0x14, 0);
+               atp_writeb_io(dev, c, 0x18, 0x08);
+
+               while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00)
                        cpu_relax();
-               tmport -= 0x08;
-               if (inb(tmport) != 0x16) {
+
+               if (atp_readb_io(dev, c, 0x17) != 0x16)
                        goto sel_ok;
-               }
+
 inq_ok:
                mbuf[36] = 0;
-               printk( KERN_INFO"         ID: %2d  %s\n", i, &mbuf[8]);
+               printk(KERN_INFO "         ID: %2d  %s\n", i, &mbuf[8]);
                dev->id[c][i].devtype = mbuf[0];
                rmb = mbuf[1];
                n = mbuf[7];
+               if (!wide_chip)
+                       goto not_wide;
                if ((mbuf[7] & 0x60) == 0) {
                        goto not_wide;
                }
-               if ((i < 8) && ((dev->global_map[c] & 0x20) == 0)) {
-                       goto not_wide;
+               if (is885(dev) || is880(dev)) {
+                       if ((i < 8) && ((dev->global_map[c] & 0x20) == 0))
+                               goto not_wide;
+               } else { /* result of is870() merge - is this a bug? */
+                       if ((dev->global_map[c] & 0x20) == 0)
+                               goto not_wide;
                }
                if (lvdmode == 0) {
-                  goto chg_wide;
-               }
-               if (dev->sp[c][i] != 0x04) {    // force u2
-                  goto chg_wide;
-               }
-
-               tmport = wkport + 0x1b;
-               outb(0x01, tmport);
-               tmport = wkport + 0x03;
-               outb(satn[0], tmport++);
-               outb(satn[1], tmport++);
-               outb(satn[2], tmport++);
-               outb(satn[3], tmport++);
-               outb(satn[4], tmport++);
-               outb(satn[5], tmport++);
-               tmport += 0x06;
-               outb(0, tmport);
-               tmport += 0x02;
-               outb(dev->id[c][i].devsp, tmport++);
-               outb(0, tmport++);
-               outb(satn[6], tmport++);
-               outb(satn[7], tmport++);
-               tmport += 0x03;
-               outb(satn[8], tmport);
-               tmport += 0x07;
-
-               while ((inb(tmport) & 0x80) == 0x00)
+                       goto chg_wide;
+               }
+               if (dev->sp[c][i] != 0x04)      // force u2
+               {
+                       goto chg_wide;
+               }
+
+               atp_writeb_io(dev, c, 0x1b, 0x01);
+               atp_writeb_io(dev, c, 3, satn[0]);
+               atp_writeb_io(dev, c, 4, satn[1]);
+               atp_writeb_io(dev, c, 5, satn[2]);
+               atp_writeb_io(dev, c, 6, satn[3]);
+               atp_writeb_io(dev, c, 7, satn[4]);
+               atp_writeb_io(dev, c, 8, satn[5]);
+               atp_writeb_io(dev, c, 0x0f, 0);
+               atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp);
+               atp_writeb_io(dev, c, 0x12, 0);
+               atp_writeb_io(dev, c, 0x13, satn[6]);
+               atp_writeb_io(dev, c, 0x14, satn[7]);
+               atp_writeb_io(dev, c, 0x18, satn[8]);
+
+               while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00)
                        cpu_relax();
-               tmport -= 0x08;
-               if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
+
+               if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e)
                        continue;
-               }
-               while (inb(tmport) != 0x8e)
+
+               while (atp_readb_io(dev, c, 0x17) != 0x8e)
                        cpu_relax();
+
 try_u3:
                j = 0;
-               tmport = wkport + 0x14;
-               outb(0x09, tmport);
-               tmport += 0x04;
-               outb(0x20, tmport);
-               tmport += 0x07;
-
-               while ((inb(tmport) & 0x80) == 0) {
-                       if ((inb(tmport) & 0x01) != 0) {
-                               tmport -= 0x06;
-                               outb(u3[j++], tmport);
-                               tmport += 0x06;
-                       }
+               atp_writeb_io(dev, c, 0x14, 0x09);
+               atp_writeb_io(dev, c, 0x18, 0x20);
+
+               while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) {
+                       if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0)
+                               atp_writeb_io(dev, c, 0x19, u3[j++]);
                        cpu_relax();
                }
-               tmport -= 0x08;
-               while ((inb(tmport) & 0x80) == 0x00)
+
+               while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00)
                        cpu_relax();
-               j = inb(tmport) & 0x0f;
+
+               j = atp_readb_io(dev, c, 0x17) & 0x0f;
                if (j == 0x0f) {
                        goto u3p_in;
                }
@@ -3098,19 +1914,13 @@ try_u3:
                }
                continue;
 u3p_out:
-               tmport = wkport + 0x18;
-               outb(0x20, tmport);
-               tmport += 0x07;
-               while ((inb(tmport) & 0x80) == 0) {
-                       if ((inb(tmport) & 0x01) != 0) {
-                               tmport -= 0x06;
-                               outb(0, tmport);
-                               tmport += 0x06;
-                       }
+               atp_writeb_io(dev, c, 0x18, 0x20);
+               while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) {
+                       if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0)
+                               atp_writeb_io(dev, c, 0x19, 0);
                        cpu_relax();
                }
-               tmport -= 0x08;
-               j = inb(tmport) & 0x0f;
+               j = atp_readb_io(dev, c, 0x17) & 0x0f;
                if (j == 0x0f) {
                        goto u3p_in;
                }
@@ -3122,25 +1932,19 @@ u3p_out:
                }
                continue;
 u3p_in:
-               tmport = wkport + 0x14;
-               outb(0x09, tmport);
-               tmport += 0x04;
-               outb(0x20, tmport);
-               tmport += 0x07;
+               atp_writeb_io(dev, c, 0x14, 0x09);
+               atp_writeb_io(dev, c, 0x18, 0x20);
                k = 0;
 u3p_in1:
-               j = inb(tmport);
+               j = atp_readb_io(dev, c, 0x1f);
                if ((j & 0x01) != 0) {
-                       tmport -= 0x06;
-                       mbuf[k++] = inb(tmport);
-                       tmport += 0x06;
+                       mbuf[k++] = atp_readb_io(dev, c, 0x19);
                        goto u3p_in1;
                }
                if ((j & 0x80) == 0x00) {
                        goto u3p_in1;
                }
-               tmport -= 0x08;
-               j = inb(tmport) & 0x0f;
+               j = atp_readb_io(dev, c, 0x17) & 0x0f;
                if (j == 0x0f) {
                        goto u3p_in;
                }
@@ -3152,16 +1956,13 @@ u3p_in1:
                }
                continue;
 u3p_cmd:
-               tmport = wkport + 0x10;
-               outb(0x30, tmport);
-               tmport = wkport + 0x14;
-               outb(0x00, tmport);
-               tmport += 0x04;
-               outb(0x08, tmport);
-               tmport += 0x07;
-               while ((inb(tmport) & 0x80) == 0x00);
-               tmport -= 0x08;
-               j = inb(tmport);
+               atp_writeb_io(dev, c, 0x10, 0x30);
+               atp_writeb_io(dev, c, 0x14, 0x00);
+               atp_writeb_io(dev, c, 0x18, 0x08);
+
+               while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00);
+
+               j = atp_readb_io(dev, c, 0x17);
                if (j != 0x16) {
                        if (j == 0x4e) {
                                goto u3p_out;
@@ -3188,54 +1989,44 @@ u3p_cmd:
                        continue;
                }
 chg_wide:
-               tmport = wkport + 0x1b;
-               outb(0x01, tmport);
-               tmport = wkport + 0x03;
-               outb(satn[0], tmport++);
-               outb(satn[1], tmport++);
-               outb(satn[2], tmport++);
-               outb(satn[3], tmport++);
-               outb(satn[4], tmport++);
-               outb(satn[5], tmport++);
-               tmport += 0x06;
-               outb(0, tmport);
-               tmport += 0x02;
-               outb(dev->id[c][i].devsp, tmport++);
-               outb(0, tmport++);
-               outb(satn[6], tmport++);
-               outb(satn[7], tmport++);
-               tmport += 0x03;
-               outb(satn[8], tmport);
-               tmport += 0x07;
-
-               while ((inb(tmport) & 0x80) == 0x00)
+               atp_writeb_io(dev, c, 0x1b, 0x01);
+               atp_writeb_io(dev, c, 3, satn[0]);
+               atp_writeb_io(dev, c, 4, satn[1]);
+               atp_writeb_io(dev, c, 5, satn[2]);
+               atp_writeb_io(dev, c, 6, satn[3]);
+               atp_writeb_io(dev, c, 7, satn[4]);
+               atp_writeb_io(dev, c, 8, satn[5]);
+               atp_writeb_io(dev, c, 0x0f, 0);
+               atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp);
+               atp_writeb_io(dev, c, 0x12, 0);
+               atp_writeb_io(dev, c, 0x13, satn[6]);
+               atp_writeb_io(dev, c, 0x14, satn[7]);
+               atp_writeb_io(dev, c, 0x18, satn[8]);
+
+               while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00)
                        cpu_relax();
-               tmport -= 0x08;
-               if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
+
+               if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e)
                        continue;
-               }
-               while (inb(tmport) != 0x8e)
+
+               while (atp_readb_io(dev, c, 0x17) != 0x8e)
                        cpu_relax();
+
 try_wide:
                j = 0;
-               tmport = wkport + 0x14;
-               outb(0x05, tmport);
-               tmport += 0x04;
-               outb(0x20, tmport);
-               tmport += 0x07;
-
-               while ((inb(tmport) & 0x80) == 0) {
-                       if ((inb(tmport) & 0x01) != 0) {
-                               tmport -= 0x06;
-                               outb(wide[j++], tmport);
-                               tmport += 0x06;
-                       }
+               atp_writeb_io(dev, c, 0x14, 0x05);
+               atp_writeb_io(dev, c, 0x18, 0x20);
+
+               while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) {
+                       if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0)
+                               atp_writeb_io(dev, c, 0x19, wide[j++]);
                        cpu_relax();
                }
-               tmport -= 0x08;
-               while ((inb(tmport) & 0x80) == 0x00)
+
+               while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00)
                        cpu_relax();
-               j = inb(tmport) & 0x0f;
+
+               j = atp_readb_io(dev, c, 0x17) & 0x0f;
                if (j == 0x0f) {
                        goto widep_in;
                }
@@ -3247,19 +2038,13 @@ try_wide:
                }
                continue;
 widep_out:
-               tmport = wkport + 0x18;
-               outb(0x20, tmport);
-               tmport += 0x07;
-               while ((inb(tmport) & 0x80) == 0) {
-                       if ((inb(tmport) & 0x01) != 0) {
-                               tmport -= 0x06;
-                               outb(0, tmport);
-                               tmport += 0x06;
-                       }
+               atp_writeb_io(dev, c, 0x18, 0x20);
+               while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) {
+                       if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0)
+                               atp_writeb_io(dev, c, 0x19, 0);
                        cpu_relax();
                }
-               tmport -= 0x08;
-               j = inb(tmport) & 0x0f;
+               j = atp_readb_io(dev, c, 0x17) & 0x0f;
                if (j == 0x0f) {
                        goto widep_in;
                }
@@ -3271,25 +2056,19 @@ widep_out:
                }
                continue;
 widep_in:
-               tmport = wkport + 0x14;
-               outb(0xff, tmport);
-               tmport += 0x04;
-               outb(0x20, tmport);
-               tmport += 0x07;
+               atp_writeb_io(dev, c, 0x14, 0xff);
+               atp_writeb_io(dev, c, 0x18, 0x20);
                k = 0;
 widep_in1:
-               j = inb(tmport);
+               j = atp_readb_io(dev, c, 0x1f);
                if ((j & 0x01) != 0) {
-                       tmport -= 0x06;
-                       mbuf[k++] = inb(tmport);
-                       tmport += 0x06;
+                       mbuf[k++] = atp_readb_io(dev, c, 0x19);
                        goto widep_in1;
                }
                if ((j & 0x80) == 0x00) {
                        goto widep_in1;
                }
-               tmport -= 0x08;
-               j = inb(tmport) & 0x0f;
+               j = atp_readb_io(dev, c, 0x17) & 0x0f;
                if (j == 0x0f) {
                        goto widep_in;
                }
@@ -3301,17 +2080,14 @@ widep_in1:
                }
                continue;
 widep_cmd:
-               tmport = wkport + 0x10;
-               outb(0x30, tmport);
-               tmport = wkport + 0x14;
-               outb(0x00, tmport);
-               tmport += 0x04;
-               outb(0x08, tmport);
-               tmport += 0x07;
-               while ((inb(tmport) & 0x80) == 0x00)
+               atp_writeb_io(dev, c, 0x10, 0x30);
+               atp_writeb_io(dev, c, 0x14, 0x00);
+               atp_writeb_io(dev, c, 0x18, 0x08);
+
+               while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00)
                        cpu_relax();
-               tmport -= 0x08;
-               j = inb(tmport);
+
+               j = atp_readb_io(dev, c, 0x17);
                if (j != 0x16) {
                        if (j == 0x4e) {
                                goto widep_out;
@@ -3334,88 +2110,81 @@ widep_cmd:
                m = m << i;
                dev->wide_id[c] |= m;
 not_wide:
-               if ((dev->id[c][i].devtype == 0x00) || (dev->id[c][i].devtype == 0x07) ||
-                   ((dev->id[c][i].devtype == 0x05) && ((n & 0x10) != 0))) {
+               if ((dev->id[c][i].devtype == 0x00) || (dev->id[c][i].devtype == 0x07) || ((dev->id[c][i].devtype == 0x05) && ((n & 0x10) != 0))) {
                        m = 1;
                        m = m << i;
                        if ((dev->async[c] & m) != 0) {
-                          goto set_sync;
+                               goto set_sync;
                        }
                }
                continue;
 set_sync:
-               if (dev->sp[c][i] == 0x02) {
-                  synu[4]=0x0c;
-                  synuw[4]=0x0c;
+               if ((!is885(dev) && !is880(dev)) || (dev->sp[c][i] == 0x02)) {
+                       synu[4] = 0x0c;
+                       synuw[4] = 0x0c;
                } else {
-                  if (dev->sp[c][i] >= 0x03) {
-                     synu[4]=0x0a;
-                     synuw[4]=0x0a;
-                  }
+                       if (dev->sp[c][i] >= 0x03) {
+                               synu[4] = 0x0a;
+                               synuw[4] = 0x0a;
+                       }
                }
-               tmport = wkport + 0x1b;
                j = 0;
                if ((m & dev->wide_id[c]) != 0) {
                        j |= 0x01;
                }
-               outb(j, tmport);
-               tmport = wkport + 0x03;
-               outb(satn[0], tmport++);
-               outb(satn[1], tmport++);
-               outb(satn[2], tmport++);
-               outb(satn[3], tmport++);
-               outb(satn[4], tmport++);
-               outb(satn[5], tmport++);
-               tmport += 0x06;
-               outb(0, tmport);
-               tmport += 0x02;
-               outb(dev->id[c][i].devsp, tmport++);
-               outb(0, tmport++);
-               outb(satn[6], tmport++);
-               outb(satn[7], tmport++);
-               tmport += 0x03;
-               outb(satn[8], tmport);
-               tmport += 0x07;
-
-               while ((inb(tmport) & 0x80) == 0x00)
+               atp_writeb_io(dev, c, 0x1b, j);
+               atp_writeb_io(dev, c, 3, satn[0]);
+               atp_writeb_io(dev, c, 4, satn[1]);
+               atp_writeb_io(dev, c, 5, satn[2]);
+               atp_writeb_io(dev, c, 6, satn[3]);
+               atp_writeb_io(dev, c, 7, satn[4]);
+               atp_writeb_io(dev, c, 8, satn[5]);
+               atp_writeb_io(dev, c, 0x0f, 0);
+               atp_writeb_io(dev, c, 0x11, dev->id[c][i].devsp);
+               atp_writeb_io(dev, c, 0x12, 0);
+               atp_writeb_io(dev, c, 0x13, satn[6]);
+               atp_writeb_io(dev, c, 0x14, satn[7]);
+               atp_writeb_io(dev, c, 0x18, satn[8]);
+
+               while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00)
                        cpu_relax();
-               tmport -= 0x08;
-               if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) {
+
+               if (atp_readb_io(dev, c, 0x17) != 0x11 && atp_readb_io(dev, c, 0x17) != 0x8e)
                        continue;
-               }
-               while (inb(tmport) != 0x8e)
+
+               while (atp_readb_io(dev, c, 0x17) != 0x8e)
                        cpu_relax();
+
 try_sync:
                j = 0;
-               tmport = wkport + 0x14;
-               outb(0x06, tmport);
-               tmport += 0x04;
-               outb(0x20, tmport);
-               tmport += 0x07;
-
-               while ((inb(tmport) & 0x80) == 0) {
-                       if ((inb(tmport) & 0x01) != 0) {
-                               tmport -= 0x06;
+               atp_writeb_io(dev, c, 0x14, 0x06);
+               atp_writeb_io(dev, c, 0x18, 0x20);
+
+               while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0) {
+                       if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0) {
                                if ((m & dev->wide_id[c]) != 0) {
-                                       if ((m & dev->ultra_map[c]) != 0) {
-                                               outb(synuw[j++], tmport);
-                                       } else {
-                                               outb(synw[j++], tmport);
-                                       }
+                                       if (is885(dev) || is880(dev)) {
+                                               if ((m & dev->ultra_map[c]) != 0) {
+                                                       atp_writeb_io(dev, c, 0x19, synuw[j++]);
+                                               } else {
+                                                       atp_writeb_io(dev, c, 0x19, synw[j++]);
+                                               }
+                                       } else
+                                               atp_writeb_io(dev, c, 0x19, synw_870[j++]);
                                } else {
                                        if ((m & dev->ultra_map[c]) != 0) {
-                                               outb(synu[j++], tmport);
+                                               atp_writeb_io(dev, c, 0x19, synu[j++]);
                                        } else {
-                                               outb(synn[j++], tmport);
+                                               atp_writeb_io(dev, c, 0x19, synn[j++]);
                                        }
                                }
-                               tmport += 0x06;
                        }
                }
-               tmport -= 0x08;
-               while ((inb(tmport) & 0x80) == 0x00)
+
+               while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00)
                        cpu_relax();
-               j = inb(tmport) & 0x0f;
+
+               j = atp_readb_io(dev, c, 0x17) & 0x0f;
                if (j == 0x0f) {
                        goto phase_ins;
                }
@@ -3427,19 +2196,13 @@ try_sync:
                }
                continue;
 phase_outs:
-               tmport = wkport + 0x18;
-               outb(0x20, tmport);
-               tmport += 0x07;
-               while ((inb(tmport) & 0x80) == 0x00) {
-                       if ((inb(tmport) & 0x01) != 0x00) {
-                               tmport -= 0x06;
-                               outb(0x00, tmport);
-                               tmport += 0x06;
-                       }
+               atp_writeb_io(dev, c, 0x18, 0x20);
+               while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00) {
+                       if ((atp_readb_io(dev, c, 0x1f) & 0x01) != 0x00)
+                               atp_writeb_io(dev, c, 0x19, 0x00);
                        cpu_relax();
                }
-               tmport -= 0x08;
-               j = inb(tmport);
+               j = atp_readb_io(dev, c, 0x17);
                if (j == 0x85) {
                        goto tar_dcons;
                }
@@ -3455,26 +2218,25 @@ phase_outs:
                }
                continue;
 phase_ins:
-               tmport = wkport + 0x14;
-               outb(0x06, tmport);
-               tmport += 0x04;
-               outb(0x20, tmport);
-               tmport += 0x07;
+               if (is885(dev) || is880(dev))
+                       atp_writeb_io(dev, c, 0x14, 0x06);
+               else
+                       atp_writeb_io(dev, c, 0x14, 0xff);
+               atp_writeb_io(dev, c, 0x18, 0x20);
                k = 0;
 phase_ins1:
-               j = inb(tmport);
+               j = atp_readb_io(dev, c, 0x1f);
                if ((j & 0x01) != 0x00) {
-                       tmport -= 0x06;
-                       mbuf[k++] = inb(tmport);
-                       tmport += 0x06;
+                       mbuf[k++] = atp_readb_io(dev, c, 0x19);
                        goto phase_ins1;
                }
                if ((j & 0x80) == 0x00) {
                        goto phase_ins1;
                }
-               tmport -= 0x08;
-               while ((inb(tmport) & 0x80) == 0x00);
-               j = inb(tmport);
+
+               while ((atp_readb_io(dev, c, 0x17) & 0x80) == 0x00);
+
+               j = atp_readb_io(dev, c, 0x17);
                if (j == 0x85) {
                        goto tar_dcons;
                }
@@ -3490,18 +2252,15 @@ phase_ins1:
                }
                continue;
 phase_cmds:
-               tmport = wkport + 0x10;
-               outb(0x30, tmport);
+               atp_writeb_io(dev, c, 0x10, 0x30);
 tar_dcons:
-               tmport = wkport + 0x14;
-               outb(0x00, tmport);
-               tmport += 0x04;
-               outb(0x08, tmport);
-               tmport += 0x07;
-               while ((inb(tmport) & 0x80) == 0x00)
+               atp_writeb_io(dev, c, 0x14, 0x00);
+               atp_writeb_io(dev, c, 0x18, 0x08);
+
+               while ((atp_readb_io(dev, c, 0x1f) & 0x80) == 0x00)
                        cpu_relax();
-               tmport -= 0x08;
-               j = inb(tmport);
+
+               j = atp_readb_io(dev, c, 0x17);
                if (j != 0x16) {
                        continue;
                }
@@ -3517,14 +2276,21 @@ tar_dcons:
                if (mbuf[3] > 0x64) {
                        continue;
                }
-               if (mbuf[4] > 0x0e) {
-                       mbuf[4] = 0x0e;
+               if (is885(dev) || is880(dev)) {
+                       if (mbuf[4] > 0x0e) {
+                               mbuf[4] = 0x0e;
+                       }
+               } else {
+                       if (mbuf[4] > 0x0c) {
+                               mbuf[4] = 0x0c;
+                       }
                }
                dev->id[c][i].devsp = mbuf[4];
-               if (mbuf[3] < 0x0c){
-                       j = 0xb0;
-                       goto set_syn_ok;
-               }
+               if (is885(dev) || is880(dev))
+                       if (mbuf[3] < 0x0c) {
+                               j = 0xb0;
+                               goto set_syn_ok;
+                       }
                if ((mbuf[3] < 0x0d) && (rmb == 0)) {
                        j = 0xa0;
                        goto set_syn_ok;
@@ -3542,16 +2308,10 @@ tar_dcons:
                        goto set_syn_ok;
                }
                j = 0x60;
-             set_syn_ok:
+set_syn_ok:
                dev->id[c][i].devsp = (dev->id[c][i].devsp & 0x0f) | j;
-#ifdef ED_DBGP         
+#ifdef ED_DBGP
                printk("dev->id[%2d][%2d].devsp = %2x\n",c,i,dev->id[c][i].devsp);
 #endif
        }
-       tmport = wkport + 0x16;
-       outb(0x80, tmport);
 }
-
-module_init(atp870u_init);
-module_exit(atp870u_exit);
-
This page took 0.128228 seconds and 5 git commands to generate.