Merge tag 'pwm/for-4.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry...
[deliverable/linux.git] / drivers / scsi / atp870u.c
index 918875bc92feb3b331b106fbc84a19e09b221ac8..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 char c, bool wide_chip, unsigned char lvdmode);
-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);
@@ -74,6 +78,16 @@ 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);
@@ -89,6 +103,17 @@ 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;
@@ -117,7 +142,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
        dev->in_int[c] = 1;
        cmdp = atp_readb_io(dev, c, 0x10);
        if (dev->working[c] != 0) {
-               if (dev->dev_id == ATP885_DEVID) {
+               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));
                }               
@@ -134,7 +159,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
                
                i = atp_readb_io(dev, c, 0x17);
                
-               if (dev->dev_id == ATP885_DEVID)
+               if (is885(dev))
                        atp_writeb_pci(dev, c, 2, 0x06);
 
                target_id = atp_readb_io(dev, c, 0x15);
@@ -155,7 +180,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
                     }
                     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);
@@ -164,7 +189,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
                        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] = atp_readb_io(dev, c, 0x12);
                                ((unsigned char *) &adrcnt)[1] = atp_readb_io(dev, c, 0x13);
@@ -235,7 +260,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
                        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;
@@ -287,7 +312,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
                        if (dev->last_cmd[c] != 0xff) {
                           dev->last_cmd[c] |= 0x40;
                        }
-                       if (dev->dev_id == ATP885_DEVID) {
+                       if (is885(dev)) {
                                j = atp_readb_base(dev, 0x29) & 0xfe;
                                atp_writeb_base(dev, 0x29, j);
                        } else
@@ -302,7 +327,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
                        } else {
                                target_id &= 0x07;
                        }
-                       if (dev->dev_id == ATP885_DEVID)
+                       if (is885(dev))
                                atp_writeb_io(dev, c, 0x10, 0x45);
                        workreq = dev->id[c][target_id].curr_req;
 #ifdef ED_DBGP                 
@@ -334,24 +359,23 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
                        atp_writeb_io(dev, c, 0x16, 0x80);
                        
                        /* enable 32 bit fifo transfer */       
-                       if (dev->dev_id == ATP885_DEVID) {
+                       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;
                                }
                                atp_writeb_pci(dev, c, 1, i);
-                       } else if ((dev->dev_id == ATP880_DEVID1) ||
-                                  (dev->dev_id == ATP880_DEVID2) ) {
+                       } 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))
-                                       atp_writeb_io(dev, c, 0x3a, (atp_readb_io(dev, c, 0x3a) & 0xf3) | 0x08);
+                                       atp_writeb_base(dev, 0x3a, (atp_readb_base(dev, 0x3a) & 0xf3) | 0x08);
                                else
-                                       atp_writeb_io(dev, c, 0x3a, atp_readb_io(dev, c, 0x3a) & 0xf3);
+                                       atp_writeb_base(dev, 0x3a, atp_readb_base(dev, 0x3a) & 0xf3);
                        }       
                        j = 0;
                        id = 1;
@@ -403,7 +427,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
 #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) {
+                       if (!is885(dev)) {
                                atp_writeb_pci(dev, c, 2, 0x06);
                                atp_writeb_pci(dev, c, 2, 0x00);
                        }
