vserver 1.9.5.x5
[linux-2.6.git] / drivers / scsi / sata_uli.c
index 1becb36..5a5c13f 100644 (file)
 #include <linux/libata.h>
 
 #define DRV_NAME       "sata_uli"
-#define DRV_VERSION    "0.11"
+#define DRV_VERSION    "0.5"
 
 enum {
        uli_5289                = 0,
        uli_5287                = 1,
+       uli_5281                = 2,
 
        /* PCI configuration registers */
-       ULI_SCR_BASE            = 0x90, /* sata0 phy SCR registers */
-       ULI_SATA1_OFS           = 0x10, /* offset from sata0->sata1 phy regs */
-
+       ULI5287_BASE            = 0x90, /* sata0 phy SCR registers */
+       ULI5287_OFFS            = 0x10, /* offset from sata0->sata1 phy regs */
+       ULI5281_BASE            = 0x60, /* sata0 phy SCR  registers */
+       ULI5281_OFFS            = 0x60, /* offset from sata0->sata1 phy regs */
 };
 
 static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
@@ -51,6 +53,7 @@ static void uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
 static struct pci_device_id uli_pci_tbl[] = {
        { PCI_VENDOR_ID_AL, 0x5289, PCI_ANY_ID, PCI_ANY_ID, 0, 0, uli_5289 },
        { PCI_VENDOR_ID_AL, 0x5287, PCI_ANY_ID, PCI_ANY_ID, 0, 0, uli_5287 },
+       { PCI_VENDOR_ID_AL, 0x5281, PCI_ANY_ID, PCI_ANY_ID, 0, 0, uli_5281 },
        { }     /* terminate list */
 };
 
@@ -94,6 +97,8 @@ static struct ata_port_operations uli_ops = {
 
        .bmdma_setup            = ata_bmdma_setup,
        .bmdma_start            = ata_bmdma_start,
+       .bmdma_stop             = ata_bmdma_stop,
+       .bmdma_status           = ata_bmdma_status,
        .qc_prep                = ata_qc_prep,
        .qc_issue               = ata_qc_issue_prot,
 
@@ -125,43 +130,27 @@ MODULE_LICENSE("GPL");
 MODULE_DEVICE_TABLE(pci, uli_pci_tbl);
 MODULE_VERSION(DRV_VERSION);
 
-static unsigned int get_scr_cfg_addr(unsigned int port_no, unsigned int sc_reg)
+static unsigned int get_scr_cfg_addr(struct ata_port *ap, unsigned int sc_reg)
 {
-       unsigned int addr = ULI_SCR_BASE + (4 * sc_reg);
-
-       switch (port_no) {
-       case 0:
-               break;
-       case 1:
-               addr += ULI_SATA1_OFS;
-               break;
-       case 2:
-               addr += ULI_SATA1_OFS*4;
-               break;
-       case 3:
-               addr += ULI_SATA1_OFS*5;
-               break;
-       default:
-               BUG();
-               break;
-       }
-       return addr;
+       return ap->ioaddr.scr_addr + (4 * sc_reg);
 }
 
 static u32 uli_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg)
 {
-       unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, sc_reg);
+       struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
+       unsigned int cfg_addr = get_scr_cfg_addr(ap, sc_reg);
        u32 val;
 
-       pci_read_config_dword(ap->host_set->pdev, cfg_addr, &val);
+       pci_read_config_dword(pdev, cfg_addr, &val);
        return val;
 }
 
 static void uli_scr_cfg_write (struct ata_port *ap, unsigned int scr, u32 val)
 {
-       unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, scr);
+       struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
+       unsigned int cfg_addr = get_scr_cfg_addr(ap, scr);
 
-       pci_write_config_dword(ap->host_set->pdev, cfg_addr, val);
+       pci_write_config_dword(pdev, cfg_addr, val);
 }
 
 static u32 uli_scr_read (struct ata_port *ap, unsigned int sc_reg)
@@ -198,14 +187,17 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        struct ata_port_info *ppi;
        int rc;
        unsigned int board_idx = (unsigned int) ent->driver_data;
+       int pci_dev_busy = 0;
 
        rc = pci_enable_device(pdev);
        if (rc)
                return rc;
 
        rc = pci_request_regions(pdev, DRV_NAME);
-       if (rc)
+       if (rc) {
+               pci_dev_busy = 1;
                goto err_out;
+       }
 
        rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
        if (rc)
@@ -220,9 +212,11 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
                rc = -ENOMEM;
                goto err_out_regions;
        }
-
+       
        switch (board_idx) {
        case uli_5287:
+               probe_ent->port[0].scr_addr = ULI5287_BASE;
+               probe_ent->port[1].scr_addr = ULI5287_BASE + ULI5287_OFFS;
                        probe_ent->n_ports = 4;
 
                        probe_ent->port[2].cmd_addr = pci_resource_start(pdev, 0) + 8;
@@ -230,19 +224,27 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
                probe_ent->port[2].ctl_addr =
                        (pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS) + 4;
                probe_ent->port[2].bmdma_addr = pci_resource_start(pdev, 4) + 16;
+               probe_ent->port[2].scr_addr = ULI5287_BASE + ULI5287_OFFS*4;
 
                probe_ent->port[3].cmd_addr = pci_resource_start(pdev, 2) + 8;
                probe_ent->port[3].altstatus_addr =
                probe_ent->port[3].ctl_addr =
                        (pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS) + 4;
                probe_ent->port[3].bmdma_addr = pci_resource_start(pdev, 4) + 24;
+               probe_ent->port[3].scr_addr = ULI5287_BASE + ULI5287_OFFS*5;
 
                ata_std_ports(&probe_ent->port[2]);
                ata_std_ports(&probe_ent->port[3]);
                break;
 
        case uli_5289:
-               /* do nothing; ata_pci_init_native_mode did it all */
+               probe_ent->port[0].scr_addr = ULI5287_BASE;
+               probe_ent->port[1].scr_addr = ULI5287_BASE + ULI5287_OFFS;
+               break;
+
+       case uli_5281:
+               probe_ent->port[0].scr_addr = ULI5281_BASE;
+               probe_ent->port[1].scr_addr = ULI5281_BASE + ULI5281_OFFS;
                break;
 
        default:
@@ -263,7 +265,8 @@ err_out_regions:
        pci_release_regions(pdev);
 
 err_out:
-       pci_disable_device(pdev);
+       if (!pci_dev_busy)
+               pci_disable_device(pdev);
        return rc;
 
 }