All of lore.kernel.org
 help / color / mirror / Atom feed
From: Lukasz Kosewski <lkosewsk@gmail.com>
To: jgarzik@pobox.com
Cc: linux-ide@vger.kernel.org, linux-scsi@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: [PATCH 1/3] Add disk hotswap support to libata RESEND #2
Date: Mon, 1 Aug 2005 03:01:12 -0700	[thread overview]
Message-ID: <355e5e5e0508010301352e05cb@mail.gmail.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 516 bytes --]

Patch 01:  add promise SATAII150 support to the sata_promise driver.

As described in the archives, this patch adds support for those
notorious SATAII150 controllers with their weird hotplug offset and
prepares us for hotplug goodness.

Jeff:  The reason that ATA_FLAG_SATA is commented out on pdc_2057x
controllers is to keep them consistent with the 2037x controllers in
libata + sata_promise support PATA ports (as seen in 2.6.13-rc3-mm1). 
I've implemented all your other suggestions.

Luke Kosewski

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 01-promise_sataII150_support-2.6.13-rc3-mm1-2.diff --]
[-- Type: text/x-patch; name="01-promise_sataII150_support-2.6.13-rc3-mm1-2.diff", Size: 6871 bytes --]

28.07.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 a resend of the original patch which in particular:
	  - does not split up the interrupt handling function, and instead uses
	    a pdc_host_priv structure to pass along the location of the hotplug
	    registers.
	  - does not use spin_lock_irqsave, but the less expensive spin_lock in
	    the interrupt handler.

Signed-off-by:  Luke Kosewski <lkosewsk@nit.ca>

--- linux/drivers/scsi/sata_promise.c.old	2005-07-26 15:52:51.000000000 -0700
+++ linux/drivers/scsi/sata_promise.c	2005-07-27 09:37:29.000000000 -0700
@@ -52,6 +52,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) |
@@ -60,8 +61,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 */
 };
@@ -72,6 +75,10 @@ struct pdc_port_priv {
 	dma_addr_t		pkt_dma;
 };
 
+struct pdc_host_priv {
+	unsigned 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);
@@ -161,6 +168,28 @@ static struct ata_port_info pdc_port_inf
 		.udma_mask	= 0x7f, /* udma0-6 ; FIXME */
 		.port_ops	= &pdc_ata_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_ata_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_ata_ops,
+	},
 };
 
 static struct pci_device_id pdc_ata_pci_tbl[] = {
@@ -175,16 +204,16 @@ 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 },
 	{ PCI_VENDOR_ID_PROMISE, 0x3319, 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 },
@@ -436,10 +465,9 @@ static irqreturn_t pdc_interrupt (int ir
 {
 	struct ata_host_set *host_set = dev_instance;
 	struct ata_port *ap;
-	u32 mask = 0;
-	unsigned int i, tmp;
-	unsigned int handled = 0;
 	void *mmio_base;
+	u32 mask = 0;
+	unsigned int i, tmp, handled = 0;
 
 	VPRINTK("ENTER\n");
 
@@ -449,7 +477,7 @@ static irqreturn_t pdc_interrupt (int ir
 	}
 
 	mmio_base = host_set->mmio_base;
-
+	
 	/* reading should also clear interrupts */
 	mask = readl(mmio_base + PDC_INT_SEQMASK);
 
@@ -457,14 +485,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++) {
@@ -480,10 +509,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);
 }
 
@@ -561,6 +590,8 @@ static void pdc_ata_setup_port(struct at
 static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe)
 {
 	void *mmio = pe->mmio_base;
+	struct pdc_host_priv *hp = pe->private_data;
+	unsigned int hotplug_offset = hp->hotplug_offset;
 	u32 tmp;
 
 	/*
@@ -575,12 +606,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);
@@ -602,6 +633,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 *mmio_base;
 	unsigned int board_idx = (unsigned int) ent->driver_data;
@@ -651,6 +683,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));
+
+	probe_ent->private_data = hp;
+	/* Set default hotplug offset */
+	hp->hotplug_offset = PDC_SATA_PLUG_CSR;
+
 	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;
@@ -673,6 +717,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;
 
@@ -685,6 +732,9 @@ static int pdc_ata_init_one (struct pci_
 		probe_ent->port_flags[2] = ATA_FLAG_SATA;
 		probe_ent->port_flags[3] = ATA_FLAG_SATA;
 		break;
+	case board_2057x:
+		/* Override hotplug_offset for SATAII150 */
+		hp->hotplug_offset = PDC2_SATA_PLUG_CSR;
 	case board_2037x:
 		/* Some boards have also PATA port */
 		tmp = readb(mmio_base + PDC_FLASH_CTL+1);

                 reply	other threads:[~2005-08-01 10:01 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=355e5e5e0508010301352e05cb@mail.gmail.com \
    --to=lkosewsk@gmail.com \
    --cc=jgarzik@pobox.com \
    --cc=linux-ide@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-scsi@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.