@@ -440,14 +464,14 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
                        }
                        if (i == 0x16) {
                                workreq->result = atp_readb_io(dev, c, 0x0f);
-                               if (((dev->r1f[c][target_id] & 0x10) != 0)&&(dev->dev_id==ATP885_DEVID)) {
+                               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 (dev->dev_id == ATP885_DEVID) {              
+                       if (is885(dev)) {
                                j = atp_readb_base(dev, 0x29) | 0x01;
                                atp_writeb_base(dev, 0x29, j);
                        }
@@ -502,7 +526,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
                        atp_writeb_pci(dev, c, 2, 0x06);
                        atp_writeb_pci(dev, c, 2, 0x00);
                        atp_writeb_io(dev, c, 0x10, 0x41);
-                       if (dev->dev_id == ATP885_DEVID) {
+                       if (is885(dev)) {
                                k = dev->id[c][target_id].last_len;
                                atp_writeb_io(dev, c, 0x12, ((unsigned char *) (&k))[2]);
                                atp_writeb_io(dev, c, 0x13, ((unsigned char *) (&k))[1]);
@@ -521,7 +545,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
                        atp_writeb_pci(dev, c, 2, 0x06);
                        atp_writeb_pci(dev, c, 2, 0x00);
                        atp_writeb_io(dev, c, 0x10, 0x41);
-                       if (dev->dev_id == ATP885_DEVID) {              
+                       if (is885(dev)) {
                                k = dev->id[c][target_id].last_len;
                                atp_writeb_io(dev, c, 0x12, ((unsigned char *) (&k))[2]);
                                atp_writeb_io(dev, c, 0x13, ((unsigned char *) (&k))[1]);
@@ -723,7 +747,7 @@ static void send_s870(struct atp_unit *dev,unsigned char c)
 #endif 
        l = scsi_bufflen(workreq);
 
-       if (dev->dev_id == ATP885_DEVID) {
+       if (is885(dev)) {
                j = atp_readb_base(dev, 0x29) & 0xfe;
                atp_writeb_base(dev, 0x29, j);
                dev->r1f[c][scmd_id(workreq)] = 0;
@@ -761,7 +785,7 @@ static void send_s870(struct atp_unit *dev,unsigned char c)
 
        atp_writeb_io(dev, c, 0x00, workreq->cmd_len);
        atp_writeb_io(dev, c, 0x01, 0x2c);
-       if (dev->dev_id == ATP885_DEVID)
+       if (is885(dev))
                atp_writeb_io(dev, c, 0x02, 0x7f);
        else
                atp_writeb_io(dev, c, 0x02, 0xcf);
@@ -859,24 +883,23 @@ static void send_s870(struct atp_unit *dev,unsigned char c)
        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 (dev->dev_id == ATP885_DEVID) {
+       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;
                }
                atp_writeb_pci(dev, c, 1, j);
-       } else if ((dev->dev_id == ATP880_DEVID1) ||
-                  (dev->dev_id == ATP880_DEVID2)) {
+       } 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))
-                       atp_writeb_io(dev, c, 0x3a, (atp_readb_io(dev, c, 0x3a) & 0xf3) | 0x08);
+                       atp_writeb_base(dev, 0x3a, (atp_readb_base(dev, 0x3a) & 0xf3) | 0x08);
                else
-                       atp_writeb_io(dev, c, 0x3a, atp_readb_io(dev, c, 0x3a) & 0xf3);
+                       atp_writeb_base(dev, 0x3a, atp_readb_base(dev, 0x3a) & 0xf3);
        }       
 
        if(workreq->sc_data_direction == DMA_TO_DEVICE) {
@@ -940,7 +963,7 @@ static unsigned char fun_scam(struct atp_unit *dev, unsigned short int *val)
        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;
@@ -963,13 +986,13 @@ static void tscam(struct Scsi_Host *host)
        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;
        }
@@ -998,7 +1021,7 @@ static void tscam(struct Scsi_Host *host)
                        k = i;
                }
                atp_writeb_io(dev, 0, 0x15, k);
-               if (dev->chip_ver == 4)
+               if (wide_chip)
                        atp_writeb_io(dev, 0, 0x1b, 0x01);
                else
                        atp_writeb_io(dev, 0, 0x1b, 0x00);
@@ -1021,7 +1044,7 @@ static void tscam(struct Scsi_Host *host)
        atp_writeb_io(dev, 0, 0x02, 0x7f);
        atp_writeb_io(dev, 0, 0x1b, 0x02);
 
-       outb(0, 0x80);
+       udelay(2);
 
        val = 0x0080;           /* bsy  */
        atp_writew_io(dev, 0, 0x1c, val);
@@ -1029,7 +1052,7 @@ static void tscam(struct Scsi_Host *host)
        atp_writew_io(dev, 0, 0x1c, val);
        val |= 0x0004;          /* msg  */
        atp_writew_io(dev, 0, 0x1c, val);
-       inb(0x80);              /* 2 deskew delay(45ns*2=90ns) */
+       udelay(2);              /* 2 deskew delay(45ns*2=90ns) */
        val &= 0x007f;          /* no bsy  */
        atp_writew_io(dev, 0, 0x1c, val);
        mdelay(128);
@@ -1037,7 +1060,7 @@ static void tscam(struct Scsi_Host *host)
        atp_writew_io(dev, 0, 0x1c, val);
        while ((atp_readb_io(dev, 0, 0x1c) & 0x04) != 0)
                ;
-       outb(1, 0x80);
+       udelay(2);
        udelay(100);
        for (n = 0; n < 0x30000; n++)
                if ((atp_readb_io(dev, 0, 0x1c) & 0x80) != 0)   /* bsy ? */
@@ -1045,13 +1068,13 @@ static void tscam(struct Scsi_Host *host)
        if (n < 0x30000)
                for (n = 0; n < 0x30000; n++)
                        if ((atp_readb_io(dev, 0, 0x1c) & 0x81) == 0x0081) {
-                               inb(0x80);
+                               udelay(2);
                                val |= 0x8003;          /* io,cd,db7  */
                                atp_writew_io(dev, 0, 0x1c, val);
-                               inb(0x80);
+                               udelay(2);
                                val &= 0x00bf;          /* no sel     */
                                atp_writew_io(dev, 0, 0x1c, val);
-                               outb(2, 0x80);
+                               udelay(2);
                                break;
                        }
        while (1) {
@@ -1078,18 +1101,18 @@ static void tscam(struct Scsi_Host *host)
        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;
 
        while (1) {
                if ((atp_readw_io(dev, 0, 0x1c) & 0x2000) == 0)
                        continue;
-               outb(5, 0x80);
+               udelay(2);
                val &= 0x00ff;          /* get ID_STRING */
                val |= 0x2000;
                k = fun_scam(dev, &val);
@@ -1214,456 +1237,345 @@ static int atp870u_init_tables(struct Scsi_Host *host)
        return 0;
 }
 
-/* return non-zero on detection */
-static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+static void atp_set_host_id(struct atp_unit *atp, u8 c, u8 host_id)
 {
-       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;
-
-       atpdev = kzalloc(sizeof(*atpdev), GFP_KERNEL);
-       if (!atpdev)
-               return -ENOMEM;
-
-       if (pci_enable_device(pdev))
-               goto err_eio;
-
-        if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
-                printk(KERN_INFO "atp870u: use 32bit DMA mask.\n");
-        } else {
-                printk(KERN_ERR "atp870u: DMA mask required but not available.\n");
-               goto err_eio;
-        }
+       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);
+}
 
-       /*
-        * 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;
+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;
        }
 
-       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;
-       }
-       base_io = pci_resource_start(pdev, 0);
-       base_io &= 0xfffffff8;
-       atpdev->baseport = base_io;
+       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;
+}
 
-       if ((ent->device == ATP880_DEVID1)||(ent->device == ATP880_DEVID2)) {
-               atpdev->chip_ver = pdev->revision;
-               pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80);//JCC082803
+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);
 
-               host_id = inb(base_io + 0x39);
-               host_id >>= 0x04;
+       atpdev->ioport[0] = shpnt->io_port + 0x40;
+       atpdev->pciport[0] = shpnt->io_port + 0x28;
 
-               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;
+       host_id = atp_readb_base(atpdev, 0x39) >> 4;
 
-               atpdev->scam_on = inb(base_io + 0x22);
-               atpdev->global_map[0] = inb(base_io + 0x35);
-               atpdev->ultra_map[0] = inw(base_io + 0x3c);
+       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;
 
-               n = 0x3f09;
-next_fblk_880:
-               if (n >= 0x4000)
-                       goto flash_ok_880;
+       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;
-               outw(n, base_io + 0x34);
+               atp_writew_base(atpdev, 0x34, n);
                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);
+               if (atp_readb_base(atpdev, 0x30) == 0xff)
+                       break;
+
+               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++] = 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);
+               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++] = 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);
+               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++] = 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);
+               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;
-               goto next_fblk_880;
-flash_ok_880:
-               outw(0, base_io + 0x34);
-               atpdev->ultra_map[0] = 0;
-               atpdev->async[0] = 0;
+       }
+       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;
+}
+
+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];
+
+       dev_info(&pdev->dev, "ACARD AEC-67162 PCI Ultra3 LVD Host Adapter: IO:%lx, IRQ:%d.\n",
+                shpnt->io_port, shpnt->irq);
+
+       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;
+
+       c = atp_readb_base(atpdev, 0x29);
+       atp_writeb_base(atpdev, 0x29, c | 0x04);
+
+       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;
+               }
+       }
+       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;
-                       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);
-               is885(p, 0, true, atp_readb_base(p, 0x3f) & 0x40);
-               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->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;
+                       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;
                }
-               
-               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();
+               atpdev->async[c] = ~(atpdev->async[c]);
 
-               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, 0, true, atp_readb_io(p, 0, 0x1b) >> 7);
-               atp_writeb_io(p, 0, 0x16, 0x80);
-               printk(KERN_INFO "   Scanning Channel B SCSI Device ...\n");
-               is885(p, 1, true, atp_readb_io(p, 1, 0x1b) >> 7);
-               atp_writeb_io(p, 1, 0x16, 0x80);
-               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);
+               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;
+               }
+       }
 
-               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);
+       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];
+}
 
-               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);
+/* return non-zero on detection */
+static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+       struct Scsi_Host *shpnt = NULL;
+       struct atp_unit *atpdev;
+       int err;
 
-               if (atpdev->ultra_map[0] == 0) {
-                       atpdev->scam_on = 0x00;
-                       atpdev->global_map[0] = 0x20;
-                       atpdev->ultra_map[0] = 0xffff;
-               }
+       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;
+       }
 
-               shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit));
-               if (!shpnt)
-                       goto err_nomem;
+       err = pci_enable_device(pdev);
+       if (err)
+               goto fail;
 
