Re: [PATCH 2.6.22-rc5 2/2] sata_promise: SATA hotplug support

2007-07-03 Thread Tejun Heo
Mikael Pettersson wrote:
 This patch enables hotplugging of SATA devices in the
 sata_promise driver. It's been tested successfully on
 both first- and second-generation Promise SATA chips:
 SATA150 TX2plus, SATAII150 TX2plus, SATA300 TX2plus,
 and SATA300 TX4.
 
 The only quirk I've seen is that hotplugging (insertion)
 on the first-generation SATA150 TX2plus requires a lengthier
 EH sequence than on the second-generation chips.
 On the second-generation chips a simple soft reset seems
 to suffice, but on the first-generation chip there's a
 port is slow to respond after the initial soft reset,
 after which libata issues a hard reset, and then the
 device is recognised.
 
 The hotplug checks are high up in the interrupt handling
 path, not deep down in error_intr as in ahci/sata_sil24.
 That's because the chip doesn't signal hotplug status changes
 in the per-port status register: instead a global register
 contains hotplug control and status flags for all ports.
 I considered following the ahci/sata_sil24 structure, but
 that would have required non-trivial changes to the interrupt
 handling path, so I chose to keep the hotplug changes simple
 and unobtrusive.
 
 Signed-off-by: Mikael Pettersson [EMAIL PROTECTED]

Some unlikely()'s might be helpful here and there but other than that.

Acked-by: Tejun Heo [EMAIL PROTECTED]

-- 
tejun
-
To unsubscribe from this list: send the line unsubscribe linux-ide in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2.6.22-rc5 2/2] sata_promise: SATA hotplug support

2007-06-19 Thread Mikael Pettersson
This patch enables hotplugging of SATA devices in the
sata_promise driver. It's been tested successfully on
both first- and second-generation Promise SATA chips:
SATA150 TX2plus, SATAII150 TX2plus, SATA300 TX2plus,
and SATA300 TX4.

The only quirk I've seen is that hotplugging (insertion)
on the first-generation SATA150 TX2plus requires a lengthier
EH sequence than on the second-generation chips.
On the second-generation chips a simple soft reset seems
to suffice, but on the first-generation chip there's a
port is slow to respond after the initial soft reset,
after which libata issues a hard reset, and then the
device is recognised.

The hotplug checks are high up in the interrupt handling
path, not deep down in error_intr as in ahci/sata_sil24.
That's because the chip doesn't signal hotplug status changes
in the per-port status register: instead a global register
contains hotplug control and status flags for all ports.
I considered following the ahci/sata_sil24 structure, but
that would have required non-trivial changes to the interrupt
handling path, so I chose to keep the hotplug changes simple
and unobtrusive.

Signed-off-by: Mikael Pettersson [EMAIL PROTECTED]
--
This patch depends on patch 1/2: sata_promise: cleanups.

Changes since the preliminary version:
- cleanups
- added testing on the first-generation SATA150 TX2plus

 drivers/ata/sata_promise.c |   40 +++-
 1 files changed, 35 insertions(+), 5 deletions(-)

--- linux-2.6.22-rc5/drivers/ata/sata_promise.c.~1~ 2007-06-19 
20:40:28.0 +0200
+++ linux-2.6.22-rc5/drivers/ata/sata_promise.c 2007-06-19 20:41:36.0 
+0200
@@ -45,7 +45,7 @@
 #include sata_promise.h
 
 #define DRV_NAME   sata_promise
-#define DRV_VERSION2.08
+#define DRV_VERSION2.09
 
 enum {
PDC_MAX_PORTS   = 4,
@@ -716,6 +716,9 @@ static irqreturn_t pdc_interrupt (int ir
unsigned int i, tmp;
unsigned int handled = 0;
void __iomem *mmio_base;
+   unsigned int hotplug_offset, ata_no;
+   u32 hotplug_status;
+   int is_sataii_tx4;
 
VPRINTK(ENTER\n);
 
@@ -726,10 +729,20 @@ static irqreturn_t pdc_interrupt (int ir
 
mmio_base = host-iomap[PDC_MMIO_BAR];
 
+   /* read and clear hotplug flags for all ports */
+   if (host-ports[0]-flags  PDC_FLAG_GEN_II)
+   hotplug_offset = PDC2_SATA_PLUG_CSR;
+   else
+   hotplug_offset = PDC_SATA_PLUG_CSR;
+   hotplug_status = readl(mmio_base + hotplug_offset);
+   if (hotplug_status  0xff)
+   writel(hotplug_status | 0xff, mmio_base + hotplug_offset);
+   hotplug_status = 0xff; /* clear uninteresting bits */
+
/* reading should also clear interrupts */
mask = readl(mmio_base + PDC_INT_SEQMASK);
 
-   if (mask == 0x) {
+   if (mask == 0x  hotplug_status == 0) {
VPRINTK(QUICK EXIT 2\n);
return IRQ_NONE;
}
@@ -737,16 +750,33 @@ static irqreturn_t pdc_interrupt (int ir
spin_lock(host-lock);
 
mask = 0x; /* only 16 tags possible */
-   if (!mask) {
+   if (mask == 0  hotplug_status == 0) {
VPRINTK(QUICK EXIT 3\n);
goto done_irq;
}
 
writel(mask, mmio_base + PDC_INT_SEQMASK);
 
+   is_sataii_tx4 = pdc_is_sataii_tx4(host-ports[0]-flags);
+
for (i = 0; i  host-n_ports; i++) {
VPRINTK(port %u\n, i);
ap = host-ports[i];
+
+   /* check for a plug or unplug event */
+   ata_no = pdc_port_no_to_ata_no(i, is_sataii_tx4);
+   tmp = hotplug_status  (0x11  ata_no);
+   if (tmp  ap 
+   !(ap-flags  ATA_FLAG_DISABLED)) {
+   struct ata_eh_info *ehi = ap-eh_info;
+   ata_ehi_clear_desc(ehi);
+   ata_ehi_hotplugged(ehi);
+   ata_ehi_push_desc(ehi, hotplug_status %#x, tmp);
+   ata_port_freeze(ap);
+   continue;
+   }
+
+   /* check for a packet interrupt */
tmp = mask  (1  (i + 1));
if (tmp  ap 
!(ap-flags  ATA_FLAG_DISABLED)) {
@@ -902,9 +932,9 @@ static void pdc_host_init(struct ata_hos
tmp = readl(mmio + hotplug_offset);
writel(tmp | 0xff, mmio + hotplug_offset);
 
-   /* mask plug/unplug ints */
+   /* unmask plug/unplug ints */
tmp = readl(mmio + hotplug_offset);
-   writel(tmp | 0xff, mmio + hotplug_offset);
+   writel(tmp  ~0xff, mmio + hotplug_offset);
 
/* don't initialise TBG or SLEW on 2nd generation chips */
if (is_gen2)
-
To unsubscribe from this list: send the line unsubscribe linux-ide in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html