diff options
Diffstat (limited to 'drivers/ata')
43 files changed, 2906 insertions, 2001 deletions
diff --git a/drivers/ata/ahci_brcm.c b/drivers/ata/ahci_brcm.c index 4e3dc2b6d67f..70c3a33eee6f 100644 --- a/drivers/ata/ahci_brcm.c +++ b/drivers/ata/ahci_brcm.c @@ -544,7 +544,7 @@ out_reset: return ret; } -static int brcm_ahci_remove(struct platform_device *pdev) +static void brcm_ahci_remove(struct platform_device *pdev) { struct ata_host *host = dev_get_drvdata(&pdev->dev); struct ahci_host_priv *hpriv = host->private_data; @@ -552,7 +552,7 @@ static int brcm_ahci_remove(struct platform_device *pdev) brcm_sata_phys_disable(priv); - return ata_platform_remove_one(pdev); + ata_platform_remove_one(pdev); } static void brcm_ahci_shutdown(struct platform_device *pdev) @@ -573,7 +573,7 @@ static SIMPLE_DEV_PM_OPS(ahci_brcm_pm_ops, brcm_ahci_suspend, brcm_ahci_resume); static struct platform_driver brcm_ahci_driver = { .probe = brcm_ahci_probe, - .remove = brcm_ahci_remove, + .remove_new = brcm_ahci_remove, .shutdown = brcm_ahci_shutdown, .driver = { .name = DRV_NAME, diff --git a/drivers/ata/ahci_ceva.c b/drivers/ata/ahci_ceva.c index bc027468decb..c2b6be083af4 100644 --- a/drivers/ata/ahci_ceva.c +++ b/drivers/ata/ahci_ceva.c @@ -369,7 +369,7 @@ MODULE_DEVICE_TABLE(of, ceva_ahci_of_match); static struct platform_driver ceva_ahci_driver = { .probe = ceva_ahci_probe, - .remove = ata_platform_remove_one, + .remove_new = ata_platform_remove_one, .driver = { .name = DRV_NAME, .of_match_table = ceva_ahci_of_match, diff --git a/drivers/ata/ahci_da850.c b/drivers/ata/ahci_da850.c index ca0924dc5bd2..55a6627d5450 100644 --- a/drivers/ata/ahci_da850.c +++ b/drivers/ata/ahci_da850.c @@ -238,7 +238,7 @@ MODULE_DEVICE_TABLE(of, ahci_da850_of_match); static struct platform_driver ahci_da850_driver = { .probe = ahci_da850_probe, - .remove = ata_platform_remove_one, + .remove_new = ata_platform_remove_one, .driver = { .name = DRV_NAME, .of_match_table = ahci_da850_of_match, diff --git a/drivers/ata/ahci_dm816.c b/drivers/ata/ahci_dm816.c index b08547b877a1..4cb70064fb99 100644 --- a/drivers/ata/ahci_dm816.c +++ b/drivers/ata/ahci_dm816.c @@ -182,7 +182,7 @@ MODULE_DEVICE_TABLE(of, ahci_dm816_of_match); static struct platform_driver ahci_dm816_driver = { .probe = ahci_dm816_probe, - .remove = ata_platform_remove_one, + .remove_new = ata_platform_remove_one, .driver = { .name = AHCI_DM816_DRV_NAME, .of_match_table = ahci_dm816_of_match, diff --git a/drivers/ata/ahci_dwc.c b/drivers/ata/ahci_dwc.c index 4bfbb09cdc02..9604a2f6ed48 100644 --- a/drivers/ata/ahci_dwc.c +++ b/drivers/ata/ahci_dwc.c @@ -478,7 +478,7 @@ MODULE_DEVICE_TABLE(of, ahci_dwc_of_match); static struct platform_driver ahci_dwc_driver = { .probe = ahci_dwc_probe, - .remove = ata_platform_remove_one, + .remove_new = ata_platform_remove_one, .shutdown = ahci_platform_shutdown, .driver = { .name = DRV_NAME, diff --git a/drivers/ata/ahci_imx.c b/drivers/ata/ahci_imx.c index 3a8c248e7c0e..9fa005965f3b 100644 --- a/drivers/ata/ahci_imx.c +++ b/drivers/ata/ahci_imx.c @@ -1223,7 +1223,7 @@ static SIMPLE_DEV_PM_OPS(ahci_imx_pm_ops, imx_ahci_suspend, imx_ahci_resume); static struct platform_driver imx_ahci_driver = { .probe = imx_ahci_probe, - .remove = ata_platform_remove_one, + .remove_new = ata_platform_remove_one, .driver = { .name = DRV_NAME, .of_match_table = imx_ahci_of_match, diff --git a/drivers/ata/ahci_mtk.c b/drivers/ata/ahci_mtk.c index 0bf83a297091..5083fb6c4927 100644 --- a/drivers/ata/ahci_mtk.c +++ b/drivers/ata/ahci_mtk.c @@ -173,7 +173,7 @@ MODULE_DEVICE_TABLE(of, ahci_of_match); static struct platform_driver mtk_ahci_driver = { .probe = mtk_ahci_probe, - .remove = ata_platform_remove_one, + .remove_new = ata_platform_remove_one, .driver = { .name = DRV_NAME, .of_match_table = ahci_of_match, diff --git a/drivers/ata/ahci_mvebu.c b/drivers/ata/ahci_mvebu.c index 596cf017f427..764501518582 100644 --- a/drivers/ata/ahci_mvebu.c +++ b/drivers/ata/ahci_mvebu.c @@ -245,7 +245,7 @@ MODULE_DEVICE_TABLE(of, ahci_mvebu_of_match); static struct platform_driver ahci_mvebu_driver = { .probe = ahci_mvebu_probe, - .remove = ata_platform_remove_one, + .remove_new = ata_platform_remove_one, .suspend = ahci_mvebu_suspend, .resume = ahci_mvebu_resume, .driver = { diff --git a/drivers/ata/ahci_octeon.c b/drivers/ata/ahci_octeon.c index 5021ab3ede49..e89807fa928e 100644 --- a/drivers/ata/ahci_octeon.c +++ b/drivers/ata/ahci_octeon.c @@ -16,7 +16,6 @@ #include <linux/of_platform.h> #include <asm/octeon/octeon.h> -#include <asm/bitfield.h> #define CVMX_SATA_UCTL_SHIM_CFG 0xE8 diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c index c18054333f7c..81fc63f6b008 100644 --- a/drivers/ata/ahci_platform.c +++ b/drivers/ata/ahci_platform.c @@ -96,7 +96,7 @@ MODULE_DEVICE_TABLE(acpi, ahci_acpi_match); static struct platform_driver ahci_driver = { .probe = ahci_probe, - .remove = ata_platform_remove_one, + .remove_new = ata_platform_remove_one, .shutdown = ahci_platform_shutdown, .driver = { .name = DRV_NAME, diff --git a/drivers/ata/ahci_qoriq.c b/drivers/ata/ahci_qoriq.c index 0ba764d283c8..3d01b118c9a1 100644 --- a/drivers/ata/ahci_qoriq.c +++ b/drivers/ata/ahci_qoriq.c @@ -359,7 +359,7 @@ static SIMPLE_DEV_PM_OPS(ahci_qoriq_pm_ops, ahci_platform_suspend, static struct platform_driver ahci_qoriq_driver = { .probe = ahci_qoriq_probe, - .remove = ata_platform_remove_one, + .remove_new = ata_platform_remove_one, .driver = { .name = DRV_NAME, .of_match_table = ahci_qoriq_of_match, diff --git a/drivers/ata/ahci_seattle.c b/drivers/ata/ahci_seattle.c index 9eda7bbd2151..2c32d58c6ae7 100644 --- a/drivers/ata/ahci_seattle.c +++ b/drivers/ata/ahci_seattle.c @@ -187,7 +187,7 @@ MODULE_DEVICE_TABLE(acpi, ahci_acpi_match); static struct platform_driver ahci_seattle_driver = { .probe = ahci_seattle_probe, - .remove = ata_platform_remove_one, + .remove_new = ata_platform_remove_one, .driver = { .name = DRV_NAME, .acpi_match_table = ahci_acpi_match, diff --git a/drivers/ata/ahci_st.c b/drivers/ata/ahci_st.c index f2c1edb36986..d4a626f87963 100644 --- a/drivers/ata/ahci_st.c +++ b/drivers/ata/ahci_st.c @@ -239,7 +239,7 @@ static struct platform_driver st_ahci_driver = { .of_match_table = st_ahci_match, }, .probe = st_ahci_probe, - .remove = ata_platform_remove_one, + .remove_new = ata_platform_remove_one, }; module_platform_driver(st_ahci_driver); diff --git a/drivers/ata/ahci_sunxi.c b/drivers/ata/ahci_sunxi.c index 076c12b4ba08..04531fa95e40 100644 --- a/drivers/ata/ahci_sunxi.c +++ b/drivers/ata/ahci_sunxi.c @@ -292,7 +292,7 @@ MODULE_DEVICE_TABLE(of, ahci_sunxi_of_match); static struct platform_driver ahci_sunxi_driver = { .probe = ahci_sunxi_probe, - .remove = ata_platform_remove_one, + .remove_new = ata_platform_remove_one, .driver = { .name = DRV_NAME, .of_match_table = ahci_sunxi_of_match, diff --git a/drivers/ata/ahci_tegra.c b/drivers/ata/ahci_tegra.c index 8e5e2b359f2d..21c20793e517 100644 --- a/drivers/ata/ahci_tegra.c +++ b/drivers/ata/ahci_tegra.c @@ -609,7 +609,7 @@ deinit_controller: static struct platform_driver tegra_ahci_driver = { .probe = tegra_ahci_probe, - .remove = ata_platform_remove_one, + .remove_new = ata_platform_remove_one, .driver = { .name = DRV_NAME, .of_match_table = tegra_ahci_of_match, diff --git a/drivers/ata/ahci_xgene.c b/drivers/ata/ahci_xgene.c index 83f5ff54ef5b..eb773f2e28fc 100644 --- a/drivers/ata/ahci_xgene.c +++ b/drivers/ata/ahci_xgene.c @@ -868,7 +868,7 @@ disable_resources: static struct platform_driver xgene_ahci_driver = { .probe = xgene_ahci_probe, - .remove = ata_platform_remove_one, + .remove_new = ata_platform_remove_one, .driver = { .name = DRV_NAME, .of_match_table = xgene_ahci_of_match, diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 9c2cb6cbea76..06aec35f88f2 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c @@ -975,44 +975,43 @@ int ahci_reset_controller(struct ata_host *host) void __iomem *mmio = hpriv->mmio; u32 tmp; - /* we must be in AHCI mode, before using anything - * AHCI-specific, such as HOST_RESET. + /* + * We must be in AHCI mode, before using anything AHCI-specific, such + * as HOST_RESET. */ ahci_enable_ahci(mmio); - /* global controller reset */ - if (!ahci_skip_host_reset) { - tmp = readl(mmio + HOST_CTL); - if ((tmp & HOST_RESET) == 0) { - writel(tmp | HOST_RESET, mmio + HOST_CTL); - readl(mmio + HOST_CTL); /* flush */ - } + /* Global controller reset */ + if (ahci_skip_host_reset) { + dev_info(host->dev, "Skipping global host reset\n"); + return 0; + } - /* - * to perform host reset, OS should set HOST_RESET - * and poll until this bit is read to be "0". - * reset must complete within 1 second, or - * the hardware should be considered fried. - */ - tmp = ata_wait_register(NULL, mmio + HOST_CTL, HOST_RESET, - HOST_RESET, 10, 1000); + tmp = readl(mmio + HOST_CTL); + if (!(tmp & HOST_RESET)) { + writel(tmp | HOST_RESET, mmio + HOST_CTL); + readl(mmio + HOST_CTL); /* flush */ + } - if (tmp & HOST_RESET) { - dev_err(host->dev, "controller reset failed (0x%x)\n", - tmp); - return -EIO; - } + /* + * To perform host reset, OS should set HOST_RESET and poll until this + * bit is read to be "0". Reset must complete within 1 second, or the + * hardware should be considered fried. + */ + tmp = ata_wait_register(NULL, mmio + HOST_CTL, HOST_RESET, + HOST_RESET, 10, 1000); + if (tmp & HOST_RESET) { + dev_err(host->dev, "Controller reset failed (0x%x)\n", + tmp); + return -EIO; + } - /* turn on AHCI mode */ - ahci_enable_ahci(mmio); + /* Turn on AHCI mode */ + ahci_enable_ahci(mmio); - /* Some registers might be cleared on reset. Restore - * initial values. - */ - if (!(hpriv->flags & AHCI_HFLAG_NO_WRITE_TO_RO)) - ahci_restore_initial_config(host); - } else - dev_info(host->dev, "skipping global host reset\n"); + /* Some registers might be cleared on reset. Restore initial values. */ + if (!(hpriv->flags & AHCI_HFLAG_NO_WRITE_TO_RO)) + ahci_restore_initial_config(host); return 0; } diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 8bf612bdd61a..d37ab6087f2f 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -665,12 +665,33 @@ u64 ata_tf_read_block(const struct ata_taskfile *tf, struct ata_device *dev) return block; } +/* + * Set a taskfile command duration limit index. + */ +static inline void ata_set_tf_cdl(struct ata_queued_cmd *qc, int cdl) +{ + struct ata_taskfile *tf = &qc->tf; + + if (tf->protocol == ATA_PROT_NCQ) + tf->auxiliary |= cdl; + else + tf->feature |= cdl; + + /* + * Mark this command as having a CDL and request the result + * task file so that we can inspect the sense data available + * bit on completion. + */ + qc->flags |= ATA_QCFLAG_HAS_CDL | ATA_QCFLAG_RESULT_TF; +} + /** * ata_build_rw_tf - Build ATA taskfile for given read/write request * @qc: Metadata associated with the taskfile to build * @block: Block address * @n_block: Number of blocks * @tf_flags: RW/FUA etc... + * @cdl: Command duration limit index * @class: IO priority class * * LOCKING: @@ -685,7 +706,7 @@ u64 ata_tf_read_block(const struct ata_taskfile *tf, struct ata_device *dev) * -EINVAL if the request is invalid. */ int ata_build_rw_tf(struct ata_queued_cmd *qc, u64 block, u32 n_block, - unsigned int tf_flags, int class) + unsigned int tf_flags, int cdl, int class) { struct ata_taskfile *tf = &qc->tf; struct ata_device *dev = qc->dev; @@ -724,11 +745,20 @@ int ata_build_rw_tf(struct ata_queued_cmd *qc, u64 block, u32 n_block, if (dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLED && class == IOPRIO_CLASS_RT) tf->hob_nsect |= ATA_PRIO_HIGH << ATA_SHIFT_PRIO; + + if ((dev->flags & ATA_DFLAG_CDL_ENABLED) && cdl) + ata_set_tf_cdl(qc, cdl); + } else if (dev->flags & ATA_DFLAG_LBA) { tf->flags |= ATA_TFLAG_LBA; - /* We need LBA48 for FUA writes */ - if (!(tf->flags & ATA_TFLAG_FUA) && lba_28_ok(block, n_block)) { + if ((dev->flags & ATA_DFLAG_CDL_ENABLED) && cdl) + ata_set_tf_cdl(qc, cdl); + + /* Both FUA writes and a CDL index require 48-bit commands */ + if (!(tf->flags & ATA_TFLAG_FUA) && + !(qc->flags & ATA_QCFLAG_HAS_CDL) && + lba_28_ok(block, n_block)) { /* use LBA28 */ tf->device |= (block >> 24) & 0xf; } else if (lba_48_ok(block, n_block)) { @@ -2367,6 +2397,139 @@ static void ata_dev_config_trusted(struct ata_device *dev) dev->flags |= ATA_DFLAG_TRUSTED; } +static void ata_dev_config_cdl(struct ata_device *dev) +{ + struct ata_port *ap = dev->link->ap; + unsigned int err_mask; + bool cdl_enabled; + u64 val; + + if (ata_id_major_version(dev->id) < 12) + goto not_supported; + + if (!ata_log_supported(dev, ATA_LOG_IDENTIFY_DEVICE) || + !ata_identify_page_supported(dev, ATA_LOG_SUPPORTED_CAPABILITIES) || + !ata_identify_page_supported(dev, ATA_LOG_CURRENT_SETTINGS)) + goto not_supported; + + err_mask = ata_read_log_page(dev, ATA_LOG_IDENTIFY_DEVICE, + ATA_LOG_SUPPORTED_CAPABILITIES, + ap->sector_buf, 1); + if (err_mask) + goto not_supported; + + /* Check Command Duration Limit Supported bits */ + val = get_unaligned_le64(&ap->sector_buf[168]); + if (!(val & BIT_ULL(63)) || !(val & BIT_ULL(0))) + goto not_supported; + + /* Warn the user if command duration guideline is not supported */ + if (!(val & BIT_ULL(1))) + ata_dev_warn(dev, + "Command duration guideline is not supported\n"); + + /* + * We must have support for the sense data for successful NCQ commands + * log indicated by the successful NCQ command sense data supported bit. + */ + val = get_unaligned_le64(&ap->sector_buf[8]); + if (!(val & BIT_ULL(63)) || !(val & BIT_ULL(47))) { + ata_dev_warn(dev, + "CDL supported but Successful NCQ Command Sense Data is not supported\n"); + goto not_supported; + } + + /* Without NCQ autosense, the successful NCQ commands log is useless. */ + if (!ata_id_has_ncq_autosense(dev->id)) { + ata_dev_warn(dev, + "CDL supported but NCQ autosense is not supported\n"); + goto not_supported; + } + + /* + * If CDL is marked as enabled, make sure the feature is enabled too. + * Conversely, if CDL is disabled, make sure the feature is turned off. + */ + err_mask = ata_read_log_page(dev, ATA_LOG_IDENTIFY_DEVICE, + ATA_LOG_CURRENT_SETTINGS, + ap->sector_buf, 1); + if (err_mask) + goto not_supported; + + val = get_unaligned_le64(&ap->sector_buf[8]); + cdl_enabled = val & BIT_ULL(63) && val & BIT_ULL(21); + if (dev->flags & ATA_DFLAG_CDL_ENABLED) { + if (!cdl_enabled) { + /* Enable CDL on the device */ + err_mask = ata_dev_set_feature(dev, SETFEATURES_CDL, 1); + if (err_mask) { + ata_dev_err(dev, + "Enable CDL feature failed\n"); + goto not_supported; + } + } + } else { + if (cdl_enabled) { + /* Disable CDL on the device */ + err_mask = ata_dev_set_feature(dev, SETFEATURES_CDL, 0); + if (err_mask) { + ata_dev_err(dev, + "Disable CDL feature failed\n"); + goto not_supported; + } + } + } + + /* + * While CDL itself has to be enabled using sysfs, CDL requires that + * sense data for successful NCQ commands is enabled to work properly. + * Just like ata_dev_config_sense_reporting(), enable it unconditionally + * if supported. + */ + if (!(val & BIT_ULL(63)) || !(val & BIT_ULL(18))) { + err_mask = ata_dev_set_feature(dev, + SETFEATURE_SENSE_DATA_SUCC_NCQ, 0x1); + if (err_mask) { + ata_dev_warn(dev, + "failed to enable Sense Data for successful NCQ commands, Emask 0x%x\n", + err_mask); + goto not_supported; + } + } + + /* + * Allocate a buffer to handle reading the sense data for successful + * NCQ Commands log page for commands using a CDL with one of the limit + * policy set to 0xD (successful completion with sense data available + * bit set). + */ + if (!ap->ncq_sense_buf) { + ap->ncq_sense_buf = kmalloc(ATA_LOG_SENSE_NCQ_SIZE, GFP_KERNEL); + if (!ap->ncq_sense_buf) + goto not_supported; + } + + /* + * Command duration limits is supported: cache the CDL log page 18h + * (command duration descriptors). + */ + err_mask = ata_read_log_page(dev, ATA_LOG_CDL, 0, ap->sector_buf, 1); + if (err_mask) { + ata_dev_warn(dev, "Read Command Duration Limits log failed\n"); + goto not_supported; + } + + memcpy(dev->cdl, ap->sector_buf, ATA_LOG_CDL_SIZE); + dev->flags |= ATA_DFLAG_CDL; + + return; + +not_supported: + dev->flags &= ~(ATA_DFLAG_CDL | ATA_DFLAG_CDL_ENABLED); + kfree(ap->ncq_sense_buf); + ap->ncq_sense_buf = NULL; +} + static int ata_dev_config_lba(struct ata_device *dev) { const u16 *id = dev->id; @@ -2534,13 +2697,14 @@ static void ata_dev_print_features(struct ata_device *dev) return; ata_dev_info(dev, - "Features:%s%s%s%s%s%s%s\n", + "Features:%s%s%s%s%s%s%s%s\n", dev->flags & ATA_DFLAG_FUA ? " FUA" : "", dev->flags & ATA_DFLAG_TRUSTED ? " Trust" : "", dev->flags & ATA_DFLAG_DA ? " Dev-Attention" : "", dev->flags & ATA_DFLAG_DEVSLP ? " Dev-Sleep" : "", dev->flags & ATA_DFLAG_NCQ_SEND_RECV ? " NCQ-sndrcv" : "", dev->flags & ATA_DFLAG_NCQ_PRIO ? " NCQ-prio" : "", + dev->flags & ATA_DFLAG_CDL ? " CDL" : "", dev->cpr_log ? " CPR" : ""); } @@ -2702,6 +2866,7 @@ int ata_dev_configure(struct ata_device *dev) ata_dev_config_zac(dev); ata_dev_config_trusted(dev); ata_dev_config_cpr(dev); + ata_dev_config_cdl(dev); dev->cdb_len = 32; if (print_info) @@ -3802,11 +3967,7 @@ int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class, return -ENODEV; /* fail early if !ATA && !ATAPI to avoid issuing [P]IDENTIFY to PMP */ - if (ata_class_enabled(new_class) && - new_class != ATA_DEV_ATA && - new_class != ATA_DEV_ATAPI && - new_class != ATA_DEV_ZAC && - new_class != ATA_DEV_SEMB) { + if (ata_class_enabled(new_class) && new_class == ATA_DEV_PMP) { ata_dev_info(dev, "class mismatch %u != %u\n", dev->class, new_class); rc = -ENODEV; @@ -4766,6 +4927,36 @@ void ata_qc_complete(struct ata_queued_cmd *qc) fill_result_tf(qc); trace_ata_qc_complete_done(qc); + + /* + * For CDL commands that completed without an error, check if + * we have sense data (ATA_SENSE is set). If we do, then the + * command may have been aborted by the device due to a limit + * timeout using the policy 0xD. For these commands, invoke EH + * to get the command sense data. + */ + if (qc->result_tf.status & ATA_SENSE && + ((ata_is_ncq(qc->tf.protocol) && + dev->flags & ATA_DFLAG_CDL_ENABLED) || + (!(ata_is_ncq(qc->tf.protocol) && + ata_id_sense_reporting_enabled(dev->id))))) { + /* + * Tell SCSI EH to not overwrite scmd->result even if + * this command is finished with result SAM_STAT_GOOD. + */ + qc->scsicmd->flags |= SCMD_FORCE_EH_SUCCESS; + qc->flags |= ATA_QCFLAG_EH_SUCCESS_CMD; + ehi->dev_action[dev->devno] |= ATA_EH_GET_SUCCESS_SENSE; + + /* + * set pending so that ata_qc_schedule_eh() does not + * trigger fast drain, and freeze the port. + */ + ap->pflags |= ATA_PFLAG_EH_PENDING; + ata_qc_schedule_eh(qc); + return; + } + /* Some commands need post-processing after successful * completion. */ @@ -5348,7 +5539,7 @@ struct ata_port *ata_port_alloc(struct ata_host *host) mutex_init(&ap->scsi_scan_mutex); INIT_DELAYED_WORK(&ap->hotplug_task, ata_scsi_hotplug); - INIT_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan); + INIT_DELAYED_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan); INIT_LIST_HEAD(&ap->eh_done_q); init_waitqueue_head(&ap->eh_wait_q); init_completion(&ap->park_req_pending); @@ -5398,6 +5589,7 @@ static void ata_host_release(struct kref *kref) kfree(ap->pmp_link); kfree(ap->slave_link); + kfree(ap->ncq_sense_buf); kfree(ap); host->ports[i] = NULL; } @@ -5954,6 +6146,7 @@ static void ata_port_detach(struct ata_port *ap) WARN_ON(!(ap->pflags & ATA_PFLAG_UNLOADED)); cancel_delayed_work_sync(&ap->hotplug_task); + cancel_delayed_work_sync(&ap->scsi_rescan_task); skip_eh: /* clean up zpodd on port removal */ @@ -6141,13 +6334,11 @@ EXPORT_SYMBOL_GPL(ata_pci_device_resume); * LOCKING: * Inherited from platform layer (may sleep). */ -int ata_platform_remove_one(struct platform_device *pdev) +void ata_platform_remove_one(struct platform_device *pdev) { struct ata_host *host = platform_get_drvdata(pdev); ata_host_detach(host); - - return 0; } EXPORT_SYMBOL_GPL(ata_platform_remove_one); diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index a6c901811802..35e03679b0bf 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -1401,8 +1401,11 @@ unsigned int atapi_eh_tur(struct ata_device *dev, u8 *r_sense_key) * * LOCKING: * Kernel thread context (may sleep). + * + * RETURNS: + * true if sense data could be fetched, false otherwise. */ -static void ata_eh_request_sense(struct ata_queued_cmd *qc) +static bool ata_eh_request_sense(struct ata_queued_cmd *qc) { struct scsi_cmnd *cmd = qc->scsicmd; struct ata_device *dev = qc->dev; @@ -1411,15 +1414,12 @@ static void ata_eh_request_sense(struct ata_queued_cmd *qc) if (ata_port_is_frozen(qc->ap)) { ata_dev_warn(dev, "sense data available but port frozen\n"); - return; + return false; } - if (!cmd || qc->flags & ATA_QCFLAG_SENSE_VALID) - return; - if (!ata_id_sense_reporting_enabled(dev->id)) { ata_dev_warn(qc->dev, "sense data reporting disabled\n"); - return; + return false; } ata_tf_init(dev, &tf); @@ -1432,13 +1432,19 @@ static void ata_eh_request_sense(struct ata_queued_cmd *qc) /* Ignore err_mask; ATA_ERR might be set */ if (tf.status & ATA_SENSE) { if (ata_scsi_sense_is_valid(tf.lbah, tf.lbam, tf.lbal)) { - ata_scsi_set_sense(dev, cmd, tf.lbah, tf.lbam, tf.lbal); + /* Set sense without also setting scsicmd->result */ + scsi_build_sense_buffer(dev->flags & ATA_DFLAG_D_SENSE, + cmd->sense_buffer, tf.lbah, + tf.lbam, tf.lbal); qc->flags |= ATA_QCFLAG_SENSE_VALID; + return true; } } else { ata_dev_warn(dev, "request sense failed stat %02x emask %x\n", tf.status, err_mask); } + + return false; } /** @@ -1588,8 +1594,9 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc) * was not included in the NCQ command error log * (i.e. NCQ autosense is not supported by the device). */ - if (!(qc->flags & ATA_QCFLAG_SENSE_VALID) && (stat & ATA_SENSE)) - ata_eh_request_sense(qc); + if (!(qc->flags & ATA_QCFLAG_SENSE_VALID) && + (stat & ATA_SENSE) && ata_eh_request_sense(qc)) + set_status_byte(qc->scsicmd, SAM_STAT_CHECK_CONDITION); if (err & ATA_ICRC) qc->err_mask |= AC_ERR_ATA_BUS; if (err & (ATA_UNC | ATA_AMNF)) @@ -1817,9 +1824,7 @@ static unsigned int ata_eh_speed_down(struct ata_device *dev, verdict = ata_eh_speed_down_verdict(dev); /* turn off NCQ? */ - if ((verdict & ATA_EH_SPDN_NCQ_OFF) && - (dev->flags & (ATA_DFLAG_PIO | ATA_DFLAG_NCQ | - ATA_DFLAG_NCQ_OFF)) == ATA_DFLAG_NCQ) { + if ((verdict & ATA_EH_SPDN_NCQ_OFF) && ata_ncq_enabled(dev)) { dev->flags |= ATA_DFLAG_NCQ_OFF; ata_dev_warn(dev, "NCQ disabled due to excessive errors\n"); goto done; @@ -1910,6 +1915,99 @@ static inline bool ata_eh_quiet(struct ata_queued_cmd *qc) return qc->flags & ATA_QCFLAG_QUIET; } +static int ata_eh_read_sense_success_non_ncq(struct ata_link *link) +{ + struct ata_port *ap = link->ap; + struct ata_queued_cmd *qc; + + qc = __ata_qc_from_tag(ap, link->active_tag); + if (!qc) + return -EIO; + + if (!(qc->flags & ATA_QCFLAG_EH) || + !(qc->flags & ATA_QCFLAG_EH_SUCCESS_CMD) || + qc->err_mask) + return -EIO; + + if (!ata_eh_request_sense(qc)) + return -EIO; + + /* + * If we have sense data, call scsi_check_sense() in order to set the + * correct SCSI ML byte (if any). No point in checking the return value, + * since the command has already completed successfully. + */ + scsi_check_sense(qc->scsicmd); + + return 0; +} + +static void ata_eh_get_success_sense(struct ata_link *link) +{ + struct ata_eh_context *ehc = &link->eh_context; + struct ata_device *dev = link->device; + struct ata_port *ap = link->ap; + struct ata_queued_cmd *qc; + int tag, ret = 0; + + if (!(ehc->i.dev_action[dev->devno] & ATA_EH_GET_SUCCESS_SENSE)) + return; + + /* if frozen, we can't do much */ + if (ata_port_is_frozen(ap)) { + ata_dev_warn(dev, + "successful sense data available but port frozen\n"); + goto out; + } + + /* + * If the link has sactive set, then we have outstanding NCQ commands + * and have to read the Successful NCQ Commands log to get the sense + * data. Otherwise, we are dealing with a non-NCQ command and use + * request sense ext command to retrieve the sense data. + */ + if (link->sactive) + ret = ata_eh_read_sense_success_ncq_log(link); + else + ret = ata_eh_read_sense_success_non_ncq(link); + if (ret) + goto out; + + ata_eh_done(link, dev, ATA_EH_GET_SUCCESS_SENSE); + return; + +out: + /* + * If we failed to get sense data for a successful command that ought to + * have sense data, we cannot simply return BLK_STS_OK to user space. + * This is because we can't know if the sense data that we couldn't get + * was actually "DATA CURRENTLY UNAVAILABLE". Reporting such a command + * as success to user space would result in a silent data corruption. + * Thus, add a bogus ABORTED_COMMAND sense data to such commands, such + * that SCSI will report these commands as BLK_STS_IOERR to user space. + */ + ata_qc_for_each_raw(ap, qc, tag) { + if (!(qc->flags & ATA_QCFLAG_EH) || + !(qc->flags & ATA_QCFLAG_EH_SUCCESS_CMD) || + qc->err_mask || + ata_dev_phys_link(qc->dev) != link) + continue; + + /* We managed to get sense for this success command, skip. */ + if (qc->flags & ATA_QCFLAG_SENSE_VALID) + continue; + + /* This success command did not have any sense data, skip. */ + if (!(qc->result_tf.status & ATA_SENSE)) + continue; + + /* This success command had sense data, but we failed to get. */ + ata_scsi_set_sense(dev, qc->scsicmd, ABORTED_COMMAND, 0, 0); + qc->flags |= ATA_QCFLAG_SENSE_VALID; + } + ata_eh_done(link, dev, ATA_EH_GET_SUCCESS_SENSE); +} + /** * ata_eh_link_autopsy - analyze error and determine recovery action * @link: host link to perform autopsy on @@ -1950,6 +2048,14 @@ static void ata_eh_link_autopsy(struct ata_link *link) /* analyze NCQ failure */ ata_eh_analyze_ncq_error(link); + /* + * Check if this was a successful command that simply needs sense data. + * Since the sense data is not part of the completion, we need to fetch + * it using an additional command. Since this can't be done from irq + * context, the sense data for successful commands are fetched by EH. + */ + ata_eh_get_success_sense(link); + /* any real error trumps AC_ERR_OTHER */ if (ehc->i.err_mask & ~AC_ERR_OTHER) ehc->i.err_mask &= ~AC_ERR_OTHER; @@ -1959,6 +2065,7 @@ static void ata_eh_link_autopsy(struct ata_link *link) ata_qc_for_each_raw(ap, qc, tag) { if (!(qc->flags & ATA_QCFLAG_EH) || qc->flags & ATA_QCFLAG_RETRY || + qc->flags & ATA_QCFLAG_EH_SUCCESS_CMD || ata_dev_phys_link(qc->dev) != link) continue; @@ -2984,7 +3091,7 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link, ehc->i.flags |= ATA_EHI_SETMODE; /* schedule the scsi_rescan_device() here */ - schedule_work(&(ap->scsi_rescan_task)); + schedule_delayed_work(&ap->scsi_rescan_task, 0); } else if (dev->class == ATA_DEV_UNKNOWN && ehc->tries[dev->devno] && ata_class_enabled(ehc->classes[dev->devno])) { @@ -3813,16 +3920,30 @@ void ata_eh_finish(struct ata_port *ap) * generate sense data in this function, * considering both err_mask and tf. */ - if (qc->flags & ATA_QCFLAG_RETRY) + if (qc->flags & ATA_QCFLAG_RETRY) { + /* + * Since qc->err_mask is set, ata_eh_qc_retry() + * will not increment scmd->allowed, so upper + * layer will only retry the command if it has + * not already been retried too many times. + */ ata_eh_qc_retry(qc); - else + } else { ata_eh_qc_complete(qc); + } } else { - if (qc->flags & ATA_QCFLAG_SENSE_VALID) { + if (qc->flags & ATA_QCFLAG_SENSE_VALID || + qc->flags & ATA_QCFLAG_EH_SUCCESS_CMD) { ata_eh_qc_complete(qc); } else { /* feed zero TF to sense generation */ memset(&qc->result_tf, 0, sizeof(qc->result_tf)); + /* + * Since qc->err_mask is not set, + * ata_eh_qc_retry() will increment + * scmd->allowed, so upper layer is guaranteed + * to retry the command. + */ ata_eh_qc_retry(qc); } } diff --git a/drivers/ata/libata-sata.c b/drivers/ata/libata-sata.c index f3e7396e3191..85e279a12f62 100644 --- a/drivers/ata/libata-sata.c +++ b/drivers/ata/libata-sata.c @@ -11,7 +11,9 @@ #include <linux/module.h> #include <scsi/scsi_cmnd.h> #include <scsi/scsi_device.h> +#include <scsi/scsi_eh.h> #include <linux/libata.h> +#include <asm/unaligned.h> #include "libata.h" #include "libata-transport.h" @@ -907,10 +909,17 @@ static ssize_t ata_ncq_prio_enable_store(struct device *device, goto unlock; } - if (input) + if (input) { + if (dev->flags & ATA_DFLAG_CDL_ENABLED) { + ata_dev_err(dev, + "CDL must be disabled to enable NCQ priority\n"); + rc = -EINVAL; + goto unlock; + } dev->flags |= ATA_DFLAG_NCQ_PRIO_ENABLED; - else + } else { dev->flags &= ~ATA_DFLAG_NCQ_PRIO_ENABLED; + } unlock: spin_unlock_irq(ap->lock); @@ -1023,7 +1032,6 @@ EXPORT_SYMBOL_GPL(dev_attr_sw_activity); /** * ata_change_queue_depth - Set a device maximum queue depth * @ap: ATA port of the target device - * @dev: target ATA device * @sdev: SCSI device to configure queue depth for * @queue_depth: new queue depth * @@ -1031,33 +1039,47 @@ EXPORT_SYMBOL_GPL(dev_attr_sw_activity); * and libata. * */ -int ata_change_queue_depth(struct ata_port *ap, struct ata_device *dev, - struct scsi_device *sdev, int queue_depth) +int ata_change_queue_depth(struct ata_port *ap, struct scsi_device *sdev, + int queue_depth) { + struct ata_device *dev; unsigned long flags; + int max_queue_depth; - if (!dev || !ata_dev_enabled(dev)) - return sdev->queue_depth; + spin_lock_irqsave(ap->lock, flags); - if (queue_depth < 1 || queue_depth == sdev->queue_depth) + dev = ata_scsi_find_dev(ap, sdev); + if (!dev || queue_depth < 1 || queue_depth == sdev->queue_depth) { + spin_unlock_irqrestore(ap->lock, flags); return sdev->queue_depth; + } - /* NCQ enabled? */ - spin_lock_irqsave(ap->lock, flags); - dev->flags &= ~ATA_DFLAG_NCQ_OFF; - if (queue_depth == 1 || !ata_ncq_enabled(dev)) { + /* + * Make sure that the queue depth requested does not exceed the device + * capabilities. + */ + max_queue_depth = min(ATA_MAX_QUEUE, sdev->host->can_queue); + max_queue_depth = min(max_queue_depth, ata_id_queue_depth(dev->id)); + if (queue_depth > max_queue_depth) { + spin_unlock_irqrestore(ap->lock, flags); + return -EINVAL; + } + + /* + * If NCQ is not supported by the device or if the target queue depth + * is 1 (to disable drive side command queueing), turn off NCQ. + */ + if (queue_depth == 1 || !ata_ncq_supported(dev)) { dev->flags |= ATA_DFLAG_NCQ_OFF; queue_depth = 1; + } else { + dev->flags &= ~ATA_DFLAG_NCQ_OFF; } - spin_unlock_irqrestore(ap->lock, flags); - /* limit and apply queue depth */ - queue_depth = min(queue_depth, sdev->host->can_queue); - queue_depth = min(queue_depth, ata_id_queue_depth(dev->id)); - queue_depth = min(queue_depth, ATA_MAX_QUEUE); + spin_unlock_irqrestore(ap->lock, flags); - if (sdev->queue_depth == queue_depth) - return -EINVAL; + if (queue_depth == sdev->queue_depth) + return sdev->queue_depth; return scsi_change_queue_depth(sdev, queue_depth); } @@ -1082,8 +1104,7 @@ int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth) { struct ata_port *ap = ata_shost_to_port(sdev->host); - return ata_change_queue_depth(ap, ata_scsi_find_dev(ap, sdev), - sdev, queue_depth); + return ata_change_queue_depth(ap, sdev, queue_depth); } EXPORT_SYMBOL_GPL(ata_scsi_change_queue_depth); @@ -1402,6 +1423,95 @@ static int ata_eh_read_log_10h(struct ata_device *dev, } /** + * ata_eh_read_sense_success_ncq_log - Read the sense data for successful + * NCQ commands log + * @link: ATA link to get sense data for + * + * Read the sense data for successful NCQ commands log page to obtain + * sense data for all NCQ commands that completed successfully with + * the sense data available bit set. + * + * LOCKING: + * Kernel thread context (may sleep). + * + * RETURNS: + * 0 on success, -errno otherwise. + */ +int ata_eh_read_sense_success_ncq_log(struct ata_link *link) +{ + struct ata_device *dev = link->device; + struct ata_port *ap = dev->link->ap; + u8 *buf = ap->ncq_sense_buf; + struct ata_queued_cmd *qc; + unsigned int err_mask, tag; + u8 *sense, sk = 0, asc = 0, ascq = 0; + u64 sense_valid, val; + int ret = 0; + + err_mask = ata_read_log_page(dev, ATA_LOG_SENSE_NCQ, 0, buf, 2); + if (err_mask) { + ata_dev_err(dev, + "Failed to read Sense Data for Successful NCQ Commands log\n"); + return -EIO; + } + + /* Check the log header */ + val = get_unaligned_le64(&buf[0]); + if ((val & 0xffff) != 1 || ((val >> 16) & 0xff) != 0x0f) { + ata_dev_err(dev, + "Invalid Sense Data for Successful NCQ Commands log\n"); + return -EIO; + } + + sense_valid = (u64)buf[8] | ((u64)buf[9] << 8) | + ((u64)buf[10] << 16) | ((u64)buf[11] << 24); + + ata_qc_for_each_raw(ap, qc, tag) { + if (!(qc->flags & ATA_QCFLAG_EH) || + !(qc->flags & ATA_QCFLAG_EH_SUCCESS_CMD) || + qc->err_mask || + ata_dev_phys_link(qc->dev) != link) + continue; + + /* + * If the command does not have any sense data, clear ATA_SENSE. + * Keep ATA_QCFLAG_EH_SUCCESS_CMD so that command is finished. + */ + if (!(sense_valid & (1ULL << tag))) { + qc->result_tf.status &= ~ATA_SENSE; + continue; + } + + sense = &buf[32 + 24 * tag]; + sk = sense[0]; + asc = sense[1]; + ascq = sense[2]; + + if (!ata_scsi_sense_is_valid(sk, asc, ascq)) { + ret = -EIO; + continue; + } + + /* Set sense without also setting scsicmd->result */ + scsi_build_sense_buffer(dev->flags & ATA_DFLAG_D_SENSE, + qc->scsicmd->sense_buffer, sk, + asc, ascq); + qc->flags |= ATA_QCFLAG_SENSE_VALID; + + /* + * If we have sense data, call scsi_check_sense() in order to + * set the correct SCSI ML byte (if any). No point in checking + * the return value, since the command has already completed + * successfully. + */ + scsi_check_sense(qc->scsicmd); + } + + return ret; +} +EXPORT_SYMBOL_GPL(ata_eh_read_sense_success_ncq_log); + +/** * ata_eh_analyze_ncq_error - analyze NCQ error * @link: ATA link to analyze NCQ error for * @@ -1481,6 +1591,7 @@ void ata_eh_analyze_ncq_error(struct ata_link *link) ata_qc_for_each_raw(ap, qc, tag) { if (!(qc->flags & ATA_QCFLAG_EH) || + qc->flags & ATA_QCFLAG_EH_SUCCESS_CMD || ata_dev_phys_link(qc->dev) != link) continue; diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 8ce90284eb34..370d18aca71e 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -37,7 +37,7 @@ #include "libata.h" #include "libata-transport.h" -#define ATA_SCSI_RBUF_SIZE 576 +#define ATA_SCSI_RBUF_SIZE 2048 static DEFINE_SPINLOCK(ata_scsi_rbuf_lock); static u8 ata_scsi_rbuf[ATA_SCSI_RBUF_SIZE]; @@ -47,15 +47,19 @@ typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc); static struct ata_device *__ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev); -#define RW_RECOVERY_MPAGE 0x1 -#define RW_RECOVERY_MPAGE_LEN 12 -#define CACHE_MPAGE 0x8 -#define CACHE_MPAGE_LEN 20 -#define CONTROL_MPAGE 0xa -#define CONTROL_MPAGE_LEN 12 -#define ALL_MPAGES 0x3f -#define ALL_SUB_MPAGES 0xff - +#define RW_RECOVERY_MPAGE 0x1 +#define RW_RECOVERY_MPAGE_LEN 12 +#define CACHE_MPAGE 0x8 +#define CACHE_MPAGE_LEN 20 +#define CONTROL_MPAGE 0xa +#define CONTROL_MPAGE_LEN 12 +#define ALL_MPAGES 0x3f +#define ALL_SUB_MPAGES 0xff +#define CDL_T2A_SUB_MPAGE 0x07 +#define CDL_T2B_SUB_MPAGE 0x08 +#define CDL_T2_SUB_MPAGE_LEN 232 +#define ATA_FEATURE_SUB_MPAGE 0xf2 +#define ATA_FEATURE_SUB_MPAGE_LEN 16 static const u8 def_rw_recovery_mpage[RW_RECOVERY_MPAGE_LEN] = { RW_RECOVERY_MPAGE, @@ -209,9 +213,6 @@ void ata_scsi_set_sense(struct ata_device *dev, struct scsi_cmnd *cmd, { bool d_sense = (dev->flags & ATA_DFLAG_D_SENSE); - if (!cmd) - return; - scsi_build_sense(cmd, d_sense, sk, asc, ascq); } @@ -221,9 +222,6 @@ void ata_scsi_set_sense_information(struct ata_device *dev, { u64 information; - if (!cmd) - return; - information = ata_tf_read_block(tf, dev); if (information == U64_MAX) return; @@ -1122,7 +1120,7 @@ int ata_scsi_dev_config(struct scsi_device *sdev, struct ata_device *dev) if (dev->flags & ATA_DFLAG_AN) set_bit(SDEV_EVT_MEDIA_CHANGE, sdev->supported_events); - if (dev->flags & ATA_DFLAG_NCQ) + if (ata_ncq_supported(dev)) depth = min(sdev->host->can_queue, ata_id_queue_depth(dev->id)); depth = min(ATA_MAX_QUEUE, depth); scsi_change_queue_depth(sdev, depth); @@ -1383,6 +1381,18 @@ static inline void scsi_16_lba_len(const u8 *cdb, u64 *plba, u32 *plen) } /** + * scsi_dld - Get duration limit descriptor index + * @cdb: SCSI command to translate + * + * Returns the dld bits indicating the index of a command duration limit + * descriptor. + */ +static inline int scsi_dld(const u8 *cdb) +{ + return ((cdb[1] & 0x01) << 2) | ((cdb[14] >> 6) & 0x03); +} + +/** * ata_scsi_verify_xlat - Translate SCSI VERIFY command into an ATA one * @qc: Storage for translated ATA taskfile * @@ -1550,6 +1560,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc) struct request *rq = scsi_cmd_to_rq(scmd); int class = IOPRIO_PRIO_CLASS(req_get_ioprio(rq)); unsigned int tf_flags = 0; + int dld = 0; u64 block; u32 n_block; int rc; @@ -1600,6 +1611,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc) goto invalid_fld; } scsi_16_lba_len(cdb, &block, &n_block); + dld = scsi_dld(cdb); if (cdb[1] & (1 << 3)) tf_flags |= ATA_TFLAG_FUA; if (!ata_check_nblocks(scmd, n_block)) @@ -1624,7 +1636,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc) qc->flags |= ATA_QCFLAG_IO; qc->nbytes = n_block * scmd->device->sector_size; - rc = ata_build_rw_tf(qc, block, n_block, tf_flags, class); + rc = ata_build_rw_tf(qc, block, n_block, tf_flags, dld, class); if (likely(rc == 0)) return 0; @@ -2203,10 +2215,123 @@ static unsigned int ata_msense_caching(u16 *id, u8 *buf, bool changeable) return sizeof(def_cache_mpage); } +/* + * Simulate MODE SENSE control mode page, sub-page 0. + */ +static unsigned int ata_msense_control_spg0(struct ata_device *dev, u8 *buf, + bool changeable) +{ + modecpy(buf, def_control_mpage, + sizeof(def_control_mpage), changeable); + if (changeable) { + /* ata_mselect_control() */ + buf[2] |= (1 << 2); + } else { + bool d_sense = (dev->flags & ATA_DFLAG_D_SENSE); + + /* descriptor format sense data */ + buf[2] |= (d_sense << 2); + } + + return sizeof(def_control_mpage); +} + +/* + * Translate an ATA duration limit in microseconds to a SCSI duration limit + * using the t2cdlunits 0xa (10ms). Since the SCSI duration limits are 2-bytes + * only, take care of overflows. + */ +static inline u16 ata_xlat_cdl_limit(u8 *buf) +{ + u32 limit = get_unaligned_le32(buf); + + return min_t(u32, limit / 10000, 65535); +} + +/* + * Simulate MODE SENSE control mode page, sub-pages 07h and 08h + * (command duration limits T2A and T2B mode pages). + */ +static unsigned int ata_msense_control_spgt2(struct ata_device *dev, u8 *buf, + u8 spg) +{ + u8 *b, *cdl = dev->cdl, *desc; + u32 policy; + int i; + + /* + * Fill the subpage. The first four bytes of the T2A/T2B mode pages + * are a header. The PAGE LENGTH field is the size of the page + * excluding the header. + */ + buf[0] = CONTROL_MPAGE; + buf[1] = spg; + put_unaligned_be16(CDL_T2_SUB_MPAGE_LEN - 4, &buf[2]); + if (spg == CDL_T2A_SUB_MPAGE) { + /* + * Read descriptors map to the T2A page: + * set perf_vs_duration_guidleine. + */ + buf[7] = (cdl[0] & 0x03) << 4; + desc = cdl + 64; + } else { + /* Write descriptors map to the T2B page */ + desc = cdl + 288; + } + + /* Fill the T2 page descriptors */ + b = &buf[8]; + policy = get_unaligned_le32(&cdl[0]); + for (i = 0; i < 7; i++, b += 32, desc += 32) { + /* t2cdlunits: fixed to 10ms */ + b[0] = 0x0a; + + /* Max inactive time and its policy */ + put_unaligned_be16(ata_xlat_cdl_limit(&desc[8]), &b[2]); + b[6] = ((policy >> 8) & 0x0f) << 4; + + /* Max active time and its policy */ + put_unaligned_be16(ata_xlat_cdl_limit(&desc[4]), &b[4]); + b[6] |= (policy >> 4) & 0x0f; + + /* Command duration guideline and its policy */ + put_unaligned_be16(ata_xlat_cdl_limit(&desc[16]), &b[10]); + b[14] = policy & 0x0f; + } + + return CDL_T2_SUB_MPAGE_LEN; +} + +/* + * Simulate MODE SENSE control mode page, sub-page f2h + * (ATA feature control mode page). + */ +static unsigned int ata_msense_control_ata_feature(struct ata_device *dev, + u8 *buf) +{ + /* PS=0, SPF=1 */ + buf[0] = CONTROL_MPAGE | (1 << 6); + buf[1] = ATA_FEATURE_SUB_MPAGE; + + /* + * The first four bytes of ATA Feature Control mode page are a header. + * The PAGE LENGTH field is the size of the page excluding the header. + */ + put_unaligned_be16(ATA_FEATURE_SUB_MPAGE_LEN - 4, &buf[2]); + + if (dev->flags & ATA_DFLAG_CDL) + buf[4] = 0x02; /* Support T2A and T2B pages */ + else + buf[4] = 0; + + return ATA_FEATURE_SUB_MPAGE_LEN; +} + /** * ata_msense_control - Simulate MODE SENSE control mode page * @dev: ATA device of interest * @buf: output buffer + * @spg: sub-page code * @changeable: whether changeable parameters are requested * * Generate a generic MODE SENSE control mode page. @@ -2215,17 +2340,27 @@ static unsigned int ata_msense_caching(u16 *id, u8 *buf, bool changeable) * None. */ static unsigned int ata_msense_control(struct ata_device *dev, u8 *buf, - bool changeable) + u8 spg, bool changeable) { - modecpy(buf, def_control_mpage, sizeof(def_control_mpage), changeable); - if (changeable) { - buf[2] |= (1 << 2); /* ata_mselect_control() */ - } else { - bool d_sense = (dev->flags & ATA_DFLAG_D_SENSE); - - buf[2] |= (d_sense << 2); /* descriptor format sense data */ + unsigned int n; + + switch (spg) { + case 0: + return ata_msense_control_spg0(dev, buf, changeable); + case CDL_T2A_SUB_MPAGE: + case CDL_T2B_SUB_MPAGE: + return ata_msense_control_spgt2(dev, buf, spg); + case ATA_FEATURE_SUB_MPAGE: + return ata_msense_control_ata_feature(dev, buf); + case ALL_SUB_MPAGES: + n = ata_msense_control_spg0(dev, buf, changeable); + n += ata_msense_control_spgt2(dev, buf + n, CDL_T2A_SUB_MPAGE); + n += ata_msense_control_spgt2(dev, buf + n, CDL_T2A_SUB_MPAGE); + n += ata_msense_control_ata_feature(dev, buf + n); + return n; + default: + return 0; } - return sizeof(def_control_mpage); } /** @@ -2298,13 +2433,25 @@ static unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf) pg = scsicmd[2] & 0x3f; spg = scsicmd[3]; + /* - * No mode subpages supported (yet) but asking for _all_ - * subpages may be valid + * Supported subpages: all subpages and sub-pages 07h, 08h and f2h of + * the control page. */ - if (spg && (spg != ALL_SUB_MPAGES)) { - fp = 3; - goto invalid_fld; + if (spg) { + switch (spg) { + case ALL_SUB_MPAGES: + break; + case CDL_T2A_SUB_MPAGE: + case CDL_T2B_SUB_MPAGE: + case ATA_FEATURE_SUB_MPAGE: + if (dev->flags & ATA_DFLAG_CDL && pg == CONTROL_MPAGE) + break; + fallthrough; + default: + fp = 3; + goto invalid_fld; + } } switch(pg) { @@ -2317,13 +2464,13 @@ static unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf) break; case CONTROL_MPAGE: - p += ata_msense_control(args->dev, p, page_control == 1); + p += ata_msense_control(args->dev, p, spg, page_control == 1); break; case ALL_MPAGES: p += ata_msense_rw_recovery(p, page_control == 1); p += ata_msense_caching(args->id, p, page_control == 1); - p += ata_msense_control(args->dev, p, page_control == 1); + p += ata_msense_control(args->dev, p, spg, page_control == 1); break; default: /* invalid page code */ @@ -2342,10 +2489,7 @@ static unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf) memcpy(rbuf + 4, sat_blk_desc, sizeof(sat_blk_desc)); } } else { - unsigned int output_len = p - rbuf - 2; - - rbuf[0] = output_len >> 8; - rbuf[1] = output_len; + put_unaligned_be16(p - rbuf - 2, &rbuf[0]); rbuf[3] |= dpofua; if (ebd) { rbuf[7] = sizeof(sat_blk_desc); @@ -3260,7 +3404,7 @@ static unsigned int ata_scsiop_maint_in(struct ata_scsi_args *args, u8 *rbuf) { struct ata_device *dev = args->dev; u8 *cdb = args->cmd->cmnd; - u8 supported = 0; + u8 supported = 0, cdlp = 0, rwcdlp = 0; unsigned int err = 0; if (cdb[2] != 1 && cdb[2] != 3) { @@ -3287,10 +3431,8 @@ static unsigned int ata_scsiop_maint_in(struct ata_scsi_args *args, u8 *rbuf) case MAINTENANCE_IN: case READ_6: case READ_10: - case READ_16: case WRITE_6: case WRITE_10: - case WRITE_16: case ATA_12: case ATA_16: case VERIFY: @@ -3300,6 +3442,28 @@ static unsigned int ata_scsiop_maint_in(struct ata_scsi_args *args, u8 *rbuf) case START_STOP: supported = 3; break; + case READ_16: + supported = 3; + if (dev->flags & ATA_DFLAG_CDL) { + /* + * CDL read descriptors map to the T2A page, that is, + * rwcdlp = 0x01 and cdlp = 0x01 + */ + rwcdlp = 0x01; + cdlp = 0x01 << 3; + } + break; + case WRITE_16: + supported = 3; + if (dev->flags & ATA_DFLAG_CDL) { + /* + * CDL write descriptors map to the T2B page, that is, + * rwcdlp = 0x01 and cdlp = 0x02 + */ + rwcdlp = 0x01; + cdlp = 0x02 << 3; + } + break; case ZBC_IN: case ZBC_OUT: if (ata_id_zoned_cap(dev->id) || @@ -3315,7 +3479,9 @@ static unsigned int ata_scsiop_maint_in(struct ata_scsi_args *args, u8 *rbuf) break; } out: - rbuf[1] = supported; /* supported */ + /* One command format */ + rbuf[0] = rwcdlp; + rbuf[1] = cdlp | supported; return err; } @@ -3605,20 +3771,11 @@ static int ata_mselect_caching(struct ata_queued_cmd *qc, return 0; } -/** - * ata_mselect_control - Simulate MODE SELECT for control page - * @qc: Storage for translated ATA taskfile - * @buf: input buffer - * @len: number of valid bytes in the input buffer - * @fp: out parameter for the failed field on error - * - * Prepare a taskfile to modify caching information for the device. - * - * LOCKING: - * None. +/* + * Simulate MODE SELECT control mode page, sub-page 0. */ -static int ata_mselect_control(struct ata_queued_cmd *qc, - const u8 *buf, int len, u16 *fp) +static int ata_mselect_control_spg0(struct ata_queued_cmd *qc, + const u8 *buf, int len, u16 *fp) { struct ata_device *dev = qc->dev; u8 mpage[CONTROL_MPAGE_LEN]; @@ -3640,7 +3797,7 @@ static int ata_mselect_control(struct ata_queued_cmd *qc, /* * Check that read-only bits are not modified. */ - ata_msense_control(dev, mpage, false); + ata_msense_control_spg0(dev, mpage, false); for (i = 0; i < CONTROL_MPAGE_LEN - 2; i++) { if (i == 0) continue; @@ -3656,6 +3813,84 @@ static int ata_mselect_control(struct ata_queued_cmd *qc, return 0; } +/* + * Translate MODE SELECT control mode page, sub-pages f2h (ATA feature mode + * page) into a SET FEATURES command. + */ +static unsigned int ata_mselect_control_ata_feature(struct ata_queued_cmd *qc, + const u8 *buf, int len, + u16 *fp) +{ + struct ata_device *dev = qc->dev; + struct ata_taskfile *tf = &qc->tf; + u8 cdl_action; + + /* + * The first four bytes of ATA Feature Control mode page are a header, + * so offsets in mpage are off by 4 compared to buf. Same for len. + */ + if (len != ATA_FEATURE_SUB_MPAGE_LEN - 4) { + *fp = min(len, ATA_FEATURE_SUB_MPAGE_LEN - 4); + return -EINVAL; + } + + /* Check cdl_ctrl */ + switch (buf[0] & 0x03) { + case 0: + /* Disable CDL */ + cdl_action = 0; + dev->flags &= ~ATA_DFLAG_CDL_ENABLED; + break; + case 0x02: + /* Enable CDL T2A/T2B: NCQ priority must be disabled */ + if (dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLED) { + ata_dev_err(dev, + "NCQ priority must be disabled to enable CDL\n"); + return -EINVAL; + } + cdl_action = 1; + dev->flags |= ATA_DFLAG_CDL_ENABLED; + break; + default: + *fp = 0; + return -EINVAL; + } + + tf->flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR; + tf->protocol = ATA_PROT_NODATA; + tf->command = ATA_CMD_SET_FEATURES; + tf->feature = SETFEATURES_CDL; + tf->nsect = cdl_action; + + return 1; +} + +/** + * ata_mselect_control - Simulate MODE SELECT for control page + * @qc: Storage for translated ATA taskfile + * @spg: target sub-page of the control page + * @buf: input buffer + * @len: number of valid bytes in the input buffer + * @fp: out parameter for the failed field on error + * + * Prepare a taskfile to modify caching information for the device. + * + * LOCKING: + * None. + */ +static int ata_mselect_control(struct ata_queued_cmd *qc, u8 spg, + const u8 *buf, int len, u16 *fp) +{ + switch (spg) { + case 0: + return ata_mselect_control_spg0(qc, buf, len, fp); + case ATA_FEATURE_SUB_MPAGE: + return ata_mselect_control_ata_feature(qc, buf, len, fp); + default: + return -EINVAL; + } +} + /** * ata_scsi_mode_select_xlat - Simulate MODE SELECT 6, 10 commands * @qc: Storage for translated ATA taskfile @@ -3673,7 +3908,7 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc) const u8 *cdb = scmd->cmnd; u8 pg, spg; unsigned six_byte, pg_len, hdr_len, bd_len; - int len; + int len, ret; u16 fp = (u16)-1; u8 bp = 0xff; u8 buffer[64]; @@ -3758,13 +3993,29 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc) } /* - * No mode subpages supported (yet) but asking for _all_ - * subpages may be valid + * Supported subpages: all subpages and ATA feature sub-page f2h of + * the control page. */ - if (spg && (spg != ALL_SUB_MPAGES)) { - fp = (p[0] & 0x40) ? 1 : 0; - fp += hdr_len + bd_len; - goto invalid_param; + if (spg) { + switch (spg) { + case ALL_SUB_MPAGES: + /* All subpages is not supported for the control page */ + if (pg == CONTROL_MPAGE) { + fp = (p[0] & 0x40) ? 1 : 0; + fp += hdr_len + bd_len; + goto invalid_param; + } + break; + case ATA_FEATURE_SUB_MPAGE: + if (qc->dev->flags & ATA_DFLAG_CDL && + pg == CONTROL_MPAGE) + break; + fallthrough; + default: + fp = (p[0] & 0x40) ? 1 : 0; + fp += hdr_len + bd_len; + goto invalid_param; + } } if (pg_len > len) goto invalid_param_len; @@ -3777,14 +4028,16 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc) } break; case CONTROL_MPAGE: - if (ata_mselect_control(qc, p, pg_len, &fp) < 0) { + ret = ata_mselect_control(qc, spg, p, pg_len, &fp); + if (ret < 0) { fp += hdr_len + bd_len; goto invalid_param; - } else { - goto skip; /* No ATA command to send */ } + if (!ret) + goto skip; /* No ATA command to send */ break; - default: /* invalid page code */ + default: + /* Invalid page code */ fp = bd_len + hdr_len; goto invalid_param; } @@ -4597,10 +4850,11 @@ int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel, void ata_scsi_dev_rescan(struct work_struct *work) { struct ata_port *ap = - container_of(work, struct ata_port, scsi_rescan_task); + container_of(work, struct ata_port, scsi_rescan_task.work); struct ata_link *link; struct ata_device *dev; unsigned long flags; + bool delay_rescan = false; mutex_lock(&ap->scsi_scan_mutex); spin_lock_irqsave(ap->lock, flags); @@ -4614,6 +4868,21 @@ void ata_scsi_dev_rescan(struct work_struct *work) if (scsi_device_get(sdev)) continue; + /* + * If the rescan work was scheduled because of a resume + * event, the port is already fully resumed, but the + * SCSI device may not yet be fully resumed. In such + * case, executing scsi_rescan_device() may cause a + * deadlock with the PM code on device_lock(). Prevent + * this by giving up and retrying rescan after a short + * delay. + */ + delay_rescan = sdev->sdev_gendev.power.is_suspended; + if (delay_rescan) { + scsi_device_put(sdev); + break; + } + spin_unlock_irqrestore(ap->lock, flags); scsi_rescan_device(&(sdev->sdev_gendev)); scsi_device_put(sdev); @@ -4623,4 +4892,8 @@ void ata_scsi_dev_rescan(struct work_struct *work) spin_unlock_irqrestore(ap->lock, flags); mutex_unlock(&ap->scsi_scan_mutex); + + if (delay_rescan) + schedule_delayed_work(&ap->scsi_rescan_task, + msecs_to_jiffies(5)); } diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 926d0d33cd29..cf993885d2b2 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -45,7 +45,7 @@ static inline void ata_force_cbl(struct ata_port *ap) { } extern u64 ata_tf_to_lba(const struct ata_taskfile *tf); extern u64 ata_tf_to_lba48(const struct ata_taskfile *tf); extern int ata_build_rw_tf(struct ata_queued_cmd *qc, u64 block, u32 n_block, - unsigned int tf_flags, int class); + unsigned int tf_flags, int dld, int class); extern u64 ata_tf_read_block(const struct ata_taskfile *tf, struct ata_device *dev); extern unsigned ata_exec_internal(struct ata_device *dev, diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c index 99a2ce723495..b1daa4d3fcd9 100644 --- a/drivers/ata/pata_ixp4xx_cf.c +++ b/drivers/ata/pata_ixp4xx_cf.c @@ -303,7 +303,7 @@ static struct platform_driver ixp4xx_pata_platform_driver = { .of_match_table = ixp4xx_pata_of_match, }, .probe = ixp4xx_pata_probe, - .remove = ata_platform_remove_one, + .remove_new = ata_platform_remove_one, }; module_platform_driver(ixp4xx_pata_platform_driver); diff --git a/drivers/ata/pata_octeon_cf.c b/drivers/ata/pata_octeon_cf.c index b1ce9f1761af..ff538b858928 100644 --- a/drivers/ata/pata_octeon_cf.c +++ b/drivers/ata/pata_octeon_cf.c @@ -16,6 +16,7 @@ #include <linux/slab.h> #include <linux/irq.h> #include <linux/of.h> +#include <linux/of_address.h> #include <linux/of_platform.h> #include <linux/platform_device.h> #include <scsi/scsi_host.h> @@ -804,9 +805,7 @@ static int octeon_cf_probe(struct platform_device *pdev) struct resource *res_cs0, *res_cs1; bool is_16bit; - const __be32 *cs_num; - struct property *reg_prop; - int n_addr, n_size, reg_len; + u64 reg; struct device_node *node; void __iomem *cs0; void __iomem *cs1 = NULL; @@ -834,15 +833,10 @@ static int octeon_cf_probe(struct platform_device *pdev) else is_16bit = false; - n_addr = of_n_addr_cells(node); - n_size = of_n_size_cells(node); - - reg_prop = of_find_property(node, "reg", ®_len); - if (!reg_prop || reg_len < sizeof(__be32)) - return -EINVAL; - - cs_num = reg_prop->value; - cf_port->cs0 = be32_to_cpup(cs_num); + rv = of_property_read_reg(node, 0, ®, NULL); + if (rv < 0) + return rv; + cf_port->cs0 = upper_32_bits(reg); if (cf_port->is_true_ide) { struct device_node *dma_node; @@ -884,13 +878,12 @@ static int octeon_cf_probe(struct platform_device *pdev) cs1 = devm_ioremap(&pdev->dev, res_cs1->start, resource_size(res_cs1)); if (!cs1) - return rv; - - if (reg_len < (n_addr + n_size + 1) * sizeof(__be32)) return -EINVAL; - cs_num += n_addr + n_size; - cf_port->cs1 = be32_to_cpup(cs_num); + rv = of_property_read_reg(node, 1, ®, NULL); + if (rv < 0) + return rv; + cf_port->cs1 = upper_32_bits(reg); } res_cs0 = platform_get_resource(pdev, IORESOURCE_MEM, 0); diff --git a/drivers/ata/pata_of_platform.c b/drivers/ata/pata_of_platform.c index 178b28eff170..4956f0f5b93f 100644 --- a/drivers/ata/pata_of_platform.c +++ b/drivers/ata/pata_of_platform.c @@ -89,7 +89,7 @@ static struct platform_driver pata_of_platform_driver = { .of_match_table = pata_of_platform_match, }, .probe = pata_of_platform_probe, - .remove = ata_platform_remove_one, + .remove_new = ata_platform_remove_one, }; module_platform_driver(pata_of_platform_driver); diff --git a/drivers/ata/pata_parport/aten.c b/drivers/ata/pata_parport/aten.c index 1bd248c42f8b..8328a49a95ef 100644 --- a/drivers/ata/pata_parport/aten.c +++ b/drivers/ata/pata_parport/aten.c @@ -1,13 +1,12 @@ -/* - aten.c (c) 1997-8 Grant R. Guenther <grant@torque.net> - Under the terms of the GNU General Public License. - - aten.c is a low-level protocol driver for the ATEN EH-100 - parallel port adapter. The EH-100 supports 4-bit and 8-bit - modes only. There is also an EH-132 which supports EPP mode - transfers. The EH-132 is not yet supported. - -*/ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * (c) 1997-8 Grant R. Guenther <grant@torque.net> + * + * aten.c is a low-level protocol driver for the ATEN EH-100 + * parallel port adapter. The EH-100 supports 4-bit and 8-bit + * modes only. There is also an EH-132 which supports EPP mode + * transfers. The EH-132 is not yet supported. + */ #include <linux/module.h> #include <linux/init.h> @@ -20,36 +19,36 @@ #define j44(a,b) ((((a>>4)&0x0f)|(b&0xf0))^0x88) -/* cont = 0 - access the IDE register file - cont = 1 - access the IDE command set -*/ - +/* + * cont = 0 - access the IDE register file + * cont = 1 - access the IDE command set + */ static int cont_map[2] = { 0x08, 0x20 }; static void aten_write_regr(struct pi_adapter *pi, int cont, int regr, int val) - -{ int r; - - r = regr + cont_map[cont] + 0x80; +{ + int r = regr + cont_map[cont] + 0x80; w0(r); w2(0xe); w2(6); w0(val); w2(7); w2(6); w2(0xc); } static int aten_read_regr(struct pi_adapter *pi, int cont, int regr) +{ + int a, b, r; -{ int a, b, r; - - r = regr + cont_map[cont] + 0x40; + r = regr + cont_map[cont] + 0x40; switch (pi->mode) { - case 0: w0(r); w2(0xe); w2(6); + case 0: + w0(r); w2(0xe); w2(6); w2(7); w2(6); w2(0); a = r1(); w0(0x10); b = r1(); w2(0xc); return j44(a,b); - case 1: r |= 0x10; - w0(r); w2(0xe); w2(6); w0(0xff); + case 1: + r |= 0x10; + w0(r); w2(0xe); w2(6); w0(0xff); w2(0x27); w2(0x26); w2(0x20); a = r0(); w2(0x26); w2(0xc); @@ -59,27 +58,30 @@ static int aten_read_regr(struct pi_adapter *pi, int cont, int regr) } static void aten_read_block(struct pi_adapter *pi, char *buf, int count) - -{ int k, a, b, c, d; +{ + int k, a, b, c, d; switch (pi->mode) { - case 0: w0(0x48); w2(0xe); w2(6); - for (k=0;k<count/2;k++) { + case 0: + w0(0x48); w2(0xe); w2(6); + for (k = 0; k < count / 2; k++) { w2(7); w2(6); w2(2); a = r1(); w0(0x58); b = r1(); w2(0); d = r1(); w0(0x48); c = r1(); - buf[2*k] = j44(c,d); - buf[2*k+1] = j44(a,b); + buf[2 * k] = j44(c, d); + buf[2 * k + 1] = j44(a, b); } w2(0xc); break; - case 1: w0(0x58); w2(0xe); w2(6); - for (k=0;k<count/2;k++) { + case 1: + w0(0x58); w2(0xe); w2(6); + for (k = 0; k < count / 2; k++) { w2(0x27); w2(0x26); w2(0x22); a = r0(); w2(0x20); b = r0(); - buf[2*k] = b; buf[2*k+1] = a; + buf[2 * k] = b; + buf[2 * k + 1] = a; } w2(0x26); w2(0xc); break; @@ -87,36 +89,37 @@ static void aten_read_block(struct pi_adapter *pi, char *buf, int count) } static void aten_write_block(struct pi_adapter *pi, char *buf, int count) - -{ int k; +{ + int k; w0(0x88); w2(0xe); w2(6); - for (k=0;k<count/2;k++) { - w0(buf[2*k+1]); w2(0xe); w2(6); - w0(buf[2*k]); w2(7); w2(6); + for (k = 0; k < count / 2; k++) { + w0(buf[2 * k + 1]); w2(0xe); w2(6); + w0(buf[2 * k]); w2(7); w2(6); } w2(0xc); } static void aten_connect(struct pi_adapter *pi) - -{ pi->saved_r0 = r0(); - pi->saved_r2 = r2(); - w2(0xc); +{ + pi->saved_r0 = r0(); + pi->saved_r2 = r2(); + w2(0xc); } static void aten_disconnect(struct pi_adapter *pi) - -{ w0(pi->saved_r0); - w2(pi->saved_r2); -} +{ + w0(pi->saved_r0); + w2(pi->saved_r2); +} static void aten_log_adapter(struct pi_adapter *pi) +{ + char *mode_string[2] = { "4-bit", "8-bit" }; -{ char *mode_string[2] = {"4-bit","8-bit"}; - - dev_info(&pi->dev, "ATEN EH-100 at 0x%x, mode %d (%s), delay %d\n", - pi->port, pi->mode, mode_string[pi->mode], pi->delay); + dev_info(&pi->dev, + "ATEN EH-100 at 0x%x, mode %d (%s), delay %d\n", + pi->port, pi->mode, mode_string[pi->mode], pi->delay); } static struct pi_protocol aten = { diff --git a/drivers/ata/pata_parport/bpck.c b/drivers/ata/pata_parport/bpck.c index 1c5035a09554..9f4309f9b57f 100644 --- a/drivers/ata/pata_parport/bpck.c +++ b/drivers/ata/pata_parport/bpck.c @@ -1,11 +1,10 @@ -/* - bpck.c (c) 1996-8 Grant R. Guenther <grant@torque.net> - Under the terms of the GNU General Public License. - - bpck.c is a low-level protocol driver for the MicroSolutions - "backpack" parallel port IDE adapter. - -*/ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * (c) 1996-1998 Grant R. Guenther <grant@torque.net> + * + * bpck.c is a low-level protocol driver for the MicroSolutions + * "backpack" parallel port IDE adapter. + */ #include <linux/module.h> #include <linux/init.h> @@ -29,59 +28,57 @@ #define j44(l,h) (((l>>3)&0x7)|((l>>4)&0x8)|((h<<1)&0x70)|(h&0x80)) -/* cont = 0 - access the IDE register file - cont = 1 - access the IDE command set - cont = 2 - use internal bpck register addressing -*/ - +/* + * cont = 0 - access the IDE register file + * cont = 1 - access the IDE command set + * cont = 2 - use internal bpck register addressing + */ static int cont_map[3] = { 0x40, 0x48, 0 }; static int bpck_read_regr(struct pi_adapter *pi, int cont, int regr) - -{ int r, l, h; +{ + int r, l, h; r = regr + cont_map[cont]; switch (pi->mode) { - - case 0: w0(r & 0xf); w0(r); t2(2); t2(4); + case 0: + w0(r & 0xf); w0(r); t2(2); t2(4); l = r1(); - t2(4); - h = r1(); - return j44(l,h); - - case 1: w0(r & 0xf); w0(r); t2(2); - e2(); t2(0x20); + t2(4); + h = r1(); + return j44(l, h); + case 1: + w0(r & 0xf); w0(r); t2(2); + e2(); t2(0x20); t2(4); h = r0(); - t2(1); t2(0x20); - return h; - + t2(1); t2(0x20); + return h; case 2: case 3: - case 4: w0(r); w2(9); w2(0); w2(0x20); + case 4: + w0(r); w2(9); w2(0); w2(0x20); h = r4(); w2(0); return h; } return -1; -} +} static void bpck_write_regr(struct pi_adapter *pi, int cont, int regr, int val) - -{ int r; +{ + int r; r = regr + cont_map[cont]; switch (pi->mode) { - case 0: case 1: w0(r); t2(2); w0(val); o2(); t2(4); t2(1); break; - case 2: case 3: case 4: w0(r); w2(9); w2(0); @@ -97,210 +94,249 @@ static void bpck_write_regr(struct pi_adapter *pi, int cont, int regr, int val) #define RR(r) (bpck_read_regr(pi,2,r)) static void bpck_write_block(struct pi_adapter *pi, char *buf, int count) - -{ int i; +{ + int i; switch (pi->mode) { - case 0: WR(4,0x40); + case 0: + WR(4, 0x40); + w0(0x40); t2(2); t2(1); + for (i = 0; i < count; i++) { + w0(buf[i]); + t2(4); + } + WR(4, 0); + break; + + case 1: + WR(4, 0x50); w0(0x40); t2(2); t2(1); - for (i=0;i<count;i++) { w0(buf[i]); t2(4); } - WR(4,0); + for (i = 0; i < count; i++) { + w0(buf[i]); + t2(4); + } + WR(4, 0x10); break; - case 1: WR(4,0x50); - w0(0x40); t2(2); t2(1); - for (i=0;i<count;i++) { w0(buf[i]); t2(4); } - WR(4,0x10); + case 2: + WR(4, 0x48); + w0(0x40); w2(9); w2(0); w2(1); + for (i = 0; i < count; i++) + w4(buf[i]); + w2(0); + WR(4, 8); break; - case 2: WR(4,0x48); + case 3: + WR(4, 0x48); w0(0x40); w2(9); w2(0); w2(1); - for (i=0;i<count;i++) w4(buf[i]); + for (i = 0; i < count / 2; i++) + w4w(((u16 *)buf)[i]); w2(0); - WR(4,8); + WR(4, 8); break; - case 3: WR(4,0x48); - w0(0x40); w2(9); w2(0); w2(1); - for (i=0;i<count/2;i++) w4w(((u16 *)buf)[i]); - w2(0); - WR(4,8); - break; - - case 4: WR(4,0x48); - w0(0x40); w2(9); w2(0); w2(1); - for (i=0;i<count/4;i++) w4l(((u32 *)buf)[i]); - w2(0); - WR(4,8); - break; + case 4: + WR(4, 0x48); + w0(0x40); w2(9); w2(0); w2(1); + for (i = 0; i < count / 4; i++) + w4l(((u32 *)buf)[i]); + w2(0); + WR(4, 8); + break; } } static void bpck_read_block(struct pi_adapter *pi, char *buf, int count) - -{ int i, l, h; +{ + int i, l, h; switch (pi->mode) { - case 0: WR(4,0x40); + case 0: + WR(4, 0x40); w0(0x40); t2(2); - for (i=0;i<count;i++) { - t2(4); l = r1(); - t2(4); h = r1(); - buf[i] = j44(l,h); + for (i = 0; i < count; i++) { + t2(4); l = r1(); + t2(4); h = r1(); + buf[i] = j44(l, h); } - WR(4,0); + WR(4, 0); break; - case 1: WR(4,0x50); + case 1: + WR(4, 0x50); w0(0x40); t2(2); t2(0x20); - for(i=0;i<count;i++) { t2(4); buf[i] = r0(); } - t2(1); t2(0x20); - WR(4,0x10); + for (i = 0; i < count; i++) { + t2(4); + buf[i] = r0(); + } + t2(1); t2(0x20); + WR(4, 0x10); break; - case 2: WR(4,0x48); + case 2: + WR(4, 0x48); w0(0x40); w2(9); w2(0); w2(0x20); - for (i=0;i<count;i++) buf[i] = r4(); + for (i = 0; i < count; i++) + buf[i] = r4(); w2(0); - WR(4,8); + WR(4, 8); break; - case 3: WR(4,0x48); - w0(0x40); w2(9); w2(0); w2(0x20); - for (i=0;i<count/2;i++) ((u16 *)buf)[i] = r4w(); - w2(0); - WR(4,8); - break; + case 3: + WR(4, 0x48); + w0(0x40); w2(9); w2(0); w2(0x20); + for (i = 0; i < count / 2; i++) + ((u16 *)buf)[i] = r4w(); + w2(0); + WR(4, 8); + break; - case 4: WR(4,0x48); - w0(0x40); w2(9); w2(0); w2(0x20); - for (i=0;i<count/4;i++) ((u32 *)buf)[i] = r4l(); - w2(0); - WR(4,8); - break; + case 4: + WR(4, 0x48); + w0(0x40); w2(9); w2(0); w2(0x20); + for (i = 0; i < count / 4; i++) + ((u32 *)buf)[i] = r4l(); + w2(0); + WR(4, 8); + break; } } static int bpck_probe_unit(struct pi_adapter *pi) - -{ int o1, o0, f7, id; +{ + int o1, o0, f7, id; int t, s; id = pi->unit; s = 0; - w2(4); w2(0xe); r2(); t2(2); + w2(4); w2(0xe); r2(); t2(2); o1 = r1()&0xf8; o0 = r0(); w0(255-id); w2(4); w0(id); t2(8); t2(8); t2(8); t2(2); t = r1()&0xf8; f7 = ((id % 8) == 7); - if ((f7) || (t != o1)) { t2(2); s = r1()&0xf8; } + if ((f7) || (t != o1)) { + t2(2); + s = r1() & 0xf8; + } if ((t == o1) && ((!f7) || (s == o1))) { w2(0x4c); w0(o0); - return 0; + return 0; } t2(8); w0(0); t2(2); w2(0x4c); w0(o0); return 1; } - -static void bpck_connect(struct pi_adapter *pi) -{ pi->saved_r0 = r0(); +static void bpck_connect(struct pi_adapter *pi) +{ + pi->saved_r0 = r0(); w0(0xff-pi->unit); w2(4); w0(pi->unit); - t2(8); t2(8); t2(8); + t2(8); t2(8); t2(8); t2(2); t2(2); - - switch (pi->mode) { - case 0: t2(8); WR(4,0); + switch (pi->mode) { + case 0: + t2(8); WR(4, 0); break; - - case 1: t2(8); WR(4,0x10); + case 1: + t2(8); WR(4, 0x10); break; - case 2: - case 3: - case 4: w2(0); WR(4,8); + case 3: + case 4: + w2(0); WR(4, 8); break; - } WR(5,8); -/* if (pi->devtype == PI_PCD) { possibly wrong, purpose unknown */ - WR(0x46,0x10); /* fiddle with ESS logic ??? */ - WR(0x4c,0x38); - WR(0x4d,0x88); - WR(0x46,0xa0); - WR(0x41,0); - WR(0x4e,8); -/* }*/ + /* + * Possibly wrong, purpose unknown (fiddle with ESS logic ???) + * if (pi->devtype == PI_PCD) { + */ + WR(0x46, 0x10); + WR(0x4c, 0x38); + WR(0x4d, 0x88); + WR(0x46, 0xa0); + WR(0x41, 0); + WR(0x4e, 8); + /* } */ } static void bpck_disconnect(struct pi_adapter *pi) - -{ w0(0); - if (pi->mode >= 2) { w2(9); w2(0); } else t2(2); +{ + w0(0); + if (pi->mode >= 2) { + w2(9); w2(0); + } else { + t2(2); + } w2(0x4c); w0(pi->saved_r0); -} +} static void bpck_force_spp(struct pi_adapter *pi) +{ + /* This fakes the EPP protocol to turn off EPP ... */ + pi->saved_r0 = r0(); + w0(0xff-pi->unit); w2(4); w0(pi->unit); + t2(8); t2(8); t2(8); + t2(2); t2(2); -/* This fakes the EPP protocol to turn off EPP ... */ - -{ pi->saved_r0 = r0(); - w0(0xff-pi->unit); w2(4); w0(pi->unit); - t2(8); t2(8); t2(8); - t2(2); t2(2); - - w2(0); - w0(4); w2(9); w2(0); - w0(0); w2(1); w2(3); w2(0); - w0(0); w2(9); w2(0); - w2(0x4c); w0(pi->saved_r0); + w2(0); + w0(4); w2(9); w2(0); + w0(0); w2(1); w2(3); w2(0); + w0(0); w2(9); w2(0); + w2(0x4c); w0(pi->saved_r0); } #define TEST_LEN 16 static int bpck_test_proto(struct pi_adapter *pi) - -{ int i, e, l, h, om; +{ + int i, e, l, h, om; char buf[TEST_LEN]; bpck_force_spp(pi); switch (pi->mode) { - case 0: bpck_connect(pi); - WR(0x13,0x7f); + case 0: + bpck_connect(pi); + WR(0x13, 0x7f); w0(0x13); t2(2); - for(i=0;i<TEST_LEN;i++) { - t2(4); l = r1(); - t2(4); h = r1(); - buf[i] = j44(l,h); + for (i = 0; i < TEST_LEN; i++) { + t2(4); l = r1(); + t2(4); h = r1(); + buf[i] = j44(l, h); } bpck_disconnect(pi); break; - case 1: bpck_connect(pi); - WR(0x13,0x7f); - w0(0x13); t2(2); t2(0x20); - for(i=0;i<TEST_LEN;i++) { t2(4); buf[i] = r0(); } - t2(1); t2(0x20); + case 1: + bpck_connect(pi); + WR(0x13, 0x7f); + w0(0x13); t2(2); t2(0x20); + for (i = 0; i < TEST_LEN; i++) { + t2(4); + buf[i] = r0(); + } + t2(1); t2(0x20); bpck_disconnect(pi); break; case 2: case 3: - case 4: om = pi->mode; + case 4: + om = pi->mode; pi->mode = 0; bpck_connect(pi); - WR(7,3); - WR(4,8); + WR(7, 3); + WR(4, 8); bpck_disconnect(pi); pi->mode = om; @@ -308,34 +344,44 @@ static int bpck_test_proto(struct pi_adapter *pi) w0(0x13); w2(9); w2(1); w0(0); w2(3); w2(0); w2(0xe0); switch (pi->mode) { - case 2: for (i=0;i<TEST_LEN;i++) buf[i] = r4(); - break; - case 3: for (i=0;i<TEST_LEN/2;i++) ((u16 *)buf)[i] = r4w(); - break; - case 4: for (i=0;i<TEST_LEN/4;i++) ((u32 *)buf)[i] = r4l(); - break; + case 2: + for (i = 0; i < TEST_LEN; i++) + buf[i] = r4(); + break; + case 3: + for (i = 0; i < TEST_LEN / 2; i++) + ((u16 *)buf)[i] = r4w(); + break; + case 4: + for (i = 0; i < TEST_LEN / 4; i++) + ((u32 *)buf)[i] = r4l(); + break; } w2(0); - WR(7,0); + WR(7, 0); bpck_disconnect(pi); - break; } dev_dbg(&pi->dev, "bpck: 0x%x unit %d mode %d: ", pi->port, pi->unit, pi->mode); - print_hex_dump_debug("bpck: ", DUMP_PREFIX_NONE, TEST_LEN, 1, buf, TEST_LEN, false); + print_hex_dump_debug("bpck: ", DUMP_PREFIX_NONE, TEST_LEN, 1, buf, + TEST_LEN, false); e = 0; - for (i=0;i<TEST_LEN;i++) if (buf[i] != (i+1)) e++; + for (i = 0; i < TEST_LEN; i++) { + if (buf[i] != i + 1) + e++; + } + return e; } static void bpck_read_eeprom(struct pi_adapter *pi, char *buf) - -{ int i, j, k, p, v, f, om, od; +{ + int i, j, k, p, v, f, om, od; bpck_force_spp(pi); @@ -343,77 +389,97 @@ static void bpck_read_eeprom(struct pi_adapter *pi, char *buf) pi->mode = 0; pi->delay = 6; bpck_connect(pi); - - WR(4,0); - for (i=0;i<64;i++) { - WR(6,8); - WR(6,0xc); - p = 0x100; - for (k=0;k<9;k++) { - f = (((i + 0x180) & p) != 0) * 2; - WR(6,f+0xc); - WR(6,f+0xd); - WR(6,f+0xc); - p = (p >> 1); - } - for (j=0;j<2;j++) { - v = 0; - for (k=0;k<8;k++) { - WR(6,0xc); - WR(6,0xd); - WR(6,0xc); - f = RR(0); - v = 2*v + (f == 0x84); + + WR(4, 0); + for (i = 0; i < 64; i++) { + WR(6, 8); + WR(6, 0xc); + p = 0x100; + for (k = 0; k < 9; k++) { + f = (((i + 0x180) & p) != 0) * 2; + WR(6, f + 0xc); + WR(6, f + 0xd); + WR(6, f + 0xc); + p = (p >> 1); + } + for (j = 0; j < 2; j++) { + v = 0; + for (k = 0; k < 8; k++) { + WR(6, 0xc); + WR(6, 0xd); + WR(6, 0xc); + f = RR(0); + v = 2 * v + (f == 0x84); + } + buf[2 * i + 1 - j] = v; } - buf[2*i+1-j] = v; - } } - WR(6,8); - WR(6,0); - WR(5,8); + WR(6, 8); + WR(6, 0); + WR(5, 8); bpck_disconnect(pi); if (om >= 2) { - bpck_connect(pi); - WR(7,3); - WR(4,8); - bpck_disconnect(pi); + bpck_connect(pi); + WR(7, 3); + WR(4, 8); + bpck_disconnect(pi); } pi->mode = om; pi->delay = od; } -static int bpck_test_port(struct pi_adapter *pi) /* check for 8-bit port */ - -{ int i, r, m; +static int bpck_test_port(struct pi_adapter *pi) +{ + int i, r, m; + /* Check for 8-bit port */ w2(0x2c); i = r0(); w0(255-i); r = r0(); w0(i); m = -1; - if (r == i) m = 2; - if (r == (255-i)) m = 0; + if (r == i) + m = 2; + if (r == (255-i)) + m = 0; + + w2(0xc); + i = r0(); + w0(255-i); + r = r0(); + w0(i); + if (r != (255-i)) + m = -1; + + if (m == 0) { + w2(6); + w2(0xc); + r = r0(); + w0(0xaa); + w0(r); + w0(0xaa); + } + if (m == 2) { + w2(0x26); + w2(0xc); + } - w2(0xc); i = r0(); w0(255-i); r = r0(); w0(i); - if (r != (255-i)) m = -1; - - if (m == 0) { w2(6); w2(0xc); r = r0(); w0(0xaa); w0(r); w0(0xaa); } - if (m == 2) { w2(0x26); w2(0xc); } + if (m == -1) + return 0; - if (m == -1) return 0; return 5; } static void bpck_log_adapter(struct pi_adapter *pi) - -{ char *mode_string[5] = { "4-bit","8-bit","EPP-8", - "EPP-16","EPP-32" }; +{ + char *mode_str[5] = { "4-bit", "8-bit", "EPP-8", "EPP-16", "EPP-32" }; char scratch[128]; bpck_read_eeprom(pi,scratch); print_hex_dump_bytes("bpck EEPROM: ", DUMP_PREFIX_NONE, scratch, 128); - dev_info(&pi->dev, "backpack %8.8s unit %d at 0x%x, mode %d (%s), delay %d\n", + dev_info(&pi->dev, + "backpack %8.8s unit %d at 0x%x, mode %d (%s), delay %d\n", &scratch[110], pi->unit, pi->port, pi->mode, - mode_string[pi->mode], pi->delay); + mode_str[pi->mode], pi->delay); } static struct pi_protocol bpck = { diff --git a/drivers/ata/pata_parport/bpck6.c b/drivers/ata/pata_parport/bpck6.c index 76febd07a9bb..c6dbd14120d1 100644 --- a/drivers/ata/pata_parport/bpck6.c +++ b/drivers/ata/pata_parport/bpck6.c @@ -1,15 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* - backpack.c (c) 2001 Micro Solutions Inc. - Released under the terms of the GNU General Public license - - backpack.c is a low-level protocol driver for the Micro Solutions - "BACKPACK" parallel port IDE adapter - (Works on Series 6 drives) - - Written by: Ken Hahn (linux-dev@micro-solutions.com) - Clive Turvey (linux-dev@micro-solutions.com) - -*/ + * (c) 2001 Micro Solutions Inc. + * + * backpack.c is a low-level protocol driver for the Micro Solutions + * "BACKPACK" parallel port IDE adapter (works on Series 6 drives). + * + * Written by: Ken Hahn (linux-dev@micro-solutions.com) + * Clive Turvey (linux-dev@micro-solutions.com) + */ #include <linux/module.h> #include <linux/init.h> @@ -326,11 +324,14 @@ static int bpck6_open(struct pi_adapter *pi) if (j != k) goto fail; - if (i & 4) // EPP + if (i & 4) { + /* EPP */ parport_frob_control(pi->pardev->port, PARPORT_CONTROL_SELECT | PARPORT_CONTROL_INIT, 0); - else // PPC/ECP + } else { + /* PPC/ECP */ parport_frob_control(pi->pardev->port, PARPORT_CONTROL_SELECT, 0); + } pi->private = 0; @@ -347,17 +348,20 @@ fail: parport_write_control(pi->pardev->port, pi->saved_r2); parport_write_data(pi->pardev->port, pi->saved_r0); - return 0; // FAIL + return 0; } static void bpck6_deselect(struct pi_adapter *pi) { - if (mode_map[pi->mode] & 4) // EPP + if (mode_map[pi->mode] & 4) { + /* EPP */ parport_frob_control(pi->pardev->port, PARPORT_CONTROL_INIT, - PARPORT_CONTROL_INIT); - else // PPC/ECP + PARPORT_CONTROL_INIT); + } else { + /* PPC/ECP */ parport_frob_control(pi->pardev->port, PARPORT_CONTROL_SELECT, - PARPORT_CONTROL_SELECT); + PARPORT_CONTROL_SELECT); + } parport_write_data(pi->pardev->port, pi->saved_r0); parport_write_control(pi->pardev->port, @@ -386,7 +390,8 @@ static void bpck6_disconnect(struct pi_adapter *pi) bpck6_deselect(pi); } -static int bpck6_test_port(struct pi_adapter *pi) /* check for 8-bit port */ +/* check for 8-bit port */ +static int bpck6_test_port(struct pi_adapter *pi) { dev_dbg(&pi->dev, "PARPORT indicates modes=%x for lp=0x%lx\n", pi->pardev->port->modes, pi->pardev->port->base); @@ -413,28 +418,26 @@ static int bpck6_probe_unit(struct pi_adapter *pi) dev_dbg(&pi->dev, "ppc_open returned %2x\n", out); - if(out) - { + if (out) { bpck6_deselect(pi); dev_dbg(&pi->dev, "leaving probe\n"); pi->mode = saved_mode; - return(1); + return 1; } - else - { - dev_dbg(&pi->dev, "Failed open\n"); - pi->mode = saved_mode; - return(0); - } + + dev_dbg(&pi->dev, "Failed open\n"); + pi->mode = saved_mode; + + return 0; } static void bpck6_log_adapter(struct pi_adapter *pi) { - char *mode_string[5]= - {"4-bit","8-bit","EPP-8","EPP-16","EPP-32"}; + char *mode_string[5] = { "4-bit", "8-bit", "EPP-8", "EPP-16", "EPP-32" }; - dev_info(&pi->dev, "Micro Solutions BACKPACK Drive unit %d at 0x%x, mode:%d (%s), delay %d\n", - pi->unit, pi->port, pi->mode, mode_string[pi->mode], pi->delay); + dev_info(&pi->dev, + "Micro Solutions BACKPACK Drive unit %d at 0x%x, mode:%d (%s), delay %d\n", + pi->unit, pi->port, pi->mode, mode_string[pi->mode], pi->delay); } static struct pi_protocol bpck6 = { diff --git a/drivers/ata/pata_parport/comm.c b/drivers/ata/pata_parport/comm.c index 4c2f9ad60ad8..cc5485bd0a5b 100644 --- a/drivers/ata/pata_parport/comm.c +++ b/drivers/ata/pata_parport/comm.c @@ -1,12 +1,11 @@ -/* - comm.c (c) 1997-8 Grant R. Guenther <grant@torque.net> - Under the terms of the GNU General Public License. - - comm.c is a low-level protocol driver for some older models - of the DataStor "Commuter" parallel to IDE adapter. Some of - the parallel port devices marketed by Arista currently - use this adapter. -*/ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * (c) 1997-1998 Grant R. Guenther <grant@torque.net> + * + * comm.c is a low-level protocol driver for some older models of the DataStor + * "Commuter" parallel to IDE adapter. Some of the parallel port devices + * marketed by Arista currently use this adapter. + */ #include <linux/module.h> #include <linux/init.h> @@ -17,165 +16,172 @@ #include <asm/io.h> #include "pata_parport.h" -/* mode codes: 0 nybble reads, 8-bit writes - 1 8-bit reads and writes - 2 8-bit EPP mode -*/ +/* + * mode codes: 0 nybble reads, 8-bit writes + * 1 8-bit reads and writes + * 2 8-bit EPP mode + */ -#define j44(a,b) (((a>>3)&0x0f)|((b<<1)&0xf0)) +#define j44(a, b) (((a >> 3) & 0x0f) | ((b << 1) & 0xf0)) #define P1 w2(5);w2(0xd);w2(0xd);w2(5);w2(4); #define P2 w2(5);w2(7);w2(7);w2(5);w2(4); -/* cont = 0 - access the IDE register file - cont = 1 - access the IDE command set -*/ - +/* + * cont = 0 - access the IDE register file + * cont = 1 - access the IDE command set + */ static int cont_map[2] = { 0x08, 0x10 }; static int comm_read_regr(struct pi_adapter *pi, int cont, int regr) - -{ int l, h, r; +{ + int l, h, r; r = regr + cont_map[cont]; - switch (pi->mode) { + switch (pi->mode) { + case 0: + w0(r); P1; w0(0); + w2(6); l = r1(); w0(0x80); h = r1(); w2(4); + return j44(l, h); - case 0: w0(r); P1; w0(0); - w2(6); l = r1(); w0(0x80); h = r1(); w2(4); - return j44(l,h); - - case 1: w0(r+0x20); P1; - w0(0); w2(0x26); h = r0(); w2(4); - return h; + case 1: + w0(r+0x20); P1; + w0(0); w2(0x26); h = r0(); w2(4); + return h; case 2: case 3: - case 4: w3(r+0x20); (void)r1(); - w2(0x24); h = r4(); w2(4); - return h; + case 4: + w3(r+0x20); (void)r1(); + w2(0x24); h = r4(); w2(4); + return h; + } - } - return -1; -} + return -1; +} static void comm_write_regr(struct pi_adapter *pi, int cont, int regr, int val) +{ + int r = regr + cont_map[cont]; -{ int r; - - r = regr + cont_map[cont]; - - switch (pi->mode) { - - case 0: - case 1: w0(r); P1; w0(val); P2; + switch (pi->mode) { + case 0: + case 1: + w0(r); P1; w0(val); P2; break; - case 2: case 3: - case 4: w3(r); (void)r1(); w4(val); - break; - } + case 4: + w3(r); (void)r1(); w4(val); + break; + } } static void comm_connect(struct pi_adapter *pi) - -{ pi->saved_r0 = r0(); - pi->saved_r2 = r2(); - w2(4); w0(0xff); w2(6); - w2(4); w0(0xaa); w2(6); - w2(4); w0(0x00); w2(6); - w2(4); w0(0x87); w2(6); - w2(4); w0(0xe0); w2(0xc); w2(0xc); w2(4); +{ + pi->saved_r0 = r0(); + pi->saved_r2 = r2(); + w2(4); w0(0xff); w2(6); + w2(4); w0(0xaa); w2(6); + w2(4); w0(0x00); w2(6); + w2(4); w0(0x87); w2(6); + w2(4); w0(0xe0); w2(0xc); w2(0xc); w2(4); } static void comm_disconnect(struct pi_adapter *pi) -{ w2(0); w2(0); w2(0); w2(4); +{ + w2(0); w2(0); w2(0); w2(4); w0(pi->saved_r0); - w2(pi->saved_r2); -} + w2(pi->saved_r2); +} static void comm_read_block(struct pi_adapter *pi, char *buf, int count) - -{ int i, l, h; - - switch (pi->mode) { - - case 0: w0(0x48); P1; - for(i=0;i<count;i++) { - w0(0); w2(6); l = r1(); - w0(0x80); h = r1(); w2(4); - buf[i] = j44(l,h); - } - break; - - case 1: w0(0x68); P1; w0(0); - for(i=0;i<count;i++) { - w2(0x26); buf[i] = r0(); w2(0x24); - } +{ + int i, l, h; + + switch (pi->mode) { + case 0: + w0(0x48); P1; + for (i = 0; i < count; i++) { + w0(0); w2(6); l = r1(); + w0(0x80); h = r1(); w2(4); + buf[i] = j44(l, h); + } + break; + case 1: + w0(0x68); P1; w0(0); + for (i = 0; i < count; i++) { + w2(0x26); + buf[i] = r0(); + w2(0x24); + } w2(4); break; - - case 2: w3(0x68); (void)r1(); w2(0x24); - for (i=0;i<count;i++) buf[i] = r4(); + case 2: + w3(0x68); (void)r1(); w2(0x24); + for (i = 0; i < count; i++) + buf[i] = r4(); + w2(4); + break; + case 3: + w3(0x68); (void)r1(); w2(0x24); + for (i = 0; i < count / 2; i++) + ((u16 *)buf)[i] = r4w(); + w2(4); + break; + case 4: + w3(0x68); (void)r1(); w2(0x24); + for (i = 0; i < count / 4; i++) + ((u32 *)buf)[i] = r4l(); w2(4); break; - - case 3: w3(0x68); (void)r1(); w2(0x24); - for (i=0;i<count/2;i++) ((u16 *)buf)[i] = r4w(); - w2(4); - break; - - case 4: w3(0x68); (void)r1(); w2(0x24); - for (i=0;i<count/4;i++) ((u32 *)buf)[i] = r4l(); - w2(4); - break; - } } /* NB: Watch out for the byte swapped writes ! */ - static void comm_write_block(struct pi_adapter *pi, char *buf, int count) - -{ int k; - - switch (pi->mode) { - - case 0: - case 1: w0(0x68); P1; - for (k=0;k<count;k++) { - w2(5); w0(buf[k^1]); w2(7); - } - w2(5); w2(4); - break; - - case 2: w3(0x48); (void)r1(); - for (k=0;k<count;k++) w4(buf[k^1]); - break; - - case 3: w3(0x48); (void)r1(); +{ + int k; + + switch (pi->mode) { + case 0: + case 1: + w0(0x68); P1; + for (k = 0; k < count; k++) { + w2(5); + w0(buf[k ^ 1]); + w2(7); + } + w2(5); w2(4); + break; + case 2: + w3(0x48); (void)r1(); + for (k = 0; k < count; k++) + w4(buf[k ^ 1]); + break; + case 3: + w3(0x48); (void)r1(); for (k = 0; k < count / 2; k++) w4w(swab16(((u16 *)buf)[k])); - break; - - case 4: w3(0x48); (void)r1(); + break; + case 4: + w3(0x48); (void)r1(); for (k = 0; k < count / 4; k++) w4l(swab16(((u16 *)buf)[2 * k]) | swab16(((u16 *)buf)[2 * k + 1]) << 16); - break; - - + break; } } static void comm_log_adapter(struct pi_adapter *pi) -{ char *mode_string[5] = {"4-bit","8-bit","EPP-8","EPP-16","EPP-32"}; +{ char *mode_string[5] = { "4-bit", "8-bit", "EPP-8", "EPP-16", "EPP-32" }; - dev_info(&pi->dev, "DataStor Commuter at 0x%x, mode %d (%s), delay %d\n", - pi->port, pi->mode, mode_string[pi->mode], pi->delay); + dev_info(&pi->dev, + "DataStor Commuter at 0x%x, mode %d (%s), delay %d\n", + pi->port, pi->mode, mode_string[pi->mode], pi->delay); } static struct pi_protocol comm = { diff --git a/drivers/ata/pata_parport/dstr.c b/drivers/ata/pata_parport/dstr.c index 2524684be206..368d7c7962a9 100644 --- a/drivers/ata/pata_parport/dstr.c +++ b/drivers/ata/pata_parport/dstr.c @@ -1,11 +1,10 @@ -/* - dstr.c (c) 1997-8 Grant R. Guenther <grant@torque.net> - Under the terms of the GNU General Public License. - - dstr.c is a low-level protocol driver for the - DataStor EP2000 parallel to IDE adapter chip. - -*/ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * (c) 1997-1998 Grant R. Guenther <grant@torque.net> + * + * dstr.c is a low-level protocol driver for the DataStor EP2000 parallel + * to IDE adapter chip. + */ #include <linux/module.h> #include <linux/init.h> @@ -16,178 +15,202 @@ #include <asm/io.h> #include "pata_parport.h" -/* mode codes: 0 nybble reads, 8-bit writes - 1 8-bit reads and writes - 2 8-bit EPP mode - 3 EPP-16 - 4 EPP-32 -*/ +/* + * mode codes: 0 nybble reads, 8-bit writes + * 1 8-bit reads and writes + * 2 8-bit EPP mode + * 3 EPP-16 + * 4 EPP-32 + */ -#define j44(a,b) (((a>>3)&0x07)|((~a>>4)&0x08)|((b<<1)&0x70)|((~b)&0x80)) +#define j44(a, b) (((a >> 3) & 0x07) | ((~a >> 4) & 0x08) | \ + ((b << 1) & 0x70) | ((~b) & 0x80)) #define P1 w2(5);w2(0xd);w2(5);w2(4); #define P2 w2(5);w2(7);w2(5);w2(4); #define P3 w2(6);w2(4);w2(6);w2(4); -/* cont = 0 - access the IDE register file - cont = 1 - access the IDE command set -*/ - +/* + * cont = 0 - access the IDE register file + * cont = 1 - access the IDE command set + */ static int cont_map[2] = { 0x20, 0x40 }; static int dstr_read_regr(struct pi_adapter *pi, int cont, int regr) +{ + int a, b, r; -{ int a, b, r; - - r = regr + cont_map[cont]; + r = regr + cont_map[cont]; w0(0x81); P1; - if (pi->mode) { w0(0x11); } else { w0(1); } + if (pi->mode) + w0(0x11); + else + w0(1); P2; w0(r); P1; - switch (pi->mode) { - - case 0: w2(6); a = r1(); w2(4); w2(6); b = r1(); w2(4); - return j44(a,b); - - case 1: w0(0); w2(0x26); a = r0(); w2(4); - return a; - + switch (pi->mode) { + case 0: + w2(6); a = r1(); w2(4); w2(6); b = r1(); w2(4); + return j44(a, b); + case 1: + w0(0); w2(0x26); a = r0(); w2(4); + return a; case 2: case 3: - case 4: w2(0x24); a = r4(); w2(4); - return a; + case 4: + w2(0x24); a = r4(); w2(4); + return a; + } - } - return -1; -} + return -1; +} static void dstr_write_regr(struct pi_adapter *pi, int cont, int regr, int val) +{ + int r = regr + cont_map[cont]; -{ int r; - - r = regr + cont_map[cont]; - - w0(0x81); P1; - if (pi->mode >= 2) { w0(0x11); } else { w0(1); } + w0(0x81); P1; + if (pi->mode >= 2) + w0(0x11); + else + w0(1); P2; w0(r); P1; - - switch (pi->mode) { - case 0: - case 1: w0(val); w2(5); w2(7); w2(5); w2(4); + switch (pi->mode) { + case 0: + case 1: + w0(val); w2(5); w2(7); w2(5); w2(4); break; - case 2: case 3: - case 4: w4(val); - break; - } + case 4: + w4(val); + break; + } } -#define CCP(x) w0(0xff);w2(0xc);w2(4);\ - w0(0xaa);w0(0x55);w0(0);w0(0xff);w0(0x87);w0(0x78);\ - w0(x);w2(5);w2(4); +#define CCP(x) \ + do { \ + w0(0xff); w2(0xc); w2(4); \ + w0(0xaa); w0(0x55); w0(0); w0(0xff); \ + w0(0x87); w0(0x78); \ + w0(x); w2(5); w2(4); \ + } while (0) static void dstr_connect(struct pi_adapter *pi) - -{ pi->saved_r0 = r0(); - pi->saved_r2 = r2(); - w2(4); CCP(0xe0); w0(0xff); +{ + pi->saved_r0 = r0(); + pi->saved_r2 = r2(); + w2(4); CCP(0xe0); w0(0xff); } static void dstr_disconnect(struct pi_adapter *pi) - -{ CCP(0x30); - w0(pi->saved_r0); - w2(pi->saved_r2); -} +{ + CCP(0x30); + w0(pi->saved_r0); + w2(pi->saved_r2); +} static void dstr_read_block(struct pi_adapter *pi, char *buf, int count) - -{ int k, a, b; +{ + int k, a, b; w0(0x81); P1; - if (pi->mode) { w0(0x19); } else { w0(9); } + if (pi->mode) + w0(0x19); + else + w0(9); P2; w0(0x82); P1; P3; w0(0x20); P1; - switch (pi->mode) { - - case 0: for (k=0;k<count;k++) { - w2(6); a = r1(); w2(4); - w2(6); b = r1(); w2(4); - buf[k] = j44(a,b); - } - break; - - case 1: w0(0); - for (k=0;k<count;k++) { - w2(0x26); buf[k] = r0(); w2(0x24); - } - w2(4); - break; - - case 2: w2(0x24); - for (k=0;k<count;k++) buf[k] = r4(); - w2(4); - break; - - case 3: w2(0x24); - for (k=0;k<count/2;k++) ((u16 *)buf)[k] = r4w(); - w2(4); - break; - - case 4: w2(0x24); - for (k=0;k<count/4;k++) ((u32 *)buf)[k] = r4l(); - w2(4); - break; - - } + switch (pi->mode) { + case 0: + for (k = 0; k < count; k++) { + w2(6); a = r1(); w2(4); + w2(6); b = r1(); w2(4); + buf[k] = j44(a, b); + } + break; + case 1: + w0(0); + for (k = 0; k < count; k++) { + w2(0x26); + buf[k] = r0(); + w2(0x24); + } + w2(4); + break; + case 2: + w2(0x24); + for (k = 0; k < count; k++) + buf[k] = r4(); + w2(4); + break; + case 3: + w2(0x24); + for (k = 0; k < count / 2; k++) + ((u16 *)buf)[k] = r4w(); + w2(4); + break; + case 4: + w2(0x24); + for (k = 0; k < count / 4; k++) + ((u32 *)buf)[k] = r4l(); + w2(4); + break; + } } static void dstr_write_block(struct pi_adapter *pi, char *buf, int count) +{ + int k; -{ int k; - - w0(0x81); P1; - if (pi->mode) { w0(0x19); } else { w0(9); } - P2; w0(0x82); P1; P3; w0(0x20); P1; - - switch (pi->mode) { - - case 0: - case 1: for (k=0;k<count;k++) { - w2(5); w0(buf[k]); w2(7); - } - w2(5); w2(4); - break; + w0(0x81); P1; + if (pi->mode) + w0(0x19); + else + w0(9); + P2; w0(0x82); P1; P3; w0(0x20); P1; - case 2: w2(0xc5); - for (k=0;k<count;k++) w4(buf[k]); + switch (pi->mode) { + case 0: + case 1: + for (k = 0; k < count; k++) { + w2(5); + w0(buf[k]); + w2(7); + } + w2(5); w2(4); + break; + case 2: + w2(0xc5); + for (k = 0; k < count; k++) + w4(buf[k]); w2(0xc4); - break; - - case 3: w2(0xc5); - for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]); - w2(0xc4); - break; - - case 4: w2(0xc5); - for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]); - w2(0xc4); - break; - - } + break; + case 3: + w2(0xc5); + for (k = 0; k < count / 2; k++) + w4w(((u16 *)buf)[k]); + w2(0xc4); + break; + case 4: + w2(0xc5); + for (k = 0; k < count / 4; k++) + w4l(((u32 *)buf)[k]); + w2(0xc4); + break; + } } - static void dstr_log_adapter(struct pi_adapter *pi) -{ char *mode_string[5] = {"4-bit","8-bit","EPP-8", - "EPP-16","EPP-32"}; +{ + char *mode_string[5] = { "4-bit", "8-bit", "EPP-8", "EPP-16", "EPP-32" }; - dev_info(&pi->dev, "DataStor EP2000 at 0x%x, mode %d (%s), delay %d\n", - pi->port, pi->mode, mode_string[pi->mode], pi->delay); + dev_info(&pi->dev, + "DataStor EP2000 at 0x%x, mode %d (%s), delay %d\n", + pi->port, pi->mode, mode_string[pi->mode], pi->delay); } static struct pi_protocol dstr = { diff --git a/drivers/ata/pata_parport/epat.c b/drivers/ata/pata_parport/epat.c index b146999368ae..016bd96bce89 100644 --- a/drivers/ata/pata_parport/epat.c +++ b/drivers/ata/pata_parport/epat.c @@ -1,13 +1,12 @@ -/* - epat.c (c) 1997-8 Grant R. Guenther <grant@torque.net> - Under the terms of the GNU General Public License. - - This is the low level protocol driver for the EPAT parallel - to IDE adapter from Shuttle Technologies. This adapter is - used in many popular parallel port disk products such as the - SyQuest EZ drives, the Avatar Shark and the Imation SuperDisk. - -*/ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * (c) 1997-1998 Grant R. Guenther <grant@torque.net> + * + * This is the low level protocol driver for the EPAT parallel + * to IDE adapter from Shuttle Technologies. This adapter is + * used in many popular parallel port disk products such as the + * SyQuest EZ drives, the Avatar Shark and the Imation SuperDisk. + */ #include <linux/module.h> #include <linux/init.h> @@ -18,276 +17,313 @@ #include <asm/io.h> #include "pata_parport.h" -#define j44(a,b) (((a>>4)&0x0f)+(b&0xf0)) -#define j53(a,b) (((a>>3)&0x1f)+((b<<4)&0xe0)) +#define j44(a, b) (((a >> 4) & 0x0f) + (b & 0xf0)) +#define j53(a, b) (((a >> 3) & 0x1f) + ((b << 4) & 0xe0)) static int epatc8; module_param(epatc8, int, 0); -MODULE_PARM_DESC(epatc8, "support for the Shuttle EP1284 chip, " - "used in any recent Imation SuperDisk (LS-120) drive."); - -/* cont = 0 IDE register file - cont = 1 IDE control registers - cont = 2 internal EPAT registers -*/ - +MODULE_PARM_DESC(epatc8, + "support for the Shuttle EP1284 chip, " + "used in any recent Imation SuperDisk (LS-120) drive."); + +/* + * cont = 0 IDE register file + * cont = 1 IDE control registers + * cont = 2 internal EPAT registers + */ static int cont_map[3] = { 0x18, 0x10, 0 }; static void epat_write_regr(struct pi_adapter *pi, int cont, int regr, int val) - -{ int r; - - r = regr + cont_map[cont]; +{ + int r = regr + cont_map[cont]; switch (pi->mode) { - case 0: case 1: - case 2: w0(0x60+r); w2(1); w0(val); w2(4); + case 2: + w0(0x60+r); w2(1); w0(val); w2(4); break; - case 3: case 4: - case 5: w3(0x40+r); w4(val); + case 5: + w3(0x40+r); w4(val); break; - } } static int epat_read_regr(struct pi_adapter *pi, int cont, int regr) - -{ int a, b, r; +{ + int a, b, r; r = regr + cont_map[cont]; switch (pi->mode) { - case 0: w0(r); w2(1); w2(3); + case 0: + w0(r); w2(1); w2(3); a = r1(); w2(4); b = r1(); - return j44(a,b); - - case 1: w0(0x40+r); w2(1); w2(4); + return j44(a, b); + case 1: + w0(0x40+r); w2(1); w2(4); a = r1(); b = r2(); w0(0xff); - return j53(a,b); - - case 2: w0(0x20+r); w2(1); w2(0x25); + return j53(a, b); + case 2: + w0(0x20+r); w2(1); w2(0x25); a = r0(); w2(4); return a; - case 3: case 4: - case 5: w3(r); w2(0x24); a = r4(); w2(4); + case 5: + w3(r); w2(0x24); a = r4(); w2(4); return a; - } + return -1; /* never gets here */ } static void epat_read_block(struct pi_adapter *pi, char *buf, int count) - -{ int k, ph, a, b; +{ + int k, ph, a, b; switch (pi->mode) { - case 0: w0(7); w2(1); w2(3); w0(0xff); + case 0: + w0(7); w2(1); w2(3); w0(0xff); ph = 0; - for(k=0;k<count;k++) { - if (k == count-1) w0(0xfd); - w2(6+ph); a = r1(); - if (a & 8) b = a; - else { w2(4+ph); b = r1(); } - buf[k] = j44(a,b); + for (k = 0; k < count; k++) { + if (k == count-1) + w0(0xfd); + w2(6 + ph); a = r1(); + if (a & 8) { + b = a; + } else { + w2(4+ph); b = r1(); + } + buf[k] = j44(a, b); ph = 1 - ph; } w0(0); w2(4); break; - case 1: w0(0x47); w2(1); w2(5); w0(0xff); + case 1: + w0(0x47); w2(1); w2(5); w0(0xff); ph = 0; - for(k=0;k<count;k++) { - if (k == count-1) w0(0xfd); - w2(4+ph); + for (k = 0; k < count; k++) { + if (k == count - 1) + w0(0xfd); + w2(4 + ph); a = r1(); b = r2(); - buf[k] = j53(a,b); + buf[k] = j53(a, b); ph = 1 - ph; } w0(0); w2(4); break; - case 2: w0(0x27); w2(1); w2(0x25); w0(0); + case 2: + w0(0x27); w2(1); w2(0x25); w0(0); ph = 0; - for(k=0;k<count-1;k++) { - w2(0x24+ph); + for (k = 0; k < count - 1; k++) { + w2(0x24 + ph); buf[k] = r0(); ph = 1 - ph; } - w2(0x26); w2(0x27); buf[count-1] = r0(); + w2(0x26); w2(0x27); + buf[count - 1] = r0(); w2(0x25); w2(4); break; - case 3: w3(0x80); w2(0x24); - for(k=0;k<count-1;k++) buf[k] = r4(); - w2(4); w3(0xa0); w2(0x24); buf[count-1] = r4(); + case 3: + w3(0x80); w2(0x24); + for (k = 0; k < count - 1; k++) + buf[k] = r4(); + w2(4); w3(0xa0); w2(0x24); + buf[count - 1] = r4(); w2(4); break; - case 4: w3(0x80); w2(0x24); - for(k=0;k<(count/2)-1;k++) ((u16 *)buf)[k] = r4w(); - buf[count-2] = r4(); - w2(4); w3(0xa0); w2(0x24); buf[count-1] = r4(); + case 4: + w3(0x80); w2(0x24); + for (k = 0; k < count / 2 - 1; k++) + ((u16 *)buf)[k] = r4w(); + buf[count - 2] = r4(); + w2(4); w3(0xa0); w2(0x24); + buf[count - 1] = r4(); w2(4); break; - case 5: w3(0x80); w2(0x24); - for(k=0;k<(count/4)-1;k++) ((u32 *)buf)[k] = r4l(); - for(k=count-4;k<count-1;k++) buf[k] = r4(); - w2(4); w3(0xa0); w2(0x24); buf[count-1] = r4(); + case 5: + w3(0x80); w2(0x24); + for (k = 0; k < count / 4 - 1; k++) + ((u32 *)buf)[k] = r4l(); + for (k = count - 4; k < count - 1; k++) + buf[k] = r4(); + w2(4); w3(0xa0); w2(0x24); + buf[count - 1] = r4(); w2(4); break; - } } static void epat_write_block(struct pi_adapter *pi, char *buf, int count) - -{ int ph, k; +{ + int ph, k; switch (pi->mode) { - case 0: case 1: - case 2: w0(0x67); w2(1); w2(5); + case 2: + w0(0x67); w2(1); w2(5); ph = 0; - for(k=0;k<count;k++) { + for (k = 0; k < count; k++) { w0(buf[k]); - w2(4+ph); + w2(4 + ph); ph = 1 - ph; } w2(7); w2(4); break; - - case 3: w3(0xc0); - for(k=0;k<count;k++) w4(buf[k]); + case 3: + w3(0xc0); + for (k = 0; k < count; k++) + w4(buf[k]); w2(4); break; - - case 4: w3(0xc0); - for(k=0;k<(count/2);k++) w4w(((u16 *)buf)[k]); + case 4: + w3(0xc0); + for (k = 0; k < count / 2; k++) + w4w(((u16 *)buf)[k]); w2(4); break; - - case 5: w3(0xc0); - for(k=0;k<(count/4);k++) w4l(((u32 *)buf)[k]); + case 5: + w3(0xc0); + for (k = 0; k < count / 4; k++) + w4l(((u32 *)buf)[k]); w2(4); break; - } } /* these macros access the EPAT registers in native addressing */ -#define WR(r,v) epat_write_regr(pi,2,r,v) -#define RR(r) (epat_read_regr(pi,2,r)) +#define WR(r, v) epat_write_regr(pi, 2, r, v) +#define RR(r) epat_read_regr(pi, 2, r) /* and these access the IDE task file */ -#define WRi(r,v) epat_write_regr(pi,0,r,v) -#define RRi(r) (epat_read_regr(pi,0,r)) +#define WRi(r, v) epat_write_regr(pi, 0, r, v) +#define RRi(r) epat_read_regr(pi, 0, r) /* FIXME: the CPP stuff should be fixed to handle multiple EPATs on a chain */ -#define CPP(x) w2(4);w0(0x22);w0(0xaa);w0(0x55);w0(0);w0(0xff);\ - w0(0x87);w0(0x78);w0(x);w2(4);w2(5);w2(4);w0(0xff); +#define CPP(x) \ + do { \ + w2(4); w0(0x22); w0(0xaa); \ + w0(0x55); w0(0); w0(0xff); \ + w0(0x87); w0(0x78); w0(x); \ + w2(4); w2(5); w2(4); w0(0xff); \ + } while (0) static void epat_connect(struct pi_adapter *pi) - -{ pi->saved_r0 = r0(); - pi->saved_r2 = r2(); +{ + pi->saved_r0 = r0(); + pi->saved_r2 = r2(); /* Initialize the chip */ CPP(0); if (epatc8) { - CPP(0x40);CPP(0xe0); - w0(0);w2(1);w2(4); - WR(0x8,0x12);WR(0xc,0x14);WR(0x12,0x10); - WR(0xe,0xf);WR(0xf,4); + CPP(0x40); CPP(0xe0); + w0(0); w2(1); w2(4); + WR(0x8, 0x12); + WR(0xc, 0x14); + WR(0x12, 0x10); + WR(0xe, 0xf); + WR(0xf, 4); /* WR(0xe,0xa);WR(0xf,4); */ - WR(0xe,0xd);WR(0xf,0); + WR(0xe, 0xd); + WR(0xf, 0); /* CPP(0x30); */ } /* Connect to the chip */ CPP(0xe0); - w0(0);w2(1);w2(4); /* Idle into SPP */ + w0(0); w2(1); w2(4); /* Idle into SPP */ if (pi->mode >= 3) { - w0(0);w2(1);w2(4);w2(0xc); - /* Request EPP */ - w0(0x40);w2(6);w2(7);w2(4);w2(0xc);w2(4); + w0(0); w2(1); w2(4); w2(0xc); + /* Request EPP */ + w0(0x40); w2(6); w2(7); w2(4); w2(0xc); w2(4); } if (!epatc8) { - WR(8,0x10); WR(0xc,0x14); WR(0xa,0x38); WR(0x12,0x10); + WR(8, 0x10); + WR(0xc, 0x14); + WR(0xa, 0x38); + WR(0x12, 0x10); } } static void epat_disconnect(struct pi_adapter *pi) -{ CPP(0x30); +{ + CPP(0x30); w0(pi->saved_r0); w2(pi->saved_r2); } static int epat_test_proto(struct pi_adapter *pi) - -{ int k, j, f, cc; - int e[2] = {0,0}; +{ + int k, j, f, cc; + int e[2] = { 0, 0 }; char scratch[512]; - epat_connect(pi); + epat_connect(pi); cc = RR(0xd); epat_disconnect(pi); epat_connect(pi); for (j=0;j<2;j++) { - WRi(6,0xa0+j*0x10); - for (k=0;k<256;k++) { - WRi(2,k^0xaa); - WRi(3,k^0x55); - if (RRi(2) != (k^0xaa)) e[j]++; - } - } - epat_disconnect(pi); - - f = 0; - epat_connect(pi); - WR(0x13,1); WR(0x13,0); WR(0xa,0x11); - epat_read_block(pi,scratch,512); - - for (k=0;k<256;k++) { - if ((scratch[2*k] & 0xff) != k) f++; - if ((scratch[2*k+1] & 0xff) != (0xff-k)) f++; - } - epat_disconnect(pi); + WRi(6, 0xa0 + j * 0x10); + for (k = 0; k < 256; k++) { + WRi(2, k ^ 0xaa); + WRi(3, k ^ 0x55); + if (RRi(2) != (k ^ 0xaa)) + e[j]++; + } + } + epat_disconnect(pi); - dev_dbg(&pi->dev, "epat: port 0x%x, mode %d, ccr %x, test=(%d,%d,%d)\n", - pi->port, pi->mode, cc, e[0], e[1], f); - - return (e[0] && e[1]) || f; + f = 0; + epat_connect(pi); + WR(0x13, 1); WR(0x13, 0); WR(0xa, 0x11); + epat_read_block(pi, scratch, 512); + + for (k = 0; k < 256; k++) { + if ((scratch[2 * k] & 0xff) != k) + f++; + if ((scratch[2 * k + 1] & 0xff) != 0xff - k) + f++; + } + epat_disconnect(pi); + + dev_dbg(&pi->dev, + "epat: port 0x%x, mode %d, ccr %x, test=(%d,%d,%d)\n", + pi->port, pi->mode, cc, e[0], e[1], f); + + return (e[0] && e[1]) || f; } static void epat_log_adapter(struct pi_adapter *pi) - -{ int ver; - char *mode_string[6] = - {"4-bit","5/3","8-bit","EPP-8","EPP-16","EPP-32"}; +{ + int ver; + char *mode_string[6] = + { "4-bit", "5/3", "8-bit", "EPP-8", "EPP-16", "EPP-32" }; epat_connect(pi); - WR(0xa,0x38); /* read the version code */ - ver = RR(0xb); - epat_disconnect(pi); + WR(0xa, 0x38); /* read the version code */ + ver = RR(0xb); + epat_disconnect(pi); - dev_info(&pi->dev, "Shuttle EPAT chip %x at 0x%x, mode %d (%s), delay %d\n", + dev_info(&pi->dev, + "Shuttle EPAT chip %x at 0x%x, mode %d (%s), delay %d\n", ver, pi->port, pi->mode, mode_string[pi->mode], pi->delay); } diff --git a/drivers/ata/pata_parport/epia.c b/drivers/ata/pata_parport/epia.c index f6db2f79fe99..920e9f40d401 100644 --- a/drivers/ata/pata_parport/epia.c +++ b/drivers/ata/pata_parport/epia.c @@ -1,14 +1,13 @@ -/* - epia.c (c) 1997-8 Grant R. Guenther <grant@torque.net> - Under the terms of the GNU General Public License. - - epia.c is a low-level protocol driver for Shuttle Technologies - EPIA parallel to IDE adapter chip. This device is now obsolete - and has been replaced with the EPAT chip, which is supported - by epat.c, however, some devices based on EPIA are still - available. - -*/ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * (c) 1997-1998 Grant R. Guenther <grant@torque.net> + * + * epia.c is a low-level protocol driver for Shuttle Technologies + * EPIA parallel to IDE adapter chip. This device is now obsolete + * and has been replaced with the EPAT chip, which is supported + * by epat.c, however, some devices based on EPIA are still + * available. + */ #include <linux/module.h> #include <linux/init.h> @@ -19,255 +18,274 @@ #include <asm/io.h> #include "pata_parport.h" -/* mode codes: 0 nybble reads on port 1, 8-bit writes - 1 5/3 reads on ports 1 & 2, 8-bit writes - 2 8-bit reads and writes - 3 8-bit EPP mode - 4 16-bit EPP - 5 32-bit EPP -*/ - -#define j44(a,b) (((a>>4)&0x0f)+(b&0xf0)) -#define j53(a,b) (((a>>3)&0x1f)+((b<<4)&0xe0)) - -/* cont = 0 IDE register file - cont = 1 IDE control registers -*/ - +/* + * mode codes: 0 nybble reads on port 1, 8-bit writes + * 1 5/3 reads on ports 1 & 2, 8-bit writes + * 2 8-bit reads and writes + * 3 8-bit EPP mode + * 4 16-bit EPP + * 5 32-bit EPP + */ + +#define j44(a, b) (((a >> 4) & 0x0f) + (b & 0xf0)) +#define j53(a, b) (((a >> 3) & 0x1f) + ((b << 4) & 0xe0)) + +/* + * cont = 0 IDE register file + * cont = 1 IDE control registers + */ static int cont_map[2] = { 0, 0x80 }; static int epia_read_regr(struct pi_adapter *pi, int cont, int regr) - -{ int a, b, r; +{ + int a, b, r; regr += cont_map[cont]; - switch (pi->mode) { - - case 0: r = regr^0x39; - w0(r); w2(1); w2(3); w0(r); - a = r1(); w2(1); b = r1(); w2(4); - return j44(a,b); - - case 1: r = regr^0x31; - w0(r); w2(1); w0(r&0x37); - w2(3); w2(5); w0(r|0xf0); - a = r1(); b = r2(); w2(4); - return j53(a,b); - - case 2: r = regr^0x29; - w0(r); w2(1); w2(0X21); w2(0x23); - a = r0(); w2(4); - return a; - + switch (pi->mode) { + case 0: + r = regr ^ 0x39; + w0(r); w2(1); w2(3); w0(r); + a = r1(); w2(1); b = r1(); w2(4); + return j44(a, b); + case 1: + r = regr ^ 0x31; + w0(r); w2(1); w0(r & 0x37); + w2(3); w2(5); w0(r | 0xf0); + a = r1(); b = r2(); w2(4); + return j53(a, b); + case 2: + r = regr^0x29; + w0(r); w2(1); w2(0X21); w2(0x23); + a = r0(); w2(4); + return a; case 3: case 4: - case 5: w3(regr); w2(0x24); a = r4(); w2(4); - return a; + case 5: + w3(regr); w2(0x24); a = r4(); w2(4); + return a; + } - } - return -1; -} + return -1; +} static void epia_write_regr(struct pi_adapter *pi, int cont, int regr, int val) - -{ int r; +{ + int r; regr += cont_map[cont]; - switch (pi->mode) { - - case 0: - case 1: - case 2: r = regr^0x19; - w0(r); w2(1); w0(val); w2(3); w2(4); - break; - + switch (pi->mode) { + case 0: + case 1: + case 2: + r = regr ^ 0x19; + w0(r); w2(1); w0(val); w2(3); w2(4); + break; case 3: case 4: - case 5: r = regr^0x40; - w3(r); w4(val); w2(4); - break; - } + case 5: + r = regr ^ 0x40; + w3(r); w4(val); w2(4); + break; + } } -#define WR(r,v) epia_write_regr(pi,0,r,v) -#define RR(r) (epia_read_regr(pi,0,r)) - -/* The use of register 0x84 is entirely unclear - it seems to control - some EPP counters ... currently we know about 3 different block - sizes: the standard 512 byte reads and writes, 12 byte writes and - 2048 byte reads (the last two being used in the CDrom drivers. -*/ +#define WR(r, v) epia_write_regr(pi, 0, r, v) +#define RR(r) epia_read_regr(pi, 0, r) +/* + * The use of register 0x84 is entirely unclear - it seems to control + * some EPP counters ... currently we know about 3 different block + * sizes: the standard 512 byte reads and writes, 12 byte writes and + * 2048 byte reads (the last two being used in the CDrom drivers. + */ static void epia_connect(struct pi_adapter *pi) - -{ pi->saved_r0 = r0(); - pi->saved_r2 = r2(); - - w2(4); w0(0xa0); w0(0x50); w0(0xc0); w0(0x30); w0(0xa0); w0(0); - w2(1); w2(4); - if (pi->mode >= 3) { - w0(0xa); w2(1); w2(4); w0(0x82); w2(4); w2(0xc); w2(4); - w2(0x24); w2(0x26); w2(4); - } - WR(0x86,8); +{ + pi->saved_r0 = r0(); + pi->saved_r2 = r2(); + + w2(4); w0(0xa0); w0(0x50); w0(0xc0); w0(0x30); w0(0xa0); w0(0); + w2(1); w2(4); + if (pi->mode >= 3) { + w0(0xa); w2(1); w2(4); w0(0x82); w2(4); w2(0xc); w2(4); + w2(0x24); w2(0x26); w2(4); + } + WR(0x86, 8); } static void epia_disconnect(struct pi_adapter *pi) - -{ /* WR(0x84,0x10); */ - w0(pi->saved_r0); - w2(1); w2(4); - w0(pi->saved_r0); - w2(pi->saved_r2); -} +{ + /* WR(0x84,0x10); */ + w0(pi->saved_r0); + w2(1); w2(4); + w0(pi->saved_r0); + w2(pi->saved_r2); +} static void epia_read_block(struct pi_adapter *pi, char *buf, int count) -{ int k, ph, a, b; - - switch (pi->mode) { - - case 0: w0(0x81); w2(1); w2(3); w0(0xc1); - ph = 1; - for (k=0;k<count;k++) { - w2(2+ph); a = r1(); - w2(4+ph); b = r1(); - buf[k] = j44(a,b); - ph = 1 - ph; - } - w0(0); w2(4); - break; - - case 1: w0(0x91); w2(1); w0(0x10); w2(3); - w0(0x51); w2(5); w0(0xd1); - ph = 1; - for (k=0;k<count;k++) { - w2(4+ph); - a = r1(); b = r2(); - buf[k] = j53(a,b); - ph = 1 - ph; - } - w0(0); w2(4); - break; - - case 2: w0(0x89); w2(1); w2(0x23); w2(0x21); - ph = 1; - for (k=0;k<count;k++) { - w2(0x24+ph); - buf[k] = r0(); - ph = 1 - ph; - } - w2(6); w2(4); - break; - - case 3: if (count > 512) WR(0x84,3); +{ + int k, ph, a, b; + + switch (pi->mode) { + case 0: + w0(0x81); w2(1); w2(3); w0(0xc1); + ph = 1; + for (k = 0; k < count; k++) { + w2(2+ph); a = r1(); + w2(4+ph); b = r1(); + buf[k] = j44(a, b); + ph = 1 - ph; + } + w0(0); w2(4); + break; + case 1: + w0(0x91); w2(1); w0(0x10); w2(3); + w0(0x51); w2(5); w0(0xd1); + ph = 1; + for (k = 0; k < count; k++) { + w2(4 + ph); + a = r1(); b = r2(); + buf[k] = j53(a, b); + ph = 1 - ph; + } + w0(0); w2(4); + break; + case 2: + w0(0x89); w2(1); w2(0x23); w2(0x21); + ph = 1; + for (k = 0; k < count; k++) { + w2(0x24 + ph); + buf[k] = r0(); + ph = 1 - ph; + } + w2(6); w2(4); + break; + case 3: + if (count > 512) + WR(0x84, 3); w3(0); w2(0x24); - for (k=0;k<count;k++) buf[k] = r4(); - w2(4); WR(0x84,0); - break; - - case 4: if (count > 512) WR(0x84,3); + for (k = 0; k < count; k++) + buf[k] = r4(); + w2(4); WR(0x84, 0); + break; + case 4: + if (count > 512) + WR(0x84, 3); w3(0); w2(0x24); - for (k=0;k<count/2;k++) ((u16 *)buf)[k] = r4w(); - w2(4); WR(0x84,0); - break; - - case 5: if (count > 512) WR(0x84,3); + for (k = 0; k < count / 2; k++) + ((u16 *)buf)[k] = r4w(); + w2(4); WR(0x84, 0); + break; + case 5: + if (count > 512) + WR(0x84, 3); w3(0); w2(0x24); - for (k=0;k<count/4;k++) ((u32 *)buf)[k] = r4l(); - w2(4); WR(0x84,0); - break; - - } + for (k = 0; k < count / 4; k++) + ((u32 *)buf)[k] = r4l(); + w2(4); WR(0x84, 0); + break; + } } static void epia_write_block(struct pi_adapter *pi, char *buf, int count) - -{ int ph, k, last, d; - - switch (pi->mode) { - - case 0: - case 1: - case 2: w0(0xa1); w2(1); w2(3); w2(1); w2(5); - ph = 0; last = 0x8000; - for (k=0;k<count;k++) { - d = buf[k]; - if (d != last) { last = d; w0(d); } - w2(4+ph); - ph = 1 - ph; - } - w2(7); w2(4); - break; - - case 3: if (count < 512) WR(0x84,1); +{ + int ph, k, last, d; + + switch (pi->mode) { + case 0: + case 1: + case 2: + w0(0xa1); w2(1); w2(3); w2(1); w2(5); + ph = 0; last = 0x8000; + for (k = 0; k < count; k++) { + d = buf[k]; + if (d != last) { + last = d; + w0(d); + } + w2(4 + ph); + ph = 1 - ph; + } + w2(7); w2(4); + break; + case 3: + if (count < 512) + WR(0x84, 1); w3(0x40); - for (k=0;k<count;k++) w4(buf[k]); - if (count < 512) WR(0x84,0); - break; - - case 4: if (count < 512) WR(0x84,1); + for (k = 0; k < count; k++) + w4(buf[k]); + if (count < 512) + WR(0x84, 0); + break; + case 4: + if (count < 512) + WR(0x84, 1); w3(0x40); - for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]); - if (count < 512) WR(0x84,0); - break; - - case 5: if (count < 512) WR(0x84,1); + for (k = 0; k < count / 2; k++) + w4w(((u16 *)buf)[k]); + if (count < 512) + WR(0x84, 0); + break; + case 5: + if (count < 512) + WR(0x84, 1); w3(0x40); - for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]); - if (count < 512) WR(0x84,0); - break; - - } - + for (k = 0; k < count / 4; k++) + w4l(((u32 *)buf)[k]); + if (count < 512) + WR(0x84, 0); + break; + } } static int epia_test_proto(struct pi_adapter *pi) - -{ int j, k, f; - int e[2] = {0,0}; +{ + int j, k, f; + int e[2] = { 0, 0 }; char scratch[512]; - epia_connect(pi); - for (j=0;j<2;j++) { - WR(6,0xa0+j*0x10); - for (k=0;k<256;k++) { - WR(2,k^0xaa); - WR(3,k^0x55); - if (RR(2) != (k^0xaa)) e[j]++; - } - WR(2,1); WR(3,1); - } - epia_disconnect(pi); - - f = 0; - epia_connect(pi); - WR(0x84,8); - epia_read_block(pi,scratch,512); - for (k=0;k<256;k++) { - if ((scratch[2*k] & 0xff) != ((k+1) & 0xff)) f++; - if ((scratch[2*k+1] & 0xff) != ((-2-k) & 0xff)) f++; - } - WR(0x84,0); - epia_disconnect(pi); + epia_connect(pi); + for (j = 0; j < 2; j++) { + WR(6, 0xa0 + j * 0x10); + for (k = 0; k < 256; k++) { + WR(2, k ^ 0xaa); + WR(3, k ^ 0x55); + if (RR(2) != (k ^ 0xaa)) + e[j]++; + } + WR(2, 1); WR(3, 1); + } + epia_disconnect(pi); + + f = 0; + epia_connect(pi); + WR(0x84, 8); + epia_read_block(pi, scratch, 512); + for (k = 0; k < 256; k++) { + if ((scratch[2 * k] & 0xff) != ((k + 1) & 0xff)) + f++; + if ((scratch[2 * k + 1] & 0xff) != ((-2 - k) & 0xff)) + f++; + } + WR(0x84, 0); + epia_disconnect(pi); dev_dbg(&pi->dev, "epia: port 0x%x, mode %d, test=(%d,%d,%d)\n", - pi->port, pi->mode, e[0], e[1], f); - - return (e[0] && e[1]) || f; + pi->port, pi->mode, e[0], e[1], f); + return (e[0] && e[1]) || f; } static void epia_log_adapter(struct pi_adapter *pi) +{ + char *mode[6] = { "4-bit", "5/3", "8-bit", "EPP-8", "EPP-16", "EPP-32"}; -{ char *mode_string[6] = {"4-bit","5/3","8-bit", - "EPP-8","EPP-16","EPP-32"}; - - dev_info(&pi->dev, "Shuttle EPIA at 0x%x, mode %d (%s), delay %d\n", - pi->port, pi->mode, mode_string[pi->mode], pi->delay); + dev_info(&pi->dev, + "Shuttle EPIA at 0x%x, mode %d (%s), delay %d\n", + pi->port, pi->mode, mode[pi->mode], pi->delay); } static struct pi_protocol epia = { diff --git a/drivers/ata/pata_parport/fit2.c b/drivers/ata/pata_parport/fit2.c index fd3b2ce426a5..6524f3033b1e 100644 --- a/drivers/ata/pata_parport/fit2.c +++ b/drivers/ata/pata_parport/fit2.c @@ -1,17 +1,16 @@ -/* - fit2.c (c) 1998 Grant R. Guenther <grant@torque.net> - Under the terms of the GNU General Public License. - - fit2.c is a low-level protocol driver for the older version - of the Fidelity International Technology parallel port adapter. - This adapter is used in their TransDisk 2000 and older TransDisk - 3000 portable hard-drives. As far as I can tell, this device - supports 4-bit mode _only_. - - Newer models of the FIT products use an enhanced protocol. - The "fit3" protocol module should support current drives. - -*/ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * (c) 1998 Grant R. Guenther <grant@torque.net> + * + * fit2.c is a low-level protocol driver for the older version + * of the Fidelity International Technology parallel port adapter. + * This adapter is used in their TransDisk 2000 and older TransDisk + * 3000 portable hard-drives. As far as I can tell, this device + * supports 4-bit mode _only_. + * + * Newer models of the FIT products use an enhanced protocol. + * The "fit3" protocol module should support current drives. + */ #include <linux/module.h> #include <linux/init.h> @@ -22,99 +21,97 @@ #include <asm/io.h> #include "pata_parport.h" -#define j44(a,b) (((a>>4)&0x0f)|(b&0xf0)) - -/* cont = 0 - access the IDE register file - cont = 1 - access the IDE command set +#define j44(a, b) (((a >> 4) & 0x0f) | (b & 0xf0)) -NB: The FIT adapter does not appear to use the control registers. -So, we map ALT_STATUS to STATUS and NO-OP writes to the device -control register - this means that IDE reset will not work on these -devices. - -*/ +/* + * cont = 0 - access the IDE register file + * cont = 1 - access the IDE command set + * + * NB: The FIT adapter does not appear to use the control registers. + * So, we map ALT_STATUS to STATUS and NO-OP writes to the device + * control register - this means that IDE reset will not work on these + * devices. + */ static void fit2_write_regr(struct pi_adapter *pi, int cont, int regr, int val) - -{ if (cont == 1) return; +{ + if (cont == 1) + return; w2(0xc); w0(regr); w2(4); w0(val); w2(5); w0(0); w2(4); } static int fit2_read_regr(struct pi_adapter *pi, int cont, int regr) - -{ int a, b, r; +{ + int a, b, r; if (cont) { - if (regr != 6) return 0xff; - r = 7; - } else r = regr + 0x10; + if (regr != 6) + return 0xff; + r = 7; + } else { + r = regr + 0x10; + } - w2(0xc); w0(r); w2(4); w2(5); - w0(0); a = r1(); - w0(1); b = r1(); + w2(0xc); w0(r); w2(4); w2(5); + w0(0); a = r1(); + w0(1); b = r1(); w2(4); - return j44(a,b); - + return j44(a, b); } static void fit2_read_block(struct pi_adapter *pi, char *buf, int count) - -{ int k, a, b, c, d; +{ + int k, a, b, c, d; w2(0xc); w0(0x10); - for (k=0;k<count/4;k++) { - + for (k = 0; k < count / 4; k++) { w2(4); w2(5); w0(0); a = r1(); w0(1); b = r1(); - w0(3); c = r1(); w0(2); d = r1(); - buf[4*k+0] = j44(a,b); - buf[4*k+1] = j44(d,c); - - w2(4); w2(5); - a = r1(); w0(3); b = r1(); - w0(1); c = r1(); w0(0); d = r1(); - buf[4*k+2] = j44(d,c); - buf[4*k+3] = j44(a,b); + w0(3); c = r1(); w0(2); d = r1(); + buf[4 * k + 0] = j44(a, b); + buf[4 * k + 1] = j44(d, c); + w2(4); w2(5); + a = r1(); w0(3); b = r1(); + w0(1); c = r1(); w0(0); d = r1(); + buf[4 * k + 2] = j44(d, c); + buf[4 * k + 3] = j44(a, b); } w2(4); - } static void fit2_write_block(struct pi_adapter *pi, char *buf, int count) +{ + int k; -{ int k; - - - w2(0xc); w0(0); - for (k=0;k<count/2;k++) { - w2(4); w0(buf[2*k]); - w2(5); w0(buf[2*k+1]); + w2(0xc); w0(0); + for (k = 0; k < count / 2; k++) { + w2(4); w0(buf[2 * k]); + w2(5); w0(buf[2 * k + 1]); } w2(4); } static void fit2_connect(struct pi_adapter *pi) - -{ pi->saved_r0 = r0(); - pi->saved_r2 = r2(); - w2(0xcc); +{ + pi->saved_r0 = r0(); + pi->saved_r2 = r2(); + w2(0xcc); } static void fit2_disconnect(struct pi_adapter *pi) - -{ w0(pi->saved_r0); - w2(pi->saved_r2); -} +{ + w0(pi->saved_r0); + w2(pi->saved_r2); +} static void fit2_log_adapter(struct pi_adapter *pi) - { dev_info(&pi->dev, "FIT 2000 adapter at 0x%x, delay %d\n", - pi->port, pi->delay); + pi->port, pi->delay); } diff --git a/drivers/ata/pata_parport/fit3.c b/drivers/ata/pata_parport/fit3.c index 75df656ac472..c172a38ae67d 100644 --- a/drivers/ata/pata_parport/fit3.c +++ b/drivers/ata/pata_parport/fit3.c @@ -1,21 +1,20 @@ -/* - fit3.c (c) 1998 Grant R. Guenther <grant@torque.net> - Under the terms of the GNU General Public License. - - fit3.c is a low-level protocol driver for newer models - of the Fidelity International Technology parallel port adapter. - This adapter is used in their TransDisk 3000 portable - hard-drives, as well as CD-ROM, PD-CD and other devices. - - The TD-2000 and certain older devices use a different protocol. - Try the fit2 protocol module with them. - - NB: The FIT adapters do not appear to support the control - registers. So, we map ALT_STATUS to STATUS and NO-OP writes - to the device control register - this means that IDE reset - will not work on these devices. - -*/ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * (c) 1998 Grant R. Guenther <grant@torque.net> + * + * fit3.c is a low-level protocol driver for newer models + * of the Fidelity International Technology parallel port adapter. + * This adapter is used in their TransDisk 3000 portable + * hard-drives, as well as CD-ROM, PD-CD and other devices. + * + * The TD-2000 and certain older devices use a different protocol. + * Try the fit2 protocol module with them. + * + * NB: The FIT adapters do not appear to support the control + * registers. So, we map ALT_STATUS to STATUS and NO-OP writes + * to the device control register - this means that IDE reset + * will not work on these devices. + */ #include <linux/module.h> #include <linux/init.h> @@ -26,152 +25,155 @@ #include <asm/io.h> #include "pata_parport.h" -#define j44(a,b) (((a>>3)&0x0f)|((b<<1)&0xf0)) - -#define w7(byte) {out_p(7,byte);} -#define r7() (in_p(7) & 0xff) +#define j44(a, b) (((a >> 3) & 0x0f) | ((b << 1) & 0xf0)) -/* cont = 0 - access the IDE register file - cont = 1 - access the IDE command set +#define w7(byte) out_p(7, byte) +#define r7() (in_p(7) & 0xff) -*/ +/* + * cont = 0 - access the IDE register file + * cont = 1 - access the IDE command set + */ static void fit3_write_regr(struct pi_adapter *pi, int cont, int regr, int val) - -{ if (cont == 1) return; +{ + if (cont == 1) + return; switch (pi->mode) { - case 0: - case 1: w2(0xc); w0(regr); w2(0x8); w2(0xc); - w0(val); w2(0xd); + case 1: + w2(0xc); w0(regr); w2(0x8); w2(0xc); + w0(val); w2(0xd); w0(0); w2(0xc); break; - - case 2: w2(0xc); w0(regr); w2(0x8); w2(0xc); + case 2: + w2(0xc); w0(regr); w2(0x8); w2(0xc); w4(val); w4(0); w2(0xc); break; - } } static int fit3_read_regr(struct pi_adapter *pi, int cont, int regr) - -{ int a, b; +{ + int a, b; if (cont) { - if (regr != 6) return 0xff; - regr = 7; - } + if (regr != 6) + return 0xff; + regr = 7; + } switch (pi->mode) { - - case 0: w2(0xc); w0(regr + 0x10); w2(0x8); w2(0xc); + case 0: + w2(0xc); w0(regr + 0x10); w2(0x8); w2(0xc); w2(0xd); a = r1(); - w2(0xf); b = r1(); + w2(0xf); b = r1(); w2(0xc); - return j44(a,b); - - case 1: w2(0xc); w0(regr + 0x90); w2(0x8); w2(0xc); - w2(0xec); w2(0xee); w2(0xef); a = r0(); + return j44(a, b); + case 1: + w2(0xc); w0(regr + 0x90); w2(0x8); w2(0xc); + w2(0xec); w2(0xee); w2(0xef); a = r0(); w2(0xc); return a; - - case 2: w2(0xc); w0(regr + 0x90); w2(0x8); w2(0xc); - w2(0xec); - a = r4(); b = r4(); + case 2: + w2(0xc); w0(regr + 0x90); w2(0x8); w2(0xc); + w2(0xec); + a = r4(); b = r4(); w2(0xc); return a; - } - return -1; + return -1; } static void fit3_read_block(struct pi_adapter *pi, char *buf, int count) - -{ int k, a, b, c, d; +{ + int k, a, b, c, d; switch (pi->mode) { - - case 0: w2(0xc); w0(0x10); w2(0x8); w2(0xc); - for (k=0;k<count/2;k++) { - w2(0xd); a = r1(); - w2(0xf); b = r1(); - w2(0xc); c = r1(); - w2(0xe); d = r1(); - buf[2*k ] = j44(a,b); - buf[2*k+1] = j44(c,d); + case 0: + w2(0xc); w0(0x10); w2(0x8); w2(0xc); + for (k = 0; k < count / 2; k++) { + w2(0xd); a = r1(); + w2(0xf); b = r1(); + w2(0xc); c = r1(); + w2(0xe); d = r1(); + buf[2 * k] = j44(a, b); + buf[2 * k + 1] = j44(c, d); } w2(0xc); break; - - case 1: w2(0xc); w0(0x90); w2(0x8); w2(0xc); + case 1: + w2(0xc); w0(0x90); w2(0x8); w2(0xc); w2(0xec); w2(0xee); - for (k=0;k<count/2;k++) { - w2(0xef); a = r0(); - w2(0xee); b = r0(); - buf[2*k ] = a; - buf[2*k+1] = b; + for (k = 0; k < count / 2; k++) { + w2(0xef); a = r0(); + w2(0xee); b = r0(); + buf[2 * k] = a; + buf[2 * k + 1] = b; } - w2(0xec); + w2(0xec); w2(0xc); break; - - case 2: w2(0xc); w0(0x90); w2(0x8); w2(0xc); - w2(0xec); - for (k=0;k<count;k++) buf[k] = r4(); - w2(0xc); + case 2: + w2(0xc); w0(0x90); w2(0x8); w2(0xc); + w2(0xec); + for (k = 0; k < count; k++) + buf[k] = r4(); + w2(0xc); break; - } } static void fit3_write_block(struct pi_adapter *pi, char *buf, int count) +{ + int k; -{ int k; - - switch (pi->mode) { - + switch (pi->mode) { case 0: - case 1: w2(0xc); w0(0); w2(0x8); w2(0xc); - for (k=0;k<count/2;k++) { - w0(buf[2*k ]); w2(0xd); - w0(buf[2*k+1]); w2(0xc); + case 1: + w2(0xc); w0(0); w2(0x8); w2(0xc); + for (k = 0; k < count / 2; k++) { + w0(buf[2 * k]); w2(0xd); + w0(buf[2 * k + 1]); w2(0xc); } break; - - case 2: w2(0xc); w0(0); w2(0x8); w2(0xc); - for (k=0;k<count;k++) w4(buf[k]); - w2(0xc); + case 2: + w2(0xc); w0(0); w2(0x8); w2(0xc); + for (k = 0; k < count; k++) + w4(buf[k]); + w2(0xc); break; } } static void fit3_connect(struct pi_adapter *pi) - -{ pi->saved_r0 = r0(); - pi->saved_r2 = r2(); +{ + pi->saved_r0 = r0(); + pi->saved_r2 = r2(); w2(0xc); w0(0); w2(0xa); - if (pi->mode == 2) { - w2(0xc); w0(0x9); w2(0x8); w2(0xc); - } + if (pi->mode == 2) { + w2(0xc); w0(0x9); + w2(0x8); w2(0xc); + } } static void fit3_disconnect(struct pi_adapter *pi) - -{ w2(0xc); w0(0xa); w2(0x8); w2(0xc); +{ + w2(0xc); w0(0xa); w2(0x8); w2(0xc); w0(pi->saved_r0); - w2(pi->saved_r2); -} + w2(pi->saved_r2); +} static void fit3_log_adapter(struct pi_adapter *pi) +{ + char *mode_string[3] = { "4-bit", "8-bit", "EPP"}; -{ char *mode_string[3] = {"4-bit","8-bit","EPP"}; - - dev_info(&pi->dev, "FIT 3000 adapter at 0x%x, mode %d (%s), delay %d\n", - pi->port, pi->mode, mode_string[pi->mode], pi->delay); + dev_info(&pi->dev, + "FIT 3000 adapter at 0x%x, mode %d (%s), delay %d\n", + pi->port, pi->mode, mode_string[pi->mode], pi->delay); } static struct pi_protocol fit3 = { diff --git a/drivers/ata/pata_parport/friq.c b/drivers/ata/pata_parport/friq.c index 1647264cd9a8..dc428f54fe0c 100644 --- a/drivers/ata/pata_parport/friq.c +++ b/drivers/ata/pata_parport/friq.c @@ -1,24 +1,23 @@ -/* - friq.c (c) 1998 Grant R. Guenther <grant@torque.net> - Under the terms of the GNU General Public License - - friq.c is a low-level protocol driver for the Freecom "IQ" - parallel port IDE adapter. Early versions of this adapter - use the 'frpw' protocol. - - Freecom uses this adapter in a battery powered external - CD-ROM drive. It is also used in LS-120 drives by - Maxell and Panasonic, and other devices. - - The battery powered drive requires software support to - control the power to the drive. This module enables the - drive power when the high level driver (pcd) is loaded - and disables it when the module is unloaded. Note, if - the friq module is built in to the kernel, the power - will never be switched off, so other means should be - used to conserve battery power. - -*/ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * (c) 1998 Grant R. Guenther <grant@torque.net> + * + * friq.c is a low-level protocol driver for the Freecom "IQ" + * parallel port IDE adapter. Early versions of this adapter + * use the 'frpw' protocol. + * + * Freecom uses this adapter in a battery powered external + * CD-ROM drive. It is also used in LS-120 drives by + * Maxell and Panasonic, and other devices. + * + * The battery powered drive requires software support to + * control the power to the drive. This module enables the + * drive power when the high level driver (pcd) is loaded + * and disables it when the module is unloaded. Note, if + * the friq module is built in to the kernel, the power + * will never be switched off, so other means should be + * used to conserve battery power. + */ #include <linux/module.h> #include <linux/init.h> @@ -29,197 +28,206 @@ #include <asm/io.h> #include "pata_parport.h" -#define CMD(x) w2(4);w0(0xff);w0(0xff);w0(0x73);w0(0x73);\ - w0(0xc9);w0(0xc9);w0(0x26);w0(0x26);w0(x);w0(x); +#define CMD(x) \ + do { \ + w2(4); w0(0xff); w0(0xff); w0(0x73); w0(0x73); \ + w0(0xc9); w0(0xc9); w0(0x26); \ + w0(0x26); w0(x); w0(x); \ + } while (0) -#define j44(l,h) (((l>>4)&0x0f)|(h&0xf0)) +#define j44(l, h) (((l >> 4) & 0x0f) | (h & 0xf0)) -/* cont = 0 - access the IDE register file - cont = 1 - access the IDE command set -*/ - -static int cont_map[2] = { 0x08, 0x10 }; +/* + * cont = 0 - access the IDE register file + * cont = 1 - access the IDE command set + */ +static int cont_map[2] = { 0x08, 0x10 }; static int friq_read_regr(struct pi_adapter *pi, int cont, int regr) - -{ int h,l,r; +{ + int h, l, r; r = regr + cont_map[cont]; CMD(r); w2(6); l = r1(); w2(4); h = r1(); - w2(4); - - return j44(l,h); + w2(4); + return j44(l, h); } static void friq_write_regr(struct pi_adapter *pi, int cont, int regr, int val) - -{ int r; - - r = regr + cont_map[cont]; +{ + int r = regr + cont_map[cont]; CMD(r); w0(val); - w2(5);w2(7);w2(5);w2(4); + w2(5); w2(7); w2(5); w2(4); } static void friq_read_block_int(struct pi_adapter *pi, char *buf, int count, int regr) +{ + int h, l, k, ph; -{ int h, l, k, ph; - - switch(pi->mode) { - - case 0: CMD(regr); - for (k=0;k<count;k++) { - w2(6); l = r1(); - w2(4); h = r1(); - buf[k] = j44(l,h); - } - w2(4); - break; - - case 1: ph = 2; - CMD(regr+0xc0); - w0(0xff); - for (k=0;k<count;k++) { - w2(0xa4 + ph); - buf[k] = r0(); - ph = 2 - ph; - } - w2(0xac); w2(0xa4); w2(4); - break; - - case 2: CMD(regr+0x80); - for (k=0;k<count-2;k++) buf[k] = r4(); + switch (pi->mode) { + case 0: + CMD(regr); + for (k = 0; k < count; k++) { + w2(6); l = r1(); + w2(4); h = r1(); + buf[k] = j44(l, h); + } + w2(4); + break; + case 1: + ph = 2; + CMD(regr + 0xc0); + w0(0xff); + for (k = 0; k < count; k++) { + w2(0xa4 + ph); + buf[k] = r0(); + ph = 2 - ph; + } + w2(0xac); w2(0xa4); w2(4); + break; + case 2: + CMD(regr + 0x80); + for (k = 0; k < count - 2; k++) + buf[k] = r4(); w2(0xac); w2(0xa4); - buf[count-2] = r4(); - buf[count-1] = r4(); + buf[count - 2] = r4(); + buf[count - 1] = r4(); w2(4); break; - - case 3: CMD(regr+0x80); - for (k=0;k<(count/2)-1;k++) ((u16 *)buf)[k] = r4w(); - w2(0xac); w2(0xa4); - buf[count-2] = r4(); - buf[count-1] = r4(); - w2(4); - break; - - case 4: CMD(regr+0x80); - for (k=0;k<(count/4)-1;k++) ((u32 *)buf)[k] = r4l(); - buf[count-4] = r4(); - buf[count-3] = r4(); - w2(0xac); w2(0xa4); - buf[count-2] = r4(); - buf[count-1] = r4(); - w2(4); - break; - - } + case 3: + CMD(regr + 0x80); + for (k = 0; k < count / 2 - 1; k++) + ((u16 *)buf)[k] = r4w(); + w2(0xac); w2(0xa4); + buf[count - 2] = r4(); + buf[count - 1] = r4(); + w2(4); + break; + case 4: + CMD(regr + 0x80); + for (k = 0; k < count / 4 - 1; k++) + ((u32 *)buf)[k] = r4l(); + buf[count - 4] = r4(); + buf[count - 3] = r4(); + w2(0xac); w2(0xa4); + buf[count - 2] = r4(); + buf[count - 1] = r4(); + w2(4); + break; + } } static void friq_read_block(struct pi_adapter *pi, char *buf, int count) - -{ friq_read_block_int(pi,buf,count,0x08); +{ + friq_read_block_int(pi, buf, count, 0x08); } static void friq_write_block(struct pi_adapter *pi, char *buf, int count) - -{ int k; - - switch(pi->mode) { +{ + int k; + switch (pi->mode) { case 0: - case 1: CMD(8); w2(5); - for (k=0;k<count;k++) { + case 1: + CMD(8); w2(5); + for (k = 0; k < count; k++) { w0(buf[k]); - w2(7);w2(5); + w2(7); w2(5); } w2(4); break; - - case 2: CMD(0xc8); w2(5); - for (k=0;k<count;k++) w4(buf[k]); + case 2: + CMD(0xc8); w2(5); + for (k = 0; k < count; k++) + w4(buf[k]); + w2(4); + break; + case 3: + CMD(0xc8); w2(5); + for (k = 0; k < count / 2; k++) + w4w(((u16 *)buf)[k]); + w2(4); + break; + case 4: + CMD(0xc8); w2(5); + for (k = 0; k < count / 4; k++) + w4l(((u32 *)buf)[k]); w2(4); break; - - case 3: CMD(0xc8); w2(5); - for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]); - w2(4); - break; - - case 4: CMD(0xc8); w2(5); - for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]); - w2(4); - break; - } +} } static void friq_connect(struct pi_adapter *pi) - -{ pi->saved_r0 = r0(); - pi->saved_r2 = r2(); +{ + pi->saved_r0 = r0(); + pi->saved_r2 = r2(); w2(4); } static void friq_disconnect(struct pi_adapter *pi) - -{ CMD(0x20); +{ + CMD(0x20); w0(pi->saved_r0); - w2(pi->saved_r2); -} + w2(pi->saved_r2); +} static int friq_test_proto(struct pi_adapter *pi) - -{ int j, k, r; - int e[2] = {0,0}; +{ + int j, k, r; + int e[2] = { 0, 0 }; char scratch[512]; - pi->saved_r0 = r0(); + pi->saved_r0 = r0(); w0(0xff); udelay(20); CMD(0x3d); /* turn the power on */ udelay(500); w0(pi->saved_r0); friq_connect(pi); - for (j=0;j<2;j++) { - friq_write_regr(pi,0,6,0xa0+j*0x10); - for (k=0;k<256;k++) { - friq_write_regr(pi,0,2,k^0xaa); - friq_write_regr(pi,0,3,k^0x55); - if (friq_read_regr(pi,0,2) != (k^0xaa)) e[j]++; - } - } + for (j = 0; j < 2; j++) { + friq_write_regr(pi, 0, 6, 0xa0 + j * 0x10); + for (k = 0; k < 256; k++) { + friq_write_regr(pi, 0, 2, k ^ 0xaa); + friq_write_regr(pi, 0, 3, k ^ 0x55); + if (friq_read_regr(pi, 0, 2) != (k ^ 0xaa)) + e[j]++; + } + } friq_disconnect(pi); friq_connect(pi); - friq_read_block_int(pi,scratch,512,0x10); - r = 0; - for (k=0;k<128;k++) if (scratch[k] != k) r++; + friq_read_block_int(pi, scratch, 512, 0x10); + r = 0; + for (k = 0; k < 128; k++) { + if (scratch[k] != k) + r++; + } friq_disconnect(pi); - dev_dbg(&pi->dev, "friq: port 0x%x, mode %d, test=(%d,%d,%d)\n", - pi->port, pi->mode, e[0], e[1], r); + dev_dbg(&pi->dev, + "friq: port 0x%x, mode %d, test=(%d,%d,%d)\n", + pi->port, pi->mode, e[0], e[1], r); - return (r || (e[0] && e[1])); + return r || (e[0] && e[1]); } - static void friq_log_adapter(struct pi_adapter *pi) +{ + char *mode_string[6] = { "4-bit", "8-bit", "EPP-8", "EPP-16", "EPP-32"}; -{ char *mode_string[6] = {"4-bit","8-bit", - "EPP-8","EPP-16","EPP-32"}; - - dev_info(&pi->dev, "Freecom IQ ASIC-2 adapter at 0x%x, mode %d (%s), delay %d\n", - pi->port, pi->mode, mode_string[pi->mode], pi->delay); + dev_info(&pi->dev, + "Freecom IQ ASIC-2 adapter at 0x%x, mode %d (%s), delay %d\n", + pi->port, pi->mode, mode_string[pi->mode], pi->delay); pi->private = 1; friq_connect(pi); CMD(0x9e); /* disable sleep timer */ friq_disconnect(pi); - } static void friq_release_proto(struct pi_adapter *pi) diff --git a/drivers/ata/pata_parport/frpw.c b/drivers/ata/pata_parport/frpw.c index 3ec0abf16fa6..28d9bb2c6baf 100644 --- a/drivers/ata/pata_parport/frpw.c +++ b/drivers/ata/pata_parport/frpw.c @@ -1,17 +1,15 @@ -/* - frpw.c (c) 1996-8 Grant R. Guenther <grant@torque.net> - Under the terms of the GNU General Public License - - frpw.c is a low-level protocol driver for the Freecom "Power" - parallel port IDE adapter. - - Some applications of this adapter may require a "printer" reset - prior to loading the driver. This can be done by loading and - unloading the "lp" driver, or it can be done by this driver - if you define FRPW_HARD_RESET. The latter is not recommended - as it may upset devices on other ports. - -*/ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * (c) 1996-1998 Grant R. Guenther <grant@torque.net> + * + * frpw.c is a low-level protocol driver for the Freecom "Power" parallel port + * IDE adapter. + * + * Some applications of this adapter may require a "printer" reset prior to + * loading the driver. This can be done by loading and unloading the "lp" + * driver, or it can be done by this driver if you define FRPW_HARD_RESET. + * The latter is not recommended as it may upset devices on other ports. + */ #include <linux/module.h> #include <linux/init.h> @@ -25,15 +23,15 @@ #define cec4 w2(0xc);w2(0xe);w2(0xe);w2(0xc);w2(4);w2(4);w2(4); #define j44(l,h) (((l>>4)&0x0f)|(h&0xf0)) -/* cont = 0 - access the IDE register file - cont = 1 - access the IDE command set -*/ - +/* + * cont = 0 - access the IDE register file + * cont = 1 - access the IDE command set + */ static int cont_map[2] = { 0x08, 0x10 }; static int frpw_read_regr(struct pi_adapter *pi, int cont, int regr) - -{ int h,l,r; +{ + int h, l, r; r = regr + cont_map[cont]; @@ -41,145 +39,156 @@ static int frpw_read_regr(struct pi_adapter *pi, int cont, int regr) w0(r); cec4; w2(6); l = r1(); w2(4); h = r1(); - w2(4); - - return j44(l,h); + w2(4); + return j44(l, h); } static void frpw_write_regr(struct pi_adapter *pi, int cont, int regr, int val) +{ + int r = regr + cont_map[cont]; -{ int r; - - r = regr + cont_map[cont]; - - w2(4); w0(r); cec4; + w2(4); w0(r); cec4; w0(val); - w2(5);w2(7);w2(5);w2(4); + w2(5); w2(7); w2(5); w2(4); } -static void frpw_read_block_int(struct pi_adapter *pi, char *buf, int count, int regr) - -{ int h, l, k, ph; - - switch(pi->mode) { - - case 0: w2(4); w0(regr); cec4; - for (k=0;k<count;k++) { - w2(6); l = r1(); - w2(4); h = r1(); - buf[k] = j44(l,h); - } - w2(4); - break; - - case 1: ph = 2; - w2(4); w0(regr + 0xc0); cec4; - w0(0xff); - for (k=0;k<count;k++) { - w2(0xa4 + ph); - buf[k] = r0(); - ph = 2 - ph; - } - w2(0xac); w2(0xa4); w2(4); - break; - - case 2: w2(4); w0(regr + 0x80); cec4; - for (k=0;k<count;k++) buf[k] = r4(); - w2(0xac); w2(0xa4); - w2(4); - break; - - case 3: w2(4); w0(regr + 0x80); cec4; - for (k=0;k<count-2;k++) buf[k] = r4(); +static void frpw_read_block_int(struct pi_adapter *pi, char *buf, int count, + int regr) +{ + int h, l, k, ph; + + switch (pi->mode) { + case 0: + w2(4); w0(regr); cec4; + for (k = 0; k < count; k++) { + w2(6); l = r1(); + w2(4); h = r1(); + buf[k] = j44(l, h); + } + w2(4); + break; + + case 1: + ph = 2; + w2(4); w0(regr + 0xc0); cec4; + w0(0xff); + for (k = 0; k < count; k++) { + w2(0xa4 + ph); + buf[k] = r0(); + ph = 2 - ph; + } + w2(0xac); w2(0xa4); w2(4); + break; + + case 2: + w2(4); w0(regr + 0x80); cec4; + for (k = 0; k < count; k++) + buf[k] = r4(); w2(0xac); w2(0xa4); - buf[count-2] = r4(); - buf[count-1] = r4(); w2(4); break; - case 4: w2(4); w0(regr + 0x80); cec4; - for (k=0;k<(count/2)-1;k++) ((u16 *)buf)[k] = r4w(); - w2(0xac); w2(0xa4); - buf[count-2] = r4(); - buf[count-1] = r4(); - w2(4); - break; - - case 5: w2(4); w0(regr + 0x80); cec4; - for (k=0;k<(count/4)-1;k++) ((u32 *)buf)[k] = r4l(); - buf[count-4] = r4(); - buf[count-3] = r4(); - w2(0xac); w2(0xa4); - buf[count-2] = r4(); - buf[count-1] = r4(); - w2(4); - break; + case 3: + w2(4); w0(regr + 0x80); cec4; + for (k = 0; k < count - 2; k++) + buf[k] = r4(); + w2(0xac); w2(0xa4); + buf[count - 2] = r4(); + buf[count - 1] = r4(); + w2(4); + break; + + case 4: + w2(4); w0(regr + 0x80); cec4; + for (k = 0; k < count / 2 - 1; k++) + ((u16 *)buf)[k] = r4w(); + w2(0xac); w2(0xa4); + buf[count - 2] = r4(); + buf[count - 1] = r4(); + w2(4); + break; + case 5: + w2(4); w0(regr + 0x80); cec4; + for (k = 0; k < count / 4 - 1; k++) + ((u32 *)buf)[k] = r4l(); + buf[count - 4] = r4(); + buf[count - 3] = r4(); + w2(0xac); w2(0xa4); + buf[count - 2] = r4(); + buf[count - 1] = r4(); + w2(4); + break; } } static void frpw_read_block(struct pi_adapter *pi, char *buf, int count) - -{ frpw_read_block_int(pi,buf,count,0x08); +{ + frpw_read_block_int(pi, buf, count, 0x08); } static void frpw_write_block(struct pi_adapter *pi, char *buf, int count) - -{ int k; - - switch(pi->mode) { +{ + int k; + switch (pi->mode) { case 0: case 1: - case 2: w2(4); w0(8); cec4; w2(5); - for (k=0;k<count;k++) { + case 2: + w2(4); w0(8); cec4; w2(5); + for (k = 0; k < count; k++) { w0(buf[k]); - w2(7);w2(5); + w2(7); w2(5); } w2(4); break; - case 3: w2(4); w0(0xc8); cec4; w2(5); - for (k=0;k<count;k++) w4(buf[k]); + case 3: + w2(4); w0(0xc8); cec4; w2(5); + for (k = 0; k < count; k++) + w4(buf[k]); w2(4); break; - case 4: w2(4); w0(0xc8); cec4; w2(5); - for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]); - w2(4); - break; + case 4: + w2(4); w0(0xc8); cec4; w2(5); + for (k = 0; k < count / 2; k++) + w4w(((u16 *)buf)[k]); + w2(4); + break; - case 5: w2(4); w0(0xc8); cec4; w2(5); - for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]); - w2(4); - break; + case 5: + w2(4); w0(0xc8); cec4; w2(5); + for (k = 0; k < count / 4; k++) + w4l(((u32 *)buf)[k]); + w2(4); + break; } } static void frpw_connect(struct pi_adapter *pi) - -{ pi->saved_r0 = r0(); - pi->saved_r2 = r2(); +{ + pi->saved_r0 = r0(); + pi->saved_r2 = r2(); w2(4); } static void frpw_disconnect(struct pi_adapter *pi) - -{ w2(4); w0(0x20); cec4; +{ + w2(4); w0(0x20); cec4; w0(pi->saved_r0); - w2(pi->saved_r2); -} - -/* Stub logic to see if PNP string is available - used to distinguish - between the Xilinx and ASIC implementations of the Freecom adapter. -*/ + w2(pi->saved_r2); +} +/* + * Stub logic to see if PNP string is available - used to distinguish + * between the Xilinx and ASIC implementations of the Freecom adapter. + * returns chip_type: 0 = Xilinx, 1 = ASIC + */ static int frpw_test_pnp(struct pi_adapter *pi) - -/* returns chip_type: 0 = Xilinx, 1 = ASIC */ - -{ int olddelay, a, b; +{ + int olddelay, a, b; #ifdef FRPW_HARD_RESET w0(0); w2(8); udelay(50); w2(0xc); /* parallel bus reset */ @@ -191,7 +200,7 @@ static int frpw_test_pnp(struct pi_adapter *pi) pi->saved_r0 = r0(); pi->saved_r2 = r2(); - + w2(4); w0(4); w2(6); w2(7); a = r1() & 0xff; w2(4); b = r1() & 0xff; w2(0xc); w2(0xe); w2(4); @@ -200,65 +209,70 @@ static int frpw_test_pnp(struct pi_adapter *pi) w0(pi->saved_r0); w2(pi->saved_r2); - return ((~a&0x40) && (b&0x40)); -} - -/* We use the pi->private to remember the result of the PNP test. - To make this work, private = port*2 + chip. Yes, I know it's - a hack :-( -*/ + return ((~a & 0x40) && (b & 0x40)); +} +/* + * We use the pi->private to remember the result of the PNP test. + * To make this work, private = port*2 + chip. Yes, I know it's a hack :-( + */ static int frpw_test_proto(struct pi_adapter *pi) - -{ int j, k, r; - int e[2] = {0,0}; +{ + int j, k, r; + int e[2] = { 0, 0 }; char scratch[512]; - if ((pi->private>>1) != pi->port) - pi->private = frpw_test_pnp(pi) + 2*pi->port; + if ((pi->private >> 1) != pi->port) + pi->private = frpw_test_pnp(pi) + 2*pi->port; - if (((pi->private%2) == 0) && (pi->mode > 2)) { - dev_dbg(&pi->dev, "frpw: Xilinx does not support mode %d\n", pi->mode); - return 1; + if (((pi->private & 0x1) == 0) && (pi->mode > 2)) { + dev_dbg(&pi->dev, + "frpw: Xilinx does not support mode %d\n", pi->mode); + return 1; } - if (((pi->private%2) == 1) && (pi->mode == 2)) { + if (((pi->private & 0x1) == 1) && (pi->mode == 2)) { dev_dbg(&pi->dev, "frpw: ASIC does not support mode 2\n"); - return 1; + return 1; } frpw_connect(pi); - for (j=0;j<2;j++) { - frpw_write_regr(pi,0,6,0xa0+j*0x10); - for (k=0;k<256;k++) { - frpw_write_regr(pi,0,2,k^0xaa); - frpw_write_regr(pi,0,3,k^0x55); - if (frpw_read_regr(pi,0,2) != (k^0xaa)) e[j]++; - } - } + for (j = 0; j < 2; j++) { + frpw_write_regr(pi, 0, 6, 0xa0 + j * 0x10); + for (k = 0; k < 256; k++) { + frpw_write_regr(pi, 0, 2, k ^ 0xaa); + frpw_write_regr(pi, 0, 3, k ^ 0x55); + if (frpw_read_regr(pi, 0, 2) != (k ^ 0xaa)) + e[j]++; + } + } frpw_disconnect(pi); frpw_connect(pi); - frpw_read_block_int(pi,scratch,512,0x10); - r = 0; - for (k=0;k<128;k++) if (scratch[k] != k) r++; + frpw_read_block_int(pi, scratch, 512, 0x10); + r = 0; + for (k = 0; k < 128; k++) { + if (scratch[k] != k) + r++; + } frpw_disconnect(pi); - dev_dbg(&pi->dev, "frpw: port 0x%x, chip %ld, mode %d, test=(%d,%d,%d)\n", - pi->port, (pi->private%2), pi->mode, e[0], e[1], r); + dev_dbg(&pi->dev, + "frpw: port 0x%x, chip %ld, mode %d, test=(%d,%d,%d)\n", + pi->port, (pi->private%2), pi->mode, e[0], e[1], r); - return (r || (e[0] && e[1])); + return r || (e[0] && e[1]); } - static void frpw_log_adapter(struct pi_adapter *pi) -{ char *mode_string[6] = {"4-bit","8-bit","EPP", - "EPP-8","EPP-16","EPP-32"}; +{ + char *mode[6] = { "4-bit", "8-bit", "EPP", "EPP-8", "EPP-16", "EPP-32"}; - dev_info(&pi->dev, "Freecom (%s) adapter at 0x%x, mode %d (%s), delay %d\n", - ((pi->private % 2) == 0) ? "Xilinx" : "ASIC", - pi->port, pi->mode, mode_string[pi->mode], pi->delay); + dev_info(&pi->dev, + "Freecom (%s) adapter at 0x%x, mode %d (%s), delay %d\n", + ((pi->private & 0x1) == 0) ? "Xilinx" : "ASIC", + pi->port, pi->mode, mode[pi->mode], pi->delay); } static struct pi_protocol frpw = { diff --git a/drivers/ata/pata_parport/kbic.c b/drivers/ata/pata_parport/kbic.c index 8213e62f8f00..6023e071516d 100644 --- a/drivers/ata/pata_parport/kbic.c +++ b/drivers/ata/pata_parport/kbic.c @@ -1,16 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* - kbic.c (c) 1997-8 Grant R. Guenther <grant@torque.net> - Under the terms of the GNU General Public License. - - This is a low-level driver for the KBIC-951A and KBIC-971A - parallel to IDE adapter chips from KingByte Information Systems. - - The chips are almost identical, however, the wakeup code - required for the 971A interferes with the correct operation of - the 951A, so this driver registers itself twice, once for - each chip. - -*/ + * (c) 1997-1998 Grant R. Guenther <grant@torque.net> + * + * This is a low-level driver for the KBIC-951A and KBIC-971A + * parallel to IDE adapter chips from KingByte Information Systems. + * + * The chips are almost identical, however, the wakeup code + * required for the 971A interferes with the correct operation of + * the 951A, so this driver registers itself twice, once for + * each chip. + */ #include <linux/module.h> #include <linux/init.h> @@ -21,212 +20,223 @@ #include <asm/io.h> #include "pata_parport.h" -#define r12w() (delay_p,inw(pi->port+1)&0xffff) +#define r12w() (delay_p, inw(pi->port + 1) & 0xffff) -#define j44(a,b) ((((a>>4)&0x0f)|(b&0xf0))^0x88) -#define j53(w) (((w>>3)&0x1f)|((w>>4)&0xe0)) +#define j44(a, b) ((((a >> 4) & 0x0f) | (b & 0xf0)) ^ 0x88) +#define j53(w) (((w >> 3) & 0x1f) | ((w >> 4) & 0xe0)) -/* cont = 0 - access the IDE register file - cont = 1 - access the IDE command set -*/ - -static int cont_map[2] = { 0x80, 0x40 }; +/* + * cont = 0 - access the IDE register file + * cont = 1 - access the IDE command set + */ +static int cont_map[2] = { 0x80, 0x40 }; static int kbic_read_regr(struct pi_adapter *pi, int cont, int regr) +{ + int a, b, s; -{ int a, b, s; - - s = cont_map[cont]; + s = cont_map[cont]; switch (pi->mode) { - - case 0: w0(regr|0x18|s); w2(4); w2(6); w2(4); w2(1); w0(8); - a = r1(); w0(0x28); b = r1(); w2(4); - return j44(a,b); - - case 1: w0(regr|0x38|s); w2(4); w2(6); w2(4); w2(5); w0(8); + case 0: + w0(regr | 0x18 | s); w2(4); w2(6); w2(4); w2(1); w0(8); + a = r1(); w0(0x28); b = r1(); w2(4); + return j44(a, b); + case 1: + w0(regr|0x38 | s); w2(4); w2(6); w2(4); w2(5); w0(8); a = r12w(); w2(4); return j53(a); - - case 2: w0(regr|0x08|s); w2(4); w2(6); w2(4); w2(0xa5); w2(0xa1); + case 2: + w0(regr | 0x08 | s); w2(4); w2(6); w2(4); w2(0xa5); w2(0xa1); a = r0(); w2(4); - return a; - + return a; case 3: case 4: - case 5: w0(0x20|s); w2(4); w2(6); w2(4); w3(regr); + case 5: + w0(0x20 | s); w2(4); w2(6); w2(4); w3(regr); a = r4(); b = r4(); w2(4); w2(0); w2(4); return a; - } + return -1; -} +} static void kbic_write_regr(struct pi_adapter *pi, int cont, int regr, int val) +{ + int s = cont_map[cont]; -{ int s; - - s = cont_map[cont]; - - switch (pi->mode) { - - case 0: - case 1: - case 2: w0(regr|0x10|s); w2(4); w2(6); w2(4); + switch (pi->mode) { + case 0: + case 1: + case 2: + w0(regr | 0x10 | s); w2(4); w2(6); w2(4); w0(val); w2(5); w2(4); break; - case 3: case 4: - case 5: w0(0x20|s); w2(4); w2(6); w2(4); w3(regr); + case 5: + w0(0x20 | s); w2(4); w2(6); w2(4); w3(regr); w4(val); w4(val); w2(4); w2(0); w2(4); - break; - + break; } } static void k951_connect(struct pi_adapter *pi) - -{ pi->saved_r0 = r0(); - pi->saved_r2 = r2(); - w2(4); +{ + pi->saved_r0 = r0(); + pi->saved_r2 = r2(); + w2(4); } static void k951_disconnect(struct pi_adapter *pi) - -{ w0(pi->saved_r0); - w2(pi->saved_r2); +{ + w0(pi->saved_r0); + w2(pi->saved_r2); } -#define CCP(x) w2(0xc4);w0(0xaa);w0(0x55);w0(0);w0(0xff);w0(0x87);\ - w0(0x78);w0(x);w2(0xc5);w2(0xc4);w0(0xff); +#define CCP(x) \ + do { \ + w2(0xc4); w0(0xaa); w0(0x55); \ + w0(0); w0(0xff); w0(0x87); \ + w0(0x78); w0(x); w2(0xc5); \ + w2(0xc4); w0(0xff); \ + } while (0) static void k971_connect(struct pi_adapter *pi) - -{ pi->saved_r0 = r0(); - pi->saved_r2 = r2(); +{ + pi->saved_r0 = r0(); + pi->saved_r2 = r2(); CCP(0x20); - w2(4); + w2(4); } static void k971_disconnect(struct pi_adapter *pi) - -{ CCP(0x30); +{ + CCP(0x30); w0(pi->saved_r0); - w2(pi->saved_r2); + w2(pi->saved_r2); } -/* counts must be congruent to 0 MOD 4, but all known applications - have this property. -*/ - +/* + * count must be congruent to 0 MOD 4, but all known applications + *have this property. + */ static void kbic_read_block(struct pi_adapter *pi, char *buf, int count) +{ + int k, a, b; -{ int k, a, b; - - switch (pi->mode) { - - case 0: w0(0x98); w2(4); w2(6); w2(4); - for (k=0;k<count/2;k++) { - w2(1); w0(8); a = r1(); - w0(0x28); b = r1(); - buf[2*k] = j44(a,b); - w2(5); b = r1(); - w0(8); a = r1(); - buf[2*k+1] = j44(a,b); + switch (pi->mode) { + case 0: + w0(0x98); w2(4); w2(6); w2(4); + for (k = 0; k < count / 2; k++) { + w2(1); w0(8); + a = r1(); + w0(0x28); + b = r1(); + buf[2 * k] = j44(a, b); + w2(5); + b = r1(); + w0(8); + a = r1(); + buf[2 * k + 1] = j44(a, b); w2(4); - } - break; - - case 1: w0(0xb8); w2(4); w2(6); w2(4); - for (k=0;k<count/4;k++) { - w0(0xb8); - w2(4); w2(5); - w0(8); buf[4*k] = j53(r12w()); - w0(0xb8); buf[4*k+1] = j53(r12w()); + } + break; + case 1: + w0(0xb8); w2(4); w2(6); w2(4); + for (k = 0; k < count / 4; k++) { + w0(0xb8); w2(4); w2(5); - buf[4*k+3] = j53(r12w()); - w0(8); buf[4*k+2] = j53(r12w()); - } - w2(4); - break; - - case 2: w0(0x88); w2(4); w2(6); w2(4); - for (k=0;k<count/2;k++) { - w2(0xa0); w2(0xa1); buf[2*k] = r0(); - w2(0xa5); buf[2*k+1] = r0(); - } - w2(4); - break; - - case 3: w0(0xa0); w2(4); w2(6); w2(4); w3(0); - for (k=0;k<count;k++) buf[k] = r4(); - w2(4); w2(0); w2(4); - break; - - case 4: w0(0xa0); w2(4); w2(6); w2(4); w3(0); - for (k=0;k<count/2;k++) ((u16 *)buf)[k] = r4w(); - w2(4); w2(0); w2(4); - break; - - case 5: w0(0xa0); w2(4); w2(6); w2(4); w3(0); - for (k=0;k<count/4;k++) ((u32 *)buf)[k] = r4l(); - w2(4); w2(0); w2(4); - break; - - - } + w0(8); + buf[4 * k] = j53(r12w()); + w0(0xb8); + buf[4 * k + 1] = j53(r12w()); + w2(4); w2(5); + buf[4 * k + 3] = j53(r12w()); + w0(8); + buf[4 * k + 2] = j53(r12w()); + } + w2(4); + break; + case 2: + w0(0x88); w2(4); w2(6); w2(4); + for (k = 0; k < count / 2; k++) { + w2(0xa0); w2(0xa1); + buf[2 * k] = r0(); + w2(0xa5); + buf[2 * k + 1] = r0(); + } + w2(4); + break; + case 3: + w0(0xa0); w2(4); w2(6); w2(4); w3(0); + for (k = 0; k < count; k++) + buf[k] = r4(); + w2(4); w2(0); w2(4); + break; + case 4: + w0(0xa0); w2(4); w2(6); w2(4); w3(0); + for (k = 0; k < count / 2; k++) + ((u16 *)buf)[k] = r4w(); + w2(4); w2(0); w2(4); + break; + case 5: + w0(0xa0); w2(4); w2(6); w2(4); w3(0); + for (k = 0; k < count / 4; k++) + ((u32 *)buf)[k] = r4l(); + w2(4); w2(0); w2(4); + break; + } } static void kbic_write_block(struct pi_adapter *pi, char *buf, int count) +{ + int k; -{ int k; - - switch (pi->mode) { - - case 0: - case 1: - case 2: w0(0x90); w2(4); w2(6); w2(4); - for(k=0;k<count/2;k++) { - w0(buf[2*k+1]); w2(0); w2(4); - w0(buf[2*k]); w2(5); w2(4); + switch (pi->mode) { + case 0: + case 1: + case 2: + w0(0x90); w2(4); w2(6); w2(4); + for (k = 0; k < count / 2; k++) { + w0(buf[2 * k + 1]); + w2(0); w2(4); + w0(buf[2 * k]); + w2(5); w2(4); } break; - - case 3: w0(0xa0); w2(4); w2(6); w2(4); w3(0); - for(k=0;k<count/2;k++) { - w4(buf[2*k+1]); - w4(buf[2*k]); - } + case 3: + w0(0xa0); w2(4); w2(6); w2(4); w3(0); + for (k = 0; k < count / 2; k++) { + w4(buf[2 * k + 1]); + w4(buf[2 * k]); + } w2(4); w2(0); w2(4); break; - - case 4: w0(0xa0); w2(4); w2(6); w2(4); w3(0); + case 4: + w0(0xa0); w2(4); w2(6); w2(4); w3(0); for (k = 0; k < count / 2; k++) w4w(swab16(((u16 *)buf)[k])); - w2(4); w2(0); w2(4); - break; - - case 5: w0(0xa0); w2(4); w2(6); w2(4); w3(0); + w2(4); w2(0); w2(4); + break; + case 5: + w0(0xa0); w2(4); w2(6); w2(4); w3(0); for (k = 0; k < count / 4; k++) w4l(swab16(((u16 *)buf)[2 * k]) | swab16(((u16 *)buf)[2 * k + 1]) << 16); - w2(4); w2(0); w2(4); - break; - - } - + w2(4); w2(0); w2(4); + break; + } } static void kbic_log_adapter(struct pi_adapter *pi, char *chip) - -{ char *mode_string[6] = {"4-bit","5/3","8-bit", - "EPP-8","EPP_16","EPP-32"}; +{ + char *mode[6] = { "4-bit", "5/3", "8-bit", "EPP-8", "EPP_16", "EPP-32"}; dev_info(&pi->dev, "KingByte %s at 0x%x, mode %d (%s), delay %d\n", - chip, pi->port, pi->mode, mode_string[pi->mode], pi->delay); + chip, pi->port, pi->mode, mode[pi->mode], pi->delay); } static void k951_log_adapter(struct pi_adapter *pi) diff --git a/drivers/ata/pata_parport/ktti.c b/drivers/ata/pata_parport/ktti.c index 4890b1f12348..bca6c20ef617 100644 --- a/drivers/ata/pata_parport/ktti.c +++ b/drivers/ata/pata_parport/ktti.c @@ -1,12 +1,11 @@ -/* - ktti.c (c) 1998 Grant R. Guenther <grant@torque.net> - Under the terms of the GNU General Public License. - - ktti.c is a low-level protocol driver for the KT Technology - parallel port adapter. This adapter is used in the "PHd" - portable hard-drives. As far as I can tell, this device - supports 4-bit mode _only_. - +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * (c) 1998 Grant R. Guenther <grant@torque.net> + * + * ktti.c is a low-level protocol driver for the KT Technology + * parallel port adapter. This adapter is used in the "PHd" + * portable hard-drives. As far as I can tell, this device + * supports 4-bit mode _only_. */ #include <linux/module.h> @@ -18,80 +17,76 @@ #include <asm/io.h> #include "pata_parport.h" -#define j44(a,b) (((a>>4)&0x0f)|(b&0xf0)) +#define j44(a, b) (((a >> 4) & 0x0f) | (b & 0xf0)) -/* cont = 0 - access the IDE register file - cont = 1 - access the IDE command set -*/ - -static int cont_map[2] = { 0x10, 0x08 }; +/* + * cont = 0 - access the IDE register file + * cont = 1 - access the IDE command set + */ +static int cont_map[2] = { 0x10, 0x08 }; static void ktti_write_regr(struct pi_adapter *pi, int cont, int regr, int val) +{ + int r = regr + cont_map[cont]; -{ int r; - - r = regr + cont_map[cont]; - - w0(r); w2(0xb); w2(0xa); w2(3); w2(6); + w0(r); w2(0xb); w2(0xa); w2(3); w2(6); w0(val); w2(3); w0(0); w2(6); w2(0xb); } static int ktti_read_regr(struct pi_adapter *pi, int cont, int regr) - -{ int a, b, r; +{ + int a, b, r; r = regr + cont_map[cont]; - w0(r); w2(0xb); w2(0xa); w2(9); w2(0xc); w2(9); + w0(r); w2(0xb); w2(0xa); w2(9); w2(0xc); w2(9); a = r1(); w2(0xc); b = r1(); w2(9); w2(0xc); w2(9); - return j44(a,b); - + return j44(a, b); } static void ktti_read_block(struct pi_adapter *pi, char *buf, int count) +{ + int k, a, b; -{ int k, a, b; - - for (k=0;k<count/2;k++) { + for (k = 0; k < count / 2; k++) { w0(0x10); w2(0xb); w2(0xa); w2(9); w2(0xc); w2(9); a = r1(); w2(0xc); b = r1(); w2(9); - buf[2*k] = j44(a,b); + buf[2*k] = j44(a, b); a = r1(); w2(0xc); b = r1(); w2(9); - buf[2*k+1] = j44(a,b); + buf[2*k+1] = j44(a, b); } } static void ktti_write_block(struct pi_adapter *pi, char *buf, int count) +{ + int k; -{ int k; - - for (k=0;k<count/2;k++) { + for (k = 0; k < count / 2; k++) { w0(0x10); w2(0xb); w2(0xa); w2(3); w2(6); - w0(buf[2*k]); w2(3); - w0(buf[2*k+1]); w2(6); + w0(buf[2 * k]); w2(3); + w0(buf[2 * k + 1]); w2(6); w2(0xb); } } static void ktti_connect(struct pi_adapter *pi) - -{ pi->saved_r0 = r0(); - pi->saved_r2 = r2(); - w2(0xb); w2(0xa); w0(0); w2(3); w2(6); +{ + pi->saved_r0 = r0(); + pi->saved_r2 = r2(); + w2(0xb); w2(0xa); w0(0); w2(3); w2(6); } static void ktti_disconnect(struct pi_adapter *pi) - -{ w2(0xb); w2(0xa); w0(0xa0); w2(3); w2(4); +{ + w2(0xb); w2(0xa); w0(0xa0); w2(3); w2(4); w0(pi->saved_r0); - w2(pi->saved_r2); -} + w2(pi->saved_r2); +} static void ktti_log_adapter(struct pi_adapter *pi) - { dev_info(&pi->dev, "KT adapter at 0x%x, delay %d\n", - pi->port, pi->delay); + pi->port, pi->delay); } static struct pi_protocol ktti = { diff --git a/drivers/ata/pata_parport/on20.c b/drivers/ata/pata_parport/on20.c index 276ace12d490..34e69da2bec8 100644 --- a/drivers/ata/pata_parport/on20.c +++ b/drivers/ata/pata_parport/on20.c @@ -1,10 +1,10 @@ -/* - on20.c (c) 1996-8 Grant R. Guenther <grant@torque.net> - Under the terms of the GNU General Public License. - - on20.c is a low-level protocol driver for the - Onspec 90c20 parallel to IDE adapter. -*/ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * (c) 1996-1998 Grant R. Guenther <grant@torque.net> + * + * on20.c is a low-level protocol driver for the + * Onspec 90c20 parallel to IDE adapter. + */ #include <linux/module.h> #include <linux/init.h> @@ -15,99 +15,114 @@ #include <asm/io.h> #include "pata_parport.h" -#define op(f) w2(4);w0(f);w2(5);w2(0xd);w2(5);w2(0xd);w2(5);w2(4); -#define vl(v) w2(4);w0(v);w2(5);w2(7);w2(5);w2(4); - -#define j44(a,b) (((a>>4)&0x0f)|(b&0xf0)) - -/* cont = 0 - access the IDE register file - cont = 1 - access the IDE command set -*/ - -static int on20_read_regr(struct pi_adapter *pi, int cont, int regr) - -{ int h,l, r ; +#define op(f) \ + do { \ + w2(4); w0(f); w2(5); w2(0xd); \ + w2(5); w2(0xd); w2(5); w2(4); \ + } while (0) - r = (regr<<2) + 1 + cont; +#define vl(v) \ + do { \ + w2(4); w0(v); w2(5); \ + w2(7); w2(5); w2(4); \ + } while (0) - op(1); vl(r); op(0); +#define j44(a, b) (((a >> 4) & 0x0f) | (b & 0xf0)) - switch (pi->mode) { - - case 0: w2(4); w2(6); l = r1(); - w2(4); w2(6); h = r1(); - w2(4); w2(6); w2(4); w2(6); w2(4); - return j44(l,h); - - case 1: w2(4); w2(0x26); r = r0(); - w2(4); w2(0x26); w2(4); - return r; +/* + * cont = 0 - access the IDE register file + * cont = 1 - access the IDE command set + */ +static int on20_read_regr(struct pi_adapter *pi, int cont, int regr) +{ + int h, l, r; + + r = (regr << 2) + 1 + cont; + + op(1); vl(r); op(0); + + switch (pi->mode) { + case 0: + w2(4); w2(6); l = r1(); + w2(4); w2(6); h = r1(); + w2(4); w2(6); w2(4); w2(6); w2(4); + return j44(l, h); + case 1: + w2(4); w2(0x26); r = r0(); + w2(4); w2(0x26); w2(4); + return r; } + return -1; -} +} static void on20_write_regr(struct pi_adapter *pi, int cont, int regr, int val) +{ + int r = (regr << 2) + 1 + cont; -{ int r; - - r = (regr<<2) + 1 + cont; - - op(1); vl(r); - op(0); vl(val); + op(1); vl(r); + op(0); vl(val); op(0); vl(val); } static void on20_connect(struct pi_adapter *pi) - -{ pi->saved_r0 = r0(); - pi->saved_r2 = r2(); - - w2(4);w0(0);w2(0xc);w2(4);w2(6);w2(4);w2(6);w2(4); - if (pi->mode) { op(2); vl(8); op(2); vl(9); } - else { op(2); vl(0); op(2); vl(8); } +{ + pi->saved_r0 = r0(); + pi->saved_r2 = r2(); + + w2(4); w0(0); w2(0xc); w2(4); w2(6); w2(4); w2(6); w2(4); + if (pi->mode) { + op(2); vl(8); op(2); vl(9); + } else { + op(2); vl(0); op(2); vl(8); + } } static void on20_disconnect(struct pi_adapter *pi) - -{ w2(4);w0(7);w2(4);w2(0xc);w2(4); - w0(pi->saved_r0); - w2(pi->saved_r2); -} +{ + w2(4); w0(7); w2(4); w2(0xc); w2(4); + w0(pi->saved_r0); + w2(pi->saved_r2); +} static void on20_read_block(struct pi_adapter *pi, char *buf, int count) - -{ int k, l, h; +{ + int k, l, h; op(1); vl(1); op(0); - for (k=0;k<count;k++) - if (pi->mode) { - w2(4); w2(0x26); buf[k] = r0(); - } else { - w2(6); l = r1(); w2(4); - w2(6); h = r1(); w2(4); - buf[k] = j44(l,h); - } + for (k = 0; k < count; k++) { + if (pi->mode) { + w2(4); w2(0x26); buf[k] = r0(); + } else { + w2(6); l = r1(); w2(4); + w2(6); h = r1(); w2(4); + buf[k] = j44(l, h); + } + } w2(4); } static void on20_write_block(struct pi_adapter *pi, char *buf, int count) - -{ int k; +{ + int k; op(1); vl(1); op(0); - for (k=0;k<count;k++) { w2(5); w0(buf[k]); w2(7); } + for (k = 0; k < count; k++) { + w2(5); w0(buf[k]); w2(7); + } w2(4); } static void on20_log_adapter(struct pi_adapter *pi) +{ + char *mode_string[2] = { "4-bit", "8-bit" }; -{ char *mode_string[2] = {"4-bit","8-bit"}; - - dev_info(&pi->dev, "OnSpec 90c20 at 0x%x, mode %d (%s), delay %d\n", - pi->port, pi->mode, mode_string[pi->mode], pi->delay); + dev_info(&pi->dev, + "OnSpec 90c20 at 0x%x, mode %d (%s), delay %d\n", + pi->port, pi->mode, mode_string[pi->mode], pi->delay); } static struct pi_protocol on20 = { diff --git a/drivers/ata/pata_parport/on26.c b/drivers/ata/pata_parport/on26.c index dc47a54b121f..5da317b394c1 100644 --- a/drivers/ata/pata_parport/on26.c +++ b/drivers/ata/pata_parport/on26.c @@ -1,11 +1,10 @@ -/* - on26.c (c) 1997-8 Grant R. Guenther <grant@torque.net> - Under the terms of the GNU General Public License. - - on26.c is a low-level protocol driver for the - OnSpec 90c26 parallel to IDE adapter chip. - -*/ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * (c) 1997-1998 Grant R. Guenther <grant@torque.net> + * + * on26.c is a low-level protocol driver for the + * OnSpec 90c26 parallel to IDE adapter chip. + */ #include <linux/module.h> #include <linux/init.h> @@ -16,260 +15,281 @@ #include <asm/io.h> #include "pata_parport.h" -/* mode codes: 0 nybble reads, 8-bit writes - 1 8-bit reads and writes - 2 8-bit EPP mode - 3 EPP-16 - 4 EPP-32 -*/ +/* + * mode codes: 0 nybble reads, 8-bit writes + * 1 8-bit reads and writes + * 2 8-bit EPP mode + * 3 EPP-16 + * 4 EPP-32 + */ -#define j44(a,b) (((a>>4)&0x0f)|(b&0xf0)) +#define j44(a, b) (((a >> 4) & 0x0f) | (b & 0xf0)) -#define P1 w2(5);w2(0xd);w2(5);w2(0xd);w2(5);w2(4); -#define P2 w2(5);w2(7);w2(5);w2(4); +#define P1 \ + do { \ + w2(5); w2(0xd); w2(5); w2(0xd); w2(5); w2(4); \ + } while (0) -/* cont = 0 - access the IDE register file - cont = 1 - access the IDE command set -*/ - -static int on26_read_regr(struct pi_adapter *pi, int cont, int regr) +#define P2 \ + do { \ + w2(5); w2(7); w2(5); w2(4); \ + } while (0) -{ int a, b, r; +/* + * cont = 0 - access the IDE register file + * cont = 1 - access the IDE command set + */ - r = (regr<<2) + 1 + cont; +static int on26_read_regr(struct pi_adapter *pi, int cont, int regr) +{ + int a, b, r; - switch (pi->mode) { + r = (regr << 2) + 1 + cont; - case 0: w0(1); P1; w0(r); P2; w0(0); P1; + switch (pi->mode) { + case 0: + w0(1); P1; w0(r); P2; w0(0); P1; w2(6); a = r1(); w2(4); w2(6); b = r1(); w2(4); w2(6); w2(4); w2(6); w2(4); - return j44(a,b); - - case 1: w0(1); P1; w0(r); P2; w0(0); P1; + return j44(a, b); + case 1: + w0(1); P1; w0(r); P2; w0(0); P1; w2(0x26); a = r0(); w2(4); w2(0x26); w2(4); - return a; - + return a; case 2: case 3: - case 4: w3(1); w3(1); w2(5); w4(r); w2(4); + case 4: + w3(1); w3(1); w2(5); w4(r); w2(4); w3(0); w3(0); w2(0x24); a = r4(); w2(4); w2(0x24); (void)r4(); w2(4); - return a; + return a; + } - } - return -1; -} + return -1; +} static void on26_write_regr(struct pi_adapter *pi, int cont, int regr, int val) +{ + int r = (regr << 2) + 1 + cont; -{ int r; - - r = (regr<<2) + 1 + cont; - - switch (pi->mode) { - - case 0: - case 1: w0(1); P1; w0(r); P2; w0(0); P1; + switch (pi->mode) { + case 0: + case 1: + w0(1); P1; w0(r); P2; w0(0); P1; w0(val); P2; w0(val); P2; break; - case 2: case 3: - case 4: w3(1); w3(1); w2(5); w4(r); w2(4); - w3(0); w3(0); + case 4: + w3(1); w3(1); w2(5); w4(r); w2(4); + w3(0); w3(0); w2(5); w4(val); w2(4); w2(5); w4(val); w2(4); - break; - } + break; + } } -#define CCP(x) w0(0xfe);w0(0xaa);w0(0x55);w0(0);w0(0xff);\ - w0(0x87);w0(0x78);w0(x);w2(4);w2(5);w2(4);w0(0xff); +#define CCP(x) \ + do { \ + w0(0xfe); w0(0xaa); w0(0x55); w0(0); \ + w0(0xff); w0(0x87); w0(0x78); w0(x); \ + w2(4); w2(5); w2(4); w0(0xff); \ + } while (0) static void on26_connect(struct pi_adapter *pi) - -{ int x; +{ + int x; pi->saved_r0 = r0(); - pi->saved_r2 = r2(); + pi->saved_r2 = r2(); - CCP(0x20); - x = 8; if (pi->mode) x = 9; + CCP(0x20); + if (pi->mode) + x = 9; + else + x = 8; w0(2); P1; w0(8); P2; w0(2); P1; w0(x); P2; } static void on26_disconnect(struct pi_adapter *pi) - -{ if (pi->mode >= 2) { w3(4); w3(4); w3(4); w3(4); } - else { w0(4); P1; w0(4); P1; } +{ + if (pi->mode >= 2) { + w3(4); w3(4); w3(4); w3(4); + } else { + w0(4); P1; w0(4); P1; + } CCP(0x30); - w0(pi->saved_r0); - w2(pi->saved_r2); -} + w0(pi->saved_r0); + w2(pi->saved_r2); +} #define RESET_WAIT 200 -static int on26_test_port(struct pi_adapter *pi) /* hard reset */ +/* hard reset */ +static int on26_test_port(struct pi_adapter *pi) +{ + int i, m, d, x = 0, y = 0; -{ int i, m, d, x=0, y=0; - - pi->saved_r0 = r0(); - pi->saved_r2 = r2(); - - d = pi->delay; - m = pi->mode; - pi->delay = 5; - pi->mode = 0; - - w2(0xc); - - CCP(0x30); CCP(0); - - w0(0xfe);w0(0xaa);w0(0x55);w0(0);w0(0xff); - i = ((r1() & 0xf0) << 4); w0(0x87); - i |= (r1() & 0xf0); w0(0x78); - w0(0x20);w2(4);w2(5); - i |= ((r1() & 0xf0) >> 4); - w2(4);w0(0xff); - - if (i == 0xb5f) { - - w0(2); P1; w0(0); P2; - w0(3); P1; w0(0); P2; - w0(2); P1; w0(8); P2; udelay(100); - w0(2); P1; w0(0xa); P2; udelay(100); - w0(2); P1; w0(8); P2; udelay(1000); - - on26_write_regr(pi,0,6,0xa0); - - for (i=0;i<RESET_WAIT;i++) { - on26_write_regr(pi,0,6,0xa0); - x = on26_read_regr(pi,0,7); - on26_write_regr(pi,0,6,0xb0); - y = on26_read_regr(pi,0,7); - if (!((x&0x80)||(y&0x80))) break; - mdelay(100); - } - - if (i == RESET_WAIT) - dev_err(&pi->dev, "on26: Device reset failed (%x,%x)\n", x, y); - - w0(4); P1; w0(4); P1; - } + pi->saved_r0 = r0(); + pi->saved_r2 = r2(); + + d = pi->delay; + m = pi->mode; + pi->delay = 5; + pi->mode = 0; + + w2(0xc); + + CCP(0x30); CCP(0); + + w0(0xfe); w0(0xaa); w0(0x55); w0(0); w0(0xff); + i = ((r1() & 0xf0) << 4); w0(0x87); + i |= (r1() & 0xf0); w0(0x78); + w0(0x20); w2(4); w2(5); + i |= ((r1() & 0xf0) >> 4); + w2(4); w0(0xff); + + if (i == 0xb5f) { + w0(2); P1; w0(0); P2; + w0(3); P1; w0(0); P2; + w0(2); P1; w0(8); P2; udelay(100); + w0(2); P1; w0(0xa); P2; udelay(100); + w0(2); P1; w0(8); P2; udelay(1000); + + on26_write_regr(pi, 0, 6, 0xa0); + + for (i = 0; i < RESET_WAIT; i++) { + on26_write_regr(pi, 0, 6, 0xa0); + x = on26_read_regr(pi, 0, 7); + on26_write_regr(pi, 0, 6, 0xb0); + y = on26_read_regr(pi, 0, 7); + if (!((x & 0x80) || (y & 0x80))) + break; + mdelay(100); + } + + if (i == RESET_WAIT) + dev_err(&pi->dev, + "on26: Device reset failed (%x,%x)\n", x, y); + + w0(4); P1; w0(4); P1; + } - CCP(0x30); + CCP(0x30); - pi->delay = d; - pi->mode = m; - w0(pi->saved_r0); - w2(pi->saved_r2); + pi->delay = d; + pi->mode = m; + w0(pi->saved_r0); + w2(pi->saved_r2); - return 5; + return 5; } - static void on26_read_block(struct pi_adapter *pi, char *buf, int count) +{ + int k, a, b; -{ int k, a, b; - - switch (pi->mode) { - - case 0: w0(1); P1; w0(1); P2; w0(2); P1; w0(0x18); P2; w0(0); P1; + switch (pi->mode) { + case 0: + w0(1); P1; w0(1); P2; w0(2); P1; w0(0x18); P2; w0(0); P1; udelay(10); - for (k=0;k<count;k++) { - w2(6); a = r1(); - w2(4); b = r1(); - buf[k] = j44(a,b); - } - w0(2); P1; w0(8); P2; - break; - - case 1: w0(1); P1; w0(1); P2; w0(2); P1; w0(0x19); P2; w0(0); P1; + for (k = 0; k < count; k++) { + w2(6); a = r1(); + w2(4); b = r1(); + buf[k] = j44(a, b); + } + w0(2); P1; w0(8); P2; + break; + case 1: + w0(1); P1; w0(1); P2; w0(2); P1; w0(0x19); P2; w0(0); P1; + udelay(10); + for (k = 0; k < count / 2; k++) { + w2(0x26); buf[2 * k] = r0(); + w2(0x24); buf[2 * k + 1] = r0(); + } + w0(2); P1; w0(9); P2; + break; + case 2: + w3(1); w3(1); w2(5); w4(1); w2(4); + w3(0); w3(0); w2(0x24); + udelay(10); + for (k = 0; k < count; k++) + buf[k] = r4(); + w2(4); + break; + case 3: + w3(1); w3(1); w2(5); w4(1); w2(4); + w3(0); w3(0); w2(0x24); udelay(10); - for (k=0;k<count/2;k++) { - w2(0x26); buf[2*k] = r0(); - w2(0x24); buf[2*k+1] = r0(); - } - w0(2); P1; w0(9); P2; - break; - - case 2: w3(1); w3(1); w2(5); w4(1); w2(4); + for (k = 0; k < count / 2; k++) + ((u16 *)buf)[k] = r4w(); + w2(4); + break; + case 4: + w3(1); w3(1); w2(5); w4(1); w2(4); w3(0); w3(0); w2(0x24); udelay(10); - for (k=0;k<count;k++) buf[k] = r4(); - w2(4); - break; - - case 3: w3(1); w3(1); w2(5); w4(1); w2(4); - w3(0); w3(0); w2(0x24); - udelay(10); - for (k=0;k<count/2;k++) ((u16 *)buf)[k] = r4w(); - w2(4); - break; - - case 4: w3(1); w3(1); w2(5); w4(1); w2(4); - w3(0); w3(0); w2(0x24); - udelay(10); - for (k=0;k<count/4;k++) ((u32 *)buf)[k] = r4l(); - w2(4); - break; - - } + for (k = 0; k < count / 4; k++) + ((u32 *)buf)[k] = r4l(); + w2(4); + break; + } } static void on26_write_block(struct pi_adapter *pi, char *buf, int count) - -{ int k; - - switch (pi->mode) { - - case 0: - case 1: w0(1); P1; w0(1); P2; - w0(2); P1; w0(0x18+pi->mode); P2; w0(0); P1; +{ + int k; + + switch (pi->mode) { + case 0: + case 1: + w0(1); P1; w0(1); P2; + w0(2); P1; w0(0x18 + pi->mode); P2; w0(0); P1; udelay(10); - for (k=0;k<count/2;k++) { - w2(5); w0(buf[2*k]); - w2(7); w0(buf[2*k+1]); - } - w2(5); w2(4); - w0(2); P1; w0(8+pi->mode); P2; - break; - - case 2: w3(1); w3(1); w2(5); w4(1); w2(4); + for (k = 0; k < count / 2; k++) { + w2(5); w0(buf[2 * k]); + w2(7); w0(buf[2 * k + 1]); + } + w2(5); w2(4); + w0(2); P1; w0(8 + pi->mode); P2; + break; + case 2: + w3(1); w3(1); w2(5); w4(1); w2(4); w3(0); w3(0); w2(0xc5); udelay(10); - for (k=0;k<count;k++) w4(buf[k]); + for (k = 0; k < count; k++) + w4(buf[k]); w2(0xc4); - break; - - case 3: w3(1); w3(1); w2(5); w4(1); w2(4); - w3(0); w3(0); w2(0xc5); - udelay(10); - for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]); - w2(0xc4); - break; - - case 4: w3(1); w3(1); w2(5); w4(1); w2(4); - w3(0); w3(0); w2(0xc5); - udelay(10); - for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]); - w2(0xc4); - break; - - } - + break; + case 3: + w3(1); w3(1); w2(5); w4(1); w2(4); + w3(0); w3(0); w2(0xc5); + udelay(10); + for (k = 0; k < count / 2; k++) + w4w(((u16 *)buf)[k]); + w2(0xc4); + break; + case 4: + w3(1); w3(1); w2(5); w4(1); w2(4); + w3(0); w3(0); w2(0xc5); + udelay(10); + for (k = 0; k < count / 4; k++) + w4l(((u32 *)buf)[k]); + w2(0xc4); + break; + } } static void on26_log_adapter(struct pi_adapter *pi) +{ + char *mode_string[5] = { "4-bit", "8-bit", "EPP-8", "EPP-16", "EPP-32" }; -{ char *mode_string[5] = {"4-bit","8-bit","EPP-8", - "EPP-16","EPP-32"}; - - dev_info(&pi->dev, "OnSpec 90c26 at 0x%x, mode %d (%s), delay %d\n", - pi->port, pi->mode, mode_string[pi->mode], pi->delay); + dev_info(&pi->dev, + "OnSpec 90c26 at 0x%x, mode %d (%s), delay %d\n", + pi->port, pi->mode, mode_string[pi->mode], pi->delay); } static struct pi_protocol on26 = { diff --git a/drivers/ata/pata_platform.c b/drivers/ata/pata_platform.c index 87479bc893b2..232c3dad7ee8 100644 --- a/drivers/ata/pata_platform.c +++ b/drivers/ata/pata_platform.c @@ -223,7 +223,7 @@ static int pata_platform_probe(struct platform_device *pdev) static struct platform_driver pata_platform_driver = { .probe = pata_platform_probe, - .remove = ata_platform_remove_one, + .remove_new = ata_platform_remove_one, .driver = { .name = DRV_NAME, }, diff --git a/drivers/ata/sata_highbank.c b/drivers/ata/sata_highbank.c index 8237ece4a46f..d6b324d03e59 100644 --- a/drivers/ata/sata_highbank.c +++ b/drivers/ata/sata_highbank.c @@ -614,7 +614,7 @@ static SIMPLE_DEV_PM_OPS(ahci_highbank_pm_ops, ahci_highbank_suspend, ahci_highbank_resume); static struct platform_driver ahci_highbank_driver = { - .remove = ata_platform_remove_one, + .remove_new = ata_platform_remove_one, .driver = { .name = "highbank-ahci", .of_match_table = ahci_of_match, diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c index c47c3fb434d5..598a872f6a08 100644 --- a/drivers/ata/sata_svw.c +++ b/drivers/ata/sata_svw.c @@ -32,6 +32,7 @@ #include <scsi/scsi.h> #include <linux/libata.h> #include <linux/of.h> +#include <linux/of_address.h> #define DRV_NAME "sata_svw" #define DRV_VERSION "2.3" @@ -319,10 +320,11 @@ static int k2_sata_show_info(struct seq_file *m, struct Scsi_Host *shost) /* Match it to a port node */ index = (ap == ap->host->ports[0]) ? 0 : 1; for (np = np->child; np != NULL; np = np->sibling) { - const u32 *reg = of_get_property(np, "reg", NULL); - if (!reg) + u64 reg; + + if (of_property_read_reg(np, 0, ®, NULL)) continue; - if (index == *reg) { + if (index == reg) { seq_printf(m, "devspec: %pOF\n", np); break; } |