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 96214035b6d6652bd243e90166e8842cdb2aabb9..8b52a9dbb9cf5a5fd18dd572f9459db57783b074 100644 (file)
@@ -42,7 +42,6 @@
 static struct scsi_host_template atp870u_template;
 static void send_s870(struct atp_unit *dev,unsigned char c);
 static void atp_is(struct atp_unit *dev, unsigned char c, bool wide_chip, unsigned char lvdmode);
-static void tscam_885(void);
 
 static inline void atp_writeb_base(struct atp_unit *atp, u8 reg, u8 val)
 {
@@ -104,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;
@@ -132,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));
                }               
@@ -149,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);
@@ -170,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);
@@ -179,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);
@@ -250,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;
@@ -302,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
@@ -317,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                 
@@ -349,15 +359,14 @@ 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
@@ -418,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);
                        }
@@ -455,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);
                        }
@@ -517,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]);
@@ -536,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]);
@@ -738,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;
@@ -776,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);
@@ -874,15 +883,14 @@ 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
@@ -955,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;
@@ -978,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;
        }
@@ -1013,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);
@@ -1241,85 +1249,85 @@ static void atp_set_host_id(struct atp_unit *atp, u8 c, u8 host_id)
        atp_writeb_io(atp, c, 0x11, 0x20);
 }
 
