diff options
author | Tejun Heo <htejun@gmail.com> | 2006-05-31 05:28:20 -0400 |
---|---|---|
committer | Tejun Heo <htejun@gmail.com> | 2006-05-31 05:28:20 -0400 |
commit | 0542925b25676543e8384edf454668f89227e905 (patch) | |
tree | ba9add993cf4c5e0499260126f23782a75a8219d /drivers | |
parent | 4296971dd36e2c2deae0826305f591480223af88 (diff) |
[PATCH] sata_sil24: convert to new probing mechanism and add hotplug support
Convert to new probing mechanism and add hotplug support by enabling
PORT_IRQ_PHYRDY_CHG, marking ehi for hotplug and scheduling EH on
PORT_IRQ_PHYRDY_CHG or PORT_IRQ_DEV_XCHG.
Sil3124/32 family of controllers don't have any mechanism to wait for
the first D2H FIS after hotplug, so ATA_FLAG_SKIP_D2H_BSY is used.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/sata_sil24.c | 27 |
1 files changed, 8 insertions, 19 deletions
diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c index d4ca6d6b402c..97e93392f928 100644 --- a/drivers/scsi/sata_sil24.c +++ b/drivers/scsi/sata_sil24.c | |||
@@ -159,7 +159,8 @@ enum { | |||
159 | PORT_IRQ_SDB_NOTIFY = (1 << 11), /* SDB notify received */ | 159 | PORT_IRQ_SDB_NOTIFY = (1 << 11), /* SDB notify received */ |
160 | 160 | ||
161 | DEF_PORT_IRQ = PORT_IRQ_COMPLETE | PORT_IRQ_ERROR | | 161 | DEF_PORT_IRQ = PORT_IRQ_COMPLETE | PORT_IRQ_ERROR | |
162 | PORT_IRQ_DEV_XCHG | PORT_IRQ_UNK_FIS, | 162 | PORT_IRQ_PHYRDY_CHG | PORT_IRQ_DEV_XCHG | |
163 | PORT_IRQ_UNK_FIS, | ||
163 | 164 | ||
164 | /* bits[27:16] are unmasked (raw) */ | 165 | /* bits[27:16] are unmasked (raw) */ |
165 | PORT_IRQ_RAW_SHIFT = 16, | 166 | PORT_IRQ_RAW_SHIFT = 16, |
@@ -228,7 +229,7 @@ enum { | |||
228 | /* host flags */ | 229 | /* host flags */ |
229 | SIL24_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | 230 | SIL24_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | |
230 | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | | 231 | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | |
231 | ATA_FLAG_NCQ, | 232 | ATA_FLAG_NCQ | ATA_FLAG_SKIP_D2H_BSY, |
232 | SIL24_FLAG_PCIX_IRQ_WOC = (1 << 24), /* IRQ loss errata on PCI-X */ | 233 | SIL24_FLAG_PCIX_IRQ_WOC = (1 << 24), /* IRQ loss errata on PCI-X */ |
233 | 234 | ||
234 | IRQ_STAT_4PORTS = 0xf, | 235 | IRQ_STAT_4PORTS = 0xf, |
@@ -325,7 +326,6 @@ static u8 sil24_check_status(struct ata_port *ap); | |||
325 | static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg); | 326 | static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg); |
326 | static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val); | 327 | static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val); |
327 | static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf); | 328 | static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf); |
328 | static int sil24_probe_reset(struct ata_port *ap, unsigned int *classes); | ||
329 | static void sil24_qc_prep(struct ata_queued_cmd *qc); | 329 | static void sil24_qc_prep(struct ata_queued_cmd *qc); |
330 | static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc); | 330 | static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc); |
331 | static void sil24_irq_clear(struct ata_port *ap); | 331 | static void sil24_irq_clear(struct ata_port *ap); |
@@ -385,8 +385,6 @@ static const struct ata_port_operations sil24_ops = { | |||
385 | 385 | ||
386 | .tf_read = sil24_tf_read, | 386 | .tf_read = sil24_tf_read, |
387 | 387 | ||
388 | .probe_reset = sil24_probe_reset, | ||
389 | |||
390 | .qc_prep = sil24_qc_prep, | 388 | .qc_prep = sil24_qc_prep, |
391 | .qc_issue = sil24_qc_issue, | 389 | .qc_issue = sil24_qc_issue, |
392 | 390 | ||
@@ -635,13 +633,6 @@ static int sil24_hardreset(struct ata_port *ap, unsigned int *class) | |||
635 | return -EIO; | 633 | return -EIO; |
636 | } | 634 | } |
637 | 635 | ||
638 | static int sil24_probe_reset(struct ata_port *ap, unsigned int *classes) | ||
639 | { | ||
640 | return ata_drive_probe_reset(ap, ata_std_probeinit, | ||
641 | sil24_softreset, sil24_hardreset, | ||
642 | ata_std_postreset, classes); | ||
643 | } | ||
644 | |||
645 | static inline void sil24_fill_sg(struct ata_queued_cmd *qc, | 636 | static inline void sil24_fill_sg(struct ata_queued_cmd *qc, |
646 | struct sil24_sge *sge) | 637 | struct sil24_sge *sge) |
647 | { | 638 | { |
@@ -772,13 +763,11 @@ static void sil24_error_intr(struct ata_port *ap) | |||
772 | 763 | ||
773 | ata_ehi_push_desc(ehi, "irq_stat 0x%08x", irq_stat); | 764 | ata_ehi_push_desc(ehi, "irq_stat 0x%08x", irq_stat); |
774 | 765 | ||
775 | if (irq_stat & PORT_IRQ_DEV_XCHG) { | 766 | if (irq_stat & (PORT_IRQ_PHYRDY_CHG | PORT_IRQ_DEV_XCHG)) { |
776 | ehi->err_mask |= AC_ERR_ATA_BUS; | 767 | ata_ehi_hotplugged(ehi); |
777 | /* sil24 doesn't recover very well from phy | 768 | ata_ehi_push_desc(ehi, ", %s", |
778 | * disconnection with a softreset. Force hardreset. | 769 | irq_stat & PORT_IRQ_PHYRDY_CHG ? |
779 | */ | 770 | "PHY RDY changed" : "device exchanged"); |
780 | ehi->action |= ATA_EH_HARDRESET; | ||
781 | ata_ehi_push_desc(ehi, ", device_exchanged"); | ||
782 | freeze = 1; | 771 | freeze = 1; |
783 | } | 772 | } |
784 | 773 | ||