aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/libata-core.c61
-rw-r--r--include/linux/libata.h8
2 files changed, 59 insertions, 10 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 3634279d896..f2e7e2f13db 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -5311,7 +5311,6 @@ static struct ata_port * ata_port_add(const struct ata_probe_ent *ent,
5311{ 5311{
5312 struct Scsi_Host *shost; 5312 struct Scsi_Host *shost;
5313 struct ata_port *ap; 5313 struct ata_port *ap;
5314 int rc;
5315 5314
5316 DPRINTK("ENTER\n"); 5315 DPRINTK("ENTER\n");
5317 5316
@@ -5333,15 +5332,7 @@ static struct ata_port * ata_port_add(const struct ata_probe_ent *ent,
5333 ata_port_init(ap, host_set, ent, port_no); 5332 ata_port_init(ap, host_set, ent, port_no);
5334 ata_port_init_shost(ap, shost); 5333 ata_port_init_shost(ap, shost);
5335 5334
5336 rc = ap->ops->port_start(ap);
5337 if (rc)
5338 goto err_out;
5339
5340 return ap; 5335 return ap;
5341
5342err_out:
5343 scsi_host_put(shost);
5344 return NULL;
5345} 5336}
5346 5337
5347/** 5338/**
@@ -5415,11 +5406,27 @@ int ata_device_add(const struct ata_probe_ent *ent)
5415 if (!ap) 5406 if (!ap)
5416 goto err_out; 5407 goto err_out;
5417 5408
5409 host_set->ports[i] = ap;
5410
5411 /* dummy? */
5412 if (ent->dummy_port_mask & (1 << i)) {
5413 ata_port_printk(ap, KERN_INFO, "DUMMY\n");
5414 ap->ops = &ata_dummy_port_ops;
5415 continue;
5416 }
5417
5418 /* start port */
5419 rc = ap->ops->port_start(ap);
5420 if (rc) {
5421 host_set->ports[i] = NULL;
5422 scsi_host_put(ap->host);
5423 goto err_out;
5424 }
5425
5418 /* Report the secondary IRQ for second channel legacy */ 5426 /* Report the secondary IRQ for second channel legacy */
5419 if (i == 1 && ent->irq2) 5427 if (i == 1 && ent->irq2)
5420 irq_line = ent->irq2; 5428 irq_line = ent->irq2;
5421 5429
5422 host_set->ports[i] = ap;
5423 xfer_mode_mask =(ap->udma_mask << ATA_SHIFT_UDMA) | 5430 xfer_mode_mask =(ap->udma_mask << ATA_SHIFT_UDMA) |
5424 (ap->mwdma_mask << ATA_SHIFT_MWDMA) | 5431 (ap->mwdma_mask << ATA_SHIFT_MWDMA) |
5425 (ap->pio_mask << ATA_SHIFT_PIO); 5432 (ap->pio_mask << ATA_SHIFT_PIO);
@@ -5941,6 +5948,39 @@ u32 ata_wait_register(void __iomem *reg, u32 mask, u32 val,
5941} 5948}
5942 5949
5943/* 5950/*
5951 * Dummy port_ops
5952 */
5953static void ata_dummy_noret(struct ata_port *ap) { }
5954static int ata_dummy_ret0(struct ata_port *ap) { return 0; }
5955static void ata_dummy_qc_noret(struct ata_queued_cmd *qc) { }
5956
5957static u8 ata_dummy_check_status(struct ata_port *ap)
5958{
5959 return ATA_DRDY;
5960}
5961
5962static unsigned int ata_dummy_qc_issue(struct ata_queued_cmd *qc)
5963{
5964 return AC_ERR_SYSTEM;
5965}
5966
5967const struct ata_port_operations ata_dummy_port_ops = {
5968 .port_disable = ata_port_disable,
5969 .check_status = ata_dummy_check_status,
5970 .check_altstatus = ata_dummy_check_status,
5971 .dev_select = ata_noop_dev_select,
5972 .qc_prep = ata_noop_qc_prep,
5973 .qc_issue = ata_dummy_qc_issue,
5974 .freeze = ata_dummy_noret,
5975 .thaw = ata_dummy_noret,
5976 .error_handler = ata_dummy_noret,
5977 .post_internal_cmd = ata_dummy_qc_noret,
5978 .irq_clear = ata_dummy_noret,
5979 .port_start = ata_dummy_ret0,
5980 .port_stop = ata_dummy_noret,
5981};
5982
5983/*
5944 * libata is essentially a library of internal helper functions for 5984 * libata is essentially a library of internal helper functions for
5945 * low-level ATA host controller drivers. As such, the API/ABI is 5985 * low-level ATA host controller drivers. As such, the API/ABI is
5946 * likely to change as new drivers are added and updated. 5986 * likely to change as new drivers are added and updated.
@@ -5950,6 +5990,7 @@ u32 ata_wait_register(void __iomem *reg, u32 mask, u32 val,
5950EXPORT_SYMBOL_GPL(sata_deb_timing_normal); 5990EXPORT_SYMBOL_GPL(sata_deb_timing_normal);
5951EXPORT_SYMBOL_GPL(sata_deb_timing_hotplug); 5991EXPORT_SYMBOL_GPL(sata_deb_timing_hotplug);
5952EXPORT_SYMBOL_GPL(sata_deb_timing_long); 5992EXPORT_SYMBOL_GPL(sata_deb_timing_long);
5993EXPORT_SYMBOL_GPL(ata_dummy_port_ops);
5953EXPORT_SYMBOL_GPL(ata_std_bios_param); 5994EXPORT_SYMBOL_GPL(ata_std_bios_param);
5954EXPORT_SYMBOL_GPL(ata_std_ports); 5995EXPORT_SYMBOL_GPL(ata_std_ports);
5955EXPORT_SYMBOL_GPL(ata_host_set_init); 5996EXPORT_SYMBOL_GPL(ata_host_set_init);
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 4504776570e..30bfe8f1666 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -353,6 +353,7 @@ struct ata_probe_ent {
353 struct ata_ioports port[ATA_MAX_PORTS]; 353 struct ata_ioports port[ATA_MAX_PORTS];
354 unsigned int n_ports; 354 unsigned int n_ports;
355 unsigned int hard_port_no; 355 unsigned int hard_port_no;
356 unsigned int dummy_port_mask;
356 unsigned int pio_mask; 357 unsigned int pio_mask;
357 unsigned int mwdma_mask; 358 unsigned int mwdma_mask;
358 unsigned int udma_mask; 359 unsigned int udma_mask;
@@ -652,6 +653,8 @@ extern const unsigned long sata_deb_timing_normal[];
652extern const unsigned long sata_deb_timing_hotplug[]; 653extern const unsigned long sata_deb_timing_hotplug[];
653extern const unsigned long sata_deb_timing_long[]; 654extern const unsigned long sata_deb_timing_long[];
654 655
656extern const struct ata_port_operations ata_dummy_port_ops;
657
655static inline const unsigned long * 658static inline const unsigned long *
656sata_ehc_deb_timing(struct ata_eh_context *ehc) 659sata_ehc_deb_timing(struct ata_eh_context *ehc)
657{ 660{
@@ -661,6 +664,11 @@ sata_ehc_deb_timing(struct ata_eh_context *ehc)
661 return sata_deb_timing_normal; 664 return sata_deb_timing_normal;
662} 665}
663 666
667static inline int ata_port_is_dummy(struct ata_port *ap)
668{
669 return ap->ops == &ata_dummy_port_ops;
670}
671
664extern void ata_port_probe(struct ata_port *); 672extern void ata_port_probe(struct ata_port *);
665extern void __sata_phy_reset(struct ata_port *ap); 673extern void __sata_phy_reset(struct ata_port *ap);
666extern void sata_phy_reset(struct ata_port *ap); 674extern void sata_phy_reset(struct ata_port *ap);