-/* return non-zero on detection */
-static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+static void atp870_init(struct Scsi_Host *shpnt)
 {
-       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;
-        }
-
-       /*
-        * 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;
+       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;
 
-               atpdev->ioport[0] = base_io + 0x40;
-               atpdev->pciport[0] = base_io + 0x28;
+       pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80);
 
-               host_id = atp_readb_base(atpdev, 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->dev_id = ent->device;
-               atpdev->host_id[0] = host_id;
+       host_id = atp_readb_base(atpdev, 0x39) >> 4;
 
-               atpdev->scam_on = atp_readb_base(atpdev, 0x22);
-               atpdev->global_map[0] = atp_readb_base(atpdev, 0x35);
-               atpdev->ultra_map[0] = atp_readw_base(atpdev, 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;
                atp_writew_base(atpdev, 0x34, n);
                n += 0x0002;
                if (atp_readb_base(atpdev, 0x30) == 0xff)
-                       goto flash_ok_880;
+                       break;
 
                atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x30);
                atpdev->sp[0][m++] = atp_readb_base(atpdev, 0x31);
@@ -1344,319 +1352,230 @@ next_fblk_880:
                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:
-               atp_writew_base(atpdev, 0x34, 0);
-               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]);
-               atp_writeb_base(atpdev, 0x35, atpdev->global_map[0]);
-               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 = atp_readb_base(p, 0x38) & 0x80;
-               atp_writeb_base(p, 0x38, k);
-               atp_writeb_base(p, 0x3b, 0x20);
-               mdelay(32);
-               atp_writeb_base(p, 0x3b, 0);
-               mdelay(32);
-               atp_readb_io(p, 0, 0x1b);
-               atp_readb_io(p, 0, 0x17);
-
-               atp_set_host_id(p, 0, host_id);
-
-               tscam(shpnt);
-               atp_is(p, 0, true, atp_readb_base(p, 0x3f) & 0x40);
-               atp_writeb_base(p, 0x38, 0xb0);
-               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 = atp_readb_base(p, 0x29);
-               atp_writeb_base(p, 0x29, c | 0x04);
-               
-               n=0x1f80;
-next_fblk_885:
-               if (n >= 0x2000) {
-                  goto flash_ok_885;
-               }
-               atp_writew_base(p, 0x3c, n);
-               if (atp_readl_base(p, 0x38) == 0xffffffff) {
-                  goto flash_ok_885;
-               }
-               for (m=0; m < 2; m++) {
-                   p->global_map[m]= 0;
-                   for (k=0; k < 4; k++) {
-                       atp_writew_base(p, 0x3c, n++);
-                       ((unsigned long *)&setupdata[m][0])[k] = atp_readl_base(p, 0x38);
-                   }
-                   for (k=0; k < 4; k++) {
-                       atp_writew_base(p, 0x3c, n++);
-                       ((unsigned long *)&p->sp[m][0])[k] = atp_readl_base(p, 0x38);
-                   }
-                   n += 8;
-               }
-               goto next_fblk_885;
-flash_ok_885:
-#ifdef ED_DBGP
-               printk( "Flash Read OK\n");
-#endif 
-               c = atp_readb_base(p, 0x29);
-               atp_writeb_base(p, 0x29, c & 0xfb);
-               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 = atp_readb_base(p, 0x28) & 0x8f;
-               k |= 0x10;
-               atp_writeb_base(p, 0x28, k);
-               atp_writeb_pci(p, 0, 1, 0x80);
-               atp_writeb_pci(p, 1, 1, 0x80);
-               mdelay(100);
-               atp_writeb_pci(p, 0, 1, 0);
-               atp_writeb_pci(p, 1, 1, 0);
-               mdelay(1000);
-               atp_readb_io(p, 0, 0x1b);
-               atp_readb_io(p, 0, 0x17);
-               atp_readb_io(p, 1, 0x1b);
-               atp_readb_io(p, 1, 0x17);
-
-               k=p->host_id[0];
-               if (k > 7)
-                  k = (k & 0x07) | 0x40;
-               atp_set_host_id(p, 0, k);
-
-               k=p->host_id[1];
-               if (k > 7)
-                  k = (k & 0x07) | 0x40;
-               atp_set_host_id(p, 1, k);
-
-               tscam_885();
-               printk(KERN_INFO "   Scanning Channel A SCSI Device ...\n");
-               atp_is(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");
-               atp_is(p, 1, true, atp_readb_io(p, 1, 0x1b) >> 7);
-               atp_writeb_io(p, 1, 0x16, 0x80);
-               k = atp_readb_base(p, 0x28) & 0xcf;
-               k |= 0xc0;
-               atp_writeb_base(p, 0x28, k);
-               k = atp_readb_base(p, 0x1f) | 0x80;
-               atp_writeb_base(p, 0x1f, k);
-               k = atp_readb_base(p, 0x29) | 0x01;
-               atp_writeb_base(p, 0x29, k);
-#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);
+               atpdev->async[c] = ~(atpdev->async[c]);
 
-               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);
+               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;
+               }
+       }
 
-               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 = atp_readb_pci(atpdev, 0, 2);
-               atpdev->global_map[0] = atp_readb_base(atpdev, 0x2d);
-               atpdev->ultra_map[0] = atp_readw_base(atpdev, 0x2e);
+       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];
+}
 
-               if (atpdev->ultra_map[0] == 0) {
-                       atpdev->scam_on = 0x00;
-                       atpdev->global_map[0] = 0x20;
-                       atpdev->ultra_map[0] = 0xffff;
-               }
+/* 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 (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 */
-                       atp_writeb_base(p, 0x3e, 0x00);
-               k = (atp_readb_base(p, 0x3a) & 0xf3) | 0x10;
-               atp_writeb_base(p, 0x3a, k);
-               atp_writeb_base(p, 0x3a, k & 0xdf);
-               mdelay(32);
-               atp_writeb_base(p, 0x3a, k);
-               mdelay(32);
-               atp_set_host_id(p, 0, host_id);
-
-               tscam(shpnt);
-               atp_writeb_base(p, 0x3a, atp_readb_base(p, 0x3a) | 0x10);
-               atp_is(p, 0, p->chip_ver == 4, 0);
-               atp_writeb_base(p, 0x3a, atp_readb_base(p, 0x3a) & 0xef);
-               atp_writeb_base(p, 0x3b, atp_readb_base(p, 0x3b) | 0x20);
-               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;
        }
-request_io_fail:
-       printk("atp870u_prob:request_io_fail\n");
-       free_irq(pdev->irq, shpnt);
+
+       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;
+       }
+
+       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
@@ -1742,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");
@@ -1791,33 +1708,7 @@ 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 atp_is(struct atp_unit *dev, unsigned char c, bool wide_chip, unsigned char lvdmode)
 {
@@ -1879,7 +1770,7 @@ static void atp_is(struct atp_unit *dev, unsigned char c, bool wide_chip, unsign
                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);
@@ -1959,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? */
@@ -2228,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 {
@@ -2272,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 {
@@ -2327,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);
@@ -2385,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;
                        }
@@ -2395,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;
@@ -2424,7 +2315,3 @@ set_syn_ok:
 #endif
        }
 }
-
-module_init(atp870u_init);
-module_exit(atp870u_exit);
-
This page took 0.041902 seconds and 5 git commands to generate.