aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/sata_sil.c
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2006-05-31 05:28:16 -0400
committerTejun Heo <htejun@gmail.com>2006-05-31 05:28:16 -0400
commite573890b00426189e1e223967a2c46fb758bf06e (patch)
tree0ab6f7f0c5561a9886cacafbb68ae0fce7e4bee0 /drivers/scsi/sata_sil.c
parentccc4672aff1861a9c80ed9e8ec11dc304b31d307 (diff)
[PATCH] sata_sil: convert to new probing mechanism and add hotplug support
Convert to new probing mechanism and add hotplug support by enabling SATA IRQ for SError.N, marking ehi for hotplug and scheduling EH on SATA IRQs. Sil3112/3512/3114 family of controllers use COMRESET as TF clearing point and can reliably wait for D2H FIS after COMRESET whether the FIS is the first D2H FIS after POR or in response to the COMRESET. Thus, setting ATA_FLAG_HRST_TO_RESUME is enough for device detection after hotplug. Signed-off-by: Tejun Heo <htejun@gmail.com>
Diffstat (limited to 'drivers/scsi/sata_sil.c')
-rw-r--r--drivers/scsi/sata_sil.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c
index 7d43cd3a50fc..0898cbe6458c 100644
--- a/drivers/scsi/sata_sil.c
+++ b/drivers/scsi/sata_sil.c
@@ -56,7 +56,7 @@ enum {
56 SIL_FLAG_MOD15WRITE = (1 << 30), 56 SIL_FLAG_MOD15WRITE = (1 << 30),
57 57
58 SIL_DFL_HOST_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | 58 SIL_DFL_HOST_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
59 ATA_FLAG_MMIO, 59 ATA_FLAG_MMIO | ATA_FLAG_HRST_TO_RESUME,
60 60
61 /* 61 /*
62 * Controller IDs 62 * Controller IDs
@@ -186,7 +186,6 @@ static const struct ata_port_operations sil_ops = {
186 .check_status = ata_check_status, 186 .check_status = ata_check_status,
187 .exec_command = ata_exec_command, 187 .exec_command = ata_exec_command,
188 .dev_select = ata_std_dev_select, 188 .dev_select = ata_std_dev_select,
189 .probe_reset = ata_std_probe_reset,
190 .post_set_mode = sil_post_set_mode, 189 .post_set_mode = sil_post_set_mode,
191 .bmdma_setup = ata_bmdma_setup, 190 .bmdma_setup = ata_bmdma_setup,
192 .bmdma_start = ata_bmdma_start, 191 .bmdma_start = ata_bmdma_start,
@@ -344,6 +343,11 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2)
344 struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag); 343 struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag);
345 u8 status; 344 u8 status;
346 345
346 if (unlikely(bmdma2 & SIL_DMA_SATA_IRQ)) {
347 ata_ehi_hotplugged(&ap->eh_info);
348 goto freeze;
349 }
350
347 if (unlikely(!qc || qc->tf.ctl & ATA_NIEN)) 351 if (unlikely(!qc || qc->tf.ctl & ATA_NIEN))
348 goto freeze; 352 goto freeze;
349 353
@@ -415,7 +419,7 @@ static irqreturn_t sil_interrupt(int irq, void *dev_instance,
415 if (unlikely(!ap || ap->flags & ATA_FLAG_DISABLED)) 419 if (unlikely(!ap || ap->flags & ATA_FLAG_DISABLED))
416 continue; 420 continue;
417 421
418 if (!(bmdma2 & SIL_DMA_COMPLETE)) 422 if (!(bmdma2 & (SIL_DMA_COMPLETE | SIL_DMA_SATA_IRQ)))
419 continue; 423 continue;
420 424
421 sil_host_intr(ap, bmdma2); 425 sil_host_intr(ap, bmdma2);
@@ -432,6 +436,9 @@ static void sil_freeze(struct ata_port *ap)
432 void __iomem *mmio_base = ap->host_set->mmio_base; 436 void __iomem *mmio_base = ap->host_set->mmio_base;
433 u32 tmp; 437 u32 tmp;
434 438
439 /* global IRQ mask doesn't block SATA IRQ, turn off explicitly */
440 writel(0, mmio_base + sil_port[ap->port_no].sien);
441
435 /* plug IRQ */ 442 /* plug IRQ */
436 tmp = readl(mmio_base + SIL_SYSCFG); 443 tmp = readl(mmio_base + SIL_SYSCFG);
437 tmp |= SIL_MASK_IDE0_INT << ap->port_no; 444 tmp |= SIL_MASK_IDE0_INT << ap->port_no;
@@ -448,6 +455,9 @@ static void sil_thaw(struct ata_port *ap)
448 ata_chk_status(ap); 455 ata_chk_status(ap);
449 ata_bmdma_irq_clear(ap); 456 ata_bmdma_irq_clear(ap);
450 457
458 /* turn on SATA IRQ */
459 writel(SIL_SIEN_N, mmio_base + sil_port[ap->port_no].sien);
460
451 /* turn on IRQ */ 461 /* turn on IRQ */
452 tmp = readl(mmio_base + SIL_SYSCFG); 462 tmp = readl(mmio_base + SIL_SYSCFG);
453 tmp &= ~(SIL_MASK_IDE0_INT << ap->port_no); 463 tmp &= ~(SIL_MASK_IDE0_INT << ap->port_no);
@@ -621,11 +631,6 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
621 mmio_base + sil_port[2].bmdma); 631 mmio_base + sil_port[2].bmdma);
622 } 632 }
623 633
624 /* mask all SATA phy-related interrupts */
625 /* TODO: unmask bit 6 (SError N bit) for hotplug */
626 for (i = 0; i < probe_ent->n_ports; i++)
627 writel(0, mmio_base + sil_port[i].sien);
628
629 pci_set_master(pdev); 634 pci_set_master(pdev);
630 635
631 /* FIXME: check ata_device_add return value */ 636 /* FIXME: check ata_device_add return value */