lkml.org 
[lkml]   [2005]   [Sep]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH 2.6.14-rc1 1/3] Add disk hotswap support to libata RESEND #3
    Patch 1/3 for libata hotswapping.  Properly masks out interrupts for
    Promise SATAII150 Tx2Plus/Tx4 controllers. More comments in patch
    header.

    Luke Kosewski
    15.09.05 Luke Kosewski <lkosewsk@nit.ca>

    * A patch to the sata_promise driver in libata for it to correctly mask
    out hotplug interrupts on SATAII150 Tx4/Tx2 Plus controllers.
    * This is resend #3. It no longer applies to a -mm tree, but to
    2.6.14-rc1. Therefore, the entry for board_2057x no longer has
    ATA_FLAG_SATA commented out.

    diff -rpuN linux-2.6.14-rc1/drivers/scsi/sata_promise.c linux-2.6.14-rc1-new/drivers/scsi/sata_promise.c
    --- linux-2.6.14-rc1/drivers/scsi/sata_promise.c 2005-09-12 23:12:09.000000000 -0400
    +++ linux-2.6.14-rc1-new/drivers/scsi/sata_promise.c 2005-09-14 14:11:49.000000000 -0400
    @@ -57,6 +57,7 @@ enum {
    PDC_GLOBAL_CTL = 0x48, /* Global control/status (per port) */
    PDC_CTLSTAT = 0x60, /* IDE control and status (per port) */
    PDC_SATA_PLUG_CSR = 0x6C, /* SATA Plug control/status reg */
    + PDC2_SATA_PLUG_CSR = 0X60, /* SATAII Plug control/status reg */
    PDC_SLEW_CTL = 0x470, /* slew rate control reg */

    PDC_ERR_MASK = (1<<19) | (1<<20) | (1<<21) | (1<<22) |
    @@ -65,8 +66,10 @@ enum {
    board_2037x = 0, /* FastTrak S150 TX2plus */
    board_20319 = 1, /* FastTrak S150 TX4 */
    board_20619 = 2, /* FastTrak TX4000 */
    + board_2057x = 3, /* SATAII150 Tx2plus */
    + board_40518 = 4, /* SATAII150 Tx4 */

    - PDC_HAS_PATA = (1 << 1), /* PDC20375 has PATA */
    + PDC_HAS_PATA = (1 << 1), /* PDC20375/20575 has PATA */

    PDC_RESET = (1 << 11), /* HDMA reset */
    };
    @@ -77,6 +80,10 @@ struct pdc_port_priv {
    dma_addr_t pkt_dma;
    };

    +struct pdc_host_priv {
    + int hotplug_offset;
    +};
    +
    static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg);
    static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
    static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
    @@ -190,6 +197,28 @@ static struct ata_port_info pdc_port_inf
    .udma_mask = 0x7f, /* udma0-6 ; FIXME */
    .port_ops = &pdc_pata_ops,
    },
    +
    + /* board_2057x */
    + {
    + .sht = &pdc_ata_sht,
    + .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
    + ATA_FLAG_SRST | ATA_FLAG_MMIO,
    + .pio_mask = 0x1f, /* pio0-4 */
    + .mwdma_mask = 0x07, /* mwdma0-2 */
    + .udma_mask = 0x7f, /* udma0-6 ; FIXME */
    + .port_ops = &pdc_sata_ops,
    + },
    +
    + /* board_40518 */
    + {
    + .sht = &pdc_ata_sht,
    + .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
    + ATA_FLAG_SRST | ATA_FLAG_MMIO,
    + .pio_mask = 0x1f, /* pio0-4 */
    + .mwdma_mask = 0x07, /* mwdma0-2 */
    + .udma_mask = 0x7f, /* udma0-6 ; FIXME */
    + .port_ops = &pdc_sata_ops,
    + },
    };

    static struct pci_device_id pdc_ata_pci_tbl[] = {
    @@ -204,9 +233,9 @@ static struct pci_device_id pdc_ata_pci_
    { PCI_VENDOR_ID_PROMISE, 0x3376, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
    board_2037x },
    { PCI_VENDOR_ID_PROMISE, 0x3574, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
    - board_2037x },
    + board_2057x },
    { PCI_VENDOR_ID_PROMISE, 0x3d75, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
    - board_2037x },
    + board_2057x },

    { PCI_VENDOR_ID_PROMISE, 0x3318, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
    board_20319 },
    @@ -217,7 +246,7 @@ static struct pci_device_id pdc_ata_pci_
    { PCI_VENDOR_ID_PROMISE, 0x3d17, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
    board_20319 },
    { PCI_VENDOR_ID_PROMISE, 0x3d18, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
    - board_20319 },
    + board_40518 },

    { PCI_VENDOR_ID_PROMISE, 0x6629, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
    board_20619 },
    @@ -478,14 +507,15 @@ static irqreturn_t pdc_interrupt (int ir
    VPRINTK("QUICK EXIT 2\n");
    return IRQ_NONE;
    }
    +
    + spin_lock(&host_set->lock);
    +
    mask &= 0xffff; /* only 16 tags possible */
    if (!mask) {
    VPRINTK("QUICK EXIT 3\n");
    - return IRQ_NONE;
    + goto done_irq;
    }

    - spin_lock(&host_set->lock);
    -
    writel(mask, mmio_base + PDC_INT_SEQMASK);

    for (i = 0; i < host_set->n_ports; i++) {
    @@ -502,10 +532,10 @@ static irqreturn_t pdc_interrupt (int ir
    }
    }

    - spin_unlock(&host_set->lock);
    -
    VPRINTK("EXIT\n");

    +done_irq:
    + spin_unlock(&host_set->lock);
    return IRQ_RETVAL(handled);
    }

    @@ -583,6 +613,8 @@ static void pdc_ata_setup_port(struct at
    static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe)
    {
    void __iomem *mmio = pe->mmio_base;
    + struct pdc_host_priv *hp = pe->private_data;
    + int hotplug_offset = hp->hotplug_offset;
    u32 tmp;

    /*
    @@ -597,12 +629,12 @@ static void pdc_host_init(unsigned int c
    writel(tmp, mmio + PDC_FLASH_CTL);

    /* clear plug/unplug flags for all ports */
    - tmp = readl(mmio + PDC_SATA_PLUG_CSR);
    - writel(tmp | 0xff, mmio + PDC_SATA_PLUG_CSR);
    + tmp = readl(mmio + hotplug_offset);
    + writel(tmp | 0xff, mmio + hotplug_offset);

    /* mask plug/unplug ints */
    - tmp = readl(mmio + PDC_SATA_PLUG_CSR);
    - writel(tmp | 0xff0000, mmio + PDC_SATA_PLUG_CSR);
    + tmp = readl(mmio + hotplug_offset);
    + writel(tmp | 0xff0000, mmio + hotplug_offset);

    /* reduce TBG clock to 133 Mhz. */
    tmp = readl(mmio + PDC_TBG_MODE);
    @@ -624,6 +656,7 @@ static int pdc_ata_init_one (struct pci_
    {
    static int printed_version;
    struct ata_probe_ent *probe_ent = NULL;
    + struct pdc_host_priv *hp;
    unsigned long base;
    void __iomem *mmio_base;
    unsigned int board_idx = (unsigned int) ent->driver_data;
    @@ -671,6 +704,18 @@ static int pdc_ata_init_one (struct pci_
    }
    base = (unsigned long) mmio_base;

    + hp = kmalloc(sizeof(*hp), GFP_KERNEL);
    + if (hp == NULL)
    + {
    + rc = -ENOMEM;
    + goto err_out_free_ent;
    + }
    + memset(hp, 0, sizeof(*hp));
    +
    + /* Set default hotplug offset */
    + hp->hotplug_offset = PDC_SATA_PLUG_CSR;
    + probe_ent->private_data = hp;
    +
    probe_ent->sht = pdc_port_info[board_idx].sht;
    probe_ent->host_flags = pdc_port_info[board_idx].host_flags;
    probe_ent->pio_mask = pdc_port_info[board_idx].pio_mask;
    @@ -690,6 +735,9 @@ static int pdc_ata_init_one (struct pci_

    /* notice 4-port boards */
    switch (board_idx) {
    + case board_40518:
    + /* Override hotplug offset for SATAII150 */
    + hp->hotplug_offset = PDC2_SATA_PLUG_CSR;
    case board_20319:
    probe_ent->n_ports = 4;

    @@ -699,6 +747,9 @@ static int pdc_ata_init_one (struct pci_
    probe_ent->port[2].scr_addr = base + 0x600;
    probe_ent->port[3].scr_addr = base + 0x700;
    break;
    + case board_2057x:
    + /* Override hotplug offset for SATAII150 */
    + hp->hotplug_offset = PDC2_SATA_PLUG_CSR;
    case board_2037x:
    probe_ent->n_ports = 2;
    break;
    \
     
     \ /
      Last update: 2005-09-15 07:08    [W:0.029 / U:0.040 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site