fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / scsi / atp870u.c
index 45b75dd..fec58cc 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/spinlock.h>
 #include <linux/pci.h>
 #include <linux/blkdev.h>
+#include <linux/dma-mapping.h>
 #include <asm/system.h>
 #include <asm/io.h>
 
@@ -43,7 +44,7 @@ static void send_s870(struct atp_unit *dev,unsigned char c);
 static void is885(struct atp_unit *dev, unsigned int wkport,unsigned char c);
 static void tscam_885(void);
 
-static irqreturn_t atp870u_intr_handle(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t atp870u_intr_handle(int irq, void *dev_id)
 {
        unsigned long flags;
        unsigned short int tmpcip, id;
@@ -297,11 +298,10 @@ stop_dma:
                        }
                        workreq = dev->id[c][target_id].curr_req;
 #ifdef ED_DBGP                 
-                       printk(KERN_DEBUG "Channel = %d ID = %d LUN = %d CDB",c,workreq->device->id,workreq->device->lun);
-                       for(l=0;l<workreq->cmd_len;l++)
-                       {
+                       scmd_printk(KERN_DEBUG, workreq, "CDB");
+                       for (l = 0; l < workreq->cmd_len; l++)
                                printk(KERN_DEBUG " %x",workreq->cmnd[l]);
-                       }
+                       printk("\n");
 #endif 
                        
                        tmport = workport + 0x0f;
@@ -473,7 +473,7 @@ go_42:
                         */
                        if (workreq->use_sg) {
                                pci_unmap_sg(dev->pdev,
-                                       (struct scatterlist *)workreq->buffer,
+                                       (struct scatterlist *)workreq->request_buffer,
                                        workreq->use_sg,
                                        workreq->sc_data_direction);
                        } else if (workreq->request_bufflen &&
@@ -622,10 +622,10 @@ static int atp870u_queuecommand(struct scsi_cmnd * req_p,
        struct atp_unit *dev;
        struct Scsi_Host *host;
 
-       c = req_p->device->channel;     
+       c = scmd_channel(req_p);
        req_p->sense_buffer[0]=0;
        req_p->resid = 0;
-       if (req_p->device->channel > 1) {
+       if (scmd_channel(req_p) > 1) {
                req_p->result = 0x00040000;
                done(req_p);
 #ifdef ED_DBGP         
@@ -640,7 +640,7 @@ static int atp870u_queuecommand(struct scsi_cmnd * req_p,
 
                
        m = 1;
-       m = m << req_p->device->id;
+       m = m << scmd_id(req_p);
 
        /*
         *      Fake a timeout for missing targets
@@ -758,9 +758,9 @@ static void send_s870(struct atp_unit *dev,unsigned char c)
                dev->quhd[c] = 0;
        }
        workreq = dev->quereq[c][dev->quhd[c]];
-       if (dev->id[c][workreq->device->id].curr_req == 0) {    
-               dev->id[c][workreq->device->id].curr_req = workreq;
-               dev->last_cmd[c] = workreq->device->id;
+       if (dev->id[c][scmd_id(workreq)].curr_req == 0) {       
+               dev->id[c][scmd_id(workreq)].curr_req = workreq;
+               dev->last_cmd[c] = scmd_id(workreq);
                goto cmd_subp;
        }       
        dev->quhd[c] = j;
@@ -787,16 +787,16 @@ abortsnd:
 oktosend:
 #ifdef ED_DBGP
        printk("OK to Send\n");
-       printk("CDB");
+       scmd_printk(KERN_DEBUG, workreq, "CDB");
        for(i=0;i<workreq->cmd_len;i++) {
                printk(" %x",workreq->cmnd[i]);
        }
-       printk("\nChannel = %d ID = %d LUN = %d\n",c,workreq->device->id,workreq->device->lun);
+       printk("\n");
 #endif 
        if (dev->dev_id == ATP885_DEVID) {
                j = inb(dev->baseport + 0x29) & 0xfe;
                outb(j, dev->baseport + 0x29);
-               dev->r1f[c][workreq->device->id] = 0;
+               dev->r1f[c][scmd_id(workreq)] = 0;
        }
        
        if (workreq->cmnd[0] == READ_CAPACITY) {
@@ -810,7 +810,7 @@ oktosend:
 
        tmport = workport + 0x1b;
        j = 0;
-       target_id = workreq->device->id;
+       target_id = scmd_id(workreq);
 
        /*
         *      Wide ?
@@ -996,6 +996,7 @@ oktosend:
 #ifdef ED_DBGP         
        printk("send_s870: prdaddr_2 0x%8x tmpcip %x target_id %d\n", dev->id[c][target_id].prdaddr,tmpcip,target_id);
 #endif 
+       dev->id[c][target_id].prdaddr = dev->id[c][target_id].prd_bus;
        outl(dev->id[c][target_id].prdaddr, tmpcip);
        tmpcip = tmpcip - 2;
        outb(0x06, tmpcip);
@@ -2572,7 +2573,7 @@ static void atp870u_free_tables(struct Scsi_Host *host)
                for (k = 0; k < 16; k++) {
                        if (!atp_dev->id[j][k].prd_table)
                                continue;
-                       pci_free_consistent(atp_dev->pdev, 1024, atp_dev->id[j][k].prd_table, atp_dev->id[j][k].prdaddr);
+                       pci_free_consistent(atp_dev->pdev, 1024, atp_dev->id[j][k].prd_table, atp_dev->id[j][k].prd_bus);
                        atp_dev->id[j][k].prd_table = NULL;
                }
        }
@@ -2584,12 +2585,13 @@ static int atp870u_init_tables(struct Scsi_Host *host)
        int c,k;
        for(c=0;c < 2;c++) {
                for(k=0;k<16;k++) {
-                               atp_dev->id[c][k].prd_table = pci_alloc_consistent(atp_dev->pdev, 1024, &(atp_dev->id[c][k].prdaddr));
+                               atp_dev->id[c][k].prd_table = pci_alloc_consistent(atp_dev->pdev, 1024, &(atp_dev->id[c][k].prd_bus));
                                if (!atp_dev->id[c][k].prd_table) {
                                        printk("atp870u_init_tables fail\n");
                                atp870u_free_tables(host);
                                return -ENOMEM;
                        }
+                       atp_dev->id[c][k].prdaddr = atp_dev->id[c][k].prd_bus;
                        atp_dev->id[c][k].devsp=0x20;
                        atp_dev->id[c][k].devtype = 0x7f;
                        atp_dev->id[c][k].curr_req = NULL;                         
@@ -2623,29 +2625,32 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        unsigned int base_io, tmport, error,n;
        unsigned char host_id;
        struct Scsi_Host *shpnt = NULL;
-       struct atp_unit atp_dev, *p;
+       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))
-               return -EIO;
+               goto err_eio;
 
-        if (!pci_set_dma_mask(pdev, 0xFFFFFFFFUL)) {
+        if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
                 printk(KERN_INFO "atp870u: use 32bit DMA mask.\n");
         } else {
                 printk(KERN_ERR "atp870u: DMA mask required but not available.\n");
-                return -EIO;
+               goto err_eio;
         }
 
-       memset(&atp_dev, 0, sizeof atp_dev);
        /*
         * 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) {
-               error = pci_read_config_byte(pdev, PCI_CLASS_REVISION, &atp_dev.chip_ver);
-               if (atp_dev.chip_ver < 2)
-                       return -EIO;
+               error = pci_read_config_byte(pdev, PCI_CLASS_REVISION, &atpdev->chip_ver);
+               if (atpdev->chip_ver < 2)
+                       goto err_eio;
        }
 
        switch (ent->device) {
@@ -2654,15 +2659,15 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        case ATP880_DEVID1:     
        case ATP880_DEVID2:     
        case ATP885_DEVID:      
-               atp_dev.chip_ver = 0x04;
+               atpdev->chip_ver = 0x04;
        default:
                break;
        }
        base_io = pci_resource_start(pdev, 0);
        base_io &= 0xfffffff8;
-       
+
        if ((ent->device == ATP880_DEVID1)||(ent->device == ATP880_DEVID2)) {
-               error = pci_read_config_byte(pdev, PCI_CLASS_REVISION, &atp_dev.chip_ver);
+               error = pci_read_config_byte(pdev, PCI_CLASS_REVISION, &atpdev->chip_ver);
                pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80);//JCC082803
 
                host_id = inb(base_io + 0x39);
@@ -2670,17 +2675,17 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
                printk(KERN_INFO "   ACARD AEC-67160 PCI Ultra3 LVD Host Adapter: %d"
                        "    IO:%x, IRQ:%d.\n", count, base_io, pdev->irq);
-               atp_dev.ioport[0] = base_io + 0x40;
-               atp_dev.pciport[0] = base_io + 0x28;
-               atp_dev.dev_id = ent->device;
-               atp_dev.host_id[0] = host_id;
+               atpdev->ioport[0] = base_io + 0x40;
+               atpdev->pciport[0] = base_io + 0x28;
+               atpdev->dev_id = ent->device;
+               atpdev->host_id[0] = host_id;
 
                tmport = base_io + 0x22;
-               atp_dev.scam_on = inb(tmport);
+               atpdev->scam_on = inb(tmport);
                tmport += 0x13;
-               atp_dev.global_map[0] = inb(tmport);
+               atpdev->global_map[0] = inb(tmport);
                tmport += 0x07;
-               atp_dev.ultra_map[0] = inw(tmport);
+               atpdev->ultra_map[0] = inw(tmport);
 
                n = 0x3f09;
 next_fblk_880:
@@ -2693,63 +2698,63 @@ next_fblk_880:
                if (inb(base_io + 0x30) == 0xff)
                        goto flash_ok_880;
 
-               atp_dev.sp[0][m++] = inb(base_io + 0x30);
-               atp_dev.sp[0][m++] = inb(base_io + 0x31);
-               atp_dev.sp[0][m++] = inb(base_io + 0x32);
-               atp_dev.sp[0][m++] = inb(base_io + 0x33);
+               atpdev->sp[0][m++] = inb(base_io + 0x30);
+               atpdev->sp[0][m++] = inb(base_io + 0x31);
+               atpdev->sp[0][m++] = inb(base_io + 0x32);
+               atpdev->sp[0][m++] = inb(base_io + 0x33);
                outw(n, base_io + 0x34);
                n += 0x0002;
-               atp_dev.sp[0][m++] = inb(base_io + 0x30);
-               atp_dev.sp[0][m++] = inb(base_io + 0x31);
-               atp_dev.sp[0][m++] = inb(base_io + 0x32);
-               atp_dev.sp[0][m++] = inb(base_io + 0x33);
+               atpdev->sp[0][m++] = inb(base_io + 0x30);
+               atpdev->sp[0][m++] = inb(base_io + 0x31);
+               atpdev->sp[0][m++] = inb(base_io + 0x32);
+               atpdev->sp[0][m++] = inb(base_io + 0x33);
                outw(n, base_io + 0x34);
                n += 0x0002;
-               atp_dev.sp[0][m++] = inb(base_io + 0x30);
-               atp_dev.sp[0][m++] = inb(base_io + 0x31);
-               atp_dev.sp[0][m++] = inb(base_io + 0x32);
-               atp_dev.sp[0][m++] = inb(base_io + 0x33);
+               atpdev->sp[0][m++] = inb(base_io + 0x30);
+               atpdev->sp[0][m++] = inb(base_io + 0x31);
+               atpdev->sp[0][m++] = inb(base_io + 0x32);
+               atpdev->sp[0][m++] = inb(base_io + 0x33);
                outw(n, base_io + 0x34);
                n += 0x0002;
-               atp_dev.sp[0][m++] = inb(base_io + 0x30);
-               atp_dev.sp[0][m++] = inb(base_io + 0x31);
-               atp_dev.sp[0][m++] = inb(base_io + 0x32);
-               atp_dev.sp[0][m++] = inb(base_io + 0x33);
+               atpdev->sp[0][m++] = inb(base_io + 0x30);
+               atpdev->sp[0][m++] = inb(base_io + 0x31);
+               atpdev->sp[0][m++] = inb(base_io + 0x32);
+               atpdev->sp[0][m++] = inb(base_io + 0x33);
                n += 0x0018;
                goto next_fblk_880;
 flash_ok_880:
                outw(0, base_io + 0x34);
-               atp_dev.ultra_map[0] = 0;
-               atp_dev.async[0] = 0;
+               atpdev->ultra_map[0] = 0;
+               atpdev->async[0] = 0;
                for (k = 0; k < 16; k++) {
                        n = 1;
                        n = n << k;
-                       if (atp_dev.sp[0][k] > 1) {
-                               atp_dev.ultra_map[0] |= n;
+                       if (atpdev->sp[0][k] > 1) {
+                               atpdev->ultra_map[0] |= n;
                        } else {
-                               if (atp_dev.sp[0][k] == 0)
-                                       atp_dev.async[0] |= n;
+                               if (atpdev->sp[0][k] == 0)
+                                       atpdev->async[0] |= n;
                        }
                }
-               atp_dev.async[0] = ~(atp_dev.async[0]);
-               outb(atp_dev.global_map[0], base_io + 0x35);
+               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)
-                       return -ENOMEM;
+                       goto err_nomem;
 
                p = (struct atp_unit *)&shpnt->hostdata;
 
-               atp_dev.host = shpnt;
-               atp_dev.pdev = pdev;
+               atpdev->host = shpnt;
+               atpdev->pdev = pdev;
                pci_set_drvdata(pdev, p);
-               memcpy(p, &atp_dev, sizeof atp_dev);
+               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, SA_SHIRQ, "atp880i", shpnt)) {
+               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;
                }
@@ -2796,31 +2801,31 @@ flash_ok_880:
                        printk(KERN_INFO "   ACARD AEC-67162 PCI Ultra3 LVD Host Adapter:  IO:%x, IRQ:%d.\n"
                               , base_io, pdev->irq);
                
-               atp_dev.pdev = pdev;    
-               atp_dev.dev_id  = ent->device;
-               atp_dev.baseport = base_io;
-               atp_dev.ioport[0] = base_io + 0x80;
-               atp_dev.ioport[1] = base_io + 0xc0;
-               atp_dev.pciport[0] = base_io + 0x40;
-               atp_dev.pciport[1] = base_io + 0x50;
+               atpdev->pdev = pdev;
+               atpdev->dev_id  = ent->device;
+               atpdev->baseport = base_io;
+               atpdev->ioport[0] = base_io + 0x80;
+               atpdev->ioport[1] = base_io + 0xc0;
+               atpdev->pciport[0] = base_io + 0x40;
+               atpdev->pciport[1] = base_io + 0x50;
                                
                shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit));
                if (!shpnt)
-                       return -ENOMEM;
+                       goto err_nomem;
                
                p = (struct atp_unit *)&shpnt->hostdata;
                
-               atp_dev.host = shpnt;
-               atp_dev.pdev = pdev;
+               atpdev->host = shpnt;
+               atpdev->pdev = pdev;
                pci_set_drvdata(pdev, p);
-               memcpy(p, &atp_dev, sizeof(struct atp_unit));
+               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, SA_SHIRQ, "atp870u", shpnt)) {
+               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;
                }
@@ -2972,43 +2977,43 @@ flash_ok_885:
                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);
 
-               atp_dev.ioport[0] = base_io;
-               atp_dev.pciport[0] = base_io + 0x20;
-               atp_dev.dev_id = ent->device;
+               atpdev->ioport[0] = base_io;
+               atpdev->pciport[0] = base_io + 0x20;
+               atpdev->dev_id = ent->device;
                host_id &= 0x07;
-               atp_dev.host_id[0] = host_id;
+               atpdev->host_id[0] = host_id;
                tmport = base_io + 0x22;
-               atp_dev.scam_on = inb(tmport);
+               atpdev->scam_on = inb(tmport);
                tmport += 0x0b;
-               atp_dev.global_map[0] = inb(tmport++);
-               atp_dev.ultra_map[0] = inw(tmport);
+               atpdev->global_map[0] = inb(tmport++);
+               atpdev->ultra_map[0] = inw(tmport);
 
-               if (atp_dev.ultra_map[0] == 0) {
-                       atp_dev.scam_on = 0x00;
-                       atp_dev.global_map[0] = 0x20;
-                       atp_dev.ultra_map[0] = 0xffff;
+               if (atpdev->ultra_map[0] == 0) {
+                       atpdev->scam_on = 0x00;
+                       atpdev->global_map[0] = 0x20;
+                       atpdev->ultra_map[0] = 0xffff;
                }
 
                shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit));
                if (!shpnt)
-                       return -ENOMEM;
+                       goto err_nomem;
 
                p = (struct atp_unit *)&shpnt->hostdata;
                
-               atp_dev.host = shpnt;
-               atp_dev.pdev = pdev;
+               atpdev->host = shpnt;
+               atpdev->pdev = pdev;
                pci_set_drvdata(pdev, p);
-               memcpy(p, &atp_dev, sizeof atp_dev);
+               memcpy(p, atpdev, sizeof(*atpdev));
                if (atp870u_init_tables(shpnt) < 0)
                        goto unregister;
 
-               if (request_irq(pdev->irq, atp870u_intr_handle, SA_SHIRQ, "atp870i", shpnt)) {
+               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 (atp_dev.chip_ver > 0x07) {  /* check if atp876 chip then enable terminator */
+               if (atpdev->chip_ver > 0x07) {  /* check if atp876 chip then enable terminator */
                        tmport = base_io + 0x3e;
                        outb(0x00, tmport);
                }
@@ -3042,10 +3047,10 @@ flash_ok_885:
                outb((inb(tmport) & 0xef), tmport);
                tmport++;
                outb((inb(tmport) | 0x20), tmport);
-               if (atp_dev.chip_ver == 4)
+               if (atpdev->chip_ver == 4)
                        shpnt->max_id = 16;
                else            
-                       shpnt->max_id = 7;
+                       shpnt->max_id = 8;
                shpnt->this_id = host_id;
                shpnt->unique_id = base_io;
                shpnt->io_port = base_io;
@@ -3091,6 +3096,12 @@ unregister:
        printk("atp870u_prob:unregister\n");
        scsi_host_put(shpnt);
        return -1;              
+err_eio:
+       kfree(atpdev);
+       return -EIO;
+err_nomem:
+       kfree(atpdev);
+       return -ENOMEM;
 }
 
 /* The abort command does not leave the device in a clean state where
@@ -3107,7 +3118,7 @@ static int atp870u_abort(struct scsi_cmnd * SCpnt)
        host = SCpnt->device->host;
 
        dev = (struct atp_unit *)&host->hostdata;
-       c=SCpnt->device->channel;
+       c = scmd_channel(SCpnt);
        printk(" atp870u: abort Channel = %x \n", c);
        printk("working=%x last_cmd=%x ", dev->working[c], dev->last_cmd[c]);
        printk(" quhdu=%x quendu=%x ", dev->quhd[c], dev->quend[c]);
@@ -3146,8 +3157,8 @@ static const char *atp870u_info(struct Scsi_Host *notused)
 }
 
 #define BLS buffer + len + size
-int atp870u_proc_info(struct Scsi_Host *HBAptr, char *buffer, 
-                     char **start, off_t offset, int length, int inout)
+static int atp870u_proc_info(struct Scsi_Host *HBAptr, char *buffer, 
+                            char **start, off_t offset, int length, int inout)
 {
        static u8 buff[512];
        int size = 0;