diff options
author | Tejun Heo <htejun@gmail.com> | 2006-05-31 05:28:16 -0400 |
---|---|---|
committer | Tejun Heo <htejun@gmail.com> | 2006-05-31 05:28:16 -0400 |
commit | e573890b00426189e1e223967a2c46fb758bf06e (patch) | |
tree | 0ab6f7f0c5561a9886cacafbb68ae0fce7e4bee0 /drivers/scsi | |
parent | ccc4672aff1861a9c80ed9e8ec11dc304b31d307 (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')
-rw-r--r-- | drivers/scsi/sata_sil.c | 21 |
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 */ |