-               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);
-               atp_writeb_io(p, 0, 0x3a, atp_readb_io(p, 0, 0x3a) | 0x10);
-               is885(p, 0, p->chip_ver == 4, 0);
-               atp_writeb_io(p, 0, 0x3a, atp_readb_io(p, 0, 0x3a) & 0xef);
-               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;
+       if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
+                printk(KERN_ERR "atp870u: DMA mask required but not available.\n");
+                err = -EIO;
+                goto disable_device;
+        }
 
-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);
+       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;
+       }
+
+       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;
        }
-request_io_fail:
-       printk("atp870u_prob:request_io_fail\n");
-       free_irq(pdev->irq, shpnt);
+
+       err = scsi_add_host(shpnt, &pdev->dev);
+       if (err)
+               goto scsi_add_fail;
+       scsi_scan_host(shpnt);
+
+       return 0;
+
+scsi_add_fail:
+       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
@@ -1749,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");
@@ -1798,35 +1708,9 @@ 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);
-}
+module_pci_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;
-}
-
-
-
-static void is885(struct atp_unit *dev, unsigned char c, bool wide_chip, unsigned char lvdmode)
+static void atp_is(struct atp_unit *dev, unsigned char c, bool wide_chip, unsigned char lvdmode)
 {
        unsigned char i, j, k, rmb, n;
        unsigned short int m;
@@ -1886,7 +1770,7 @@ static void is885(struct atp_unit *dev, unsigned char c, bool wide_chip, unsigne
                dev->active_id[c] |= m;
 
                atp_writeb_io(dev, c, 0x10, 0x30);
-               if (dev->dev_id == ATP885_DEVID || dev->dev_id == ATP880_DEVID1 || dev->dev_id == ATP880_DEVID2)
+               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);
@@ -1966,7 +1850,7 @@ inq_ok:
                if ((mbuf[7] & 0x60) == 0) {
                        goto not_wide;
                }
-               if (dev->dev_id == ATP885_DEVID || dev->dev_id == ATP880_DEVID1 || dev->dev_id == ATP880_DEVID2) {
+               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? */
@@ -2235,7 +2119,7 @@ not_wide:
                }
                continue;
 set_sync:
-               if ((dev->dev_id != ATP885_DEVID && dev->dev_id != ATP880_DEVID1 && dev->dev_id != ATP880_DEVID2) || (dev->sp[c][i] == 0x02)) {
+               if ((!is885(dev) && !is880(dev)) || (dev->sp[c][i] == 0x02)) {
                        synu[4] = 0x0c;
                        synuw[4] = 0x0c;
                } else {
@@ -2279,7 +2163,7 @@ try_sync:
                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 (dev->dev_id == ATP885_DEVID || dev->dev_id == ATP880_DEVID1 || dev->dev_id == ATP880_DEVID2) {
+                                       if (is885(dev) || is880(dev)) {
                                                if ((m & dev->ultra_map[c]) != 0) {
                                                        atp_writeb_io(dev, c, 0x19, synuw[j++]);
                                                } else {
@@ -2334,7 +2218,7 @@ phase_outs:
                }
                continue;
 phase_ins:
-               if (dev->dev_id == ATP885_DEVID || dev->dev_id == ATP880_DEVID1 || dev->dev_id == ATP880_DEVID2)
+               if (is885(dev) || is880(dev))
                        atp_writeb_io(dev, c, 0x14, 0x06);
                else
                        atp_writeb_io(dev, c, 0x14, 0xff);
@@ -2392,7 +2276,7 @@ tar_dcons:
                if (mbuf[3] > 0x64) {
                        continue;
                }
-               if (dev->dev_id == ATP885_DEVID || dev->dev_id == ATP880_DEVID1 || dev->dev_id == ATP880_DEVID2) {
+               if (is885(dev) || is880(dev)) {
                        if (mbuf[4] > 0x0e) {
                                mbuf[4] = 0x0e;
                        }
@@ -2402,7 +2286,7 @@ tar_dcons:
                        }
                }
                dev->id[c][i].devsp = mbuf[4];
-               if (dev->dev_id == ATP885_DEVID || dev->dev_id == ATP880_DEVID1 || dev->dev_id == ATP880_DEVID2)
+               if (is885(dev) || is880(dev))
                        if (mbuf[3] < 0x0c) {
                                j = 0xb0;
                                goto set_syn_ok;
@@ -2431,7 +2315,3 @@ set_syn_ok:
 #endif
        }
 }
-
-module_init(atp870u_init);
-module_exit(atp870u_exit);
-
This page took 0.046032 seconds and 5 git commands to generate.